Adds the sniffer extension for testing
git-svn-id: file:///home/svn/framework3/trunk@6762 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
608ca7aae8
commit
82cf85680c
Binary file not shown.
|
@ -0,0 +1,107 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rex/post/meterpreter/extensions/sniffer/tlv'
|
||||
require 'rex/proto/smb/utils'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Extensions
|
||||
module Sniffer
|
||||
|
||||
###
|
||||
#
|
||||
# This meterpreter extension can be used to capture remote traffic
|
||||
#
|
||||
###
|
||||
class Sniffer < Extension
|
||||
|
||||
|
||||
def initialize(client)
|
||||
super(client, 'sniffer')
|
||||
|
||||
client.register_extension_aliases(
|
||||
[
|
||||
{
|
||||
'name' => 'sniffer',
|
||||
'ext' => self
|
||||
},
|
||||
])
|
||||
end
|
||||
|
||||
|
||||
# Enumerate the remote sniffable interfaces
|
||||
def interfaces()
|
||||
ifaces = []
|
||||
ifacei = 0
|
||||
request = Packet.create_request('sniffer_interfaces')
|
||||
response = client.send_request(request)
|
||||
response.each(TLV_TYPE_SNIFFER_INTERFACES) { |p|
|
||||
vals = p.tlvs.map{|x| x.value }
|
||||
iface = { }
|
||||
ikeys = %W{idx name description type mtu wireless usable dhcp}
|
||||
ikeys.each_index { |i| iface[ikeys[i]] = vals[i] }
|
||||
ifaces << iface
|
||||
}
|
||||
return ifaces
|
||||
end
|
||||
|
||||
# Start a packet capture on an opened interface
|
||||
def capture_start(intf,maxp=200000)
|
||||
request = Packet.create_request('sniffer_capture_start')
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_PACKET_COUNT, maxp.to_i)
|
||||
response = client.send_request(request)
|
||||
end
|
||||
|
||||
# Stop an active packet capture
|
||||
def capture_stop(intf)
|
||||
request = Packet.create_request('sniffer_capture_stop')
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||
response = client.send_request(request)
|
||||
end
|
||||
|
||||
# Retrieve stats about a current capture
|
||||
def capture_stats(intf)
|
||||
request = Packet.create_request('sniffer_capture_stats')
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||
response = client.send_request(request)
|
||||
{
|
||||
'packets' => response.get_tlv_value(TLV_TYPE_SNIFFER_PACKET_COUNT),
|
||||
'bytes' => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||
}
|
||||
end
|
||||
|
||||
# Retrieve the packet dump for this capture
|
||||
def capture_dump(intf)
|
||||
request = Packet.create_request('sniffer_capture_dump')
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||
response = client.send_request(request)
|
||||
|
||||
res = {}
|
||||
data = response.tlvs.map{|x| x.value}
|
||||
data.shift # sniffer_capture_dump
|
||||
data.shift # request id
|
||||
data.pop # result code
|
||||
|
||||
# Grab the packet and byte count stats
|
||||
res[:packet_count] = data.shift
|
||||
res[:byte_count] = data.shift
|
||||
res[:packets] = []
|
||||
|
||||
# Parse the packet queue
|
||||
while(data.length > 3)
|
||||
res[:packets] << {
|
||||
:id => data.shift,
|
||||
:time => Time.at(Rex::Proto::SMB::Utils.time_smb_to_unix(data.shift, data.shift)),
|
||||
:data => data.shift
|
||||
}
|
||||
end
|
||||
|
||||
# Sort the packets by receive order
|
||||
res[:packets].sort!{|a,b| a[:id] <=> b[:id]}
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
end; end; end; end; end
|
|
@ -0,0 +1,24 @@
|
|||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Extensions
|
||||
module Sniffer
|
||||
|
||||
TLV_TYPE_EXTENSION_SNIFFER = 0
|
||||
TLV_TYPE_SNIFFER_INTERFACES = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 1)
|
||||
TLV_TYPE_SNIFFER_INTERFACE_ID = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 2)
|
||||
TLV_TYPE_SNIFFER_INTERFACE_HANDLE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 3)
|
||||
TLV_TYPE_SNIFFER_PACKET_COUNT = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 4)
|
||||
TLV_TYPE_SNIFFER_BYTE_COUNT = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 5)
|
||||
|
||||
TLV_TYPE_SNIFFER_EXCLUDE_PORTS = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 6)
|
||||
TLV_TYPE_SNIFFER_INCLUDE_PORTS = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 7)
|
||||
|
||||
TLV_TYPE_SNIFFER_PACKETS = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 8)
|
||||
TLV_TYPE_SNIFFER_PACKET = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_SNIFFER + TLV_EXTENSIONS + 9)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,142 @@
|
|||
require 'rex/post/meterpreter'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Ui
|
||||
|
||||
###
|
||||
#
|
||||
# Privilege escalation extension user interface.
|
||||
#
|
||||
###
|
||||
class Console::CommandDispatcher::Sniffer
|
||||
|
||||
Klass = Console::CommandDispatcher::Sniffer
|
||||
|
||||
include Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# Initializes an instance of the sniffer command interaction.
|
||||
#
|
||||
def initialize(shell)
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# List of supported commands.
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"sniffer_interfaces" => "List all remote sniffable interfaces",
|
||||
"sniffer_start" => "Capture packets on a previously opened interface",
|
||||
"sniffer_stop" => "Stop packet captures on the specified interface",
|
||||
"sniffer_stats" => "View statistics of an active capture",
|
||||
"sniffer_dump" => "Retrieve captured packet data",
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
def cmd_sniffer_interfaces(*args)
|
||||
|
||||
ifaces = client.sniffer.interfaces()
|
||||
|
||||
print_line()
|
||||
|
||||
ifaces.each do |i|
|
||||
print_line(sprintf("%d - '%s' ( type:%d mtu:%d usable:%s dhcp:%s wifi:%s )",
|
||||
i['idx'], i['description'],
|
||||
i['type'], i['mtu'], i['usable'], i['dhcp'], i['wireless'])
|
||||
)
|
||||
end
|
||||
|
||||
print_line()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_start(*args)
|
||||
intf = args[0].to_i
|
||||
if (intf == 0)
|
||||
print_error("Usage: sniffer_start [interface-id] [packet-buffer]")
|
||||
return
|
||||
end
|
||||
maxp = args[1].to_i
|
||||
maxp = 200000 if maxp == 0
|
||||
|
||||
client.sniffer.capture_start(intf, maxp)
|
||||
print_status("Capture started on interface #{intf} (#{maxp} packet buffer)")
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_stop(*args)
|
||||
intf = args[0].to_i
|
||||
if (intf == 0)
|
||||
print_error("Usage: sniffer_stop [interface-id]")
|
||||
return
|
||||
end
|
||||
|
||||
client.sniffer.capture_stop(intf)
|
||||
print_status("Capture stopped on interface #{intf}")
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_stats(*args)
|
||||
intf = args[0].to_i
|
||||
if (intf == 0)
|
||||
print_error("Usage: sniffer_stats [interface-id]")
|
||||
return
|
||||
end
|
||||
|
||||
stats = client.sniffer.capture_stats(intf)
|
||||
print_status("Capture statistics for interface #{intf}")
|
||||
stats.each_key do |k|
|
||||
puts "\t#{k}: #{stats[k]}"
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_dump(*args)
|
||||
intf = args[0].to_i
|
||||
if (intf == 0 or not args[1])
|
||||
print_error("Usage: sniffer_dump [interface-id] [pcap-file]")
|
||||
return
|
||||
end
|
||||
|
||||
fd = nil
|
||||
if(::File.exist?(args[1]) and ::File.size(args[1]) >= 24)
|
||||
fd = ::File.new(args[1], 'ab+')
|
||||
else
|
||||
fd = ::File.new(args[1], 'wb+')
|
||||
fd.write([0xa1b2c3d4, 2, 4, 0, 0, 65536, 1].pack('NnnNNNN'))
|
||||
end
|
||||
|
||||
print_status("Dumping packets from interface #{intf}...")
|
||||
|
||||
res = client.sniffer.capture_dump(intf)
|
||||
res[:packets].each do |pkt|
|
||||
fd.write([pkt[:time].to_i, pkt[:time].usec, pkt[:data].length, pkt[:data].length].pack('NNNN') + pkt[:data])
|
||||
end
|
||||
|
||||
# print_status("#{pkt[:id]} - #{pkt[:time].to_s} - #{pkt[:data].length}")
|
||||
|
||||
print_status("Wrote #{res[:packet_count]} packets to PCAP file #{args[1]}")
|
||||
fd.close
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Name for this dispatcher
|
||||
# sni
|
||||
def name
|
||||
"Sniffer"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue