声明:本文针对的是已公开、有官方修复方案的配置类安全问题(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 1935 端口网络可达

攻击者能访问 SRS 的 RTMP 端口

✅ 公网可达

推流无需认证

SRS 默认不限制推流来源

✅ 默认配置

无需受害者交互

攻击者主动推送即可

✅ 纯主动

默认配置是否安全

SRS 默认不限制推流

❌ 默认不安全

关键判断:这不是 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 连接参数(tcUrlpageUrl 等)虽然不会直接触发 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,建议立即检查:

  1. 1935 端口是否暴露在公网

  2. 推流是否开启了认证(http_hooks 或 security)

  3. API 端口(1985/8080)是否限制访问

  4. _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