扫描器篇(十)之python+nmap实现系统识别

Maha ·
更新时间:2024-11-13
· 976 次阅读

为什么要进行操作系统识别 扫描操作系统是因为一些系统在安装完成后会默认开放一些端口无论是linux,windows还是Mac 在开放端口上跑什么服务,在该服务版本上有什么漏洞,或者有什么半身自带的漏洞。 扫描操作系统这个步骤在渗透测试中是必不可少的过程 最简单的系统识别可通过ttl值来获得 windows : 128(65-128)起始为128每经过一跳路由ttl值就会减一 unix/linux:64(1-64) 某些unix特殊的unix版本:255 起始为255经过一个路由就会递减 以上ttl值可以参考不可以完全信任,因为不排除有人在发包的时候特意通过编程实现修改ttl值 将linux的ttl值改成windows的,让数据包的接受者误以为这是一个windows操作系统 代码部分 通过ttl值对操作系统进行判断 构造ping 包向目标主机发送,再通过读取响应包中的ttl值来判断操作系统 def ttl_scan(ip): packet = IP(dst=ip)/ICMP() result = sr1(packet,timeout=1,verbose=0) # 构造ping包向目标主机发送 if result is None: pass elif int(result[IP].ttl) <= 64: # 判断目标主机响应包中TTL值是否小于等于64 print ("%s is Linux/Unix"%ip) # 是的话就为linux/Unix else: print("%s is Windwows"%ip) # 反之就是linux 通过python-nmap对操作系统进行识别 使用nmap提供的python-nmap模块,调用-O参数对主机操作系统进行识别 返回回来的数据排序很乱,需要通过切片提取数据 def nmap_scan(ip): nm = nmap.PortScanner() try: result = nm.scan(hosts=ip,arguments='-O') #调用nmap执行-O扫描操作系统 os = result["scan"][ip]['osmatch'][0]['name'] # 从返回值里通过切片提取出操作系统版本 time.sleep(0.1) print(ip,os) except: pass 主函数 功能 判断用户是选择ttl扫描还是nmap扫描 判断用户输入的参数是扫描整个网段还是单个ip地址 调用多线程完成操作系统识别 def main(): parser = OptionParser("Usage:%prog -i -n or -t ttl_scan") # 输出帮助信息 parser.add_option('-i',type='string',dest='tgtIP',help='specify target host') # 获取ip地址参数 parser.add_option('-t', type='string', dest='ttl', help='input -t ttl') # 是否使用ttl模块扫描 parser.add_option('-n',type="string",dest='tgtNetwork',help='specify target host') #获取网段信息 options,args = parser.parse_args() # 实例化用户的参数 tgtip = options.tgtIP Network = options.tgtNetwork TTL = options.ttl if tgtip is None and Network is None: # 判断文件是否存在 print(parser.usage) sys.exit() if tgtip is not None: # 单个地址时执行的操作 if TTL: # 判断是否调用ttl扫描 ttl_scan(tgtip) else: nmap_scan(tgtip) if Network: prefix = Network.split(".")[0]+'.'+Network.split(".")[1]+'.'+ Network.split(".")[2]+'.' # 以点为分割提取ip地址前三位 if TTL : # 判断是否调用ttl扫描 for i in range(1, 255): ip = prefix + str(i) # 结合ip地址前缀生成网段扫描所需ip t = Thread(target=ttl_scan,args=(ip,)) t.start() time.sleep(0.1) else: for i in range(1, 255): ip = prefix + str(i) t = Thread(target=nmap_scan,args=(ip,)) t.start() 整体代码 #!/usr/bin/python3.7 #!coding:utf-8 import nmap import sys import time from optparse import OptionParser from threading import Thread from scapy.all import * def ttl_scan(ip): packet = IP(dst=ip)/ICMP() result = sr1(packet,timeout=1,verbose=0) if result is None: pass elif int(result[IP].ttl) <= 64: # 判断目标主机响应包中TTL值是否小于等于64 print ("%s is Linux/Unix"%ip) # 是的话就为linux/Unix else: print("%s is Windwows"%ip) # 反之就是linux def nmap_scan(ip): nm = nmap.PortScanner() try: result = nm.scan(hosts=ip,arguments='-O') #调用nmap执行-O扫描操作系统 os = result["scan"][ip]['osmatch'][0]['name'] # 从返回值里通过切片提取出操作系统版本 time.sleep(0.1) print(ip,os) except: pass def main(): parser = OptionParser("Usage:%prog -i -n or -t ttl_scan") # 输出帮助信息 parser.add_option('-i',type='string',dest='tgtIP',help='specify target host') # 获取ip地址参数 parser.add_option('-t', type='string', dest='ttl', help='input -t ttl') # 是否使用ttl模块扫描 parser.add_option('-n',type="string",dest='tgtNetwork',help='specify target host') #获取网段信息 options,args = parser.parse_args() # 实例化用户的参数 tgtip = options.tgtIP Network = options.tgtNetwork TTL = options.ttl if tgtip is None and Network is None: # 判断文件是否存在 print(parser.usage) sys.exit() if tgtip is not None: # 单个地址时执行的操作 if TTL: # 判断是否调用ttl扫描 ttl_scan(tgtip) else: nmap_scan(tgtip) if Network: prefix = Network.split(".")[0]+'.'+Network.split(".")[1]+'.'+ Network.split(".")[2]+'.' # 以点为分割提取ip地址前三位 if TTL : # 判断是否调用ttl扫描 for i in range(1, 255): ip = prefix + str(i) # 结合ip地址前缀生成网段扫描所需ip t = Thread(target=ttl_scan,args=(ip,)) t.start() time.sleep(0.1) else: for i in range(1, 255): ip = prefix + str(i) t = Thread(target=nmap_scan,args=(ip,)) t.start() if __name__ == "__main__": main() 运行效果

在这里插入图片描述


作者:猪儿虫鸭



nmap 系统 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号