
このリポジトリには、以下の最終報告書と再現性の成果物が含まれています。
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クライアント(推奨、必須ではありません)このデモは2つのPostgreSQLコンテナを使用します:
ポート15432と15433が空いていることを確認してください。
期待される実行順序は次のとおりです:
exploit.sqlをattackerとして実行します。victim_query.sqlをvictimとして実行し、CVE-2018-1058 DEMO: プレフィックスを確認します。verify_qualify.sqlをvictimとして実行し、通常の小文字出力を確認します。fix.sqlをpostgresとして実行します。victim_query.sqlを再実行し、通常の小文字出力を確認します。exploit.sqlをポート15433で再実行し、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"
期待されるロール:
postgresattackervictim攻撃者は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
これは、被害者の通常のクエリが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に少なくとも2行あり、被害者クエリで処理された各行に対応します。
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
次に被害者クエリを再実行:
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 | 修正済み/強化済みの比較 |