PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/msf/core/exploit/capture.rb

https://github.com/Jonono2/metasploit-framework
Ruby | 573 lines | 446 code | 72 blank | 55 comment | 74 complexity | 041efddc22341a5f3fd4fee1d378d87f MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, GPL-3.0, LGPL-2.1, GPL-2.0
  1. # -*- coding: binary -*-
  2. module Msf
  3. ###
  4. #
  5. # This module provides methods for sending and receiving
  6. # raw packets. It should be preferred over the soon-to-be
  7. # deprecated Rex::Socket::Ip and Msf::Exploite::Remote::Ip
  8. # mixins.
  9. #
  10. # Please see the pcaprub documentation for more information
  11. # on how to use capture objects.
  12. #
  13. ###
  14. class Exploit
  15. module Capture
  16. #
  17. # Initializes an instance of an exploit module that captures traffic
  18. #
  19. def initialize(info = {})
  20. super
  21. register_options(
  22. [
  23. OptPath.new('PCAPFILE', [false, 'The name of the PCAP capture file to process']),
  24. OptString.new('INTERFACE', [false, 'The name of the interface']),
  25. OptString.new('FILTER', [false, 'The filter string for capturing traffic']),
  26. OptInt.new('SNAPLEN', [true, 'The number of bytes to capture', 65535]),
  27. OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 500]),
  28. Opt::RHOST
  29. ], Msf::Exploit::Capture
  30. )
  31. register_advanced_options(
  32. [
  33. OptInt.new('UDP_SECRET', [true, 'The 32-bit cookie for UDP probe requests.', 1297303091]),
  34. OptAddress.new('GATEWAY', [false, 'The gateway IP address. This will be used rather than a random remote address for the UDP probe, if set.']),
  35. OptInt.new('NETMASK', [false, 'The local network mask. This is used to decide if an address is in the local network.', 24]),
  36. ], Msf::Exploit::Capture
  37. )
  38. require 'packetfu'
  39. begin
  40. require 'pcaprub'
  41. @pcaprub_loaded = true
  42. rescue ::LoadError => e
  43. @pcaprub_loaded = false
  44. @pcaprub_error = e
  45. end
  46. begin
  47. require 'network_interface'
  48. @network_interface_loaded = true
  49. rescue ::LoadError => e
  50. @network_interface_loaded = false
  51. @network_interface_error = e
  52. end
  53. end
  54. def stats_recv(pcap=self.capture)
  55. return(0) unless pcap
  56. pcap.stats['recv']
  57. end
  58. def stats_drop(pcap=self.capture)
  59. return(0) unless pcap
  60. pcap.stats['drop']
  61. end
  62. def stats_ifdrop(pcap=self.capture)
  63. return(0) unless pcap
  64. pcap.stats['ifdrop']
  65. end
  66. #
  67. # Opens a handle to the specified device
  68. #
  69. def open_pcap(opts={})
  70. check_pcaprub_loaded
  71. if RUBY_PLATFORM == "i386-mingw32"
  72. if opts['INTERFACE'] or datastore['INTERFACE']
  73. dev = opts['INTERFACE'] || datastore['INTERFACE']
  74. if is_interface?(dev)
  75. dev = get_interface_guid(dev)
  76. end
  77. end
  78. else
  79. dev = opts['INTERFACE'] || datastore['INTERFACE'] || nil
  80. end
  81. len = (opts['SNAPLEN'] || datastore['SNAPLEN'] || 65535).to_i
  82. tim = (opts['TIMEOUT'] || datastore['TIMEOUT'] || 0).to_i
  83. fil = opts['FILTER'] || datastore['FILTER']
  84. do_arp = (opts['ARPCAP'] == false) ? false : true
  85. # Look for a PCAP file
  86. cap = datastore['PCAPFILE'] || ''
  87. if (not cap.empty?)
  88. if (not File.exists?(cap))
  89. raise RuntimeError, "The PCAP file #{cap} could not be found"
  90. end
  91. self.capture = ::Pcap.open_offline(cap)
  92. else
  93. dev ||= ::Pcap.lookupdev
  94. unless RUBY_PLATFORM == "i386-mingw32"
  95. system("ifconfig", dev, "up")
  96. end
  97. self.capture = ::Pcap.open_live(dev, len, true, tim)
  98. if do_arp
  99. self.arp_capture = ::Pcap.open_live(dev, 512, true, tim)
  100. preamble = datastore['UDP_SECRET'].to_i
  101. arp_filter = "arp[6:2] = 2 or (udp[8:4] = #{preamble})"
  102. self.arp_capture.setfilter(arp_filter)
  103. end
  104. end
  105. if (not self.capture)
  106. raise RuntimeError, "Could not start the capture process"
  107. elsif (do_arp and !self.arp_capture and cap.empty?)
  108. raise RuntimeError, "Could not start the ARP capture process"
  109. end
  110. self.capture.setfilter(fil) if fil
  111. end
  112. def close_pcap
  113. return unless self.capture
  114. self.capture = nil
  115. self.arp_capture = nil
  116. GC.start()
  117. end
  118. def capture_extract_ies(raw)
  119. set = {}
  120. idx = 0
  121. len = 0
  122. while (idx < raw.length)
  123. len = raw[idx+1]
  124. return set unless len
  125. set[raw[idx]] ||= []
  126. set[raw[idx]].push(raw[idx + 2, len])
  127. idx += len + 2
  128. end
  129. return set
  130. end
  131. #
  132. # This monstrosity works around a series of bugs in the interrupt
  133. # signal handling of Ruby 1.9
  134. #
  135. def each_packet
  136. return unless capture
  137. begin
  138. @capture_count = 0
  139. reader = framework.threads.spawn("PcapReceiver", false) do
  140. capture.each do |pkt|
  141. yield(pkt)
  142. @capture_count += 1
  143. end
  144. end
  145. reader.join
  146. rescue ::Exception
  147. raise $!
  148. ensure
  149. reader.kill if reader.alive?
  150. end
  151. @capture_count
  152. end
  153. # Injects a packet on the wire. For all injection-related functions, it's
  154. # on the module to open up a capture device first (this way, we don't
  155. # needlessly spawn new capture devices).
  156. def inject(pkt="", pcap=self.capture)
  157. check_pcaprub_loaded
  158. if not pcap
  159. raise RuntimeError, "Could not access the capture process (remember to open_pcap first!)"
  160. else
  161. pcap.inject(pkt.to_s) # Can be a PacketFu Packet object or a pre-packed string
  162. end
  163. end
  164. # Injects an Ethernet packet with an optional payload. The payload
  165. # may be a regular PacketFu packet, an EthHeader, or a string.
  166. def inject_eth(args={})
  167. eth_daddr = args[:eth_daddr] || "ff:ff:ff:ff:ff:ff"
  168. eth_saddr = args[:eth_saddr] || "00:00:00:00:00:00"
  169. eth_type = args[:eth_type] || 0x0800 # IP default
  170. payload = args[:payload]
  171. pcap = args[:pcap] || self.capture
  172. p = PacketFu::EthPacket.new
  173. p.eth_daddr = eth_daddr
  174. p.eth_saddr = eth_saddr
  175. p.eth_proto = eth_type
  176. if payload
  177. if payload.kind_of? PacketFu::EthPacket
  178. p.payload = payload.eth_header.body
  179. elsif payload.kind_of? PacketFu::EthHeader
  180. p.payload = payload.body
  181. else
  182. p.payload = payload.to_s
  183. end
  184. end
  185. inject p.to_s, pcap
  186. end
  187. def inject_pcap(pcap_file, filter=nil, delay = 0, pcap=self.capture)
  188. check_pcaprub_loaded
  189. unless pcap
  190. raise RuntimeError, "Could not access the capture process (remember to open_pcap first!)"
  191. end
  192. if (not File.exists?(pcap_file))
  193. raise RuntimeError, "The PCAP file #{pcap_file} could not be found"
  194. end
  195. if (pcap_file.empty?)
  196. raise RuntimeError, "The PCAP file #{pcap_file} is empty"
  197. end
  198. capture_file = ::Pcap.open_offline(pcap_file)
  199. capture_file.setfilter(filter) if filter
  200. while (pkt = capture_file.next) do
  201. pcap.inject(pkt)
  202. Rex.sleep((delay * 1.0)/1000)
  203. end
  204. GC.start
  205. end
  206. # Capture_sendto is intended to replace the old Rex::Socket::Ip.sendto method. It requires
  207. # a payload and a destination address. To send to the broadcast address, set bcast
  208. # to true (this will guarantee that packets will be sent even if ARP doesn't work
  209. # out).
  210. def capture_sendto(payload="", dhost=nil, bcast=false, dev=nil)
  211. raise RuntimeError, "Could not access the capture process (remember to open_pcap first!)" unless self.capture
  212. raise RuntimeError, "Must specify a host to sendto" unless dhost
  213. dev ||= datastore['INTERFACE']
  214. dst_mac, src_mac = lookup_eth(dhost, dev)
  215. if dst_mac == nil and not bcast
  216. return false
  217. end
  218. inject_eth(:payload => payload, :eth_daddr => dst_mac, :eth_saddr => src_mac)
  219. end
  220. # The return value either be a PacketFu::Packet object, or nil
  221. def inject_reply(proto=:udp, pcap=self.capture)
  222. reply = nil
  223. to = (datastore['TIMEOUT'] || 500).to_f / 1000.0
  224. if not pcap
  225. raise RuntimeError, "Could not access the capture process (remember to open_pcap first!)"
  226. else
  227. begin
  228. ::Timeout.timeout(to) do
  229. pcap.each do |r|
  230. packet = PacketFu::Packet.parse(r)
  231. next unless packet.proto.map { |x| x.downcase.to_sym }.include? proto
  232. reply = packet
  233. break
  234. end
  235. end
  236. rescue ::Timeout::Error
  237. end
  238. end
  239. return reply
  240. end
  241. # This ascertains the correct Ethernet addresses one should use to
  242. # ensure injected IP packets actually get where they are going, and
  243. # manages the self.arp_cache hash. It always uses self.arp_capture
  244. # to inject and capture packets, and will always first fire off a
  245. # UDP packet using the regular socket to learn the source host's
  246. # and gateway's mac addresses.
  247. def lookup_eth(addr=nil, iface=nil)
  248. raise RuntimeError, "Could not access the capture process." unless self.arp_capture
  249. self.arp_cache ||= {}
  250. self.dst_cache ||= {}
  251. return self.dst_cache[addr] if self.dst_cache[addr]
  252. if !self.arp_cache[Rex::Socket.source_address(addr)]
  253. probe_gateway(addr)
  254. end
  255. src_mac = self.arp_cache[Rex::Socket.source_address(addr)]
  256. if should_arp?(addr)
  257. dst_mac = self.arp_cache[addr] || arp(addr)
  258. else
  259. dst_mac = self.arp_cache[:gateway]
  260. end
  261. self.dst_cache[addr] = [dst_mac, src_mac]
  262. end
  263. def probe_gateway(addr)
  264. dst_host = (datastore['GATEWAY'] || IPAddr.new((rand(16777216) + 2969567232), Socket::AF_INET).to_s)
  265. dst_port = rand(30000)+1024
  266. preamble = [datastore['UDP_SECRET']].pack("N")
  267. secret = "#{preamble}#{Rex::Text.rand_text(rand(0xff)+1)}"
  268. begin
  269. UDPSocket.open.send(secret, 0, dst_host, dst_port)
  270. rescue Errno::ENETUNREACH
  271. # This happens on networks with no gatway. We'll need to use a
  272. # fake source hardware address.
  273. self.arp_cache[Rex::Socket.source_address(addr)] = "00:00:00:00:00:00"
  274. end
  275. begin
  276. to = (datastore['TIMEOUT'] || 1500).to_f / 1000.0
  277. ::Timeout.timeout(to) do
  278. while (my_packet = inject_reply(:udp, self.arp_capture))
  279. if my_packet.payload == secret
  280. dst_mac = self.arp_cache[:gateway] = my_packet.eth_daddr
  281. src_mac = self.arp_cache[Rex::Socket.source_address(addr)] = my_packet.eth_saddr
  282. return [dst_mac, src_mac]
  283. else
  284. next
  285. end
  286. end
  287. end
  288. rescue ::Timeout::Error
  289. # Well, that didn't work (this common on networks where there's no gatway, like
  290. # VMWare network interfaces. We'll need to use a fake source hardware address.
  291. self.arp_cache[Rex::Socket.source_address(addr)] = "00:00:00:00:00:00"
  292. end
  293. end
  294. # A pure-Ruby ARP exchange. It uses self.arp_capture to send and recv
  295. # packets, rather than self.capture.
  296. def arp(target_ip=nil)
  297. return self.arp_cache[target_ip] if self.arp_cache[target_ip]
  298. return self.arp_cache[:gateway] unless should_arp? target_ip
  299. source_ip = Rex::Socket.source_address(target_ip)
  300. raise RuntimeError, "Could not access the capture process." unless self.arp_capture
  301. p = arp_packet(target_ip, source_ip)
  302. inject_eth(:eth_type => 0x0806,
  303. :payload => p,
  304. :pcap => self.arp_capture,
  305. :eth_saddr => self.arp_cache[Rex::Socket.source_address(target_ip)]
  306. )
  307. begin
  308. to = (datastore['TIMEOUT'] || 500).to_f / 1000.0
  309. ::Timeout.timeout(to) do
  310. while (my_packet = inject_reply(:arp, self.arp_capture))
  311. if my_packet.arp_saddr_ip == target_ip
  312. self.arp_cache[target_ip] = my_packet.eth_saddr
  313. return self.arp_cache[target_ip]
  314. else
  315. next
  316. end
  317. end
  318. end
  319. rescue ::Timeout::Error
  320. end
  321. end
  322. # Creates a full ARP packet, mainly for use with inject_eth()
  323. def arp_packet(target_ip=nil, source_ip=nil)
  324. p = PacketFu::ARPPacket.new
  325. p.arp_opcode = 1
  326. p.arp_daddr_ip = target_ip || datastore['RHOST']
  327. p.arp_saddr_ip = source_ip || datastore['LHOST']
  328. my_eth = self.arp_cache[Rex::Socket.source_address(target_ip)]
  329. p.arp_saddr_mac = my_eth || "00:00:00:00:00:00"
  330. return p
  331. end
  332. # Allow modules to reset their arp caches arbitrarily.
  333. def expire_arpcache
  334. self.arp_cache = {}
  335. end
  336. # For compatabilty with Msf::Exploit::Remote::Ip
  337. def rhost
  338. datastore['RHOST']
  339. end
  340. def check_pcaprub_loaded
  341. if not @pcaprub_loaded
  342. print_status("The Pcaprub module is not available: #{@pcaprub_error}")
  343. raise RuntimeError, "Pcaprub not available"
  344. elsif not @network_interface_loaded
  345. print_status("The NetworkInterface module is not available: #{@network_interface_error}")
  346. raise RuntimeError, "NetworkInterface not available"
  347. else
  348. true
  349. end
  350. end
  351. def lookupnet
  352. check_pcaprub_loaded
  353. dev = datastore['INTERFACE'] || ::Pcap.lookupdev
  354. mask = datastore['NETMASK'] || 24
  355. begin
  356. my_net = IPAddr.new("#{Pcap.lookupnet(dev).first}/#{mask}")
  357. rescue RuntimeError => e
  358. @pcaprub_error = e
  359. print_status("Cannot stat device: #{@pcaprub_error}")
  360. raise RuntimeError, "Pcaprub error: #{@pcaprub_error}"
  361. end
  362. return my_net
  363. end
  364. def should_arp?(ip)
  365. @mydev ||= datastore['INTERFACE'] || ::Pcap.lookupdev
  366. @mymask ||= datastore['NETMASK'] || 24
  367. @mynet ||= lookupnet
  368. @mynet.include?(IPAddr.new(ip))
  369. end
  370. attr_accessor :capture, :arp_cache, :arp_capture, :dst_cache
  371. # Netifaces code
  372. def netifaces_implemented?
  373. @network_interface_loaded and
  374. NetworkInterface.respond_to?(:interfaces) and
  375. NetworkInterface.respond_to?(:addresses)
  376. end
  377. def list_interfaces
  378. check_pcaprub_loaded
  379. NetworkInterface.interfaces
  380. end
  381. def is_interface?(dev)
  382. check_pcaprub_loaded
  383. if RUBY_PLATFORM == "i386-mingw32"
  384. if dev =~ /\\Device\\NPF_\{[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\}/
  385. return NetworkInterface.interfaces.include?(dev)
  386. elsif dev.to_s =~ /^[0-9]{1,2}$/
  387. if (dev.to_i <= NetworkInterface.interfaces.length) and (dev.to_i >= 0)
  388. return true
  389. else
  390. return false
  391. end
  392. else
  393. return false
  394. end
  395. else
  396. return NetworkInterface.interfaces.include?(dev)
  397. end
  398. end
  399. # This function is usefull only on windows where pcaprub use the GUID
  400. def get_interface_guid(dev)
  401. check_pcaprub_loaded
  402. if RUBY_PLATFORM == "i386-mingw32"
  403. if dev.to_s =~ /^[0-9]{1,2}$/
  404. if is_interface?(dev)
  405. NetworkInterface.interfaces[(dev.to_i) - 1]
  406. else
  407. return dev
  408. end
  409. else
  410. return dev
  411. end
  412. else #Non windows
  413. return dev
  414. end
  415. end
  416. def get_mac(dev)
  417. check_pcaprub_loaded
  418. dev = get_interface_guid(dev)
  419. addrs = NetworkInterface.addresses(dev)
  420. raise RuntimeError, "Interface #{dev} does not exist" if !addrs
  421. raise RuntimeError, "Can not get mac address for interface #{dev}" if !addrs[NetworkInterface::AF_LINK][0]['addr']
  422. addrs[NetworkInterface::AF_LINK][0]['addr']
  423. end
  424. def get_ipv4_addr_count(dev)
  425. check_pcaprub_loaded
  426. dev = get_interface_guid(dev)
  427. addrs = NetworkInterface.addresses(dev)
  428. raise RuntimeError, "Interface #{dev} does not exist" if !addrs
  429. addrs[NetworkInterface::AF_INET].length
  430. end
  431. def get_ipv4_addr(dev, num=0)
  432. check_pcaprub_loaded
  433. dev = get_interface_guid(dev)
  434. addrs = NetworkInterface.addresses(dev)
  435. raise RuntimeError, "Interface #{dev} does not exist" if !addrs
  436. raise RuntimeError, "Interface #{dev} does not have an ipv4 address at position #{num}" if addrs[NetworkInterface::AF_INET].length < num + 1
  437. raise RuntimeError, "Can not get the IPv4 address for interface #{dev}" if !addrs[NetworkInterface::AF_INET][num]['addr']
  438. addrs[NetworkInterface::AF_INET][num]['addr']
  439. end
  440. def get_ipv4_netmask(dev, num=0)
  441. check_pcaprub_loaded
  442. dev = get_interface_guid(dev)
  443. addrs = NetworkInterface.addresses(dev)
  444. raise RuntimeError, "Interface #{dev} does not exist" if !addrs
  445. raise RuntimeError, "Interface #{dev} does not have an ipv4 address at position #{num}" if addrs[NetworkInterface::AF_INET].length < num + 1
  446. raise RuntimeError, "Can not get IPv4 netmask for interface #{dev}" if !addrs[NetworkInterface::AF_INET][num]['netmask']
  447. addrs[NetworkInterface::AF_INET][num]['netmask']
  448. end
  449. def get_ipv4_broadcast(dev, num=0)
  450. check_pcaprub_loaded
  451. dev = get_interface_guid(dev)
  452. addrs = NetworkInterface.addresses(dev)
  453. raise RuntimeError, "Interface #{dev} do not exists" if !addrs
  454. raise RuntimeError, "Interface #{dev} do not have an ipv4 address at position #{num}" if addrs[NetworkInterface::AF_INET].length < num + 1
  455. raise RuntimeError, "Can not get IPv4 broadcast address for interface #{dev}" if !addrs[NetworkInterface::AF_INET][num]['broadcast']
  456. addrs[NetworkInterface::AF_INET][num]['broadcast']
  457. end
  458. def get_ipv6_addr_count(dev)
  459. check_pcaprub_loaded
  460. dev = get_interface_guid(dev)
  461. raise RuntimeError, "IPv6 information is not available on this platform" unless ::NetworkInterface.const_defined?(:AF_INET6)
  462. addrs = NetworkInterface.addresses(dev)
  463. raise RuntimeError, "Interface #{dev} do not exists" if !addrs
  464. addrs[NetworkInterface::AF_INET6].length
  465. end
  466. # NOTE: IPv6 is not implemented on Windows
  467. def get_ipv6_addr(dev, num=0)
  468. check_pcaprub_loaded
  469. dev = get_interface_guid(dev)
  470. raise RuntimeError, "IPv6 information is not available on this platform" unless ::NetworkInterface.const_defined?(:AF_INET6)
  471. addrs = NetworkInterface.addresses(dev)
  472. raise RuntimeError, "Interface #{dev} do not exists" if !addrs
  473. raise RuntimeError, "Interface #{dev} do not have an ipv6 address at position #{num}" if addrs[NetworkInterface::AF_INET6].length < num + 1
  474. raise RuntimeError, "Can not get ipv6 address for interface #{dev}" if !addrs[NetworkInterface::AF_INET6][num]['addr']
  475. addrs[NetworkInterface::AF_INET6][num]['addr'].gsub(/%(.)*$/, '')
  476. end
  477. def get_ipv6_netmask(dev, num=0)
  478. check_pcaprub_loaded
  479. dev = get_interface_guid(dev)
  480. raise RuntimeError, "IPv6 information is not available on this platform" unless ::NetworkInterface.const_defined?(:AF_INET6)
  481. addrs = NetworkInterface.addresses(dev)
  482. raise RuntimeError, "Interface #{dev} do not exists" if !addrs
  483. raise RuntimeError, "Interface #{dev} do not have an ipv6 address at position #{num}" if addrs[NetworkInterface::AF_INET6].length < num + 1
  484. raise RuntimeError, "Can not get ipv6 netmask address for interface #{dev}" if !addrs[NetworkInterface::AF_INET6][num]['netmask']
  485. addrs[NetworkInterface::AF_INET6][num]['netmask']
  486. end
  487. # Protocol-specific encoding/decoding methods until more
  488. # application protos get into PacketFu proper
  489. # Intended to be used as the payload to an ICMP echo request's payload
  490. def capture_icmp_echo_pack(id=nil, seq=nil, payload=nil)
  491. id ||= rand(0x10000)
  492. seq ||= rand(0x10000)
  493. [id, seq, payload.to_s].pack("nna*")
  494. end
  495. # Decodes and ICMP echo request or response.
  496. def capture_icmp_echo_unpack(data)
  497. data.unpack("nna*")
  498. end
  499. end
  500. end
  501. end