
"DEF CON 32 - SQL 인젝션은 죽지 않았다: 프로토콜 수준에서의 쿼리 밀반입 - Paul Gerste"의 PoC
로그인 기능이 있는 간단한 웹 애플리케이션입니다. 관리자만 로그인할 수 있습니다.
이 애플리케이션은 PostgreSQL과 pgx v5.5.3(취약한 버전)을 사용합니다.
공격자는 users 테이블에 레코드를 악의적으로 삽입하여 로그인을 시도합니다. 그러나 플레이스홀더가 사용되므로 기존의 SQL 인젝션은 동작하지 않습니다.
PostgreSQL 메시지 형식: https://www.postgresql.org/docs/17/protocol-message-formats.html
이 익스플로잇은 pgx가 SQL을 실행할 때 데이터베이스 서버로 전송하는 메시지 형식에 의존합니다.
기본적으로 pgx는 P(Parse)로 prepared statement를 보낸 다음, B(Bind)로 파라미터를 전송합니다.
다음과 같은 설정이 적용되면 pgx는 보간된 쿼리를 Q(Query)로 전송합니다:
cfg.ConnConfig.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
실제 메시지는 tcpdump에 -X 옵션을 사용하여 확인할 수 있습니다.
Q_simple.py: Q(Query)로 오버플로를 발생시킵니다. 공격자가 실행 중인 쿼리를 완전히 알고 있다고 가정합니다(블랙박스라면 브루트포스가 필요합니다).Q_nop_sled.py: Q(Query)로 오버플로를 발생시킵니다. 5회 이내의 시도로 익스플로잇에 성공합니다.B_simple.py: B(Bind)로 오버플로를 발생시킵니다. 공격자가 실행 중인 쿼리를 완전히 알고 있다고 가정합니다(제 생각에는 블랙박스 시나리오에서 B(Bind) 익스플로잇은 어렵습니다).