Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/plugins/pcap_log.rb
Views: 11705
##1# This file is part of the Metasploit Framework and may be subject to2# redistribution and commercial restrictions. Please see the Metasploit3# Framework web site for more information on licensing and terms of use.4# https://metasploit.com/framework/5##67module Msf8class Plugin::PcapLog < Msf::Plugin910# Only little-endian is supported in this implementation.11PCAP_FILE_HEADER = "\xD4\xC3\xB2\xA1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x01\x00\x00\x00".freeze1213#14# Implements a pcap console command dispatcher.15#16class PcapLogDispatcher1718include Msf::Ui::Console::CommandDispatcher1920def name21'PcapLog'22end2324def commands25{26'pcap_filter' => 'Set/Get a BPF-style packet filter',27'pcap_dir' => 'Set/Get a directory to log pcaps to',28'pcap_prefix' => 'Set/Get a filename prefix to log pcaps to',29'pcap_iface' => 'Set/Get an interface to capture from',30'pcap_start' => 'Start a capture',31'pcap_stop' => 'Stop a running capture',32'pcap_show_config' => 'Show the current PcapLog configuration'33}34end3536def cmd_pcap_filter(*args)37@filter = args.join(' ') || @filter38print_line "#{name} BPF filter: #{@filter}"39end4041def cmd_pcap_prefix(*args)42@prefix = args[0] || @prefix || 'msf3-session'43print_line "#{name} prefix: #{@prefix}"44end4546def cmd_pcap_dir(*args)47@dir = args[0] || @dir || '/tmp'48print_line "#{name} Directory: #{@dir}"49end5051def cmd_pcap_iface(*args)52@iface = args[0] || @iface53print_line "#{name} Interface: #{@iface}"54end5556def cmd_pcap_start(*_args)57unless @pcaprub_loaded58print_error('Pcap module not available')59return false60end6162if @capture_thread && @capture_thread.alive?63print_error 'Capture already started.'64return false65end6667gen_fname68print_line "Starting packet capture from #{@iface} to #{@fname}"69okay, msg = validate_options70unless okay71print_error msg72return false73end74dev = (@iface || ::Pcap.lookupdev)75@capture_file.write(PCAP_FILE_HEADER)76@capture_file.flush77@pcap = ::Pcap.open_live(dev, 65535, true, 1)78@pcap.setfilter(@filter) if @filter79@capture_thread = Thread.new do80@pcap.each do |pkt|81@capture_file.write(convert_to_pcap(pkt))82@capture_file.flush83end84end85end8687def cmd_pcap_stop(*_args)88if @capture_thread && @capture_thread.alive?89print_line "Stopping packet capture from #{@iface} to #{@fname}"90print_line "Capture Stats: #{@pcap.stats.inspect}"91@pcap = nil92@capture_file.close if @capture_file.respond_to? :close93@capture_thread.kill94@capture_thread = nil95else96print_error 'No capture running.'97end98end99100def convert_to_pcap(packet)101t = Time.now102sz = packet.size103[t.to_i, t.usec, sz, sz, packet].pack('V4A*')104end105106def gen_fname107t = Time.now108file_part = format('%s_%04d-%02d-%02d_%02d-%02d-%02d.pcap', @prefix, t.year, t.month, t.mday, t.hour, t.min, t.sec)109@fname = File.join(@dir, file_part)110end111112# Check for euid 0 and check for a valid place to write files113def validate_options114# Check for root.115unless Process.euid.zero?116msg = 'You must run as root in order to capture packets.'117return [false, msg]118end119120# Check directory suitability.121unless File.directory? @dir122msg = "Invalid pcap directory specified: '#{@dir}'"123return [false, msg]124end125126unless File.writable? @dir127msg = "No write permission to directory: '#{@dir}'"128return [false, msg]129end130131@capture_file = File.open(@fname, 'ab')132unless File.writable? @fname133msg = "Cannot write to file: '#{@fname}'"134return [false, msg]135end136137# If you got this far, you're golden.138msg = "We're good!"139return [true, msg]140end141142# Need to pretend to have a datastore for Exploit::Capture to143# function.144def datastore145{}146end147148def initialize(*args)149super150@dir = File.join(Msf::Config.config_directory, 'logs')151@prefix = 'msf3-session'152@filter = nil153@pcaprub_loaded = false154begin155require 'pcaprub'156@pcaprub_loaded = true157@iface = ::Pcap.lookupdev158rescue ::Exception => e159print_error "#{e.class}: #{e}"160@pcaprub_loaded = false161@pcaprub_error = e162end163end164165end166167def initialize(framework, opts)168super169add_console_dispatcher(PcapLogDispatcher)170print_status 'PcapLog plugin loaded.'171end172173# Kill the background thread174def cleanup175@capture_thread.kill if @capture_thread && @capture_thread.alive?176@capture_file.close if @capture_file.respond_to? :close177remove_console_dispatcher('PcapLog')178end179180def name181'pcap_log'182end183184def desc185'Logs all socket operations to pcaps (in /tmp by default)'186end187188end189end190191192