我们在判定远程操作系统类型的时候,最熟悉的方法就是使用ICMP协议Ping同一局域网内的不同主机,屏幕上回显的TTL值会因不同主机操作系统的不同而不同,甚至是由于系统版本、防火墙、补丁等细节不同,在不同的主机,即使相同的操作系统,回显的TTL值也会有所不同。
下图是ping同一局域网内的Windows XP主机,TTL值为128。选择ping局域网中主机的原因是由于以太网中两台主机进行通信中间没有跳点,TTL是从发起端发出的原始值。
下图是ping同一局域网内的Ubuntu主机,TTL值为64。
下图是ping 百度网站的例子。通过地址解析我们ping的是61.135.169.125,TTL值为56。直接ping互联网上的主机,虽然TTL值也有不同,但是不能直接显示发送端的原始值。TTL是由发送主机设置的,可防止数据包在互联网上无限循环。转发IP数据包时,要求路由器至少将TTL减小1。不过这个值会接近2^n (1≤n≤8),所以可认为以下对端主机为Linux系统。
然而单纯依赖TTL数值也是不准确的,还需要更加完整和系统性的识别技术,这就催生出操作系统识别技术的迅速发展。
其中最具代表性的就是基于各种操作系统TCP/IP协议栈指纹的识别。常用的网络协议是标准的,因而从理论上讲各种操作系统的协议栈应该是相同的。但在实际情况中,各种操作系统的协议栈的实现存在细微的差异,这些差异称作网络协议栈的指纹。由于每个操作系统对于网络部分的实现不尽相同,虽然在一些核心功能上都是一样的,但细节上可以区分,这样就为识别操作系统提供了可行性。
TCP/IP规范并不是被严格地执行,每个不同的实现将会拥有自身的特性,规范可能被打乱,一些选择性的特性被使用,而其他的一些系统则可能没有使用。某些对IP协议的改进也可能被实现,这就成为了某些操作系统的特性。根据TCP数据包的响应来进行探测,它是依靠不同操作系统对特定TCP的不同反应来区分的。
对TCP协议族来说,这些差异通常表现在数据包头的标志字段中,如窗口大小(Window Size)、ACK序号、TTL等的不同取值。通过对这些差别进行归纳总结,可以比较准确地识别出远程系统的类型。TTL(Time To Live)是数据包的存活时间,表示一个数据包在被丢弃之前可以通过多少跃点。不同操作系统的默认TTL值往往是不同的。DF位表示不分段的标志,在IP协议中设定,不同操作系统对DF位有不同的处理方式,有些操作系统设置DF位,有些不设置DF位,还有一些操作系统在特定场合设置DF位,在其他场合不设置DF位。Window Size表示TCP接收或者发送窗口大小,它决定了接收信息的机器在收到多少数据包后发送ACK包,一个特定操作系统的默认Window Size基本是常数。ACK序号也可以用来判断,不同的操作系统处理ACK序号时是不同的。如果发送一个含有FIN、PSH、URG的数据包到一个关闭的TCP端口,大多数操作系统会把回应ACK包的序号设置为发送的包的初始序号,而Windows系统则会发送序号为初始序号加1的ACK包。发送一个只有FIN标志位的TCP数据包给一个打开的端口,Linux等系统不响应,有些系统,例如Windows、HP-UX等,会返回一个RESET数据包。在SYN包的TCP头里设置一个未定义的TCP标记,目标系统在响应时,有的会保持这个标记,有的不保持,还有一些系统在收到这样的包的时候会复位连接。还可以利用初始化序列号ISN来识别,不同的操作系统在选择TCP ISN时采用不同的方法。不同的操作系统有不同的默认MSS值,对不同的MSS值的回应也不同。
介绍一个多功能的远程OS指纹被动识别工具——P0F,这是继Nmap和Xprobe2之后又一款指纹识别软件。
P0F的特色是探测:
- 是否运行于防火墙之后
- 是否运行于NAT模式
- 是否运行于负载均衡模式
- 远程系统已启动时间
- 远程系统的DSL和ISP信息等
那现在就让我们来体验P0F的神奇魅力。实验环境安装在Ubuntu 12.04.1 LTS,同时要安装大名鼎鼎的数据包捕获数据库LibPcap,Windows下的版本叫做WinPcap,Wireshark就是利用这个库开发的。下载P0F并使用WinSCP软件将安装包和数据包上传到实验环境,通过tar进行解压缩,并./build进行编译后就可以使用了,如果还不放心可运行./build debug,正常情况出现提示信息如下图。
那现在我们就可以对数据包进行系统识别了,运行./p0f –r [文件路径],就可以识别出操作系统的类型。
以下两张图可针对数据包识别出Windows7和HP-UX系统。