Hijacking TCP
by kpcyrd, medium read,
I was working on a TAMUctf level which was a 2FA protected telnet server. Since I was already in a mitm position and I didn’t want to mess around with their authentication, I came up with the idea of hijacking the tcp connection.
After a quick google search I found shijack. Turned out that it’s from 2001 and I couldn’t find a libnet version which was compatible. Also, I didn’t feel like running the precompiled binaries.
So I started writing rshijack, doing this required the following steps:
- (setup) get in a mitm position and find a connection you’re interested in, then start rshijack
- sniff on the interface until a tcp packet of that connection is found
- read the seq and ack fields
- send a spoofed tcp packet with matching src/dst ip, src/dst port, seq and ack with our own data
The sniffing part is rather straight forward: use a pcap library, use the packet parser that’s also used for sniffglue and check each packet until you find a good one.
SEQ and ACK are both random numbers that are increased by the number of bytes sent/received. SEQ is for our bytes sent, ACK for the bytes we received from our peer.
Next, we increase SEQ by the number of bytes we found in the packet to ensure our state of the connection is in-sync.
Afterwards, I’ve opened a raw socket with pnet and crafted a packet manually. This involved:
- Build an IP header with the correct src/dest ip address
- Build a TCP header with the correct SEQ, ACK, src/dest port
It took me about an hour to get it to work because I forgot to calculate the tcp checksum.
There are ways to improve this, the original shijack implementation sent 1024 null bytes to hijack the connection to ensure we don’t get de-synced. This wasn’t needed for me because the connection was slow enough and I only needed to inject a single packet.