syurhia 님의 블로그
Blind SQL injection with time delays and information retrieval 본문
Blind SQL injection with time delays and information retrieval
syurhia 2026. 5. 6. 21:05이번에는 에러가 발생을 해도 아무런 출력을 안 해주는 경우에 쓰는 공격기법이다.
SQL쿼리에 sleep함수를 넣어줌으로써 딜레이를 발생시키는데, 서버에서 오는 응답에 딜레이가 생긴다면 SQL 인젝션이 존재한다는 방법이다.
이번에 공격을 할 사이트는 쿠키에 취약점이 있다고 한다. 다만 UNION을 ㅆ이번에는 에러가 발생을 해도 아무런 출력을 안 해주는 경우에 쓰는 공격기법이다.
SQL쿼리에 sleep함수를 넣어줌으로써 딜레이를 발생시키는데, 서버에서 오는 응답에 딜레이가 생긴다면 SQL 인젝션이 존재한다는 방법이다.
이번에 공격을 할 사이트는 쿠키에 취약점이 있다고 한다.
전제 조건으로서 이 서버는 users라는 테이블을 사용하고, username과 password라는 필드를 사용한다고 한다.
여기서 administrator의 password를 탈취해서 로그인하는 게 목적이다.
한 번 살펴보자.

그림 1은 쿠키에 취약점이 있는 사이트라고 한다.

그림 2와 같이 session과 TrackingId라는 쿠키 데이터가 존재한다.
TrackingId이니 이 쿠키 데이터를 통해 사이트는 본 유저가 이미 접속한 적 있는 유저인지 아닌지 판단할 수 있을 것이다.
그리고 그 판단에 대해서는 데이터베이스를 이용해서 쿼리에 이 쿠키 값을 전해주는 것으로 판단을 하는 거라고 유추할 수 있다.
예를 들면 다음과 같은 쿼리라고 추측이 가능하다. (실제로 그렇다는 건 아니니 참고하길 바란다.)
SELECT count(*) From tracking where TrackingId = 'cDrT5M8eFXHGoTVi';
이러한 쿼리를 가지고 있으며, SQL인젝션에 취약하다는 힌트를 웹사이트에서 사전에 제공을 해줬기에 TrackingId에다가 우리가 원하는 쿼리를 추가로 넣어주면 될 듯하다.
그래도, SQL인젝션에 취약한지 실제로 알아봐야 한다.
다만, 중요한 점이 있다!
다량의 쿠키 데이터를 전달할 때 보면 그림2와 같이 세미콜론으로 쿠키들을 구분한다.
즉, TrackingId 쿠키에 아래와 같이 쿼리를 넣어서 전해주면 제대로 전해지지 않는다는 이야기다.
TrackingId = cDrT5M8eFXHGoTVi'; IF(1=1) WAITFOR DELAY '0:0:10'--
위와 같이 값을 전해주면, 서버는 쿠키가 3개가 전달이 되었다고 판단할 것이다.
첫 번째는 session, 두 번째는 TrackingId, 세 번째는 세미콜론으로 나눠준 IF(1=2)... 말이다.
다만 세 번째는 쿠키의 이름이 IF(1=2).... '0:0:10'--가 될 것이고, 값은 비어있는 게 될 것이다. 왜냐하면 등호( = )가 없기 때문이다.
그러니, 쿼리를 작성해줄 때 있어서, 서버가 세미콜론을 세미콜론으로 인식하지 않게 인코딩해줄 필요가 있다. (url인코딩)
예를들면 아래의 쿼리와 같이 말이다. 참고로 세미콜론은 ASCII코드로 %3B이다.
TrackingId = cDrT5M8eFXHGoTVi'%3B IF(1=1) WAITFOR DELAY '0:0:10'--
그러면 이제 쿼리를 작성해보자.
우리는 서버 관리자가 아니기 때문에 공격 대상이 어떠한 서버인지 알 수 없다.
일단 서버가 쓰는 데이터베이스 쿼리 언어는 총 4개이다. Oracle, Microsoft SQL Server, PostgreSQL, MySQL(MariaDB)
이 중에 무슨 언어를 쓰는지 모르기 때문에 모든 언어로 다 시도해봐야 한다.
아래가 예시이고, 4가지 서버에서 10초간 딜레이를 발생시키는 쿼리이다.
Oracle dbms_pipe.receive_message(('a'),10)
Microsoft WAITFOR DELAY '0:0:10'
PostgreSQL SELECT pg_sleep(10)
MySQL SELECT SLEEP(10)

이 4개를 시도해본 결과 아래의 쿼리만이 그림 3과 같이 10초간 딜레이가 발생했다.
즉, 이 서버는 PostgreSQL을 사용하고 있다는 얘기이다.
TrackingId = cDrT5M8eFXHGoTVi'%3BSELECT pg_sleep(10)--
SQL인젝션이 통한다는 것도 확인이 되었고, 쿠키에서 취약점이 있다는 것도 확인이 되었으니 이제 본격적으로 아이디를 추출해보자.
코드는 맨 아래에 깃허브에 올려놨으니 참고바란다.
Burp Suite를 써야 하는 문제이지만, 나는 Burp Suite가 좀 불편하기도 하고, 코드를 작성해도 충분히 할 수 있다고 생각했기에 코드로 작성했다.
예전에는 한 문자씩 때려넣는 방식으로 했는데, 시간이 걸려서 이번에는 이진트리 알고리즘을 적용시켜서 업그레이드 해봤다. 예전보다 훨씬 빠르긴 한데, 다음에는 멀티쓰레드로 하면 더 빠를 듯 하다.

코드를 실행시킨 결과가 그림 4이다.
비밀번호가 hm56xvcvmnycd4cel4rz라고 한다.
그러면 이제 로그인을 해보자.

성공이다.
아래 접은 글에 깃헙 주소
'보안관련 > PortSwigger' 카테고리의 다른 글
| SQL injection with filter bypass via XML encoding (0) | 2026.05.07 |
|---|---|
| Out-of-band (OAST) (0) | 2026.05.06 |
| Visible error-based SQL injection (0) | 2026.04.30 |
| Blind SQL injection with conditional erros (0) | 2026.04.30 |
| SQL Injection 순서 정리 (0) | 2026.04.28 |