Fixes #1109 -- ARP is now less picky about ARP replies, but does conform to normal networking standards.

git-svn-id: file:///home/svn/framework3/trunk@8832 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Tod Beardsley 2010-03-16 16:04:02 +00:00
parent 32fb7653ca
commit cb640571b0
1 changed files with 9 additions and 8 deletions

View File

@ -35,7 +35,7 @@ module Exploit::Capture
register_advanced_options(
[
OptInt.new('ARP_SECRET', [true, 'The 32-bit cookie for ARP and UDP probe requests.', 1297303091]),
OptInt.new('UDP_SECRET', [true, 'The 32-bit cookie for UDP probe requests.', 1297303091]),
OptAddress.new('GATEWAY', [false, 'The gateway IP address. This will be used rather than a random remote address for the UDP probe, if set.']),
OptInt.new('NETMASK', [false, 'The local network mask. This is used to decide if an address is in the local network.', 24]),
], Msf::Exploit::Capture
@ -95,8 +95,8 @@ module Exploit::Capture
self.capture = ::Pcap.open_live(dev, len, true, tim)
if arp
self.arp_capture = ::Pcap.open_live(dev, 512, true, tim)
preamble = datastore['ARP_SECRET'].to_i
arp_filter = "arp host #{IPAddr.new(preamble, Socket::AF_INET).to_s} or (udp[8:4] = #{preamble})"
preamble = datastore['UDP_SECRET'].to_i
arp_filter = "arp[6:2] = 2 or (udp[8:4] = #{preamble})"
self.arp_capture.setfilter(arp_filter)
end
end
@ -276,14 +276,14 @@ module Exploit::Capture
def probe_gateway(addr)
dst_host = (datastore['GATEWAY'] || IPAddr.new((rand(16777216) + 2969567232), Socket::AF_INET).to_s)
dst_port = rand(30000)+1024
preamble = [datastore['ARP_SECRET']].pack("N")
preamble = [datastore['UDP_SECRET']].pack("N")
secret = "#{preamble}#{Rex::Text.rand_text(rand(0xff)+1)}"
UDPSocket.open.send(secret,0,dst_host,dst_port)
begin
to = (datastore['TIMEOUT'] || 1500).to_f / 1000.0
::Timeout.timeout(to) do
while(my_packet = inject_reply(:udp,self.arp_capture))
if my_packet[:payload] = secret
if my_packet[:payload] == secret
dst_mac = self.arp_cache[:gateway] = my_packet[:eth].dst_mac
src_mac = self.arp_cache[Rex::Socket.source_address(addr)] = my_packet[:eth].src_mac
return [dst_mac,src_mac]
@ -304,8 +304,9 @@ module Exploit::Capture
def arp(target_ip=nil)
return self.arp_cache[target_ip] if self.arp_cache[target_ip]
return self.arp_cache[:gateway] unless should_arp? target_ip
source_ip = Rex::Socket.source_address(target_ip)
raise RuntimeError, "Could not access the capture process." if not self.arp_capture
n = arp_packet(target_ip)
n = arp_packet(target_ip,source_ip)
inject_eth(:eth_type => 0x0806,
:payload => n.pack,
:pcap => self.arp_capture,
@ -327,12 +328,12 @@ module Exploit::Capture
end
end
def arp_packet(target_ip)
def arp_packet(target_ip,source_ip)
n = Racket::Racket.new
n.l3 = Racket::L3::ARP.new
n.l3.opcode = 1
n.l3.tpa = target_ip || datastore['RHOST']
n.l3.spa = IPAddr.new(datastore['ARP_SECRET'].to_i, Socket::AF_INET).to_s
n.l3.spa = datastore['LHOST'] || source_ip
my_eth = self.arp_cache[Rex::Socket.source_address(target_ip)]
n.l3.sha = my_eth || "00:00:00:00:00:00"
return n