Python 实现端口扫描

  • TCP Connect扫描
TCP Connect扫描又叫做全连接扫描 , 客户端与服务器建立 TCP 连接要进行一次三次握手 , 如果进行了一次成功的三次握手 , 则说明端口开放 。假设客户端想与服务端的80端口进行通信 , 首先客户端会发送一个带有SYN标识和端口号的TCP数据包给服务器 , 如果服务器这个端口是开放的 , 则会接受这个连接并返回一个带有SYN和ACK标识的数据包给客户端 , 随后客户端会发送带有ACK和RST标识的数据包给服务点 , 此时客户端与服务器建立了连接 。

Python 实现端口扫描

文章插图
 
当客户端发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器后 , 如果服务器端返回一个带 RST 标识的数据包 , 则说明端口处于关闭状态 。

Python 实现端口扫描

文章插图
【Python 实现端口扫描】 
  • 实现代码
# #!/usr/bin/Python3#sacn.py# python3 TCP 连接扫描import sysfrom socket import *import time#统计端口开启数量open_num = 0def scan(ip,port):global open_numtry:s = socket(AF_INET,SOCK_STREAM)s.connect((ip,port))open_num+=1print('{0} port {1} is open'.format(ip, port))except Exception as err:#print('{0} port {1} is close'.format(ip,port))passfinally:s.close()def main():#设置超时时间 , 秒为单位setdefaulttimeout(1)#获取第一个参数为主机名称host = sys.argv[1]#获取端口区间ports= sys.argv[2].split('-')start_pt = int(ports[0])end_pt = int(ports[1])#获取主机IP地址target_ip = gethostbyname(host)#开始计时start_time = time.time()for port in range(start_pt,end_pt):scan(target_ip,port)#计时结束end_time = time.time()#输出存活端口数量print('存活端口%d 个'%(open_num))#输出扫描耗费市场print('总共用时{:.2f}秒'.format(end_time-start_time))if __name__=='__main__':main()
上述代码实现了TCP connect单线程扫描功能 , 如果全端口扫描将会超级慢 , 下面引入多线程改造 。
  • 多线程操作实现
#!/usr/bin/python3# python3 TCP 连接扫描import sysfrom socket import *import timeimport threadinglock = threading.Lock()threads =[]open_num = 0setdefaulttimeout(1)def scan(ip,port):global open_numtry:s = socket(AF_INET,SOCK_STREAM)s.connect((ip,port))lock.acquire()open_num+=1print('{0} port {1} is open'.format(ip, port))lock.release()except Exception as err:#print('{0} port {1} is close'.format(ip,port))passfinally:#lock.release()s.close()def main():host = sys.argv[1]ports= sys.argv[2].split('-')start_pt = int(ports[0])end_pt = int(ports[1])target_ip = gethostbyname(host)start_time = time.time()for port in range(start_pt,end_pt):t = threading.Thread(target=scan,args=(target_ip,port))threads.Append(t)t.start()#scan(target_ip,port)for t in threads:t.join()end_time = time.time()print('存活端口 %d 个'%(open_num))print('总共用时{:.2f}秒'.format(end_time-start_time))if __name__=='__main__':main()
  • 相同扫描执行时间对比
moke@moke:~/moke_python$ python3 scan.py www.jd.com 22-28218.203.117.211 port 25 is open存活端口1 个总共用时5.01秒moke@moke:~/moke_python$ python3 scan_thread.py www.jd.com 22-28218.203.111.82 port 25 is open存活端口 1 个总共用时1.00秒
  • 本章节知识点
1.socket:Socket 是在应用层和传输层之间的一个抽象层 , 它把 TCP/IP 层复杂的操作抽象为几个简单的接口 , 供应用层调用实现进程在网络中的通信 。2.threading:多线程
  • 下一讲内容
python多线程




    推荐阅读