Simple Construction of a RAW TCP/IP Packet
Wednesday, August 11th, 2010 - 9:12 am - Programming
001 | #!/usr/local/bin/perl |
002 |
003 | use Socket ; |
004 |
005 | $src_host = $ARGV [0]; # The source IP/Hostname |
006 | $src_port = $ARGV [1]; # The Source Port |
007 | $dst_host = $ARGV [2]; # The Destination IP/Hostname |
008 | $dst_port = $ARGV [3]; # The Destination Port. |
009 |
010 | if (! defined $src_host or ! defined $src_port or ! defined $dst_host or ! defined $dst_port ) { |
011 | print "Usage: $0 <source host> <source port> <dest host> <dest port>\n" ; |
012 | exit ; |
013 | } |
014 | else { |
015 | main(); |
016 | } |
017 | |
018 | sub main { |
019 | my $src_host = ( gethostbyname ( $src_host ))[4]; |
020 | my $dst_host = ( gethostbyname ( $dst_host ))[4]; |
021 |
022 | socket (RAW, AF_INET, SOCK_RAW, 255) || die $!; |
023 | setsockopt (RAW, 0, 1, 1); |
024 | |
025 | my ( $packet ) = makeheaders( $src_host , $src_port , $dst_host , $dst_port ); |
026 | my ( $destination ) = pack ( 'Sna4x8' , AF_INET, $dst_port , $dst_host ); |
027 | send (RAW, $packet ,0, $destination ); |
028 | } |
029 |
030 | sub makeheaders { |
031 | local ( $src_host , $src_port , $dst_host , $dst_port ) = @_ ; |
032 | my $zero_cksum = 0; |
033 | # Lets construct the TCP half |
034 | my $tcp_proto = 6; |
035 | my ( $tcp_len ) = 20; |
036 | my $syn = 13456; |
037 | my $ack = 0; |
038 | my $tcp_headerlen = "5" ; |
039 | my $tcp_reserved = 0; |
040 | my $tcp_head_reserved = $tcp_headerlen . |
041 | $tcp_reserved ; |
042 | my $tcp_urg = 0; # Flag bits |
043 | my $tcp_ack = 0; # eh no |
044 | my $tcp_psh = 0; # eh no |
045 | my $tcp_rst = 0; # eh no |
046 | my $tcp_syn = 1; # yeah lets make a connexion! :) |
047 | my $tcp_fin = 0; |
048 | my $null = 0; |
049 | my $tcp_win = 124; |
050 | my $tcp_urg_ptr = 0; |
051 | my $tcp_all = $null . $null . |
052 | $tcp_urg . $tcp_ack . |
053 | $tcp_psh . $tcp_rst . |
054 | $tcp_syn . $tcp_fin ; |
055 |
056 | # In order to calculate the TCP checksum we have |
057 | # to create a fake tcp header, hence why we did |
058 | # all this stuff :) Stevens called it psuedo headers :) |
059 |
060 | my ( $tcp_pseudo ) = pack ( 'a4a4CCnnnNNH2B8nvn' , |
061 | $tcp_len , $src_port , $dst_port , $syn , $ack , |
062 | $tcp_head_reserved , $tcp_all , $tcp_win , $null , $tcp_urg_ptr ); |
063 |
064 | my ( $tcp_checksum ) = &checksum( $tcp_pseudo ); |
065 |
066 | # Now lets construct the IP packet |
067 | my $ip_ver = 4; |
068 | my $ip_len = 5; |
069 | my $ip_ver_len = $ip_ver . $ip_len ; |
070 | my $ip_tos = 00; |
071 | my ( $ip_tot_len ) = $tcp_len + 20; |
072 | my $ip_frag_id = 19245; |
073 | my $ip_frag_flag = "010" ; |
074 | my $ip_frag_oset = "0000000000000" ; |
075 | my $ip_fl_fr = $ip_frag_flag . $ip_frag_oset ; |
076 | my $ip_ttl = 30; |
077 |
078 | # Lets pack this baby and ship it on out! |
079 | my ( $pkt ) = pack ( 'H2H2nnB16C2na4a4nnNNH2B8nvn' , |
080 | $ip_ver_len , $ip_tos , $ip_tot_len , $ip_frag_id , |
081 | $ip_fl_fr , $ip_ttl , $tcp_proto , $zero_cksum , $src_host , |
082 | $dst_host , $src_port , $dst_port , $syn , $ack , $tcp_head_reserved , |
083 | $tcp_all , $tcp_win , $tcp_checksum , $tcp_urg_ptr ); |
084 |
085 | return $pkt ; |
086 | } |
087 |
088 | sub checksum { |
089 | # This of course is a blatent rip from _the_ GOD, |
090 | # W. Richard Stevens. |
091 | |
092 | my ( $msg ) = @_ ; |
093 | my ( $len_msg , $num_short , $short , $chk ); |
094 | $len_msg = length ( $msg ); |
095 | $num_short = $len_msg / 2; |
096 | $chk = 0; |
097 | foreach $short ( unpack ( "S$num_short" , $msg )) { |
098 | $chk += $short ; |
099 | } |
100 | $chk += unpack ( "C" , substr ( $msg , $len_msg - 1, 1)) if $len_msg % 2; |
101 | $chk = ( $chk >> 16) + ( $chk & 0xffff); |
102 | return (~(( $chk >> 16) + $chk ) & 0xffff); |
103 | } |
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