« torrenty.org update | Main | Perfect Deniability »
This can only mean one Thing! Injection!
By supergrobi | January 30, 2007
Today, supergrobi explains how a connection to a tracker should NOT look like!
You ever wondered why it seems that our tracker answers your announce requests with an RST packet thus destroying your connection? Think again! It is your ISP who tries to kill your connection without admitting it to save bandwidth for which you probably paid money.
Lets look how an ordinary TCP connection is set up.
First you send a SYN packet to the tracker:
03:38:07.763665 IP (tos 0x0, ttl 104, id 28391, offset 0, flags [DF], proto: TCP (6), length: 48) 1.2.3.4.1737 > 217.13.206.147.6969: S, cksum 0x764c (correct), 3957760381:3957760381(0) win 16384
Our tracker answers this with a SYN and ACK:
03:38:07.763687 IP (tos 0x0, ttl 64, id 51007, offset 0, flags [DF], proto: TCP (6), length: 48) 217.13.206.147.6969 > 1.2.3.4.1737: S, cksum 0x0bcb (correct), 2652573014:2652573014(0) ack 3957760382 win 65535
Your clients also acknowledges this with an ACK:
03:38:08.163338 IP (tos 0x0, ttl 104, id 28398, offset 0, flags [DF], proto: TCP (6), length: 40) 1.2.3.4.1737 > 217.13.206.147.6969: ., cksum 0xf31d (correct), ack 1 win 17520
Now both ends of the connection have exchanged the sequence numbers (3957760381 and 2652573014) – the client could send the actual request to the client. But look closer and see what happens next:
03:38:08.165227 IP (tos 0x0, ttl 13, id 0, offset 0, flags [DF], proto: TCP (6), length: 62) 1.2.3.4.1737 > 217.13.206.147.6969: R, cksum 0xf303 (correct), 1:23(22) ack 1 win 17520 [RST 00000000000000000000000000000000000000000000]
This is an RST packet which destroys the connection no matter what. The tracker will not accept any more packets from this connection after it received this RST packet. So this client will never get any peers from our tracker.
But why did I choose the peculiar title of this blog entry? This RST is NOT sent by the client – it is injected. It even has a different TTL and a payload of 22 bytes filled with zeros which is unusual AND useless for an RST packet. Let’s look at the next packet:
03:38:17.151116 IP (tos 0x0, ttl 104, id 29025, offset 0, flags [DF], proto: TCP (6), length: 471) 1.2.3.4.1737 > 217.13.206.147.6969: P, cksum 0xddd8 (correct), 1:432(431) ack 1 win 17520
This is the actual announce request from client to tracker. But it comes ca. nine seconds later and has the same sequence number as the RST packet. So one of both packets is injected. You can guess which! Since our tracker has no state for this connection anymore it will answer this request with another RST, which is normal behavior.
So what happened here? After some head scratching and googling we think we can explain it. Somewhere between client and tracker sits a filter. THEY use it to sniff the first data packet of a connection. There is not so much else THEY can do to detect bittorrent traffic. Bittorrents tracker protocol can use any port and uses HTTP GET request for its tracker⇔client communication. So THEY need to look inside packets and scan for strings like ‘info_hash’ (‘info_hash’ is unavoidable because it is part of the bittorrent spec).
Once THEY identifiy that it is a bittorrent announce request, THEY drop it and send an RST packet instead. Some ISPs do not send such an RST packet back to the client. Your client still waits for an ACK for this request packet. But our tracker got THEIR RST packet and will not send this ACK, so your client is sending the announce request again. Since THEIR filter only sniffs the first data packet of a connection (it would be too much work to inspect every packet from every connection) this packet does not get filtered and arrives nine seconds later at the tracker.
Actually once we tried to filter incoming RST packets for our tracker, enabling us to successfully answer the arriving (second) announce request packet. The problem is, that we can not filter the RST packets from the whole internet because it costs us too much open sockets while it generates alot of connections in a wait state (they invented this RST flag with a reason after all!).
So if anyone has some suggestions how this ISP p2p blocking can be avoided, leave a comment.
Topics: tech | 9 Comments »
January 30th, 2007 at 10:00 pm
btw. this is the same technique the “great firewall” of china uses (lost the source but I think fefe posted it once), sending RST to both ends if unwanted traffic occurs…
January 31st, 2007 at 12:47 am
But in this case they only sends an RST to the server, not to the client! Otherwise the client wouldn’t try again with another announce 9 seconds after we got the injected RST.
Sending an RST to the client would be useless anyway, because this is easy to filter on the client-side. Sending it to the tracker is much more useful, because most tracker owners don’t care!
January 31st, 2007 at 8:56 pm
You might want to look here: http://www.cl.cam.ac.uk/~rnc1/ for the firewall-of-china paper.
February 4th, 2007 at 12:51 pm
HTTPS –
http://wiki.theory.org/BitTorrentSpecification#Tracker_HTTP.2FHTTPS_Protocol
February 7th, 2007 at 7:47 pm
Well, some problems DO occur.
• First, only a fraction, a really tiny fraction, of torrents do include https-URLs for their trackers.
• Second, to circumvent omnipotent firewalls you would have to include your tracker’s fingerprint in those torrents or buy a signature for your certificate.
• Third, clients will need to talk https (the most recent ones, using their OS’s http-engine do).
• Fourth, handling thousands of connections per second suddenly becomes a problem when bignum arithmetics get involved. One would use an ssl proxy to do that, anyway and with an appropriate amount of money you can use crypto accelerators. Until now no open tracker seems to be willing to spend that amount of money or cpu ressources.
However, thanks for pointing out that option.
March 25th, 2007 at 6:46 pm
Hmm,
just a thought: Instead of dropping RST packets, maybe just hold them back? This ensures that legitimate RST packets get to the kernel and can properly close connections and injected packets (hopfully) arrive after the original packet. You’re out of luck if the ISP drops the original packet, which they probably will if the filter vendor notices this “delay” trick in wide use…
November 22nd, 2007 at 7:59 pm
Using HTTPS with RC4 or what ever bad but fast crypto is available.
November 24th, 2007 at 8:54 am
“Since THEIR filter only sniffs the first data packet of a connection [...]”
Would it be possible to send a dummy ‘first packet’?
July 3rd, 2008 at 12:01 pm
Salam
What do your think about remove downloader ?