Archive

Archive for the ‘Python’ Category

Understanding traceroute using Scapy

April 18, 2015 Leave a comment

 

Scapy is a packet generator/sniffer and in this post we will be discussing the use of scapy to understand the working of traceroute. And the best part is that, its pythonic 😀

 

Assumptions made:

 

1) I am having a test vm with following details,

Hostname: client1.jackal.com
IP : 192.168.122.101
interface: eth0
Gateway: 192.168.122.1

2) tcpdump is installed on the test vm
3) We are doing a traceroute to google open dns ip 8.8.8.8

 

Explanation:

 

Open two command prompts on your test VM in which one interface contains the traceroute running with the following options,

 

root@client1:~# tcpdump -v -i eth0 -n -t icmp and port not 22

On the other prompt type “scapy” which will open up an interpreter,

 

root@client1:~# 
root@client1:~# scapy
>>> 

Now follow the steps outlined below,

1) Send packet 1 with ttl set as 1,

>>> send(IP(dst='8.8.8.8', ttl=1)/ICMP())
.
Sent 1 packets.
>>> 

In tcpdump output you will see the following(step 2,3, etc. also contains tcpdump output shown after packet send operation),

IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0xc0, ttl 64, id 18982, offset 0, flags [none], proto ICMP (1), length 56)
    192.168.122.1 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
2) Send packet 2 with ttl set as 2,

>>> send(IP(dst='8.8.8.8', ttl=2)/ICMP())
.
Sent 1 packets.
>>> 

tcpdump output,

IP (tos 0x0, ttl 2, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 253, id 51505, offset 0, flags [none], proto ICMP (1), length 56)
    10.111.44.1 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
3) Send packet 3 with ttl set as 3. Here you won’t get “ICMP time exceeded in-transit” message. That means that router have either disabled icmp responses or not accessible. You usually see “3 * * *” as responses in such cases of traceroute. Retry 3 times and if you are receiving the same response then display ” * * *”

>>> send(IP(dst='8.8.8.8', ttl=3)/ICMP())
.
Sent 1 packets.
>>> send(IP(dst='8.8.8.8', ttl=3)/ICMP())
.
Sent 1 packets.
>>> send(IP(dst='8.8.8.8', ttl=3)/ICMP())
.
Sent 1 packets.
>>> 
IP (tos 0x0, ttl 3, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 3, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 3, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
4) Send packet 4 with ttl set as 4.

>>> send(IP(dst='8.8.8.8', ttl=4)/ICMP())
.
Sent 1 packets.
>>> 
IP (tos 0x0, ttl 4, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 252, id 62907, offset 0, flags [none], proto ICMP (1), length 96)
    182.73.11.177 > 192.168.122.101: ICMP time exceeded in-transit, length 76
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
5) Send packet 5 with ttl set as 5,

>>> send(IP(dst='8.8.8.8', ttl=5)/ICMP())
.
Sent 1 packets.
>>> 
IP (tos 0x0, ttl 5, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 250, id 25844, offset 0, flags [none], proto ICMP (1), length 96)
    182.79.247.9 > 192.168.122.101: ICMP time exceeded in-transit, length 76
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
6) Send packet 6 with ttl set as 6,

>>> send(IP(dst='8.8.8.8', ttl=6)/ICMP())
.
Sent 1 packets.
>>> 
IP (tos 0x0, ttl 6, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 247, id 0, offset 0, flags [none], proto ICMP (1), length 56)
    72.14.223.230 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
7) Send packet 7 with ttl set as 7,

>>> send(IP(dst='8.8.8.8', ttl=7)/ICMP())
.
Sent 1 packets.
>>> 
IP (tos 0x0, ttl 7, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0xc0, ttl 246, id 31013, offset 0, flags [none], proto ICMP (1), length 56)
    72.14.237.3 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x80, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8

 
8) Send packet 8 with ttl set as 8,

>>> send(IP(dst='8.8.8.8', ttl=8)/ICMP())
.
Sent 1 packets.
>>> 
IP (tos 0x0, ttl 8, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 54, id 23662, offset 0, flags [none], proto ICMP (1), length 28)
    8.8.8.8 > 192.168.122.101: ICMP echo reply, id 0, seq 12535, length 8

This means that the source server is able to identify the destination host in the 8th hop. By default the traceroute program performs upto 30 hops and if its unable to find the destination in 30 hops, it will print a host unreachable message.

The traceroute program actually sends/forwards an ICMP packet with source address set as the machine’s ip in which traceroute is run, and it also sets the TTL value to 1 initially. So when the packet reaches the immediate next router, it reduces the packets TTL by 1 and finds the TTL has reached 0. So it returns a message ICMP time exceeded in-transit to the sender address in packet header. Next time, the sender again increments the TTL value by 1(TTL is now 2) and sends the packet to the destination which will fail on the second router because the TTL of packet will be 0 after it reaches the second router and hence it won’t forward it, but instead reply back to sender with the same message as before. This same logic is applied for subsequent hops, until the packet reaches the destination.
 

 

To Send all 8 packets at once,

>>> send(IP(dst='8.8.8.8', ttl=(1,8))/ICMP())
........
Sent 8 packets.
>>> 

 

IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0xc0, ttl 64, id 18988, offset 0, flags [none], proto ICMP (1), length 56)
        192.168.122.1 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 2, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 253, id 55537, offset 0, flags [none], proto ICMP (1), length 56)
        10.111.44.1 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 3, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 4, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 5, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 6, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 250, id 29640, offset 0, flags [none], proto ICMP (1), length 96)
        182.79.247.9 > 192.168.122.101: ICMP time exceeded in-transit, length 76
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 252, id 14334, offset 0, flags [none], proto ICMP (1), length 96)
        182.73.11.177 > 192.168.122.101: ICMP time exceeded in-transit, length 76
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 7, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 8, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 247, id 0, offset 0, flags [none], proto ICMP (1), length 56)
        72.14.223.230 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0xc0, ttl 246, id 40140, offset 0, flags [none], proto ICMP (1), length 56)
        72.14.237.3 > 192.168.122.101: ICMP time exceeded in-transit, length 36
	IP (tos 0x80, ttl 1, id 1, offset 0, flags [none], proto ICMP (1), length 28)
    192.168.122.101 > 8.8.8.8: ICMP echo request, id 0, seq 0, length 8
IP (tos 0x0, ttl 54, id 28109, offset 0, flags [none], proto ICMP (1), length 28)
        8.8.8.8 > 192.168.122.101: ICMP echo reply, id 0, seq 14816, length 8

Install paramiko on linux without root access

August 21, 2012 1 comment

 

Install python paramiko module. This module requires the python-dev and pycrypto package. If you dont have root access to the system, then you can manage to add these modules to python as depicted below,

 

 

 

1) List the download url of python-dev packages, and then extract it to python-dev directory.

 

# apt-get --print-uris install python-dev -y|awk ' /http/ {print $1}'|cut -d\' -f2
http://us.archive.ubuntu.com/ubuntu/pool/main/p/python2.6/python2.6-dev_2.6.5-1ubuntu6_i386.deb
http://us.archive.ubuntu.com/ubuntu/pool/main/p/python-defaults/python-dev_2.6.5-0ubuntu1_all.deb
# mkdir -p /home/username/python/{modules,custommodules}
# mkdir /home/username/python/modules/python-dev
# cd /home/username/python/modules
# wget http://us.archive.ubuntu.com/ubuntu/pool/main/p/python2.6/python2.6-dev_2.6.5-1ubuntu6_i386.deb
# wget http://us.archive.ubuntu.com/ubuntu/pool/main/p/python-defaults/python-dev_2.6.5-0ubuntu1_all.deb
# dpkg-deb -x python2.6-dev_2.6.5-1ubuntu6_i386.deb python-dev/
# dpkg-deb -x python-dev_2.6.5-0ubuntu1_all.deb python-dev/

 

Copy the development files of python from python-dev to source files directory of pycrypto-2.6 and use it for installing pycrypto. If you are not doing this then you will get an error like “error: Python.h: No such file or directory

 

# wget http://pypi.python.org/packages/source/p/pycrypto/pycrypto-2.6.tar.gz#md5=88dad0a270d1fe83a39e0467a66a22bb
# tar xzf pycrypto-2.6.tar.gz
# cd /home/username/python/modules/pycrypto-2.6
# cp -pr ../python-dev/usr/include/python2.6/* src/
# python setup.py install --prefix=/home/username/python/custommodules

 

 

2) Install paramiko

 

# cd /home/username/python/modules
# wget http://www.lag.net/paramiko/download/paramiko-1.7.7.1.tar.gz
# tar xzf paramiko-1.7.7.1.tar.gz
# python paramiko-1.7.7.1/setup.py  install --prefix=/home/username/python/custommodules

 

3) Now test whether python paramiko module is loaded or not

 

# python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import sys
>>> sys.path.append('/home/username/python/custommodules/lib/python2.6/site-packages')
>>> import paramiko
>>> ssh = paramiko.SSHClient()
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect('10.19.54.63',username='root',password='dK7:?Yjo')
>>> stdin, stdout, stderr = ssh.exec_command("ls /root")
>>> stdout.readlines()
['file1\n', '\\\n', 'ljsh\n', 'test\n', 'tmp\n']
>>> ssh.close()
>>> exit()
# 

 

 

Hope this helps someone:)

 

Categories: Python