Pi-hole 的 FTLDNS 引擎(6.0 至 6.5 版本)中存在一个远程代码执行漏洞,允许已认证的攻击者通过向 dns.upstreams API 参数中嵌入换行符(\n)来注入任意的 dnsmasq 配置指令。由于 dnsmasq 支持可执行 shell 命令的指令,这种换行符注入可直接转化为在主机系统上执行任意命令。
这不仅仅是一个单一漏洞,而是一类影响五个不同配置参数的注入问题,全部已在 FTL v6.6 中一并修复。
Pi-hole 是全球部署最广泛的 DNS 黑洞之一。它位于你的网络中,处理 DNS 查询,并在广告和追踪器到达浏览器之前就在 DNS 层面将其拦截。从公寓中的单个 Raspberry Pi 到保护数千台设备的企业级部署,Pi-hole 无处不在。
FTLDNS(超光速 DNS)是 Pi-hole 的核心引擎。它是围绕 dnsmasq(著名的 DNS 和 DHCP 服务器)构建的自定义分支/封装。FTLDNS 负责:
关键细节在于:FTLDNS 通过其 API 根据用户提供的设置生成 dnsmasq 配置文件。如果你在 Pi-hole 管理面板中更改上游 DNS 服务器,FTLDNS 会将该值写入 dnsmasq 配置文件并重启服务。漏洞就存在于这个写入路径中。
+------------------+ +------------------+ +------------------+
| 管理面板 | API/Web | FTLDNS 引擎 | 配置写入 | dnsmasq |
| (Web UI) | ---------> | (pihole-FTL) | ------------> | (DNS/DHCP) |
+------------------+ +------------------+ +------------------+
| |
读取设置, 读取配置,
写入配置文件 向网络提供
到磁盘 DNS/DHCP 服务
当管理员通过 Pi-hole Web UI 或 API 更改上游 DNS 服务器时,流程如下:
dns.upstreams 参数旨在接受 DNS 服务器地址,如 8.8.8.8 或 1.1.1.1。FTLDNS 将这些地址以 server= 指令的形式写入 dnsmasq 配置:
# 正常输入:"8.8.8.8"
# 生成:
server=8.8.8.8
问题在于:FTLDNS 未对输入中的换行符进行过滤。攻击者可以注入 \n 来跳出预期的 server= 指令,并注入全新的配置行:
# 恶意输入:"8.8.8.8\ndhcp-option=6,evil.dns.server"
# 生成:
server=8.8.8.8
dhcp-option=6,evil.dns.server
仅此一点就足以令人担忧(通过 DHCP 选项注入实现 DNS 劫持)。但情况更糟。
dnsmasq 支持一个名为 dhcp-option 的配置指令,该指令可以引用外部脚本;更重要的是,它还支持多个可在特定场景下执行命令的指令。利用链如下:
步骤 1:攻击者认证到 Pi-hole
(默认凭据、弱密码、CSRF、会话被劫持)
步骤 2:攻击者发送 API 请求更新 dns.upstreams:
POST /api/dns/upstream
{
"upstreams": ["8.8.8.8\n<恶意 dnsmasq 指令>"]
}
步骤 3:FTLDNS 将值写入 dnsmasq 配置文件,
未对换行符进行过滤
步骤 4:注入的 dnsmasq 指令被解析为
合法配置选项
步骤 5:根据注入的指令,攻击者可以实现:
- DNS 劫持(重定向所有 DNS 查询)
- DHCP 投毒(向客户端推送恶意配置)
- 通过 dnsmasq 的脚本能力执行命令
- 向任意路径写入文件
关键洞察在于,这不是利用 dnsmasq 的漏洞——dnsmasq 正在按设计工作。漏洞在于 FTLDNS 允许不受信任的输入渗入配置文件,将配置管理 API 变成了任意配置注入点。
研究人员(T0X1Cx)发现,相同的换行符注入模式影响了五个不同的 FTLDNS 配置参数。这是一个系统性问题——代码在各个方面都缺乏输入过滤:
这些参数中的每一个都会写入 dnsmasq 配置文件,且都未能过滤换行符。FTL v6.6 中的修复添加了适当的输入验证,在所有配置参数中拒绝换行符(及其他控制字符)。
对 Pi-hole 主机的影响:
对网络的影响(下游影响):
风险放大因素:
| 版本 | 状态 |
|---|---|
| FTLDNS 6.6+ | 已修复 |
| FTLDNS 6.0 – 6.5 | 存在漏洞 |
| FTLDNS 5.x 及更早版本 | 不受影响(API 架构不同) |
检查你的版本:
pihole -v
# 或
pihole-FTL --version
高风险:
中风险:
较低风险(但仍应修补):
Python 脚本通过基于版本的分析来检测存在漏洞的 Pi-hole 实例。
工作原理:
不会发送任何注入负载。该测试完全是只读且安全的。
用法:
# 安装依赖
pip install -r requirements.txt
# 单个目标(HTTP,默认端口 80)
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 192.168.1.1
# 自定义端口
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t pi.hole -p 8080
# HTTPS 模式(自动切换到端口 443)
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 10.0.0.1 --https
# 从文件批量扫描
python CVE-2026-35517_PiHole_FTLDNS_detector.py -f targets.txt
# JSON 输出保存到文件
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 192.168.1.1 --json -o results.json
# 增加超时时间
python CVE-2026-35517_PiHole_FTLDNS_detector.py -t 192.168.1.1 --timeout 20
选项:
示例输出:
╔══════════════════════════════════════════════════════════════╗
║ CVE-2026-35517 - Pi-hole FTLDNS RCE 检测器 ║
║ dns.upstreams 中的换行符注入 → 命令执行 ║
║ CVSS: 8.8(高危)| 影响版本:FTLDNS 6.0 - 6.5 ║
╚══════════════════════════════════════════════════════════════╝
[*] 正在扫描 192.168.1.1:80...
目标:192.168.1.1:80
============================================================
[*] 检测到 Pi-hole
管理界面:可访问
API 可访问:是
FTL 版本: v6.4
Core 版本: v6.3
Web 版本: v6.4
CVE-2026-35517 评估:
[存在漏洞] FTLDNS 6.4 在漏洞范围内(6.0 - 6.5)。
请立即升级到 FTL v6.6 或更高版本。
相关漏洞(同样在 FTL v6.6 中修复):
[-] GHSA-wxhv-w77q-6qwp:通过 dns.hostRecord 换行符注入实现 RCE
[-] GHSA-28g5-gg88-wh5m:通过 dns.cnameRecords 换行符注入实现 RCE
[-] GHSA-fqv2-qhfh-ghcj:通过 dhcp.leaseTime 换行符注入实现 RCE
[-] GHSA-vfmq-jrx3-wv3c:通过 dhcp.hosts 换行符注入实现 RCE
修复措施:
1. 将 Pi-hole FTL 升级到 6.6 或更高版本
2. 运行:pihole -up
3. 使用以下命令验证:pihole -v
4. 审查 API 访问控制和认证设置
5. 检查日志中是否有利用迹象(异常的 DNS 配置更改)
# 安装 NSE 脚本
sudo cp CVE-2026-35517_PiHole_FTLDNS.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# 基本扫描
nmap -p 80 --script CVE-2026-35517_PiHole_FTLDNS <目标>
# 扫描常见 Pi-hole 端口
nmap -p 80,443,8080,4711 --script CVE-2026-35517_PiHole_FTLDNS <目标>
# 子网扫描 — 查找网络上的所有 Pi-hole 实例
nmap -p 80 --script CVE-2026-35517_PiHole_FTLDNS 192.168.1.0/24
# 结合版本检测
nmap -sV -p 80,443 --script CVE-2026-35517_PiHole_FTLDNS <目标>
# 从文件扫描目标
nmap -p 80 --script CVE-2026-35517_PiHole_FTLDNS -iL targets.txt
示例 Nmap 输出:
PORT STATE SERVICE
80/tcp open http
| CVE-2026-35517_PiHole_FTLDNS:
| 存在漏洞:
| Pi-hole FTLDNS 通过上游 DNS 配置实现 RCE
| 状态:存在漏洞
| ID: CVE:CVE-2026-35517
| 风险因素:高(CVSS:8.8)
| 披露日期:2026-04-07
| 附加信息:
| FTL 版本:v6.4
| Core 版本:v6.3
| Web 版本:v6.4
| 同样在 FTL v6.6 中修复的相关公告:
| GHSA-wxhv-w77q-6qwp(dns.hostRecord 注入)
| GHSA-28g5-gg88-wh5m(dns.cnameRecords 注入)
| GHSA-fqv2-qhfh-ghcj(dhcp.leaseTime 注入)
| GHSA-vfmq-jrx3-wv3c(dhcp.hosts 注入)
| 修复措施:升级到 Pi-hole FTL v6.6+(pihole -up)
| 参考:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-35517
|_ https://github.com/pi-hole/FTL/security/advisories/GHSA-23w8-7333-p9fj
如果你有 Pi-hole 主机的 SSH 访问权限:
# 检查 FTL 版本
pihole-FTL --version
# 或通过 Pi-hole CLI
pihole -v
# 通过 API 检查(v6)
curl -s http://pi.hole/api/info/version | python3 -m json.tool
# 通过 API 检查(v5)
curl -s http://pi.hole/admin/api.php?versions | python3 -m json.tool
如果 FTL 版本在 6.0 到 6.5(含)之间,则存在漏洞。
需要关注的内容:
/etc/dnsmasq.d/ 和 /etc/pihole/ 中是否有意外指令调查命令:
# 检查 dnsmasq 配置中是否有注入行
grep -r "dhcp-option\|addn-hosts\|conf-file\|log-facility" /etc/dnsmasq.d/
# 检查最近的配置修改
find /etc/pihole /etc/dnsmasq.d -mtime -7 -ls
# 查看 Pi-hole 的调试日志
pihole -d
# 检查运行进程是否有异常
ps aux | grep -E "dnsmasq|pihole"
# 检查 crontab 是否有持久化
crontab -l
cat /etc/crontab
ls -la /etc/cron.d/
立即行动 — 立即升级:
# 更新 Pi-hole(包括 FTL、Web 和 Core)
pihole -up
# 验证更新
pihole -v
# FTL 版本应 >= 6.6
如果无法立即升级:
pihole -a -p修补后操作:
Kerem Oruç - 网络安全工程师
| 字段 | 详情 |
|---|
| CVE ID | CVE-2026-35517 |
| 厂商 | Pi-hole 项目 |
| 产品 | FTLDNS (pihole-FTL) |
| 受影响版本 | 6.0 至 < 6.6 |
| CVSS v3.1 | 8.8(高危) |
| CWE | CWE-93 — CRLF 序列中和不当 |
| 攻击向量 | 网络 |
| 认证 | 需要(Pi-hole 管理员/API 访问权限) |
| 用户交互 | 无 |
| 发布时间 | 2026 年 4 月 7 日 |
| 修复版本 | FTL v6.6(2026 年 4 月 3 日发布) |
| 发现者 | T0X1Cx |
| 相关公告 | GHSA-23w8-7333-p9fj、GHSA-wxhv-w77q-6qwp、GHSA-28g5-gg88-wh5m、GHSA-fqv2-qhfh-ghcj、GHSA-vfmq-jrx3-wv3c |
| 公告 | 参数 | 控制内容 |
|---|
| GHSA-23w8-7333-p9fj | dns.upstreams | 上游 DNS 服务器 |
| GHSA-wxhv-w77q-6qwp | dns.hostRecord | 自定义 DNS 主机记录 |
| GHSA-28g5-gg88-wh5m | dns.cnameRecords | CNAME 记录映射 |
| GHSA-fqv2-qhfh-ghcj | dhcp.leaseTime | DHCP 租约时长 |
| GHSA-vfmq-jrx3-wv3c | dhcp.hosts | 静态 DHCP 主机分配 |
| 标志 | 描述 | 默认值 |
|---|
-t, --target | 目标 IP 或主机名 | — |
-f, --file | 包含目标的文件,每行一个(支持 # 注释) | — |
-p, --port | 目标端口 | 80 |
--https | 使用 HTTPS(如果端口为 80 则自动切换到 443) | 关闭 |
--timeout | 连接超时时间(秒) | 10 |
--json | 以 JSON 格式输出 | 关闭 |
-o, --output | 将结果保存到文件 | — |