syurhia 님의 블로그

Blind SQL injection with time delays and information retrieval 본문

보안관련/PortSwigger

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. 취약점이 있는 사이트

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

 

그림 2. 쿠키 데이터

그림 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)

 

그림 3. 딜레이 발생

이 4개를 시도해본 결과 아래의 쿼리만이 그림 3과 같이 10초간 딜레이가 발생했다.

즉, 이 서버는 PostgreSQL을 사용하고 있다는 얘기이다.

TrackingId = cDrT5M8eFXHGoTVi'%3BSELECT pg_sleep(10)--

 

 

SQL인젝션이 통한다는 것도 확인이 되었고, 쿠키에서 취약점이 있다는 것도 확인이 되었으니 이제 본격적으로 아이디를 추출해보자.

 

코드는 맨 아래에 깃허브에 올려놨으니 참고바란다.

 

Burp Suite를 써야 하는 문제이지만, 나는 Burp Suite가 좀 불편하기도 하고, 코드를 작성해도 충분히 할 수 있다고 생각했기에 코드로 작성했다.

예전에는 한 문자씩 때려넣는 방식으로 했는데, 시간이 걸려서 이번에는 이진트리 알고리즘을 적용시켜서 업그레이드 해봤다. 예전보다 훨씬 빠르긴 한데, 다음에는 멀티쓰레드로 하면 더 빠를 듯 하다.

 

 

그림 4. 비밀번호 찾는 중

코드를 실행시킨 결과가 그림 4이다. 

비밀번호가 hm56xvcvmnycd4cel4rz라고 한다.

 

그러면 이제 로그인을 해보자.

 

그림 5. 성공

성공이다.

 

 

아래 접은 글에 깃헙 주소

'보안관련 > 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