端口扫描工具-python
2022/7/8 14:24:12
本文主要是介绍端口扫描工具-python,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
端口扫描工具
TCP模式-socket
原理
目标主机的一个端口如果是监听状态(LISTENING或者LINSTEN),那么当我connect目标主机时就能成功,否则说明端口是关闭的。 优点: 编程简单,是需要一个API connect(),比较可靠,因为TCP是可靠协议,当丢包的时候,会重传SYN帧。 缺点: 正因为TCP的可靠性,所以当端口不存在的时候,源主机会不断尝试发SYN帧企图得到ack的应答,多次尝试后才会放弃,因此造成了扫描的时间较长。并且,connect的扫描方式可能较容易被目标主机发现。
主要是一个编程思路,代码很简单
1、定义portscan函数,创建socke对象,进行TCP端口扫描 2、启动多线程运行PortScan函数 3、记录并输出扫描结果与时间
主要还是利用了三次握手来判断目标端口是否开启:
创建端口扫描函数
def portscan(target,port): # 定义portscan函数,进行TCP端口扫描 try: client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建socket对象 client.connect((target,port)) #建立socket连接,判断端口是否开放 print("[*] %s:%d端口开放" % (target,port)) client.close() except: pass #捕获异常,避免socket连接建立失败造成程序退出
直接测试调用函数,简单完善一次,测试100个端口:
import socket import time def portscan(target,port): # 定义portscan函数,进行TCP端口扫描 try: client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建socket对象 client.connect((target,port)) #建立socket连接,判断端口是否开放 print("[*] %s:%d端口开放" % (target,port)) client.close() except: pass #捕获异常,避免socket连接建立失败造成程序退出 start_time = time.time() for i in range(0,1001,1): print('正在进行第{}个端口'.format(i)) portscan('127.0.0.1',i) print('end') end_time = time.time() print("[*] All done in %.2f s" % (end_time - start_time))
可以看到非常的慢,看下用时,50个端口用了近100秒
加入多线程
for port in range(1,9999): # 启动多线程运行PortScan函数 t = Thread(target=portscan,args=(target,port)) #创建线程对象 t.start() #开始线程
完整代码
扫描1-65535
import socket #创建TCP连接 from threading import Thread #多线程模块,进行多线程扫描 import time #时间模块,记录扫描所需时间 def main(): target = input("IP:") start_time = time.time() s_time = time.ctime() print("[*] Start port scan at %s" % s_time) for port in range(1,65536): #定义扫描的端口范围 # 2、启动多线程运行PortScan函数 t = Thread(target=portscan, args=(target, port)) # 创建线程对象 t.start() # 开始线程 end_time = time.time() print("[*] All done in %.2f s" % (end_time - start_time)) def portscan(target,port): # 定义portscan函数,进行TCP端口扫描 try: client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建socket对象 client.connect((target,port)) #建立socket连接,判断端口是否开放 print("[*] %s:%d端口开放" % (target,port)) client.close() except: pass #捕获异常,避免socket连接建立失败造成程序退出 if __name__ == '__main__': main()
可以看到多线程快了很多,只用了9秒钟
完善功能
import socket #创建TCP连接 from threading import Thread #多线程模块,进行多线程扫描 import time #时间模块,记录扫描所需时间 def main(): target = input("IP:") start_time = time.time() s_time = time.ctime() port_tmp = int(input("选择全端口(数字1)还是指定端口(数字2):")) if port_tmp==1: print("[*] Start port scan at %s" % s_time) for port in range(1,65536): #定义扫描的端口范围 # 2、启动多线程运行PortScan函数 t = Thread(target=portscan, args=(target, port)) # 创建线程对象 t.start() # 开始线程 elif port_tmp==2: port_tmp2 = input("请输入端口列表,以逗号分割,列如80,8080,7001:") prot_list=port_tmp2.split(',') print(prot_list) for port_i in prot_list: t = Thread(target=portscan, args=(target, int(port_i))) # 创建线程对象 t.start() # 开始线程 end_time = time.time() print("[*] All done in %.2f s" % (end_time - start_time)) def portscan(target,port): # 定义portscan函数,进行TCP端口扫描 try: client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建socket对象 client.connect((target,port)) #建立socket连接,判断端口是否开放 print("[*] %s:%d端口开放" % (target,port)) client.close() except: pass #捕获异常,避免socket连接建立失败造成程序退出 if __name__ == '__main__': main()
SYN扫描
原理
TCP SYN 扫描也就是半开扫描(半开式扫描),这种扫描方式与全连接扫描类似,但客户端不会和服务端建立完整的连接。 扫描过程为:客户端会发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器,如果服务器这个端口是开放的,则会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端,随后客户端会返回带有 RST 标识的数据包,而不是像全连接扫描一样返回一个带有 ACK和 RST 标识的数据包,这样就不会与服务端建立完整的连接了。如果目标端口处于关闭状态,则服务端会返回一个 RST 标识的数据包。
代码(多线程)
import threading,time import sys from scapy.all import * from scapy.layers.inet import IP, TCP, ICMP def get_ip(): '''从命令行参数中获取 IP''' try: parameter = sys.argv ip = parameter[1] print('The IP you test is : ', end = '') font.print_YELLOW(ip) except Exception as e: print(e) return ip def port_scan(port): '''扫描端口''' try: packet = IP(dst=ip)/TCP(dport=port,flags='S') # 构造一个 flags 的值为 S 的报文 send = sr1(packet,timeout=2,verbose=0) if send.haslayer('TCP'): if send['TCP'].flags == 'SA': # 判断目标主机是否返回 SYN+ACK send_1 = sr1(IP(dst=ip)/TCP(dport=port,flags='R'),timeout=2,verbose=0) # 只向目标主机发送 RST font.print_GREEN('[+] %d is open' % port) elif send['TCP'].flags == 'RA': pass except: pass def main(): packet_ping = IP(dst=ip)/ICMP() # 在扫描端口之前先用 ICMP 协议探测一下主机是否存活 ping = sr1(packet_ping,timeout=2,verbose=0) if ping is not None: for p in range(1,65535): # 默认扫描1-1000的端口,可以手动修改这里的端口范围 t = threading.Thread(target=port_scan,args=(p,)) t.start() elif ping is None: font.print_RED('该主机处于关闭状态或本机被该主机过滤,无法对其使用 ping 探测') if __name__ == '__main__': ip = get_ip() start_time = time.time() main() end_time = time.time() print('[time cost] : ' + str(end_time-start_time) + ' 秒')
这篇关于端口扫描工具-python的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Python基础编程
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南