使用Python协程实现TCP端口嗅探
本文将介绍如何使用Python协程和asyncio库实现TCP端口嗅探。我们将会构建一个简单的TCP连接器,以扫描目标主机的开放端口。
正文:
一、导入必要的库
import asyncio
import socket
import time
二、定义TCP协程嗅探类
在Python中,我们可以使用async def来定义协程函数。为了实现TCP端口嗅探,我们需要创建一个协程类来尝试与目标主机的每个端口建立连接。为此,我们定义了一个名为Multi TCP的类。
class MultiTCP:
def __init__(self, ips, ports, pool_size=100, timeout=2, isEcho=True):
self.ips = ips
self.ports = ports
self.timeout = timeout
self.pool_size = pool_size
self.result = []
self.table = {'IP': 15, 'Port': 5, 'State': 5, 'Time': 4, 'Service': 10}
self.response = {}
self.isEcho = isEcho
async def scan_port(self, ip, port):
try:
start = time.time()
rev = {}
rev['IP'] = ip
reader, writer = await asyncio.wait_for(asyncio.open_connection(ip, port), timeout=self.timeout)
writer.close()
rev['Port'] = port
rev['State'] = 'OPEN'
rev['Time'] = str(round(time.time() - start, 3))
rev['Service'] = self.getPortServer(port)
if self.isEcho:
for k, v in rev.items():
print('%-{0}s\t'.format(self.table.get(k)) % v, end='')
print()
else:
if self.response.get(ip) == None:
self.response[ip] = [port]
else:
self.response[ip].append(port)
except:
pass
async def Create_tasks(self):
semaphore = asyncio.Semaphore(self.pool_size)
async with semaphore:
tasks = []
for i in self.ips:
tasks += [asyncio.create_task(self.scan_port(i, port)) for port in self.ports]
await asyncio.gather(*tasks)
def TCPing(self):
if self.isEcho:
for k, v in self.table.items():
print('%-{0}s\t'.format(v) % k, end='')
print()
loop = asyncio.get_event_loop()
task = loop.create_task(self.Create_tasks())
loop.run_until_complete(task)
loop.close()
def getPortServer(self, port):
try:
return (socket.getservbyport(port, 'tcp'))
except:
return 'unknown'
三、主函数:启动TCP端口嗅探器
最后,我们定义了一个名为main的函数,用于启动TCP端口嗅探器。该函数将调用MultiTCP,并将目标IP地址和端口作为参数传递给它。然后,该类将输出所有开放的端口。
if __name__ == '__main__':
MultiTCP(['www.baidu.com', 'www.taobao.com'], [80, 443]).TCPing()
四、运行程序
在运行程序之前,请确保已经输入了目标IP地址。然后,调用main函数以启动TCP端口嗅探器。该程序将尝试连接目标主机的所有端口,并输出所有开放的端口。
五、全部代码
import asyncio
import socket
import time
class MultiTCP:
def __init__(self, ips, ports, pool_size=100, timeout=2, isEcho=True):
self.ips = ips
self.ports = ports
self.timeout = timeout
self.pool_size = pool_size
self.result = []
self.table = {'IP': 15, 'Port': 5, 'State': 5, 'Time': 4, 'Service': 10}
self.response = {}
self.isEcho = isEcho
async def scan_port(self, ip, port):
try:
start = time.time()
rev = {}
rev['IP'] = ip
reader, writer = await asyncio.wait_for(asyncio.open_connection(ip, port), timeout=self.timeout)
writer.close()
rev['Port'] = port
rev['State'] = 'OPEN'
rev['Time'] = str(round(time.time() - start, 3))
rev['Service'] = self.getPortServer(port)
if self.isEcho:
for k, v in rev.items():
print('%-{0}s\t'.format(self.table.get(k)) % v, end='')
print()
else:
if self.response.get(ip) == None:
self.response[ip] = [port]
else:
self.response[ip].append(port)
except:
pass
async def Create_tasks(self):
semaphore = asyncio.Semaphore(self.pool_size)
async with semaphore:
tasks = []
for i in self.ips:
tasks += [asyncio.create_task(self.scan_port(i, port)) for port in self.ports]
await asyncio.gather(*tasks)
def TCPing(self):
if self.isEcho:
for k, v in self.table.items():
print('%-{0}s\t'.format(v) % k, end='')
print()
loop = asyncio.get_event_loop()
task = loop.create_task(self.Create_tasks())
loop.run_until_complete(task)
loop.close()
def getPortServer(self, port):
try:
return (socket.getservbyport(port, 'tcp'))
except:
return 'unknown'
if __name__ == '__main__':
MultiTCP(['www.baidu.com', '192.168.8.'], [80, 443]).TCPing()