Skip to content

Instantly share code, notes, and snippets.

@ricardojba
Forked from DiabloHorn/ipless-scan.py
Created October 30, 2017 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricardojba/590f0dd099dffd2d440427f1f74bf786 to your computer and use it in GitHub Desktop.
Save ricardojba/590f0dd099dffd2d440427f1f74bf786 to your computer and use it in GitHub Desktop.
Perform a port scan without having an IP configured on your network interface
#!/usr/bin/env python
# DiabloHorn - https://diablohorn.com
# scan target IP from an interface with no IP configured
# POC - scapy
# pkt = Ether(dst='00:0c:29:f6:a5:65',src='00:08:19:2c:e0:15') / IP(dst='172.16.218.178',src='172.16.218.255') / TCP(dport=445,flags='S')
# sendp(pkt,iface='eth0')
import sys
from scapy.all import *
import time
import threading
import argparse
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
class checkreply(threading.Thread):
def __init__(self, iface, dip, dports):
self.started = True
self.iface = iface
self.dip = dip
self.dports = dports
self.portseen = []
threading.Thread.__init__(self)
def run(self):
logging.debug('Sniffer thread called')
sniff(iface=self.iface,store=0,prn=self.checkport,stop_filter=self.stopflag,filter="tcp and host {0}".format(self.dip))
def checkport(self,pktdata):
logging.debug('Sniffer packet inspection triggered')
if pktdata.haslayer(TCP):
tcpdata = pktdata.getlayer(TCP)
#check if syn and ack flags are set
if tcpdata.sport not in self.portseen:
if ((tcpdata.flags >> 1) & 1) and ((tcpdata.flags >> 4) & 1):
if tcpdata.sport in self.dports:
logging.info('Found open port - %s' % tcpdata.sport)
self.portseen.append(tcpdata.sport)
#check if reset flag set
if ((tcpdata.flags >> 2) & 1):
if tcpdata.sport in self.dports:
logging.info('Found closed port - %s' % tcpdata.sport)
self.portseen.append(tcpdata.sport)
def stopflag(self, pktdata):
logging.debug('Sniffer thread check stop flag')
if self.started:
return False
return True
def stopsniffer(self):
self.started = False
def convert2bcast(ip):
parts = ip.split('.')
parts[3] = 255
return '.'.join(str(x) for x in parts)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='port scan target IPs from interface without IP assigned')
parser.add_argument('targetip',type=str,help='target ip to perform port scan on')
parser.add_argument('targetmac',type=str,help='target MAC address of IP')
parser.add_argument('-i', '--iface',type=str,required=True,help='network interface to use')
parser.add_argument('-p', '--ports',nargs='+',type=int,required=True,help='space separated list of ports')
parser.add_argument('-m', '--smac',type=str,help='mac address used to send packets, defaults to current')
myargs = parser.parse_args()
logging.info('Started ipless port scan')
#https://stackoverflow.com/a/32080877
if myargs.smac is None:
with open('/sys/class/net/{0}/address'.format(myargs.iface),'r') as macfile:
myargs.smac = macfile.readline().strip()
replychecker = checkreply(myargs.iface,convert2bcast(myargs.targetip),myargs.ports)
replychecker.start()
logging.info('Started sniffer and waiting 10s')
time.sleep(10)
logging.info('Starting port scan')
for port in myargs.ports:
logging.debug('Scanning port - %s' % port)
pkt = Ether(dst='{0}'.format(myargs.targetmac),src='{0}'.format(myargs.smac)) / IP(dst='{0}'.format(myargs.targetip),src='{0}'.format(convert2bcast(myargs.targetip))) / TCP(dport=port,flags='S')
sendp(pkt,verbose=False)
logging.info('Finished port scan, waiting 5s for packets')
time.sleep(5)
replychecker.stopsniffer()
replychecker.join()
logging.info('Stopped sniffer')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment