#!/usr/bin/ruby ## macfinder.rb v0.1 : Find mac Address in a pcap file. ## Copyright (C) 2009 Franck GUENICHOT ## franck {dot} guenichot {at} orange {dot} fr ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## Written for the Network Forensic Puzzle #3 ## http://forensicscontest.com require 'rubygems' require 'packetfu' require 'optparse' require "rubygems" $VERSION = "0.1" $PROGNAME = "macfinder" ################################################################################################# # handle command line args $options = {} opts = OptionParser.new do|opts| opts.banner = " #{$PROGNAME} version #{$VERSION} Copyright (C) 2009 Franck GUENICHOT #{$PROGNAME} comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions. (GPL v3) Usage: #{$PROGNAME} [options] " $options[:ipaddr] = nil opts.on( '-i ', '--ip', 'Display Mac address for the given IP address only (4-digit decimal dot notation form)' ) do|addr| $options[:ipaddr] = addr end opts.on( '-v', '--version', 'Display version information' ) do puts $VERSION exit end opts.on( '-h', '--help', 'Display this screen' ) do puts opts exit end end #parse command line args opts.parse! $filename = ARGV[ARGV.length-1] # if no file in input => display help and exit if $filename == nil puts opts exit(0) end unless File.exist?($filename) puts "File: #{$filename} does not exist." exit(0) end mac_ip_h = {} pkt_array = PacketFu::Read.f2a(:file => $filename) pkt_array.each { |pkt| packet = PacketFu::Packet.parse(pkt) if not mac_ip_h.has_key?(packet.ip_saddr) mac_ip_h[packet.ip_saddr] = [packet.eth_saddr] else mac_ip_h[packet.ip_saddr] << packet.eth_saddr unless mac_ip_h[packet.ip_saddr].include?(packet.eth_saddr) end } if $options[:ipaddr] =~ /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/ if mac_ip_h.has_key?($options[:ipaddr]) number_of_mac = mac_ip_h[$options[:ipaddr]].length if number_of_mac > 1 puts "Warning ! found %d Mac address for %s" % [number_of_mac, $options[:ipaddr]] mac_ip_h[$options[:ipaddr]].each { |mac| puts "Mac Address: #{mac}" } else puts "Mac: %s" % [mac_ip_h[$options[:ipaddr]]] end else puts "No Mac address found for %s" % [$options[:ipaddr]] end else puts "Listing all Mac Address found !" mac_ip_h.each {|ip, mac| puts "IP: %s | Mac: %s" % [ip, mac] } end #End of macfinder.rb