这里实现的端口扫描器有两种,一种是使用socket模块通过与目标主机相应端口建立TCP连接(完成完整的三次握手),来确定端口是否开放。
核心代码:
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.settimeout(2)
sock.connect((host,port))
sock.send('test socket\n')
result = sock.recv(100)
if result:
print "某某端口开放"
else:
print "某某端口关闭"
sock.close()
另一种是直接利用nmap模块,直接用它内置的方法PortScanner(),输出返回信息,nmap支持使用ACK、FIN、SYN-ACK等扫描方式,如向指定端口发送TCP SYN包,等待TCP ACk响应来确定该端口是否开放。
核心代码:
import nmap
nm = nmap.PortScanner()
nm.scan(host,port)
#nmap扫描结果有一个state变量
state = nm['host']['tcp'][int(port)]['state']
print host+" "+port+" "+state+"\n"
下面是考虑了两种扫描方式的综合版:
#encoding:utf-8
import optparse
import socket
from threading import Thread,Semaphore
import nmap
screenLock = Semaphore(1)
def main():
usage = 'Usage:%prog -H -P -N'
parser = optparse.OptionParser(usage)
parser.add_option('-H',dest='tg_host',type = 'string',help = 'specify the target host')
parser.add_option('-P',dest='tg_ports',type = 'string',help = 'specify the target ports separated by comma')
parser.add_option('-N',dest='con_nmap',type = 'string',help = 'specify the approach used to scan,N --->nmap,C --->tcp connction')
(options,args) = parser.parse_args()
if options.tg_host == None or options.tg_ports[0] == None or options.con_nmap == None:
print parser.usage
exit(0)
else:
target_host = options.tg_host
target_ports = str(options.tg_ports).split(',')
nmap = options.con_nmap
portScan(target_host, target_ports,nmap)
def nmapScanner(host,port):
nmap_scan = nmap.PortScanner()
nmap_scan.scan(host,port)
state = nmap_scan[host]['tcp'][int(port)]['state']
screenLock.acquire()
print "***\nhost:"+host+" port:"+port+" state:"+state+"\n****"
screenLock.release()
def connScan(host,port):
port = int(port)
try:
conScocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
conScocket.settimeout(10)
conScocket.connect((host,port))
conScocket.send('ViolentPython\r\n')
result = conScocket.recv(100)
screenLock.acquire()
print "***\nthe port(tcp):"+str(port)+" on the host:"+host+" is on.\nrecv:"+result+"\n***\n"
except Exception as e:
print "the port(tcp):"+str(port)+" on the host:"+host+" closed"
finally:
screenLock.release()
conScocket.close()
def portScan(host,ports,nmap):
try:
target_hostIP = socket.gethostbyname(host)
except Exception as e:
print "Can not find the host ip for hostname:"+host+"\n"
try:
target_name = socket.gethostbyaddr(target_hostIP)
except Exception as e:
print "Scan result for host:"+target_hostIP+"\n"
if nmap == 'N':
target_function = nmapScanner
else:
target_function = connScan
for port in ports:
t = Thread(target = target_function,args = (host,port))
t.start()
if __name__ == '__main__':
main()