前言
上一篇我们讲到利用python进行信息收集,此篇我们将要学习如何利用python的nmap模块来编写一些实用的扫描工具。初出茅庐,如有错误望各位不吝赐教。
3.1 概念
端口扫描工具是用于检测计算机或网络上开放的端口的工具。以下是我们可以通过端口扫描工具获取什么信息:
- 安全评估:端口扫描工具可以用于评估计算机或网络的安全性。它可以帮助管理员发现可能存在的安全漏洞或开放的不必要的端口,从而采取相应的措施来加强安全性。
- 检测端口状态:端口扫描工具可以帮助管理员检测端口的状态,即确定端口是开放还是关闭。这对于识别网络中活动的服务和应用程序非常有用。
- 端口映射:端口扫描工具可以用于检测网络中的端口映射。它可以确定网络中的具体设备和端口之间的映射关系,帮助管理员更好地理解网络拓扑和配置。
- 故障诊断:端口扫描工具可以用于故障排除和排查网络或计算机的问题。通过检测端口状态和连接问题,管理员可以更快地找到问题的根源。
3.2 Nmap基本用法:
Nmap库是一个用于扫描和探测网络主机的Python库。nmap库提供了一种简单的方法来执行nmap扫描,并解析扫描结果。它可以发送各种nmap扫描请求,如ping扫描、端口扫描、操作系统检测等。我们先来看看Python Nmap库的几个基本用法示例:
使用Python Nmap库进行端口扫描:
import nmap
# 创建Nmap PortScanner对象
scanner = nmap.PortScanner()
# 扫描指定IP的所有开放端口
result = scanner.scan('192.168.1.1', '1-1000')
# 打印扫描结果
print(result)
使用Python Nmap库进行服务和操作系统探测:
import nmap
# 创建Nmap PortScanner对象
scanner = nmap.PortScanner()
# 扫描指定IP的服务和操作系统信息
result = scanner.scan('192.168.1.1', arguments='-O')
# 打印扫描结果
print(result)
使用Python Nmap库进行漏洞扫描:
import nmap
# 创建Nmap PortScanner对象
scanner = nmap.PortScanner()
# 扫描指定IP的漏洞信息
result = scanner.scan('192.168.1.1', arguments='--script vuln')
# 打印扫描结果
print(result)
这里补充一下,scan方法的参数是用来指定nmap扫描的选项和参数的,有许多可选参数,那么常见的有以下几项:
- arguments: 用来指定nmap的命令行参数。例如,
-sS
表示TCP SYN扫描,-sU
表示UDP扫描,-p
表示指定端口范围等等。可以根据需要传递不同的参数来进行不同类型的扫描。 - ports: 用来指定要扫描的端口范围。可以传递单个端口号,或者使用连接符
-
来表示一个范围。例如,ports='80,443'
表示扫描80和443端口,ports='1-1000'
表示扫描1到1000之间的所有端口。 - arguments_file: 可以将nmap参数保存到一个文件中,然后通过该参数指定文件路径,以便进行扫描。
- sudo: 用于指定是否使用sudo权限来运行nmap。默认值为False,表示不使用sudo权限。如果需要进行特权扫描,则可以将该参数设置为True。
- sudo_password: 如果需要使用sudo权限,可以通过该参数设置sudo密码。
- scan_type: 用于指定扫描类型。可以是
syn
、udp
、tcp
等。根据不同的扫描类型,scan()方法会自动根据参数进行相应的配置。 - callback_result: 可以在扫描完成后指定一个回调函数来处理扫描结果。回调函数接受一个参数,即nmap扫描结果。
3.3 ping扫描
ping扫描可用于测试主机的可达性。它发送一个ICMP Echo Request(ping)消息到目标主机,并等待目标主机返回一个ICMP Echo Reply(pong)消息作为响应。通过检查响应的时间和结果,我们就可以判断目标主机是否在线,以及网络延迟的情况。下面我们将利用Nmap模块来实现此功能:
import nmap
def ping_scan(hosts):
nm = nmap.PortScanner()
nm.scan(hosts, arguments='-sn')
for host in nm.all_hosts():
if nm[host]['status']['state'] == 'up':
print(f'{host} is up')
else:
print(f'{host} is down')
if __name__ == "__main__":
hosts = '192.168.0.1,192.168.0.2,192.168.0.3'
ping_scan(hosts)
我们使用nmap.PortScanner()
创建一个nmap扫描器对象。然后使用scan()
方法扫描指定的主机。参数-sn
表示只进行ping扫描。你可以根据需要添加其他nmap参数来进行更复杂的扫描操作。
之后,我们通过遍历nm.all_hosts()
来获取扫描结果,如果主机状态为'up',则表示主机存活,否则表示主机宕机。
最后,在主程序的if __name__ == "__main__":
部分,我们指定要扫描的主机列表,并调用ping_scan()
函数进行扫描。
3.4 操作系统检测
操作系统检测可以帮助安全专家识别潜在的漏洞或安全问题。不同的操作系统可能存在不同的安全风险和漏洞。以下是使用python-nmap进行操作系统检测的基本示例:
1、导入所需的库和模块:
import nmap
2、创建一个NmapPortScanner对象:
nm = nmap.PortScanner()
3、使用scan()方法扫描目标IP:
target_ip = "192.168.0.1"
scan_results = nm.scan(hosts=target_ip, arguments='-O')
4、从扫描结果中获取操作系统信息:
os_info = scan_results['scan'][target_ip]['osmatch'][0]['osclass'][0]['osfamily']
print("操作系统:", os_info)
完整的示例代码如下所示:
import nmap
nm = nmap.PortScanner()
target_ip = "192.168.0.1"
scan_results = nm.scan(hosts=target_ip, arguments='-O')
os_info = scan_results['scan'][target_ip]['osmatch'][0]['osclass'][0]['osfamily']
print("操作系统:", os_info)
注:执行此代码需要在具有root或管理员权限的环境中,不然有可能导致获取信息不完整或报错。
3.5 检测网络中的端口映射
检测网络中的端口映射是为了确定网络设备和服务的安全性。通过检测端口映射,可以确定网络上的哪些端口对公众可见,确保只有授权的服务和设备才能访问网络,通过确定哪些端口对外开放,可以识别潜在的攻击面和漏洞。
1、创建一个Nmap扫描器对象:
scanner = nmap.PortScanner()
2、使用scan()
方法来扫描指定的目标IP地址:
scanner.scan('192.168.1.1', '1-1000')
上面的例子中,我们扫描了IP地址为192.168.1.1的主机的1到1000端口。
3、使用all_hosts()
方法获取所有扫描到的主机列表:
hosts_list = scanner.all_hosts()
4、遍历主机列表,使用[host][proto].keys()
来获取映射的端口列表:
for host in hosts_list:
for proto in scanner[host].all_protocols():
lport = scanner[host][proto].keys()
for port in lport:
print(f'Host: {host}, Port: {port}, State: {scanner[host][proto][port]["state"]}')
上述代码中,我们遍历主机列表,然后遍历每个主机的协议列表,获取映射的端口列表,并打印出端口、主机和状态信息。
这样,你就可以使用Python的Nmap库来检测网络中的端口映射了。记得在运行代码之前确保你有足够的权限来使用Nmap扫描器。
3.6主机存活/开放端口扫描
最后要讲的应该是大家最耳熟能详的渗透工具功能了,通过检测主机或端口是否有回应来判断主机存活与端口开放情况,那么我们话不多说,来实现一下这个功能吧!
import nmap
def scan_ports(target_host, target_ports):
nm = nmap.PortScanner()
open_ports = []
# 扫描指定主机的指定端口
for target_port in target_ports:
result = nm.scan(target_host, target_port)
state = result['scan'][target_host]['tcp'][int(target_port)]['state']
# 如果端口是开放的,则将其添加到开放端口列表中
if state == 'open':
open_ports.append(target_port)
return open_ports
def scan_hosts(target_hosts, target_ports):
nm = nmap.PortScanner()
alive_hosts = []
# 扫描指定主机的存活状态
for target_host in target_hosts:
result = nm.scan(target_host, arguments='-sn')
state = result['scan'][target_host]['status']['state']
# 如果主机存活,则将其添加到存活主机列表中
if state == 'up':
alive_hosts.append(target_host)
# 对存活主机进行端口扫描
for host in alive_hosts:
open_ports = scan_ports(host, target_ports)
print(f'Open ports on {host}: {open_ports}')
# 例子使用
target_hosts = ['192.168.0.1', '192.168.0.2']
target_ports = ['80', '443', '22']
scan_hosts(target_hosts, target_ports)
注:使用此代码进行扫描可能需要管理员权限。