Simple Construction of a RAW TCP/IP Packet
Wednesday, August 11th, 2010 - 9:12 am - Programming
#!/usr/local/bin/perl
use Socket;
$src_host = $ARGV[0]; # The source IP/Hostname
$src_port = $ARGV[1]; # The Source Port
$dst_host = $ARGV[2]; # The Destination IP/Hostname
$dst_port = $ARGV[3]; # The Destination Port.
if(!defined $src_host or !defined $src_port or !defined $dst_host or !defined $dst_port) {
print "Usage: $0 <source host> <source port> <dest host> <dest port>\n";
exit;
}
else {
main();
}
sub main {
my $src_host = (gethostbyname($src_host))[4];
my $dst_host = (gethostbyname($dst_host))[4];
socket(RAW, AF_INET, SOCK_RAW, 255) || die $!;
setsockopt(RAW, 0, 1, 1);
my ($packet) = makeheaders($src_host, $src_port, $dst_host, $dst_port);
my ($destination) = pack('Sna4x8', AF_INET, $dst_port, $dst_host);
send(RAW,$packet,0,$destination);
}
sub makeheaders {
local($src_host,$src_port,$dst_host,$dst_port) = @_;
my $zero_cksum = 0;
# Lets construct the TCP half
my $tcp_proto = 6;
my ($tcp_len) = 20;
my $syn = 13456;
my $ack = 0;
my $tcp_headerlen = "5";
my $tcp_reserved = 0;
my $tcp_head_reserved = $tcp_headerlen .
$tcp_reserved;
my $tcp_urg = 0; # Flag bits
my $tcp_ack = 0; # eh no
my $tcp_psh = 0; # eh no
my $tcp_rst = 0; # eh no
my $tcp_syn = 1; # yeah lets make a connexion! :)
my $tcp_fin = 0;
my $null = 0;
my $tcp_win = 124;
my $tcp_urg_ptr = 0;
my $tcp_all = $null . $null .
$tcp_urg . $tcp_ack .
$tcp_psh . $tcp_rst .
$tcp_syn . $tcp_fin ;
# In order to calculate the TCP checksum we have
# to create a fake tcp header, hence why we did
# all this stuff :) Stevens called it psuedo headers :)
my ($tcp_pseudo) = pack('a4a4CCnnnNNH2B8nvn',
$tcp_len,$src_port,$dst_port,$syn,$ack,
$tcp_head_reserved,$tcp_all,$tcp_win,$null,$tcp_urg_ptr);
my ($tcp_checksum) = &checksum($tcp_pseudo);
# Now lets construct the IP packet
my $ip_ver = 4;
my $ip_len = 5;
my $ip_ver_len = $ip_ver . $ip_len;
my $ip_tos = 00;
my ($ip_tot_len) = $tcp_len + 20;
my $ip_frag_id = 19245;
my $ip_frag_flag = "010";
my $ip_frag_oset = "0000000000000";
my $ip_fl_fr = $ip_frag_flag . $ip_frag_oset;
my $ip_ttl = 30;
# Lets pack this baby and ship it on out!
my ($pkt) = pack('H2H2nnB16C2na4a4nnNNH2B8nvn',
$ip_ver_len,$ip_tos,$ip_tot_len,$ip_frag_id,
$ip_fl_fr,$ip_ttl,$tcp_proto,$zero_cksum,$src_host,
$dst_host,$src_port,$dst_port,$syn,$ack,$tcp_head_reserved,
$tcp_all,$tcp_win,$tcp_checksum,$tcp_urg_ptr);
return $pkt;
}
sub checksum {
# This of course is a blatent rip from _the_ GOD,
# W. Richard Stevens.
my ($msg) = @_;
my ($len_msg,$num_short,$short,$chk);
$len_msg = length($msg);
$num_short = $len_msg / 2;
$chk = 0;
foreach $short (unpack("S$num_short", $msg)) {
$chk += $short;
}
$chk += unpack("C", substr($msg, $len_msg - 1, 1)) if $len_msg % 2;
$chk = ($chk >> 16) + ($chk & 0xffff);
return(~(($chk >> 16) + $chk) & 0xffff);
}
nice entry, it isn’t the primary time i come accross your weblog, i all the time discover it looking information about many various subjects