See #782. Fixing GWHOST/GATEWAY, implementing a new capture option for ARP requests.

git-svn-id: file:///home/svn/framework3/trunk@8257 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Tod Beardsley 2010-01-27 15:11:18 +00:00
parent cf26fcb9ad
commit 5adb1aef7e
1 changed files with 19 additions and 7 deletions

View File

@ -26,8 +26,7 @@ module Exploit::Capture
OptString.new('FILTER', [false, 'The filter string for capturing traffic']),
OptInt.new('SNAPLEN', [true, 'The number of bytes to capture', 65535]),
OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 500]),
# This needs some explaining, really.
OptAddress.new('GWHOST', [false, 'The gateway IP address']),
OptAddress.new('GATEWAY', [false, 'The gateway IP address']),
OptAddress.new('LHOST', [false, 'The local IP address'])
], Msf::Exploit::Capture
@ -75,6 +74,7 @@ module Exploit::Capture
len = (opts['SNAPLEN'] || datastore['SNAPLEN'] || 65535).to_i
tim = (opts['TIMEOUT'] || datastore['TIMEOUT'] || 0).to_i
fil = opts['FILTER'] || datastore['FILTER']
arp = opts['ARPCAP'] || false
# Look for a PCAP file
cap = datastore['PCAPFILE'] || ''
@ -88,10 +88,13 @@ module Exploit::Capture
dev = datastore['INTERFACE'] || ::Pcap.lookupdev
system("ifconfig", dev, "up")
self.capture = ::Pcap.open_live(dev, len, true, tim)
self.arp_capture = ::Pcap.open_live(dev, 512, true, tim) if arp
end
if (not self.capture)
raise RuntimeError, "Could not start the capture process"
elsif (arp and !self.arp_capture)
raise RuntimeError, "Could not start the ARP capture process"
end
self.capture.setfilter(fil) if fil
@ -100,6 +103,7 @@ module Exploit::Capture
def close_pcap
return if not self.capture
self.capture = nil
self.arp_capture = nil
GC.start()
end
@ -171,6 +175,14 @@ module Exploit::Capture
inject pkt
end
def sendto(payload="", dhost=nil, bcast=false)
dst_mac,src_mac = lookup_eth(dhost)
if dst_mac == "ff:ff:ff:ff:ff:ff" and not bcast
return false
end
inject_eth(:payload => payload, :eth_daddr => dst_mac, :eth_saddr => src_mac)
end
# Depending on what kind of packet you get, the resultant hash returned will
# contain one or several Racket objects.
def readreply(proto=:udp)
@ -225,10 +237,10 @@ module Exploit::Capture
#
# We still need to know our own src_mac, though, since we assume we want
# a response. To do this, we send a UDP trigger packet with a normal
# UDPSocket connect, to either the gateway host (GWHOST), if known, or to
# UDPSocket connect, to either the gateway host (GATEWAY), if known, or to
# a random(ish) IP known to be beyond the default gateway. We then listen
# for our own UDP packet (via readreply) -- it need not get a response
# from GWHost or the random fake IP.
# from GATEWAY or the random fake IP.
#
# Note, if IANA assigns 177/8 in the future, then the default fake-remote
# IP address will have to be changed (unless you don't mind sending them
@ -247,7 +259,7 @@ module Exploit::Capture
#
# TODO: Reorganize this.
#
def lookup_eth(addr=nil)
def lookup_eth(addr=nil,iface=nil)
self.arp_cache = {} unless self.arp_cache.kind_of? Hash
eth_pair = [nil,nil] # [dst_mac, src_mac] will go here.
raise RuntimeError, "Could not access the capture process." if not self.capture
@ -256,7 +268,7 @@ module Exploit::Capture
eth_pair[0] = self.arp_cache[addr] || arp(addr) || self.arp_cache[:gateway]
eth_pair[1] = self.arp_cache[Rex::Socket.source_address(addr)]
if (eth_pair[0].nil? || eth_pair[1].nil?)
dst_host = (datastore['GWHOST'] || IPAddr.new((rand(16777216) + 2969567232), Socket::AF_INET).to_s)
dst_host = (datastore['GATEWAY'] || IPAddr.new((rand(16777216) + 2969567232), Socket::AF_INET).to_s)
dst_port = rand(30000)+1024
secret = "#{Rex::Text.rand_text(rand(0xff)+1)}"
UDPSocket.open.send(secret,0,dst_host,dst_port)
@ -312,7 +324,7 @@ module Exploit::Capture
self.arp_cache = {}
end
attr_accessor :capture, :arp_cache
attr_accessor :capture, :arp_cache, :arp_capture
end