Skip to content

Instantly share code, notes, and snippets.

@picatz
Last active November 6, 2016 00:24
Show Gist options
  • Save picatz/0da17a5813031223e73b0b41c34eae4c to your computer and use it in GitHub Desktop.
Save picatz/0da17a5813031223e73b0b41c34eae4c to your computer and use it in GitHub Desktop.
A very simple sample of using PacketFu to be able to keep statistics of your machines ssh connections using ipv4 on port 22.
require 'packetfu'
class SshStatistics
attr_accessor :stats
# initialize() is the method that is called
# when we create a new SshStatistics object.
#
# == Example
#
# # Typical use case for this class.
# stats = Statistics.new
# => #<SshStatistics:0x007fc5433d8730 @stats={:connections=>[]}>
def initialize
@stats = Hash.new(0)
@stats[:connections] = []
end
# count_up() will add 1 to the total
# number of packets processed.
def count_up
@stats[:count] += 1
end
# count_connections() will count the number of
# uniq connections that have been processed.
def count_connections
@stats[:uniq] = @stats[:connections].count
end
# processed_connection() will keep track of the connection
# statistics for this SshStatistics class including the source
# and destination IP addresses that is processed including counting
# the packet and counting the ammout of uniq connections. This
# method is the main work horse of this class.
#
# == Examples
#
# # Typical use case to process connections.
# stats = SshStatistics.new
# stats.process_connection(:source => "10.0.0.1", :destination => "10.0.0.2")
# => [{:source=>"10.0.0.1", :destination=>"10.0.0.2", :count=>1}]
# stats.process_connection(:source => "10.0.0.2", :destination => "10.0.0.1")
# => [{:source=>"10.0.0.1", :destination=>"10.0.0.2", :count=>1}, {:source=>"10.0.0.2", :destination=>"10.0.0.1", :count=>1}]
# stats.process_connection(:source => "10.0.0.2", :destination => "10.0.0.1")
# => [{:source=>"10.0.0.1", :destination=>"10.0.0.2", :count=>1}, {:source=>"10.0.0.2", :destination=>"10.0.0.1", :count=>2}]
# stats.stats
# => #<SshStatistics:0x007f9c33bd6858
# @stats=
# {:connections=>
# [{:source=>"10.0.0.1", :destination=>"10.0.0.2", :count=>1},
# {:source=>"10.0.0.2", :destination=>"10.0.0.1", :count=>2}],
# :count=>3,
# :uniq=>2}>
#
def process_connection(args)
processed = false
@stats[:connections].each_with_index do |connection,index|
if connection[:source] == args[:source] and connection[:destination] == args[:destination]
@stats[:connections][index][:count] += 1
processed = true
end
end
unless processed
@stats[:connections] << { :source => args[:source], :destination => args[:destination], :count => 1 }
end
count_up
count_connections
@stats[:connections]
end
end
# Create a new object of a Statistics class
stats = SshStatistics.new
# get the default routable interface
iface = PacketFu::Utils.default_int
# Get my local ip
my_ip = PacketFu::Utils.ifconfig(iface)[:ip_saddr]
# Create a new capture on the en0 interface
cap = PacketFu::Capture.new(:iface => iface)
cap.bpf(:filter => "ip host #{my_ip} and tcp port 22")
cap.start
# Parse each packet
cap.stream.each do | packet |
info = PacketFu::Packet.parse(packet)
stats.process_connection(:source => info.ip_saddr, :destination => info.ip_daddr)
# clear screen and puts stats
system('clear')
puts stats.stats
end
# => example output ...
# {
# :connections=>[{ :source=>"10.0.0.2", :destination=>"10.0.0.3", :count=>25 },
# { :source=>"10.0.0.2", :destination=>"10.0.0.3", :count=>25 }],
# :count=>50,
# :uniq=>2
# }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment