一道关于 rtmp、rtsp、mpeg-dash 视频提取的流量分析题

MISC 专栏收录该内容
1 篇文章 0 订阅

这道题是参加企赛中出现的一道题,当时感觉不难而且主办方也放出了足够多的提示,但是没做出来有点遗憾。后来踩了无数天坑,终于前后花了五天时间把它做出来了。
这道题很好没有脑洞,而且都是基础知识,因此做题的过程中学到了视频流相关的基础知识,即使是在现实中也非常的实用。记录一下,分享给大家。


题目下载:
链接: https://pan.baidu.com/s/1jq6SxwtrMBE–xYwO-zWWA 提取码: 1ivr

题目中提示该流量包中包含三种不同类型的视频,对应的协议分别为RTMP、RTSP、MPEG-DASH。

RTMP

查阅相关资料,该协议流量主要通过 tcp 传输。
先看 rtmp2flv 的使用说明,要用到 tcpflow,这个工具在 kali 中直接 apt-get 安装就行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以直接用该工具对题目的流量包进行过滤:
tcpflow -T %T_%A%C%c.rtmp -r rtmp.pcap
当时做的时候少打了一个 “-T” 浪费了一晚上时间,我是菜鸡我是菜鸡
因为tcp会话很多所以会过滤出很多包来,这时候可以尝试选其中最大的那个流量包,多半就是视频了。不过这样做多少有点不够准确,因此我们也可以先在 wireshark 中把视频相关的 tcp 流量筛选出来。流程如下:
统计—>会话—>tcp—>按会话数据大小排序—>追踪最大的包

回到 wireshark 主界面—>导出选定流量包(选择 displayed)
在这里插入图片描述

一番操作后再将导出的流量包扔给 tcpflow 即可得到一个 rtmp 后缀的文件,然后将该文件用 rtmp2flv 转换即可。使用 vlc 播放器播放兼容性会好些。视频中有第一段 flag,音频中为第二段 flag。
在这里插入图片描述

RTSP

查阅相关资料,该协议流量主要通过 udp 传输。
看提示应该是要使用 rtptools 这个工具包。这里有个坑,就是该工具只提供源码,如果在 kali 下编译会报错,用 win 的 vscode 编译会好很多。如果比赛时候没有提前准备环境心态要爆炸。好在 Mac 有 homebrew (一款包管理软件),上面有提供编译好的软件包开袋即食,非常方便。没有 Mac 的同学也可以选择在 linux 下安装 homebrew,win10 现在提供有 linux 虚拟化技术,可以在其中直接安装 homebrew。
Homebrew 安装的软件还有个好处就是可以用 man 命令查看相关软件的操作手册。
在这里插入图片描述

翻阅后得知 rtpdump 重要的设置参数有 -F(数据格式) -f(输入文件) -o (输出文件),其中当存在 -f 参数时就可以不用输入后面的视频在线地址和端口号。不过文档中并没有明确指出怎么获取输入文件。
在这里插入图片描述

因此百度关键词 “wireshark rtpdump”
在这里插入图片描述

第一个链接要收费……挨个找,这个链接中明确指出 wireshark 可以直接导出 rtpdump 所需要的文件。
wireshark 导出rtpdump 并使用 ffmpeg播放_拒绝黑盒,享受开源-CSDN博客_rtpdump
操作步骤:电话—>RTP—>RTP流—>找到数据容量大的那个包 选择导出:
在这里插入图片描述

这里我 Mac 的 wireshark 抽风了,死活导不出数据包,改用 kali 自带的 wireshark 才成功导出。
现在成功得到一个 .rtpdump 文件后,按说明中要求的命令进行操作:
rtpdump -F dump -f /Users/Downloads/Live.rtpdump -o Live.rtp
由于之前也没了解过这个 rtmp 协议,查阅一番资料后得知,它播放时需要有一个发送端和接收段才行。这里需要用 rtptools 中的 rtpplay 这个工具。文章中同时提到了要播放视频还需要一个 sdp 文件。继续搜索相关资料,得知 sdp 相关的信息一般会在推流前由服务端向客户端发送,因此我们可以直接在题目的流量包输入 “sdp” 将其过滤出来:
在这里插入图片描述

然后追踪该流量包把 sdp 相关内容复制出来保存为后缀名为 sdp 的文件即可。
在这里插入图片描述

文件内容如下:

v=0
o=- 0 0 IN IP4 127.0.0.1
s=Stream
c=IN IP4 127.0.0.1
t=0 0
m=video 5002 RTP/AVP 96
b=AS:803
a=rtpmap:96 H264/90000
a=fmtp:96 a=fmtp:96 packetization-mode=1;sprop-parameter-sets=Z0LAHoyNQEQLbfAPCIRq,aM48gA==;profile-level-id=42C01E
a=control:trackID=0
m=audio 0 RTP/AVP 97
b=AS:128
a=rtpmap:97 MPEG4-GENERIC/48000/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=119056E500
a=control:trackID=1

注意等号两边不能有空格
需要特别注意的是 “c” 后面的参数要改成本地 127.0.0.1,因为要推送到本地播放。m=video 5002 RTP/AVP 96其中 “5002” 为视频指定的播放端口,rtpplay 推送时需要填写。该部分的一些参考资料如下:
协作设备抓包后提取H263,H264视频流,并在本地播放的方法 - Cisco Community
Wireshark 抓包分析 RTSP/RTP/RTCP 基本工作过程
然后查看 rtpplay 相关说明后得知,和 rtpdump 的使用方法大同小异。不过这里推流的时候需要带上 “-T”,否则视频无法完整播放。
rtpplay -T -f /Users/Downloads/Live.rtp -v 127.0.0.1/5002
然后用 vlc 打开 sdp 文件即可开始播放。
尝试使用 ffplay 播放只能看到一些残影,没有 vlc 兼容性好。
不过播放时只有视频没有音频。音频中应该也有一段 flag。sdp 中有音频流的参数,因此音频流是存在的。尝试将音频流的播放端口改为 5002,m=audio 5002 RTP/AVP 97,无果。
打开 vlc 的视频信息窗口,发现接收不到音频流的数据。于是猜测音频和视频流是分开推送的,应该是刚才 wireshark 里找到的另外一条。其实在 SIP 流中也可以发现,视频流和音频流的 payload 和 sdp 里的是一一对应的。

这里也是拜 Mac wireshark 所赐,抽风导不出来,我忘了之前视频也是导不出来,还以为其他问题查了好半天资料
用相同的方法将它导出为 rtpplay 适用的文件。这里推流的时候可以考虑开两个终端,一个推视频流,一个推音频流。并且要用不同的端口。也可以用下面的命令直接推:
rtpplay -T -f /Users/live_video.rtp 127.0.0.1/4848 & rtpplay -T -f /Users/live_audio.rtp 127.0.0.1/4646
vlc 这边直接播放就行。
这里的推流和播放用的端口号必须是偶数不能是奇数,不要问为什么,问就是规定
第三段 flag 在视频开始后不久的某一帧,第四段 flag 在之后的一段音频里。
虽然题目已经完成,但我们再尝试拓展一下。rtpplay 推送的流是可以保存成视频的。这里需要用到 ffmpeg。还是用刚才的方法推流,ffmpeg 作接收端,使用如下命令即可:
ffmpeg - how to convert RTPDUMP video file to mp4 - Stack Overflow
ffmpeg -v warning -protocol_whitelist file,udp,rtp -f sdp -i /Users/Downloads/rtsp_video.sdp -copyts -c copy -y /Users/Downloads/rtsp_video.mkv
不过最终效果并不好,可能有些参数需要调整,这里不做深究仅仅是抛砖引玉。

MPEG-DASH

查阅相关资料,该协议流量主要通过 http 进行传输。而且大名鼎鼎的 B 站正是使用的此协议。因为是 http 流,所以可以直接通过 wireshark 分离。
操作如下:
文件—>导出对象—>http
在这里插入图片描述

这里 Mac 主环境再次抽风无法解析 http 协议,因此在 kali 里做的
因为wireshark不能选取一部分保存,要么全部保存,要么保存一个。这里我们看到视频流和音频流同名,区分他们的办法只能同过数据包大小来判断。这里我们全部导出后,在文件管理器中按大小排序的方式将视频和音频文件进行分离。由于很多文件重名,此时会得到很多类似 seg-1(1).m4s 的文件。分离后编写一个 py 脚本将他们的名字中的 ”(1)“ 去掉。

import os,re,sys
current_dir = os.path.dirname(os.path.abspath(__file__))
for foldName, subfolders, filenames in os.walk(current_dir):     #用os.walk方法取得path路径下的文件夹路径,子文件夹名,所有文件名
	for filename in filenames:     #遍历列表下的子文件夹名
		if current_dir + os.sep + filename!= sys.argv[0]:#排除自身
			#print(filename)
			if "(1)" in filename:
				new_name = filename.replace("(1)","")
				print(new_name)
				os.rename(current_dir + os.sep + filename, current_dir + os.sep + new_name)

现在在 kali 中将所有的视频文件拼接起来:
cat init.mp4 $(ls -vx seg-*.m4s) > source.mp4
查阅相关资料可知 inti.mp4 是 MESH 视频的文件头,因此也要拼上。这里稍大一点的 init 文件对应视频文件的文件头。
拼接好后此时的视频文件是无法播放的。我们可以看到分离出来的文件里有一个后缀名为 “mdp” 的文件,他的文件名显示为 “encrypted_stream”,怀疑这里的视频经过了加密处理。
再次查阅相关资料,得知 dash 加密的通用标准:MPEG-DASH CENC。但是并未找到更具体的内容。换个方向突破,已知通过 http 协议传输,于是在 http 流量中尝试搜索关键字 “key”,找到如下内容:
在这里插入图片描述

注意图中标红的内容搜索时需要自行填写或更改。根据 html 前后文内容可以判断该关键字字符串与视频加解密有关。追踪该流量包的 http 流,导出如下内容:

<!DOCTYPE html>
<html>
  <head>
    <title>DASH</title>
    <link rel="stylesheet" href="css/style.css" />
    <script src="js/dash.all.debug.js"></script>
  </head>
  <body>
    <h1>DASH</h1>
    <div>
      <video id="videoPlayer" controls></video>
    </div>
    <script>
      const protData = {
        'org.w3.clearkey': {
          'clearkeys': {
            'jPbIa2O58Gm0x5mfVRs1XQ': 'EEtHaFGANGC05yZiPlGhWA',
          },
        },
      };
      var video,
        player,
        url = 'media/encrypted_stream.mpd';

      video = document.querySelector('#videoPlayer');
      player = dashjs.MediaPlayer().create();
      player.initialize(video, url, true);
      player.setProtectionData(protData);
    </script>
  </body>
</html>

现在就是弄明白这个密钥应该怎么用。尝试搜索了一些播放 dash 内容的方法。 其中使用 ffplay 的方法似乎因为兼容性不佳无法播放,遂舍弃。 在一个 stack overflow 的问答中 How to Decrypt and Play CENC protected contents in DASH? - Stack Overflow 找到一个名为 bento4 的工具包,这个工具包是专门用来处理 mp4 以及 dash 视频流的,官方介绍如下:
在这里插入图片描述

里面有专门用来解密的模块 mp4decrypt。该库也可以通过 homebrew 直接安装。查看使用说明后,尝试破解视频。但是将 “keys” 里的内容带入后提示参数错误,看来还需要继续学习关于 dash 视频流加密的原理。搜索 “clearkeys” 相关的内容,找到了 dash 标准官方的 github 账号,其中两篇文章提到了 clearkeys 在 dash 视频流中加解密的原理:
The repository holds a description and an issue tracker for how ClearKey-based content protection should be used with MPEG DASH.
Generate MPEG DASH content encrypted with MPEG CENC ClearKey
在这里插入图片描述
在这里插入图片描述

简单说就是 “clearkeys” 后面那两串看起来像 base64 的字符串分别名为 “kid” 和 “k”,该字符串需要在后面补齐 “==” 后用 base64 解码取解码后的十六进制值即为原始值。因此我们将 k 还原后带入 mp4decrypt,即可解密视频:
努力使用Bento4工具解密CENC編碼的文件 - 優文庫
mp4decrypt --show-progress --key 8cf6c86b63b9f069b4c7999f551b355d:104b476851803460b4e726623e51a158 /Users/Downloads/video/video.mp4 /Users/Downloads/video_decrypet.mp4
这里模块的具体使用方法说明文档里有写不做赘述
在这里插入图片描述

用 vlc 播放,第五段 flag 就在第一帧。
音频流用同样的方式解密播放,得到第六段 flag。到此结束。
拓展一下,要将音视频合并的话也可以用 ffmpeg 来做:
如何无损合并video.m4s与audio.m4s为mp4文件 - 哔哩哔哩
ffmpeg -i video.mp4 -i audio.mp4 -codec copy output.mp4
组合后的视频用其他播放器也能播放了。

吐槽:这些视频是一个比一个阴间辣眼睛,还都得看完,出题人你有毒- -。

总结

  1. 做题时候尽量保证环境靠谱,不然会浪费很多时间,简单问题复杂化,然后心态爆炸; 不知道系统是不是该重装了,环境奇葩问题有点多
  2. 遇到没见过的工具和协议要静下心来多看官方文档和使用说明,磨刀不误砍柴工,这才是捷径。
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

打赏作者

weixin_40729354

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值