扫描操作系统是因为一些系统在安装完成后会默认开放一些端口无论是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()
运行效果