Analysis of ffmpeg arbitrary file reading vulnerability

Time:2020-7-11

On June 24, hackerone website announced a local file disclosure vulnerability of ffmpeg, which can affect many versions of ffmpeg, including 3.2.2, 3.2.5, 3.1.2, 2.6.8, and so on.

Vulnerabilities on hackerone website: https://hackerone.com/reports… 。 Associated with it are several other vulnerability reports on hackerone: https://hackerone.com/reports… , https://hackerone.com/reports…

In fact, the vulnerability @ emillerner and @ Pavel cheremushkin were first disclosed at this year’s phydays conference. Videos can be downloaded from https://www.phdays.com/broadc… Search attacks on video converter, but it is all Russian, and there are no English letters for the time being. You can also refer to the PPT of vulnerability author at phday conference

In fact, the author discovered the vulnerability in May and submitted it. It was released on June 26. The latest ffmpeg version 3.3.2 has been fixed, but the old version is not guaranteed.

Background
Ffmpeg is a very popular open source computer program which can be used to record, convert digital audio and video, and convert it into stream. It provides a complete solution for recording, converting and streaming audio and video. At present, there are a lot of video and audio software, video websites and mobile apps that use this library, but there are many loopholes in the history of this library. This vulnerability is to take advantage of ffmpeg’s ability to process HLS playlists. An HLS file is embedded in the GAB2 subtitle block of AVI file, which is then provided to ffmpeg for transcoding. In the process of parsing, it is treated as an xbin video stream, and then it is processed through xbin The codec includes the local files and puts them in the transcoded video files.

Vulnerability recurrence method
1) Download script https://github.com/neex/ffmpe…
2) Running script: python3 Gen_ xbin_ avi.py file:///etc/passwd sxcurity.avi
3) Visit https://arxius.io , upload sxcurity.avi
4) Waiting for upload processing video
5) After the video processing is completed, click play to see the content of / etc / passwd

Consider the past you shall know the future
In fact, this loophole is very similar to a CVE exposed before. It can be said that new wine in old bottles and new flowers in old trees.

An analysis of previous vulnerabilities:
SSRF and local file disclosure (cve-2016-1897 / 8) http://static.hx99.net/static…

This vulnerability actually exploits the fact that ffmpeg supports a lot of protocols, such as HTTP, file, concat, and so on, in the process of processing HLS playlist files, it can construct malicious URLs and cause SSRF attacks and local file disclosure. The following figure shows the whole attack process.
Analysis of ffmpeg arbitrary file reading vulnerability

The official fix for this vulnerability is to add the concat protocol to the blacklist and add protocol to the structure_ Blacklist and protocol_ The whitelist fields. However, this vulnerability makes use of the m3u8 file embedded in the subtitle block to successfully bypass some limitations of ffmpeg.

Brief introduction of HLS protocol
HLS (HTTP live streaming) is a streaming media solution based on HTTP protocol developed by apple for mobile devices such as iPhone, iPod, iTouch and iPad. In HLS technology, web server provides the client with near real-time audio and video stream. However, the standard HTTP protocol is used in the process of use, so at this time, as long as HLS technology is used, it can directly provide on-demand and live broadcast on ordinary HTTP applications. The basic principle of this technology is to cut video file or video stream into small pieces (TS) and establish index file (m3u8). The client will first request the server for the m3u8 index file, and then request the real TS video file according to the URL in the index file. If it is a multi-level m3u8 index, it will start from the root index file and go down layer by layer to request the sub index file to obtain the HTTP request address and time period of the final TS stream file.

There are many tags in the m3u8 file. For the detailed functions of each tag, please refer to this article: http://blog.csdn.net/cabbage2…

Vulnerability analysis of ffmpeg version 3.1.2
This paper first introduces how ffmpeg transcodes an input file into a video file of another format. The flow chart is as follows: (picture quoted from http://blog.csdn.net/leixiaoh… )
Analysis of ffmpeg arbitrary file reading vulnerability

Then we look at the POC provided by the attacker sxcurity.avi File structure
Analysis of ffmpeg arbitrary file reading vulnerability

At first, it is the file header of AVI file, and then there is a file header “GAB2” with GAB2 subtitle in the middle. After the header of GAB2, there is the file header of HLS play list “ා extm3u”. After the file header, the file content of HLS is displayed.

This vulnerability mainly exploits the logic error when ffmpeg processes GAB2 subtitle block, so we focus on calling read when ffmpeg opens the input file_ Gab2sub() this function starts to analyze, read_ The gab2sub() function is avformat_ find_ stream_ Info() is called by this function. The whole function call flow chart is as follows:
Analysis of ffmpeg arbitrary file reading vulnerability

We can see that the format of xbin was detected when we determined the demuxer for the play list, but just look at it sxcurity.avi There is no xbin header in the file, so how does ffmpeg determine that the format is xbin. This is closely related to the parsing process of HLS. When judging the format of a play list, ffmpeg will read the first segment of the play list, then request the file content according to the URL of the segment, and then judge the format according to the read file content.

We can see that sxcurity.avi This is the first few lines of the embedded playlist

EXT-X-MEDIA-SEQUENCE:0

echoing b’XBINx1a x00x0fx00x10x04x01x00x00x00x00′

EXT-X-KEY: METHOD=AES-128, URI=/dev/zero, IV=0x4c4d465e0b95223279487316ffd9ec3a

EXTINF:1,

EXT-X-BYTERANGE: 16

/dev/zero

EXT-X-KEY: METHOD=NONE

echoing b’x00x00x00x00x00x00x00x00x00x01x00x00x00x00xbfn’

EXT-X-KEY: METHOD=AES-128, URI=/dev/zero, IV=0x140f0f1011b5223d79597717ffd95330

The tags in the m3u8 file start with ා, the others start with #, are comments, and those that do not start with #, are a URL

Introduce the meaning of the labels that appear above

Ext-x-media-sequence: each media URI has only a unique serial number in playlist, and the sequence number between adjacent sequences is + 1. A media URI is not required to be included. If not, the default value is 0.

Extinf: duration specifies the duration (in seconds) of each media segment (TS), which is valid only for the URI following it.

Ext-x-key indicates how to decode mediaelements. Its scope is all mediauris before the next tag appears, and the attribute is none or AES-128. In the case of AES-128, the URI attribute represents a key file, which can be obtained through the URI. If there is no IV (initialization vector), the serial number is used as the IV for encoding and decoding; if there is IV, the modified value is regarded as a 16 byte hexadecimal number.

Then the above lines of code include two segments. Each segment needs to be decrypted using AES-128. The ciphertext is the 16 bytes obtained from the URL / dev / zero, which is actually 16 ‘0’. The key is also the 16 bytes obtained from the URL of / dev / zero. The 16 ‘0’, IV is a string of hexadecimal numbers specified by ourselves. After decrypting the first segment by ffmpeg, the result is b’xbinx1a x00x0fx00x04x01x00x00x00x00 ‘, which is the same as that given by the vulnerability author in the comments. The first four bytes of xbin are the header of xbin. Thus, ffmpeg determines that the format of the play list is xbin.

In open_ input_ File function end, the program will call AV_ dump_ The format function prints the format information. The print result is as follows
Input #0, avi, from ‘../sxcurity.avi’:
Duration: 00:00:05.00, start: 0.000000, bitrate: 547 kb/s

Stream #0:0: Video: xbin, pal8, 256x240, 25 tbr, 25 tbn, 25 tbc

We can see that there is only one video stream in the file, and the format encoding format of the video stream is recognized as xbin
After opening the input file and the output file, the program will start transcoding
In the process of transcoding, we can get_ input_ Packet function upper and lower breakpoints, the function is to obtain input a frame of compressed video data, put in avpacket.

gdb-peda$ bt

0 get_input_packet (f=0x6dfc00, pkt=0x7fffffffe460) at ffmpeg.c:3663

1 0x000000000042d40c in process_input (file_index=0x0) at ffmpeg.c:3798

2 0x000000000042eed2 in transcode_step () at ffmpeg.c:4108

3 0x000000000042effc in transcode () at ffmpeg.c:4162

4 0x000000000042f716 in main (argc=0x4, argv=0x7fffffffea48) at ffmpeg.c:4357

5 0x00007ffff48a543a in __libc_start_main () from /usr/lib/libc.so.6

6 0x0000000000407ada in _start ()

get_ input_ After the packet() call is finished, print the content of pkt, and you can see that there are some information at the beginning of the / etc / passwd file.

Analysis of ffmpeg arbitrary file reading vulnerability

Then ffmpeg will be transcoded into MPEG 2 encoding format, and finally packaged into an MP4 file. Open the MP4 file, we can see the contents of the leaked file.

The non transcoding AVI file can also be played, but the file he plays is the current application of calling ffmpeg. For example, if you open it with Iqiyi, you call the Iqiyi player, and Iqiyi uses the ffmpeg code to read the internal files of Iqiyi application, resulting in information leakage, because these files do not have permission to read.

For example, you can read data / data/ com.qiyi.video/shared_ prefs/ cn.com.mma . mobile.tracking.sdkconfig .xml

The purpose of transcoding is to write the server file of the video you upload to the file after transcoding, that is, you can play it no matter it is converted to. MP4 or flv.

Another way to attack
Attackers target https://hackerone.com/reports… The fix of this hole proposes another bypass method https://hackerone.com/reports… 。 This approach is much simpler than using xbin.

The length of the playlist generated by this POC is as follows

EXTM3U

EXT-X-MEDIA-SEQUENCE:0

EXTINF:1.0

GOD.txt

EXTINF:1.0

/etc/passwd

EXT-X-ENDLIST

Translate the author’s comments in the comments section
First of all, we need to know how HLS playlist is handled
1. When processing a playlist, ffmpeg links all the segment contents together and processes them as a separate file
2. Ffmpeg uses the first segment of playlist to determine the file type
3. Ffmpeg uses a special way to process files with. TXT suffix. It will try to print the contents of the file on the screen as a terminal

Therefore, the processing flow of the above playlist is as follows:
1. Ffmpeg sees the ා extm3u tag in the GAB2 subtitle block, and confirms that the file type is HLS playlist.
Two GOD.txt This file doesn’t even need to exist, but its name is enough for ffmpeg to detect the file type as TXT
3. Ffmpeg links the contents of all segments of the playlist together, because only the file / etc / passwd actually exists, so the final content is the content of the / etc / passwd file
4. Because the file type is TXT, ffmpeg draws a terminal to print the file.

It should be noted that when parsing the playlist file, the whitelist of URL protocol D of each segment is’ file, crypto ‘, so here, directly change / etc / passwd to http://vul.com : 21 SSRF attack is not feasible.

Analysis of official patch
Patch link: https://github.com/FFmpeg/FFm…
The official fix to this vulnerability is also very simple. It only uses the whitelist to filter the file extension of the file protocol in the play list. To some extent, the attack is mitigated, but the multimedia files can still be leaked.

typedefstructHLSContext {

//The content of the structure is omitted
  • char *allowed_ Extensions; / / add a field to limit the allowed file extensions
    } HLSContext;

staticintopen_url(AVFormatContext s, AVIOContext pb, constchar url,
AVDictionary opts, AVDictionary opts2, int *is_http)
{

        //...

// only http(s) & file are allowed

    • if (!av_strstart(proto_name, “http”, NULL) && !av_strstart(proto_name, “file”, NULL))
    • if (av_strstart(proto_name, “file”, NULL)) {
    • if (strcmp(c->allowed_extensions, “ALL”) && !av_match_ext(url, c->allowed_extensions)) {
    • av_log(s, AV_LOG_ERROR,
    • “Filename extension of ‘%s’ is not a common multimedia extension, blocked for security reasons.n”
    • “If you wish to override this adjust allowed_extensions, you can set it to ‘ALL’ to allow alln”,
    • url);
    • return AVERROR_INVALIDDATA;
    • }
    • } elseif (av_strstart(proto_name, “http”, NULL)) {
    • ;
    • } else
    1. AVERROR_INVALIDDATA;

    +
    //…
    }

    summary
    The core of this vulnerability and the past is that the m3u8 file can obtain the image text according to the specified URL. However, the HTTP protocol and File Protocol in it are not filtered well, resulting in SSRF and reading of arbitrary files. The previous vulnerability is that the leaked information can be transmitted back to the attacker by using concat, which can show the information to the attacker by playing video. In the future, it is possible to trigger other processes of ffmpeg in other ways to bypass the filtering of File protocol.

    reference material
    http://blogs.360.cn/blog/ffmp…
    https://github.com/radman1/xbin
    https://hackerone.com/reports…
    http://static.hx99.net/static…
    https://tools.ietf.org/html/d…
    http://blog.csdn.net/cabbage2…
    http://blogs.360.cn/blog/ffmp…
    Detailed introduction of xbin file format: https://en.wikipedia.org/wiki…


    • Author: stack long, fat Miao, Super Six @ ant financial services, for more security knowledge sharing and hot information, please pay attention to the official blog of aliju security