一:简介
主要用到socket实现tcp包发送,gevent实现并发操作。支持网段。
二:代码实现
#!/usr/bin/env python3
# coding:utf-8
import argparse
import socket
import time
from IPy import IP
from gevent import monkey
monkey.patch_all()
import gevent
import gevent.pool
class PortScan():
def __init__(self, ipaddr, port=None):
self.ipaddr = ipaddr
if port is None:
port = '1-65535'
self.fat(port)
'''解析port,支持80-100的格式'''
def fat(self, ports):
if isinstance(ports, int):
self.port = ports
else:
self.port = [port for port in range(int(ports.split('-')[0]), int(ports.split('-')[1]) + 1)]
'''端口连接'''
def tcp_conn(self, ip, port):
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket.settimeout(0.1)
try:
res = tcp_socket.connect_ex((ip, int(port)))
if res == 0:
print("{0} TCP Open".format(port))
tcp_socket.close()
except Exception as e:
print("Error: {0}".format(e))
'''使用多线程加快端口扫描的过程'''
def scan(self, ip):
if isinstance(self.port, list):
g = gevent.pool.Pool(100)
runs = [g.spawn(self.tcp_conn, ip, port) for port in self.port]
gevent.joinall(runs)
elif isinstance(self.port, int):
self.tcp_conn(ip=ip, port=self.port)
'''解析ip address'''
def run(self):
for ip in IP(self.ipaddr):
print("IP:{}".format(str(ip)))
self.scan(ip=str(ip))
if __name__ == "__main__":
start_time = time.time()
'''命令行帮助'''
parser = argparse.ArgumentParser()
parser.description = 'Port Scan'
parser.add_argument("--ip", help="ip or ip address", required=True, type=str)
parser.add_argument("--port", help="80 or 80-100", default=None, type=str)
args = parser.parse_args()
r = PortScan(ipaddr=args.ip)
r.run()
print("耗时:{}".format(time.time() - start_time))
三:使用方法
1.不指定ip的话,默认为1-65535
./port_scan.py --ip 127.0.0.1
2.嗅探指定网段
./port_scan.py --ip 192.168.1.0/24 --port 1024-65535
网友评论