Search code examples
pythonpython-2.7tcpscapyport-scanning

TCP port scanner written in Python using Scapy yields no response


I’m trying to make a TCP port scanner, but I’m sticking to a very simple example that I lined together from a more advanced example I found online.

I don’t get any errors.

I’m expecting the code to show me that port 80 is open since I started my Apache server on my Linux box.

Here is the code:

#!/usr/bin/python

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *

ip = "127.0.0.1"
port = 80

response = sr1(IP(dst=ip)/TCP(dport=port, flags="S"),verbose=False, timeout=0.2)

if response :
    if response[TCP].flags == 18 :    
        print "Port open"

Warning I had (but that does not show up any more):

WARNING: No route found for IPv6 destination :: (no default route?)

I read that including these two lines below would help on the error:

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

Nmap scan:

STATE SERVICE
80/tcp   open  http

The output is… Nothing at all.

I tried several things like changing the port to different other ports, some which I had open and some which I did not.

Any ideas as to what I did wrong?


Solution

  • The scapy docs mention that the loopback address is a special case

    The loopback interface is a very special interface. Packets going through it are not really assembled and dissassembled. The kernel routes the packet to its destination while it is still stored an internal structure. What you see with tcpdump -i lo is only a fake to make you think everything is normal. The kernel is not aware of what Scapy is doing behind his back, so what you see on the loopback interface is also a fake. Except this one did not come from a local structure. Thus the kernel will never receive it.

    In order to speak to local applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems that Linux):

    >>> conf.L3socket
    <class __main__.L3PacketSocket at 0xb7bdf5fc>
    >>> conf.L3socket=L3RawSocket
    >>> sr1(IP(dst="127.0.0.1")/ICMP())
    <IP  version=4L ihl=5L tos=0x0 len=28 id=40953 flags= frag=0L ttl=64 proto=ICMP chksum=0xdce5 src=127.0.0.1 dst=127.0.0.1 options=''
    

    |\>

    However testing this on my OS-X machine results in the following error:

    >>> conf.L3socket=L3RawSocket
    >>> sr1(IP(dst="127.0.0.1")/ICMP())
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scapy/sendrecv.py", line 334, in sr1
        s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scapy/supersocket.py", line 64, in __init__
        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
    AttributeError: 'module' object has no attribute 'AF_PACKET'
    

    So your mileage may vary

    EDIT

    Apparently this is a known bug in scapy on BSD like systems (including OS-X): http://bb.secdev.org/scapy/issue/174/sniffing-loopback-in-mac-os-x-darwin