Thứ Năm, 16 tháng 10, 2014

Port Scanner in Python

Python is a great tool to do some socket operations. I have written a piece of code by which I can scan a port range.
It is very basic and missing bunch of checks as aim is the simplicity here.

#!/usr/bin/python
 
import socket,sys
 
try:
  sys.argv[3]
except:
  print "Usage: port_scanner.py [hostname|IP] [port_start] [port_end]"
  sys.exit()
 
host = sys.argv[1]
start_port = int(sys.argv[2])
end_port = int(sys.argv[3])
 
#CREATE SOCKET
try:
  s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except socket.error,err_msg:
  print 'Socket creation failed. Error code: '+ str(err_msg[0]) + ' Error mesage: ' + err_msg[1]
  sys.exit()
 
#RESOLVE HOSTNAME
try:
  remote_ip = socket.gethostbyname(host)
 
except socket.error,error_msg:
  print 'ERROR:'
  print error_msg
  sys.exit()
 
#ITERATE PORT RANGE
end_port+=1
for port in range(start_port,end_port):
  try:
    s.connect((remote_ip,port))
    print 'port ' + str(port) + ' open'
 
    s.close()
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  except socket.error:
    pass
 
You can run the script in the following way by which you scan ports between 1 and 1024:
[stextbox id="grey" caption="portscanner"]
$ ./port_scanner.py remotehost.com 1 1024
port 80 open
port 443 open
[/stextbox]
However I need to give some more info in here. If you send a TCP SYN segment to a closed port, normal behavior is to send a TCP RST segment back to the source. Under normal circumstances script runs through the port range and knocks every port on the remote destination. If a TCP RST is received, socket is closed and script knocks the other port in the list but what if you don’t receive any TCP RST back? For example there is a firewall in between and you can’t even knock some ports. Then what happens?  In this case Linux kernel does 5 TCP SYN by default according to my ubuntu sysctl settings;
[stextbox id="grey" caption="sysctl"]
$ sysctl -a | grep tcp_syn_retries
net.ipv4.tcp_syn_retries = 5
[/stextbox]
This is a terrible setting which causes lots of delay in every port knock. That is why to speed up test I decrease this retry value to 1 temporarily
[stextbox id="grey" caption="sysctl"]
# sysctl net.ipv4.tcp_syn_retries=1
net.ipv4.tcp_syn_retries = 1
[/stextbox]
Actually I wanted to set my own retry scheme via python but it seems it isn’t possible to manipulate kernel’s behavior on this.  In python there is a “setsockopt” method of socket by which you can send certain options but no related option I could find in socket manual of Linux. There may be a way but I don’t know it yet.
When you run the test,  you can check the SYN requests with the following tcpdump command, you can have a better picture of what the script is doing;
[stextbox id="grey" caption="tcpdump"]
#tcpdump -nni any host remotehost.com and ‘tcp[tcpflags] & tcp-syn!=0′
[/stextbox]


source : http://rtoodtoo.net/2012/12/20/port-scanner-in-python/#more-964

Không có nhận xét nào:

Đăng nhận xét