Skip to content

Instantly share code, notes, and snippets.

@garyconstable
Last active September 6, 2022 21:32
Show Gist options
  • Save garyconstable/5611be3154d8cde9ee28 to your computer and use it in GitHub Desktop.
Save garyconstable/5611be3154d8cde9ee28 to your computer and use it in GitHub Desktop.
Python port scanner - TCP SYN (half open) scanning
from scapy.all import sr, IP, TCP
import argparse
import time
class scanner():
def __init__(self, host_start, host_end):
self.host_start = host_start
self.host_end = host_end
self.init_packet()
def ipRange(self, start_ip, end_ip):
start = list(map(int, start_ip.split(".")))
end = list(map(int, end_ip.split(".")))
temp = start
ip_range = []
ip_range.append(start_ip)
while temp != end:
start[3] += 1
for i in (3, 2, 1):
if temp[i] == 256:
temp[i] = 0
temp[i-1] += 1
ip_range.append(".".join(map(str, temp)))
return ip_range
def init_packet(self):
if self.host_end != None:
ip_range = self.ipRange(self.host_start, self.host_end)
for ip in ip_range:
packet = IP(dst=ip)
packet /= TCP(dport=range(1, 1025), flags="S")
self.scan( packet, ip )
time.sleep(1)
else:
packet = IP(dst=self.host_start)
packet /= TCP(dport=range(1, 1025), flags="S")
self.scan( packet, self.host_start )
def scan(self, packet, ip_address):
answered, unanswered = sr(packet, timeout=1)
res = {}
#process unanswered packets
for packet in unanswered:
res[packet.dport] = "filtered"
#processed answered packets
for (send, recv) in answered:
#got ICMP error message
if recv.getlayer("ICMP"):
type = recv.getlayer("ICMP").type
code = recv.getlayer("ICMP").code
#port unrecable
if code == 3 and type == 3:
res[send.dport] = "Closed"
else:
res[send.dport] = "Got ICMP with type " + str(type) + " and code " + str(code)
else:
flags = recv.getlayer("TCP").sprintf("%flags%")
#Got SYN/ACK
if flags == "SA":
res[send.dport] = "Open"
#Got RST
elif flags == "R" or flags == "RA":
res[send.dport] = "Closed"
#Got something
else:
res[send.dport] = "Got packets with flags " + str(flags)
#Print res
ports = res.keys()
ports.sort()
for port in ports:
if res[port] != "Closed":
print ("[" + str(ip_address) + ":" + str(port) + "] " + res[port])
def main():
parser = argparse.ArgumentParser( description = 'scan.py - Port Scanner - python scan.py')
parser.add_argument('-s', '--start', dest='host_start', type=str, required=True, help='Please Enter the Start Host Address')
parser.add_argument('-e', '--end', dest='host_end', type=str, required=False, help='Please Enter the End Host Address')
args = parser.parse_args()
if args.host_start != None:
s = scanner(args.host_start, args.host_end)
else:
s = scanner(args.host_start, None)
if __name__ == "__main__":
main()
@garyconstable
Copy link
Author

TCP 3 Way Handshake

  • Host A sends a TCP SYNchronize packet to Host B
  • Host B receives A's SYN
  • Host B sends a SYNchronize-ACKnowledgement
  • Host A receives B's SYN-ACK
  • Host A sends ACKnowledge
  • Host B receives ACK.
  • TCP socket connection is ESTABLISHED.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment