Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Insert the 4th TCP packet after TCP three-times handshakes

by shanleiguang (Initiate)
on May 03, 2005 at 07:33 UTC ( [id://453500]=sourcecode: print w/replies, xml ) Need Help??
Category: Networking Code
Author/Contact Info i_am_jojo@msn.com
Description: Insert the 4th TCP packet after TCP three-times handshakes. Parent process calss socket API 'connect()' to complete TCP 3times handshakes, at the same time, child process sniffing and inserts the 4th packet.
#!/usr/bin/perl
#By i_am_jojo@msn.com, 2005/04
use strict;
use warnings;

use Net::RawIP;
use Net::PcapUtils;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;

use Socket;
use Getopt::Std;
use POSIX qw(strftime);

my %opts;
getopts('ht:p:u:n:', \%opts);

print_help() and exit if(defined($opts{'h'}));
print_help() and exit if(not defined($opts{'t'}) or not defined($opts{
+'p'}));

die "\tInvalid Target Ipaddress!\n"
    if(defined($opts{'t'}) and $opts{'t'} !~ m/^\d+.\d+.\d+.\d+$/);

die "\tInvalid Service Port!\n"
    if(defined($opts{'p'}) and $opts{'p'} !~ m/^\d+$/);

my $request;
if(defined($opts{'u'})) {
    $request = "GET $opts{'u'} HTTP/1.1\r\n";
    $request.= "Accept: text/html; text/plain\r\n";
    $request.= "\r\n";
} else {
    $request = "GET / HTTP/1.1\r\n";
    $request.= "Accept: text/html; text/plain\r\n";
    $request.= "\r\n";
}

my $child = fork();

if($child == 0) {
    #child process
    my ($next_packet, %next_header);
    my ($ip_obj, $tcp_obj);
    my $counter = 0;

    my $pkt_descriptor = Net::PcapUtils::open(
        FILTER  => 'ip',
        PROMISC => 0,
        DEV     => 'eth0',
    );

    die "Net::PcapUtils::open returned: $pkt_descriptor\n" if (!ref($p
+kt_descriptor));
    print strftime '%Y/%m/%d %H:%M:%S, ', localtime and print "begin s
+niffing ...\n";
    
    while (($next_packet, %next_header) = Net::PcapUtils::next($pkt_de
+scriptor)) {
        $ip_obj = NetPacket::IP->decode(NetPacket::Ethernet::eth_strip
+($next_packet));
        
        next if ($ip_obj->{'proto'} != 6);
        next if (($ip_obj->{'src_ip'} ne $opts{'t'}) and ($ip_obj->{'d
+est_ip'} ne $opts{'t'}));
        
        $tcp_obj = NetPacket::TCP->decode($ip_obj->{'data'});
        next if (($tcp_obj->{'src_port'} ne $opts{'p'}) and ($tcp_obj-
+>{'dest_port'} ne $opts{'p'}));
        
        $counter++;
        
        print "==ID.$counter==", '=' x 60, "\n";
        print get_ip_hdr($ip_obj);
        print get_tcp_hdr($tcp_obj);
        if($tcp_obj->{'data'}) {
            my $data;
            $data = unpack 'a*', $tcp_obj->{'data'};
            $data =~ s/[\r][\n]//g;
            print pretty_table('TCP data', [$data]);
        }
        
        if($counter == 3) {
            my $a = new Net::RawIP;
            $a->set({
                'ip' => {
                    'id'    => $ip_obj->{'id'} + 1,
                    'saddr' => $ip_obj->{'src_ip'},
                    'daddr' => $ip_obj->{'dest_ip'}
                    },
                'tcp' => {
                    'source'  => $tcp_obj->{'src_port'},
                    'dest'    => $tcp_obj->{'dest_port'},
                    'seq'     => $tcp_obj->{'seqnum'},
                    'ack_seq' => $tcp_obj->{'acknum'},
                    'window'  => $tcp_obj->{'winsize'},
                    'data'    => $request,
                    'psh'     => 1,
                    'ack'     => 1
                    }
                });
            $a->send;
        }
        last if($counter == 5);
    }
    exit;
} else {
    sleep(1);
    my $trans_serv = getprotobyname('tcp');
    my $dest_sockaddr = sockaddr_in($opts{'p'}, inet_aton($opts{'t'}))
+;
    
    socket(TCP_SOCK, PF_INET, SOCK_STREAM, $trans_serv);
    connect(TCP_SOCK, $dest_sockaddr);
    sleep(1);
    #close TCP_SOCK;
}

exit;

sub print_help {
    print <<HELP
    
    %./iamFool.pl [-h] <-t,-p,-u,-n>
    -h    print help
    -t    target ipaddr
    -p    service port
    -u    requested url
    
                by:i_am_jojo\@msn.com
                
HELP
}

sub get_ip_hdr {
    my $ip_obj = shift;
    my @ip_hdr;
    
    push @ip_hdr, [qw(ver tos flags id src_ip proto)];
    push @{$ip_hdr[1]}, $ip_obj->{$_} foreach (qw(ver tos flags id src
+_ip proto));
    push @ip_hdr, [qw(hlen len foffset ttl dest_ip cksum)];
    push @{$ip_hdr[3]}, $ip_obj->{$_} foreach (qw(hlen len foffset ttl
+ dest_ip cksum));
    
    return pretty_table('IP Header', @ip_hdr);
}

sub get_tcp_hdr {
    my $tcp_obj = shift;
    my @tcp_hdr;
    
    push @tcp_hdr, [qw(src_port seqnum hlen flags)];
    push @{$tcp_hdr[1]}, $tcp_obj->{$_} foreach (qw(src_port seqnum hl
+en flags));
    push @tcp_hdr, [qw(dest_port acknum reserved winsize)];
    push @{$tcp_hdr[3]}, $tcp_obj->{$_} foreach (qw(dest_port acknum r
+eserved winsize));
    
    return pretty_table('TCP Header', @tcp_hdr);
}

sub pretty_table {
    # prettyTable($aString, @aList); @aList = ( [...], [...] );
    # by i_am_jojo@msn.com
    my ($title, @data) = @_;
    my @temp;
    my @max_length;
    my $row_length;
    my $indent = 4;
    my $the_table;

    foreach my $col (0..$#{$data[0]}) { push @{$temp[$col]}, $_->[$col
+] foreach (@data); }
    $max_length[$_] = length( (sort{length($b) <=> length($a)} @{$data
+[$_]} )[0]) + 2 foreach (0..$#data);
    $row_length+= $max_length[$_] foreach (0..$#{$temp[0]});  
    $row_length+= $#data;
    
    $the_table = ' ' x $indent.'+'.'-' x $row_length."+\n";
    $the_table.= ' ' x $indent.'| '.$title.' ' x ($row_length - length
+($title) - 1)."|\n";
    foreach my $row (0..$#temp) {
        $the_table.= ' ' x $indent;
        $the_table.= '+'.'-' x $max_length[$_] foreach (0.. $#{$temp[0
+]});
        $the_table.= "+\n";
        $the_table.= ' ' x $indent;
        $the_table.= '| '.@{$temp[$row]}[$_].' ' x ($max_length[$_] - 
+length(@{$temp[$row]}[$_]) - 1) foreach (0.. $#{$temp[0]});
        $the_table.= "|\n";
    }
    $the_table.= ' ' x $indent;
    $the_table.= '+'.'-' x $max_length[$_] foreach (0.. $#{$temp[0]});
    $the_table.= "+\n";
    
    return $the_table;
}

#==Output eXample==
#>./iamfool.pl -t xxx.xxx.x.xx -p 80
#2005/05/02 21:49:11, begin sniffing ...
#==ID.1====================================================
#    +-------------------------------------------------+
#    | IP Header                                       |
#    +--------+---------------+---------+--------------+
#    | ver    | 4             | hlen    | 5            |
#    +--------+---------------+---------+--------------+
#    | tos    | 0             | len     | 60           |
#    +--------+---------------+---------+--------------+
#    | flags  | 2             | foffset | 0            |
#    +--------+---------------+---------+--------------+
#    | id     | 16649         | ttl     | 64           |
#    +--------+---------------+---------+--------------+
#    | src_ip | 218.11.149.14 | dest_ip | xxx.xxx.x.xx |
#    +--------+---------------+---------+--------------+
#    | proto  | 6             | cksum   | 44477        |
#    +--------+---------------+---------+--------------+
#    +-----------------------------------------+
#    | TCP Header                              |
#    +----------+-----------+-----------+------+
#    | src_port | 32850     | dest_port | 80   |
#    +----------+-----------+-----------+------+
#    | seqnum   | 976483812 | acknum    | 0    |
#    +----------+-----------+-----------+------+
#    | hlen     | 10        | reserved  | 0    |
#    +----------+-----------+-----------+------+
#    | flags    | 2         | winsize   | 5808 |
#    +----------+-----------+-----------+------+
#==ID.2====================================================
#    +-------------------------------------------------+
#    | IP Header                                       |
#    +--------+--------------+---------+---------------+
#    | ver    | 4            | hlen    | 5             |
#    +--------+--------------+---------+---------------+
#    | tos    | 0            | len     | 64            |
#    +--------+--------------+---------+---------------+
#    | flags  | 2            | foffset | 0             |
#    +--------+--------------+---------+---------------+
#    | id     | 3931         | ttl     | 113           |
#    +--------+--------------+---------+---------------+
#    | src_ip | xxx.xxx.x.xx | dest_ip | 218.11.149.14 |
#    +--------+--------------+---------+---------------+
#    | proto  | 6            | cksum   | 44647         |
#    +--------+--------------+---------+---------------+
#    +----------------------------------------------+
#    | TCP Header                                   |
#    +----------+-----------+-----------+-----------+
#    | src_port | 80        | dest_port | 32850     |
#    +----------+-----------+-----------+-----------+
#    | seqnum   | 780872939 | acknum    | 976483813 |
#    +----------+-----------+-----------+-----------+
#    | hlen     | 11        | reserved  | 0         |
#    +----------+-----------+-----------+-----------+
#    | flags    | 18        | winsize   | 4356      |
#    +----------+-----------+-----------+-----------+
#==ID.3====================================================
#    +-------------------------------------------------+
#    | IP Header                                       |
#    +--------+---------------+---------+--------------+
#    | ver    | 4             | hlen    | 5            |
#    +--------+---------------+---------+--------------+
#    | tos    | 0             | len     | 52           |
#    +--------+---------------+---------+--------------+
#    | flags  | 2             | foffset | 0            |
#    +--------+---------------+---------+--------------+
#    | id     | 16651         | ttl     | 64           |
#    +--------+---------------+---------+--------------+
#    | src_ip | 218.11.149.14 | dest_ip | xxx.xxx.x.xx |
#    +--------+---------------+---------+--------------+
#    | proto  | 6             | cksum   | 44483        |
#    +--------+---------------+---------+--------------+
#    +----------------------------------------------+
#    | TCP Header                                   |
#    +----------+-----------+-----------+-----------+
#    | src_port | 32850     | dest_port | 80        |
#    +----------+-----------+-----------+-----------+
#    | seqnum   | 976483813 | acknum    | 780872940 |
#    +----------+-----------+-----------+-----------+
#    | hlen     | 8         | reserved  | 0         |
#    +----------+-----------+-----------+-----------+
#    | flags    | 16        | winsize   | 1452      |
#    +----------+-----------+-----------+-----------+
#==ID.4====================================================
#    +-------------------------------------------------+
#    | IP Header                                       |
#    +--------+---------------+---------+--------------+
#    | ver    | 4             | hlen    | 5            |
#    +--------+---------------+---------+--------------+
#    | tos    | 16            | len     | 89           |
#    +--------+---------------+---------+--------------+
#    | flags  | 2             | foffset | 0            |
#    +--------+---------------+---------+--------------+
#    | id     | 16652         | ttl     | 64           |
#    +--------+---------------+---------+--------------+
#    | src_ip | 218.11.149.14 | dest_ip | xxx.xxx.x.xx |
#    +--------+---------------+---------+--------------+
#    | proto  | 6             | cksum   | 44429        |
#    +--------+---------------+---------+--------------+
#    +----------------------------------------------+
#    | TCP Header                                   |
#    +----------+-----------+-----------+-----------+
#    | src_port | 32850     | dest_port | 80        |
#    +----------+-----------+-----------+-----------+
#    | seqnum   | 976483813 | acknum    | 780872940 |
#    +----------+-----------+-----------+-----------+
#    | hlen     | 5         | reserved  | 0         |
#    +----------+-----------+-----------+-----------+
#    | flags    | 24        | winsize   | 1452      |
#    +----------+-----------+-----------+-----------+
#    +--------------------------------------------+
#    | TCP data                                   |
#    +--------------------------------------------+
#    | GET / HTTP/1.1Accept: text/html; text/plai |
#    +--------------------------------------------+
#==ID.5====================================================#    +-----
+--------------------------------------------+
#    | IP Header                                       |
#    +--------+--------------+---------+---------------+
#    | ver    | 4            | hlen    | 5             |
#    +--------+--------------+---------+---------------+
#    | tos    | 0            | len     | 52            |
#    +--------+--------------+---------+---------------+
#    | flags  | 2            | foffset | 0             |
#    +--------+--------------+---------+---------------+
#    | id     | 3933         | ttl     | 113           |
#    +--------+--------------+---------+---------------+
#    | src_ip | xxx.xxx.x.xx | dest_ip | 218.11.149.14 |
#    +--------+--------------+---------+---------------+
#    | proto  | 6            | cksum   | 44657         |
#    +--------+--------------+---------+---------------+
#    +----------------------------------------------+
#    | TCP Header                                   |
#    +----------+-----------+-----------+-----------+
#    | src_port | 80        | dest_port | 32850     |
#    +----------+-----------+-----------+-----------+
#    | seqnum   | 780872940 | acknum    | 976483862 |
#    +----------+-----------+-----------+-----------+
#    | hlen     | 8         | reserved  | 0         |
#    +----------+-----------+-----------+-----------+
#    | flags    | 16        | winsize   | 4356      |
#    +----------+-----------+-----------+-----------+
#==End==
Replies are listed 'Best First'.
Re: Insert the 4th TCP packet after TCP three-times handshakes
by merlyn (Sage) on May 03, 2005 at 10:13 UTC
      The code is ejecting packets into its own session (see fork + connect). As it stands right now this can't be used for "Evil".

      There are legit uses for injecting packets like this. I do something similar for testing IP stacks. Though, I handle the full session by hand.

        If the initial sequence number of the other side could be predicted, blind tcp initial and inject(use a source ip address that not alive)may be possible.
      People seem to be overreacting here. You admittedly took only a brief look at the code, saw the use of raw IP, and assumed the worst. (And even made a consideration based on that). If raw IP is so terrible, why not campaign for the module to be removed from CPAN? Lots of things are potentially usable for "bad stuff", but aren't used that way. If we're not going to trust our fellow man to some degree, we might as well all stay home in bed all day.

      C.

        You presume things that are not so. There's a lot more that went on in my head than your simplified model.

        Keep in mind that I've made it both a personal and professional interest over the years to understand ways to subvert authentication schemes and bypass firewalls and generally reek havoc.

        And also keep in mind that my default setting for any new encounter is "trust".

        I did in fact scan the code about half a dozen times, looking carefully at the design of the packets. I still don't completely understand what it starts to do, but there's obviously a lot of work going on, and that means that there's a payoff for the user.

        So, this thing smells. My spidey sense is not easily activated, and yet it was.

        Also, my initial observation was also supported later in the thread. This person is potentially up to no good, and has not yet shown anything to the contrary. This also contributes to a validation of my initial observations.

        I'm not as prejudiced as you think I might be. I'm wondering why you're so prejudiced about me. {sigh}

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: Insert the 4th TCP packet after TCP three-times handshakes
by mstone (Deacon) on May 04, 2005 at 01:06 UTC

    I'm provisionally with merlyn on this. While the code may be an interesting example of how to do TCP/IP, please give us some discussion on that subject. All we have here is a code listing and an output dump.

    Yes, the code is interesting, in the sense that all non-trivial code is interesting, but as mentioned, it also has the whiff of potential naughtiness. Without some other information to give this node/thread more oomph, I don't see how the monastery would be harmed by having the Powers That Be say, "thank you, that was very nice, and now we're making it go away."

      it also has the whiff of potential naughtiness

      Oh, great. Republicans have made it in here, too.

        Pardonnez? I vote a straight-Pogo ticket. ;-)

        I also happen to do network security, which involves paranoia and concepts like, "trust, but verify." I've requested verification, and will be happy to support the node if I see some. In the absence of verification, I will consider witholding my trust.

      Okay, firstly sorry to my poor english.

      (1).TCP three-times handshakes: A( SYN, ISN_A ) -> B A <- B( SYN/ACK, ISN_B/ACK_AISN_A+1 ) A( SYN/ACK, ACK_A/ACK_BISN_B+1 ) -> B Socket API 'connect()' just does the 3times handshakes. 'sleep(1)' is to sure that sniffer child is running. In sniffer child, only captures the related packets, it's object is to get the ISN_B of this connection. After the handshakes is over, pack a packet to B and inject it into the connection. And if you don't want the connection closed, you must pack a correct packet to A too. (2).Blind handshakes If the ISN of B is predicted. You can capture ISNs of each connection and analyst the numbers. For example, the ISN of B is not change anytime. A - i B - you, ISN will not change. C - he I: A(src_ip:C, SYN, ISN_Cany) -> B II: C <- B(dest_ip:C, SYN/ACK, ISN_B/ACK_CISN_C+1 ) if C is active: III: C(dest_ip:B, RST) -> B if C is not active: IV: A(src_ip:C, SYN/ACK, ACK_C/ACK_BISN_B+1 ) -> B If i can 'see' the packet II(for example, C and A are in the same network), i can get the ISN_B correctly. And if the C is not alive, i can generate the packet IV to complete the 3times handshakes from C->B. And if i can not 'see' the packet II(C is not in my networks and not in my HUB/Switch device), i could guess the ISN_B as before analyst. This is called ip spoof. ... It's an old tcp game.
      -------------------------- I 4m jU$t A $cRipt /<iddi3

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://453500]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found