sniffMyPackets: Finding Tor

I don’t normally do short random posts but I figure once in a while won’t hurt.

So I’ve been busy working on new transforms for my Maltego pcap analysis package and things are moving along nicely. Part of my process is making notes on things I think would be cool to see and then working my way through the list.

Over the weekend I added “Tor Traffic” to my list, I know most of the traffic is encrypted so wasn’t sure if I could get an end result from it but figure it was worth a look.

Anyway I ‘ve thrown together some Scapy/Python code (soon to be a transform if it’s right) that I think will highlight Tor traffic in a pcap file. Now this is just a work in progress so let me know if I’ve miles off the mark (so to speak).

I created a pcap file by stopping the Tor service on my copy of Backtrack and then starting it again while capturing some packets. I’ve also tested it on another pcap file from the internet with some Tor bot traffic and the results are similar.

Looking through the pcap file I noticed some “strange” entries during the SSL handshake that lead me to my PoC code (no I didn’t Google first to see if it already existed).

During the SSL handshake the “Client Hello” packet includes a Server Name record which in a “normal” handshake might be similar to however with a Tor SSL handshake its something like ““, which if you ping doesn’t actually exist.

The other thing to note is that the SSL server name doesn’t have a corresponding DNS query, in fact for all the packets in the pcap file there are no DNS queries/responses which is another way to narrow down possible Tor traffic.

The sniffMyPackets transform can be found HERE:

So basically my python code reads a pcap file and looks for any TCP packet with a payload, that has http://www.xxxxxx in it. It then pulls out the key information (src ip, dst ip, sport, dport and www. value). and just displays it as neat little lines.

The code is below:

#!/usr/bin/env python

import logging, sys
from scapy.all import *

pcap = sys.argv[1]

pkts = rdpcap(pcap)

for x in pkts:
if x.haslayer(TCP) and x.haslayer(Raw):
if ‘www.’ in x.getlayer(Raw).load:
for s in re.finditer(‘www.\w.\w‘, str(x)):
dnsrec =
srcip = x.getlayer(IP).src
dstip = x.getlayer(IP).dst
sport = x.getlayer(TCP).sport
dport = x.getlayer(TCP).dport
ipaddr = srcip, dstip, sport, dport, dnsrec
print ipaddr

If I run this against my pcap file I get these results:

root@bt:~# ./ /root/pcaps/tor-startup.pcap
src: dst: sport: 40651 dport: 9001 dnsrec:
src: dst: sport: 9001 dport: 40651 dnsrec: www.vlkkj3kgxh56ibujher.net0
src: dst: sport: 48459 dport: 443 dnsrec:
src: dst: sport: 443 dport: 48459 dnsrec: www.yhlkhxjmzg3.net0
src: dst: sport: 44829 dport: 443 dnsrec:
src: dst: sport: 443 dport: 44829 dnsrec: www.uvk2wwbbvwpqpkux.net0

What you will notice is that the reply packet has a different dnsrec which always has a 0 (zero) on the end..

I’ve tested this on a few pcap files and the results look consistent. Let me know what you think.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s