Blind SQL Injection - Boolean Based

반응형

Blind SQL Injection 

SQL Injection의 결과가 참 과 거짓으로만 나오는 페이지에서 참, 거짓만으로 DB의 정보를 가지고오는 SQL Injection 공격

˙ Blind SQL Injection 쿼리에 사용하는 함수

1. substr : 첫번째 인자로 받은 문자열을 지정한 길이만큼 출력하는데 사용하는 함수

2. ascii : 문자를 아스키코드로 변환하는데 사용하는 함수, 작은따옴표 같은 특수문자 우회할 때 사용한다.

3. limit : 문자열의 길이를 반환할 때 사용

 

Boolean Based Injection

˙ 참과 거짓만 출력하는 페이지에 공격자가 조작한 쿼리로 인해 DB 내용을 노출하는 취약점

 

실습하기

1. SQL Injection - Blind - Boolean Based 찾아 들어가기

찾아 들어가면 다음과 같이 나온다.

 

2. sql 공격이 먹히는지 확인하기 - '(작은 따옴표)

검색창에 '를 입력해보면 

다음과 같이 나오는데 이는 SQL Injection이 가능하다는 소리이다.

 

3. sql injection 공격 실행하기 - ' or 1=1#(항상 참), ' or 1=2#(항상 거짓)

1. 쿼리문이 항상 참일경우(' or 1=1#)

sql 공격을 실행하면 영화가 DB에 존재한다는 메시지가 나온다.

이번 문제는 결과를 참 또는 거짓으로 표현하기 때문이다.

 

2. sql문이 거짓일 경우(' or 1=2#)

다음과 같이 영화가 존재하지 않는다는 메시지가 나온다.

이제 컬럼 갯수를 찾아보자

 

3. 컬럼 갯수 찾기 - ' order by 숫자#

숫자 안에 1부터 숫자를 하나 씩 늘려 나가보자

1. 컬럼갯수>= 숫자

현재 DB에 있는 컬럼 갯수가 숫자보다 많거나 같을 경우 거짓의 결과가 출력된다.

숫자가 7일 경우까지 다음과 같은 메시지가 출력된다.

 

2. 컬럼갯수 < 숫자

숫자에 8을 대입하면 다음과 같은 메시지가 출력된다.

이를 통해 우리는 컬럼의 갯수가 7개인 것을 알 수 있다.

blind sql injection은 참과 거짓으로밖에 표현을 하지 않기에 UNION 공격으로도 쿼리의 결과를 출력하지 않는다. 그러므로 우리는 substring 함수와 length() 함수를 사용하여 DB 내용을 추측하는 인젝션 공격을 수행해야 한다.

 

4.  DB의 이름 길이 알아내기 - ' or1=1 and length(database())=숫자#

결과를 참 또는 거짓으로만 나타내기 때문에 우리는 찍기(?)로 DB의 이름과 길이를 알아내야 한다.

한마디로 노가다 작업을 해야한다는 것이다.

Blind SQL Injection 공격을 할 때는 항상 참이 되는 쿼리와 정보를 추출할 쿼리를 조합해야 한다.

DB명을 알아내기 전에 DB명의 길이를 먼저 알아내야 하기 때문에 길이를 알아내는 length() 함수를 사용하기로 했다.

˙ length() : 문자의 길이를 출력해주는 함수

-> ' or 1=1(항상 참인 값) and length(database())=1#부터 숫자를 하나씩 높여가 길이를 맞춰야 한다.

database() : 서버의 데이터베이스 명을 반환하는 시스템 함수

1. DB명 길이 != 숫자

거짓이라는 결과가 나온다.

 

2. DB명 길이 == 숫자

숫자에 5를 대입한 경우 다음과 같이 참의 결과가 나온다. 이를 통해 우리는 DB명이 5글자라는 것을 알 수 있다.

 

5. DB명 알아내기 - ' or 1=1 and substring(database(),1,1)='문자'#

DB길이가 5인것을 알아냈으니 이제 DB의 이름을 알아내기 위해 substring이라는 함수를 사용한다.

˙ substring(시작, 끝) = 시작부분부터 끝부분까지 문자만 출력

이제 맨 처음인 a부터 시작해서 일일이 대입해봐야한다.

1. a를 대입하였을 때(거짓일 때)

2. b를 대입하였을 때(참)

이를 통해 첫번째 글자는 b라는 것을 알 수 있었다.

만약 '가 필터링으로 막힌경우 '대신 '에 해당하는 아스키 함수와 아스키 번호(98)을 입력하면 된다.

ex) ' or 1=1 and ascii(substring(database(),1,1))= 98#

또한 부등호를 이용하여 해당 아스키 값이 내가 입력한 아스키 코드보다 큰지 작은지 알 수도 있다.

ex) ' or 1=1 and ascii(substring(database(),1,1))<= 90#

이를 통해 계속해서 알아내면 bWAPP이라는 것을 알 수 있다.

 

6. 테이블 명 길이 알아내기 - ' or 1=1 and length((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1))= 숫자#

 

이제 DB명이 bWAPP이라는 것을 알아 냈으니 테이블 명을 알아내보자

위에 언급한 명령어는 이미 여러번 봤을것이지만 table_type='base table'이라는 문구는 처음볼 것이다.

table_type = 'base table'은 information_schema에서 메타 데이터 저장용 테이블을 제외한 테이블이라는 의미이다.

이제 숫자에 1부터 숫자를 증겨시켜 대입해보자

1. 숫자 != 테이블명 길이

2. 숫자 == 테이블 명 길이

숫자에 4를 대입하면 다음과 같이 참인 결과가 나온다. 이를 통해 테이블명 길이는 4라는 것을 알 수 있다.

 

7. 테이블 명 알아내기 - ' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1)1,1)) >숫자#

테이블 길이가 4인것을 알아냈으니 이제 테이블 명을 알아볼 차례이다.

테이블 명을 알아낼 때는 ascii 함수와 부등호를 이용해서 알아보는게 훨씬 빠르게 구할 수 있다.

우선 a(아스키 코드97)보다 큰지 체크하여 소문자인지 대문자인지 확인하자

만약 97보다 크면 소문자일것이고 97보다 작으면 대문자일 것이다.

97보다 크다. 이 뜻은 소문자라는 뜻이다.

이제 이렇게 해서 범위를 UP&Down 게임 처럼 범위를 좁혀나가보면 처음으로 시작하는 단어가 b라는 것을 알 수 있다.

b(ascii code 98)를 입력하였을 경우

이 방식을 이용해 계속 구하다보면 첫번째 테이블(limit 0,1)의 이름은 blog라는 것을 알아낼 수 있다.

계속 이 노가다를 시행하다보면 4번째 테이블 명이 users라는 것을 알 수 있고 users에 계정정보가 있다고 추측할 수 있다.

이제 users의 컬럼을 구해보자

 

8. users안 첫번째 컬럼길이 구하기 - ' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 0,1)) = 숫자#

이제 첫번째 컬럼 길이 부터 구해보자

 

1을 대입한 경우 거짓이라고 나온다.

다음으로 2를 대입해 보았다.

2를 대입하니 참의 결과가 나왔다.

첫번째 컬럼의 길이는 2라는 것을 알 수 있다.

솔직히 지금까지 문제를 풀어오면서 컬럼의 길이가 2인 것은 id 밖에 없기 때문에 id라는 것을 알고는 있으나

연습하는 사이트인 만큼 첫번째 컬럼의 첫번째 글자를 구해보도록 하겠다.

 

9. users 안 첫번째 컬럼 구하기 - ' or 1=1 and ascii(substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)) = 숫자#

첫번째로 대문자인지 소문자인지 구분하기 위해 숫자에 97을 넣었다.

그 결과

참이 나왔다. 이를 통해 소문자라는 것을 알 았고 UP&Down 게임으로 알아낸 결과 첫번째 글자는 i(ascii=105)라는 것을 알아냈다. 이를 통해 첫번째 컬럼이 i라고 거의 확신하였고 두번째에는 substring을 사용하여 문자에 'd'를 대입해 보았다.

-> ' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,2)= 'id'#

-> 첫번째 글자부터 2개의 글자를 확인하기 때문에 1,2로 바꿔줘야한다.

결과

역시 id가 맞았다.

이제 8,9번을 계속 반복하면서 id, login, password 이정도는 유추 및 알아낼 수 있다.

 

10. login 컬럼 내용의 길이 파악하기 - ' or 1=1 and length((select login from users limit 1,1))=숫자#

이제 로그인 컬럼안에 있는 내용을 파악해보자(컬럼 안 두번째 것 내용)

첫번째로 길이를 알아내야 하므로 다음과 같이 입력하자

1을 입력하였을 때(거짓일 때)

3을 입력하였을 때 (참)

이를 통해 컬럼 안의 첫번째 내용은 3글자라는 것을 유추 할 수 있다.

이제 컬럼 내용 길이는 파악했으니 컬럼안에 무엇이 있는지 파악해보자

 

11. login 컬럼 내용의 길이 파악하기 - ' or 1=1 and substring((select login from users limit 1,1),1,1) ='문자'#

이제 3자리인것까지 구했으니까 컬럼 안 내용을 알아보자

솔직히 이것은 위에서 했던 내용 반복에 노가다 이므로 설명은 생략하도록 하겠다.

첫번째 글자에서 'b'를 입력했을 때  참인 결과가 뜨니까 첫번째 글자는 b일것이고 b로 시작하는 세글자 bee 일거 같아서 bee가 맞는지 확인하였다.

-> ' or 1=1 and substring((select login from users limit  1,1),1,3)='bee'#

참이란다. 이제 login 두번째 컬럼이 bee라는 것까지 알아냈다. 이방식을 통해 password도 구해야하지만 숫자를 20까지 올려도 되지 않아 책을 확인하니 40자리라고 하였다.

그 뜻은 지금 비밀번호가 hash되어 있다는 소리이다. 

3자리 노가다도 시간이 오래걸리는데 40자리 노가다 하다가 1년 버려야 할거 같아서 이것은 노가다하는 것을 포기하였다. 추후에 blind sql injection 공격 툴 만드는 기술을 배워서 패스워드를 알아보도록 해야겠다.

이제부터는 책에 나온 방식대로 해보기로 했다.

책에서는 먼저 MD5해시함수를 사용하는지 확인하였다.

12. Password가 MD5 인지 확인하기 - ' or 1=1 and md5("bug")=(select password form users where login='bee')#

-> bee로 로그인 했을때 패스워드가 bug인데 md5 해시함수를 사용하였냐고 물어보았다.

아니란다.

13. Password가 SHA-1 인지 확인하기 - ' or 1=1 and sha1("bug") = (select password from users where login='bee')#

맞단다. 이로써 bee에 대한 패스워드는 bug이고 패스워드는 sha-1 해시화 되어있다는 것을 알았다.

 

난이도 - (중,상)

난이도 - 중, 상에 처음에 sql injection이 먹히는지 확인하기 위해 '를 입력하였다.

결과

sql 에러메시지가 출력되지 않는다. 

이제 페이지의 코드를 확인해보면 된다.

sql_4.php 페이지를 확인하면 되는데

다음과 같이 나온다.

다음 함수의 내용은https://tkdrms568.tistory.com/138

에 설명 되어있다.

 

[bee-box]SQL Injection(Get/Search)

SQL Injection 코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터 베이스를 공겨할 수 있는 공격방식 주로 사용자가 입력한 데이터를 제대로 필터링 하지 않았을 경우 발생한다 공격은 쉬..

tkdrms568.tistory.com

 

반응형

'웹해킹 > bee-box' 카테고리의 다른 글

XML / XPATH 인젝션 - Login Form  (0) 2019.08.07
SQL Injection - Blind - Time Based  (0) 2019.08.06
SQL-Injection(Blog)  (0) 2019.08.04
SQL-Injection - Login Form/Hero  (0) 2019.08.04
SQL Injection(AJAX/JSON/JQuery)  (0) 2019.08.03