1.NmapがOSを認識する
オペレーティング システムをスキャンする最も一般的な方法は、TCP/IP プロトコル スタック フィンガープリント テクノロジです。これは、TCP/IP プロトコル スタックの特性を使用してオペレーティング システムを識別します。
この方法は、異なるオペレーティング システム間のネットワーク データ パケットの処理の違いを見つけ、これらの違いを組み合わせてフィンガープリントを形成し、TTL、DF フラグ、ウィンドウ、サイズ、ACK、シーケンスなど、ターゲット デバイスのオペレーティング システムのバージョン情報を正確に識別します。番号、ICMP アドレス マスキング要求、FIN パケットへの応答、誤ってマークされた SYN パケット、ISN (初期化シーケンス番号) など。
次の図は、Nmap フィンガープリント識別ライブラリの部分的なスクリーンショットです。TCP
/IP プロトコル スタックに基づくフィンガープリントの実装は、8 つの異なるデータ パケットを継続的に構築してホスト ホストに送信し、特定のフィールドを計算することにより、比較的複雑です。返されたメッセージ、計算結果と一致する指紋ライブラリによると、この方法の検出結果はより正確であり、より詳細なオペレーティング システム情報を検出できます。
この部分は Nmap を呼び出すことで実装されており、実装コードは次のとおりです。
# _*_ coding:utf-8 _*_
import nmap
import time
def os_scan_nmap(ip):
# python-nmap模块类的实例化
nm = nmap.PortScanner()
try:
# 调用nmap执行-O扫描操作系统
result = nm.scan(hosts=ip,arguments='-O')
# 从返回值里通过切片提取出操作系统版本
# print(result)
# print(ip)
# print(result['scan'][ip])
os = result['scan'][ip]['osmatch'][0]['name'] + " (accuracy: " + result['scan'][ip]['osmatch'][0]['accuracy'] + "%)"
time.sleep(0.1)
# print(ip)
# print(os)
return os
except:
print(ip)
# print("Warning: test conditions non-ideal. we could not find at least 1 open and 1 closed port")
return "Warning: test conditions non-ideal. we could not find at least 1 open and 1 closed port"
pass
def os_scan_nmap_list(iplist):
for ip in iplist:
os_scan_nmap(ip)
if __name__ == '__main__':
ip = "36.152.147.7"
print(os_scan_nmap(ip))
# iplist = ["192.168.1.108", "www.baidu.com"]
# os_scan_nmap_list(iplist)
実行結果を次の図に示します。
2. TTL フィールドは OS を識別します
Nmap 検出方式と比較して、TTL 検出方式はよりシンプルで高速です。
TTL (Time To Live) は、データ パケットの "time to live" であり、データ パケットが破棄される前に通過できるホップ (Hop) の数を示します。
異なるオペレーティング システムのデフォルトの TTL 値は、多くの場合異なります。一般的なオペレーティング システムの TTL 値を次の表に示します。
オペレーティング·システム | TTL |
---|---|
ウィンドウズ2000 | 108 |
WindowsNT | 107 |
Windows 9x | 127/128 |
ウィンドウズ7 | 64 |
Windows95/98 | 32 |
Linux | 64 |
ソラリス | 252 |
イリックス | 240 |
シスコ 12.0 2514 | 255 |
AIX | 247 |
この部分の実装コードは次のとおりです。
# _*_ coding:utf-8 _*_
import sys
import importlib
importlib.reload(sys)
from scapy.all import *
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
'''
操作系统的探测利用ttl进行判断
win2000---->108
winNT------>107
win9x------>128 or 127
WIN7------->64
WINDOWS 95/98 --> 32
solaris---->252
IRIX------->240
AIX------->247
Linux----->64
'''
def os_scan_ttl(ip):
ans = sr1(IP(dst=ip)/ICMP(id=RandShort()), timeout=1, retry=2, verbose=0)
print(ip)
if not ans:
ip_for_os = "操作系统类型:" + "None"
elif ans[IP].ttl <= 64:
ip_for_os = "操作系统类型:" + "Linux or Unix"
# print("Linux or Unix!")
elif ans[IP].ttl == 108:
ip_for_os = "操作系统类型:" + "Window2000"
# print("Window2000!")
elif ans[IP].ttl == 107:
ip_for_os = "操作系统类型:" + "win NT"
# print("win NT!")
elif ans[IP].ttl == 127:
ip_for_os = "操作系统类型:" + "win9x"
# print("win9x")
elif ans[IP].ttl == 252:
ip_for_os = "操作系统类型:" + "solaris"
# print("solaris")
elif ans[IP].ttl == 128:
ip_for_os = "操作系统类型:" + "Windows XP"
# print("Windows XP")
else:
ip_for_os = "操作系统类型:" + "Unix"
# print("Unix!")
return ip_for_os
def os_scan_ttl_list(iplist):
for ip in iplist:
print(os_scan_ttl(ip))
if __name__ == '__main__':
print(os_scan_ttl("www.baidu.com"))
# iplist = ["192.168.1.108", "www.aliyun.com"]
# os_scan_ttl_list(iplist)
実行結果は次の図のとおりです。