Skip to content

Instantly share code, notes, and snippets.

@maleadt
Created September 18, 2011 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maleadt/1224916 to your computer and use it in GitHub Desktop.
Save maleadt/1224916 to your computer and use it in GitHub Desktop.
Simple HTTP file sniffer.
#!/usr/bin/perl
#
# Configuration
#
# Write nicely
use warnings;
use strict;
# Modules
use Net::Pcap;
use Sniffer::HTTP;
use Net::Pcap::FindDevice;
use URI::Escape;
use DateTime;
# Constants
my $VERBOSE = 0;
#
# Main
#
# Get the output path
my $path = shift || die("Usage: ./capture <path> <opt:device> <opt:pcap filter>");
die("Output path not accessible") unless (-d $path);
# Generate a subfolder
my $dt = DateTime->now;
$path .= '/' . $dt->strftime('%Y%m%dT%H%M%SZ');
die("Session subfolder already exists") if (-d $path);
mkdir $path || die("Could not create session subfolder");
# Get the device
my $device = shift;
if ($^O =~ /MSWin32|cygwin/ && $device) {
$device = qr/$device/i
};
# Get the filter
my $filter = shift;
# Sniff for data
my %counters;
print "* Starting sniffer\n";
my $sniffer = Sniffer::HTTP->new(
callbacks => {
request => sub {
my ($req, $conn) = @_;
print "REQUEST\t", $req->uri, "\n";
},
response => sub {
my ($res, $req, $conn) = @_;
print "REPLY\t", $res->status_line, "\n";
# Get the host
my $host = $req->header("host") || "unknown";
my $subfolder = "$path/$host";
mkdir $subfolder unless (-d $subfolder);
# Get a filename
my $filename = $res->filename;
if (!$filename && uri_unescape($req->uri) =~ m{/([^/]+\.\w+)($|\?.*)}) {
$filename = $1;
}
if (!$filename) {
$counters{$host} = 0 unless defined($counters{$host});
$filename = ++$counters{$host};
}
# Save the contents
if (length $res->content) {
# Detect duplicates
my $filepath = "$subfolder/$filename";
my $dupcount = 0;
$filepath = "$subfolder/$filename." . ++$dupcount while (-e $filepath);
# Write!
open(my $write, ">", $filepath) || die("Could not write data");
print $write $res->decoded_content;
close($write);
}
},
log => sub {
print $_[0] if $VERBOSE
},
tcp_log => sub {
print $_[0] if $VERBOSE > 1
},
}
)->run($device, $filter);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment