728x90

정의

데이터베이스에 전송되는 SQL 쿼리문을 조작하여 데이터를 변조하거나 허가되지 않은 정보에 접근

 

실습

Low 단계

 

첫번째 방법(전체 데이터 조회)

id에 1' or '1'='1 을 입력하면 데이터베이스에 저장된 전체 데이터가 조회된다.

MySQL의 주석문자를 이용해서 1' or 1=1 #을 입력해도 같은 결과가 나온다.

 

두번째 방법(칼럼 개수 찾기)

order by 문법을 사용해서도 알 수 있다. order by는 정렬할때 사용한다. 첫번째 칼럼을 기준으로 정렬하면 order by 1이다. 적용해보면 order by 3부터 에러가 뜬다. 즉, 해당 테이블에 두 개의 칼럼을 조회하고 있음을 알 수 있다.

 

세번째 방법

union 연산자를 사용할 수 있다. union 연산자는 집합 연산자로 합집합을 의미한다. 중복 데이터는 제거한다.

union 연산자를 사용하려면 union 앞의 select 문과 뒤의 select 문의 칼럼 개수가 같아야한다.

1' union select 1,1#을 입력했을때 에러없이 결과가 나온다. 즉, 해당 테이블에 두 개의 칼럼을 조회하고 있음을 알 수 있다.

union 연산자를 이용한 공격 코드는 다음과 같다.

https://github.com/SecuAcademy/webhacking/blob/master/SQL%EC%9D%B8%EC%A0%9D%EC%85%98%EC%8B%A4%EC%8A%B5.txt

 

GitHub - SecuAcademy/webhacking: '화이트해커가 되기 위한 8가지 웹 해킹 기술' 강의자료

'화이트해커가 되기 위한 8가지 웹 해킹 기술' 강의자료. Contribute to SecuAcademy/webhacking development by creating an account on GitHub.

github.com

MySQL에는 information_schema라는 데이터베이스가 있다. 모든 테이블과 칼럼에 대한 정보를 가진 데이터베이스다. 이를 이용하여 정보를 찾는다.

위 링크의 데이터베이스명~테이블명 쿼리를 대입하면 각각의 결과를 얻을 수 있다. db명은 다른 쿼리를 썼다.

 

db명 구하는 쿼리: 1' union select database(),1#

database()는 현재 사용중인 db를 반환한다.

 

테이블명 구하는 쿼리: 1' union select table_schema, table_name from information_schema.tables where table_schema = 'dvwa' #

table_schema는 db명, table_name은 테이블명이다.

 

users라는 테이블의 칼럼을 조회해본다.

users의 칼럼 구하는 쿼리: 1' union select table_name, column_name from information_schema.columns where table_schema = 'dvwa' and table_name = 'users'#

 

user와 password 칼럼을 조회한다.

쿼리: 1' union select user, password from users#

패스워드의 해시값이 128bits(32bytes)인 걸로 봐서 md5 알고리즘이 적용된 것 같다.

아래의 링크에 접속해서 admin의 패스워드를 복호화한다.

https://www.md5online.org/md5-decrypt.html

admin의 패스워드는 hacker임을 알 수 있다.

Medium 단계

Medium 단계는 id 값을 1~5 중에 선택할 수 밖에 없기에 버프스위트를 이용해서 값을 변조한다.

주의할 것은 소스코드를 보면 Low 단계와 다르게 쿼리문에서 id 변수를 '로 감싸고 있지 않다는 것이다.

union select 공격도 가능하다.

High 단계

새 창에서 id를 입력받고 있다. 소스코드를 보자.

LIMIT 1을 이용해 결과 데이터를 하나만 반환하도록 하였다. 주석문자를 이용해 쉽게 우회가능하다.

마찬가지로 union select 공격도 가능하다.

대응 방안

Impossible 단계를 참고하자.

먼저 is_numeric 함수를 이용해서 id가 숫자인지 확인한다. 즉, 화이트리스트 방식으로 허용할 입력값 형식을 설정하는 것이다.

그리고 prepared statement를 사용한다.

prepared statement란 사용자의 입력값이 부분을 제외한 쿼리를 먼저 컴파일하고 사용자의 입력값은 후에 바인딩하는 것이다. 이렇게 하면 입력값은 문자(열)로만 취급되어 입력값에 의해 쿼리를 악의적으로 변조할 수 없다. 따라서 SQL Injection을 막을 수 있다.

위의 코드에서는 prepare 함수를 통해 입력값을 제외한 쿼리문을 먼저 컴파일 하고 bindParam 함수로 입력값을 바인딩 후 execute 함수로 쿼리를 실행한다. 다른 언어에서도 prepared statement 방식과 같은 함수들이 제공된다.

 

728x90

'dvwa' 카테고리의 다른 글

XSS  (0) 2023.05.22
Blind SQL Injection  (0) 2023.05.17
File Upload  (0) 2023.05.06
File Inclusion  (0) 2023.05.06
CSRF  (0) 2023.05.05

+ Recent posts