Wednesday, July 15, 2015

Traceroute and scapy

Recently I was conducting few interviews for a NOC position. One of the questions asked to candidates was quite simple: how traceroute works?

We know that each router decrements TTL of the packet by 1. When TTL=0 ICMP message with type 11 should be sent by router. Type 11 is Time Exceeded.

Traceroute works on this basic principle. For instance we would like see the path from HostA to HostB:

1) HostA sends the packet with TTL=1
2) See who sends back ICMP message with Time Exceeded
3) If it is HostB - finish
4) Otherwise - we found our first hop. Increase TTL by one and go to step #1

That's it.

It is also good to remember, that Windows uses ICMP by default for tracert, whereas Linux and Cisco use UDP for their traceroute command. Anyhow, even TCP could be used.

Here is a simple python script with scapy that shows how traceroute works:
#!/usr/bin/env python

from scapy.all import *
import sys
import socket

def usage():

    print("""
    ./traceroute.py host

    example: ./traceroute.py 8.8.8.8
    """)

    return

def print_hop(number = 0, host = ''):

    print("%s %s" % (number, host))
    return


if len(sys.argv) < 2:

    usage()
    sys.exit(0)

HOST = sys.argv[1]

DSTHOST = socket.gethostbyname(HOST)
MAXTTL = 30

print("trace to %s (%s)" % (HOST, DSTHOST))

for i in range(1, MAXTTL, 1):
    packet = IP(dst=DSTHOST, ttl=i)/ICMP()
    resp = sr(packet, timeout=2, verbose=False)

    try:
        srcip = resp[0][0][1].src
        print_hop(i, srcip)

        if srcip == DSTHOST:
            break
    except:
        print_hop(i, "***")

Try replacing ICMP() with TCP(dport=12345) or UDP(dport=12345) at line #36 an see what happens.

No comments:

Post a Comment