概述
网络扫描工具可以帮助我们自动化地扫描网络设备上开放的端口和服务,从而检测网络中的漏洞和弱点,进而制定安全策略。Python是一种强大的编程语言,它拥有许多用于网络扫描的功能和模块。
在这篇文章中,我们将介绍如何使用Python编写一个简单的网络扫描器,可以通过该扫描器扫描指定IP地址的所有开放端口,并列出开放的端口号。
实现原理
网络扫描器的实现原理很简单。扫描器通过遍历一系列端口,向每个端口发送TCP SYN包,并等待对方的响应。当接收到响应时,扫描器判断该端口是开放还是关闭,并列出开放端口的端口号。
在Python中,我们可以使用socket模块来创建socket对象,通过该对象发送和接收数据。我们还可以使用threading模块来创建线程,从而将扫描过程并行化。
现在,让我们来看一看如何使用Python实现网络扫描器。
示例代码
以下是一个简单的Python程序,可用于扫描指定IP地址的所有开放端口,并列出开放的端口号:
import socket
import threading
class PortScanner:
def __init__(self, host):
self.host = host
self.open_ports = []
def scan(self, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
sock.connect((self.host, port))
sock.close()
self.open_ports.append(port)
except:
pass
def scan_range(self, start, end):
for port in range(start, end+1):
t = threading.Thread(target=self.scan, args=[port])
t.start()
def scan_all(self):
self.scan_range(1, 65535)
while threading.active_count() > 1:
pass
for port in sorted(self.open_ports):
print(f"Port {port} is open")
if __name__ == "__main__":
scanner = PortScanner("localhost")
scanner.scan_all()
在这个程序中,我们定义了一个名为`PortScanner`的类,并使用多线程扫描指定IP地址的所有端口。我们首先使用`socket`模块创建了一个TCP连接:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
然后,我们使用`sock.settimeout()`方法来设置每个端口连接的超时时间。超时时间设置得越短,扫描速度就越快,但是可能会漏掉一些开放端口。
在扫描过程中,我们会遍历指定的端口范围,并使用多线程来并行扫描每个端口。我们使用`threading`模块的`Thread`类来创建新线程,并使用`self.scan()`方法作为线程的入口点:
t = threading.Thread(target=self.scan, args=[port])
t.start()
在启动扫描后,我们使用`while`循环等待所有线程完成:
while threading.active_count() > 1:
pass
最后,我们将所有开放的端口进行排序并打印出来:
for port in sorted(self.open_ports):
print(f"Port {port} is open")
使用说明
使用本网络扫描器很简单,只需做以下两个步骤:
1. 将程序中的`localhost`替换为你想要扫描的主机的IP地址或主机名。
2. 运行程序,等待程序自动扫描所有端口并输出结果。
上述示例程序中的`PortScanner()`类支持三个方法:
- `__init__(self, host)`:初始化扫描器,并指定要扫描的主机地址。
- `scan(self, port)`:扫描指定端口。
- `scan_range(self, start, end)`:扫描指定端口范围内的所有端口。
要使用这些方法,你需要实例化一个`PortScanner()`类,并调用相应的方法。例如,要扫描一个指定的端口号(例如,`80`),可以调用`scan()`方法:
scanner = PortScanner("localhost")
scanner.scan(80)
请注意,这个示例程序并不完备。如果你需要更强大的网络扫描功能,你应该考虑使用专业的网络扫描工具,如Nmap或Masscan。但是,在许多情况下,Python编写的网络扫描器足以满足你的需求。
实现端口扫描器
5.1 实现思路
在Python中,我们可以使用`socket`模块来实现端口扫描器。具体实现思路如下:
1. 输入要扫描的主机名或IP地址。
2. 输入要扫描的端口范围(起始端口号和结束端口号)。
3. 对指定的端口列表进行遍历。
4. 对于每个端口,创建一个socket连接,发送一个探测数据包,等待响应。如果响应是一个SYN/ACK数据包,说明该端口是开放的,将其添加到一个开放端口的列表中。
5.2 编写代码
根据上述的实现思路,我们使用Python编写了一个简单的端口扫描器:
import socket
import argparse
def scan_port(host, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
sock.connect((host, port))
print(f"Port {port} is open")
sock.close()
except:
pass
def scan_range(host, start_port, end_port):
for port in range(start_port, end_port+1):
scan_port(host, port)
def main():
parser = argparse.ArgumentParser(description="Python Port Scanner")
parser.add_argument("-H", "--host", type=str, required=True, help="The hostname or IP address to scan")
parser.add_argument("-p", "--port", type=str, required=True, help="The port range to scan, example: '-p 1-65535'")
args = parser.parse_args()
host = args.host
start_port, end_port = args.port.split("-")
start_port = int(start_port)
end_port = int(end_port)
scan_range(host, start_port, end_port)
if __name__ == "__main__":
main()
该程序使用了`socket`模块和`argparse`模块,实现了上述的实现思路。我们通过命令行参数传递要扫描的主机名或IP地址和端口号范围。程序使用`scan_port()`函数扫描指定主机上的一个端口,并将扫描结果(如果发现端口开放)输出到终端上。
在`main()`函数中,我们使用`argparse`模块解析命令行参数,并将它们传递给`scan_range()`函数,该函数循环遍历指定范围内的所有端口,并调用`scan_port()`函数对每个端口进行扫描。
为了方便你的使用,下面我将为你提供详细的操作步骤。
使用说明
6.1 安装Python
要使用Python编写端口扫描器,你需要首先安装Python。Python3推荐使用3.7及以上的版本,你可以从[Python官方网站](https://www.python.org/downloads/)下载最新的稳定版。
6.2 运行程序
以下是使用该端口扫描器的步骤:
1. 打开终端窗口或命令提示符窗口。
2. 移动到存放`scanner.py`代码文件的目录中。
3. 输入以下命令启动程序:
python scanner.py -H [HOST] -p [PORT_RANGE]
其中,`HOST`表示要扫描的主机名或IP地址,`PORT_RANGE`表示要扫描的端口范围,可以按照`[FROM]-[TO]`的格式指定起始端口号和结束端口号,也可以使用逗号将多个端口号隔开,例如`80,443,8080`。
例如,要扫描在本地主机上所有开放的端口,可以使用以下命令:
python scanner.py -H localhost -p 1-65535
备注:在某些情况下,您需要使用管理员或root权限来运行该扫描器。
6.3 实例演示
以下是在本地主机上使用该端口扫描器扫描所有开放端口的演示结果:
$ python scanner.py -H localhost -p 1-65535
Port 22 is open
Port 3306 is open
在这个例子中,我们的扫描器检测到本地主机上有两个开放端口:22(SSH)和3306(MySQL)。

总结

Python是一种强大的编程语言,拥有很多用于网络扫描的模块和库。在这篇文章中,我们介绍了如何使用Python编写一个简单的端口扫描器,帮助你快速找到指定主机上的所有开放端口。
当然,这个示例程序仅仅是一个入门示例,你可以添加更多的功能来增强它,例如:
- 添加多线程功能,从而加快扫描速度。
- 使用UDP协议扫描UDP端口。
- 使用异步编程模型,从而进一步提高扫描速度。
总之,Python为我们提供了丰富的网络编程工具和模块,我们可以根据实际需求来灵活地使用这些工具和模块,实现我们想要的网络扫描功能。希望本篇文章对你有所帮助,如果有任何其他问题,欢迎再次和我交流。

点击⬇️方“公众号”,关注更多精彩
转载于:https://mp.weixin.qq.com/s/ZNAjsdjEcESyguM6W1FaqQ