作者:uncle2

文章目录(红字标识为上篇内容)

一、前言:操作系统指纹识别与SMB协议
二、各大知名产品或项目如何做SMB OS探测

  1. Nmap
  2. Zoomeye
  3. Goby
  4. Fofa
  5. Censys
  6. Shodan
  7. Quake
  8. Metasploit
  9. 综述

三、应该如何做SMB OS指纹探测
四、后话

前言:操作系统指纹识别与SMB协议
无论在渗透测试、自动化漏洞扫描还是网络空间测绘中,目标资产探测都是重要的一环,而资产探测中的重中之重就是操作系统指纹探测,当说到操作系统指纹探测,首先应该提到的就是SMB协议。
从 Shodan的445端口的OS统计结果 来看,通过SMB可以直接得到全球近110万台主机的操作系统,因此SMB绝对应该是探测OS版本————尤其是探测Windows版本的首选。
image-1661839852915
关于SMB协议的介绍,这里摘选 #1 SMB小传 —— SMB网络文件系统协议介绍 (https://developer.aliyun.com/article/675647)
“SMB网络文件系统协议, 全名服务器消息块(Server Message Block),曾用名CIFS(通用互联网文件系统 Common Internet File System), 公元1983年诞生于IBM[1],幼年得到英特尔和微软的照料,最终在微软的培养下成长为当今世上网络文件系统协议两极之一的存在。”
“SMB1协议有太多的缺点,除了近期在2017年因为WannaCry病毒事件而再次暴露出来的巨大安全漏洞之外,便是SMB1协议特性导致了其对于网络资源的巨大耗费以及在远距通信场景下极差的性能。”
“从1983年到2007年这整整24年中,SMB作为一个网络文件系统的基本功能已经比较完整了,各种文件系统操作、用户认证、消息签名、客户端缓存等等的功能都有,更是取消了对NetBIOS协议层的依赖从而直接使用445端口运行在TCP/IP之上。”
“至于为何SMB在1996年一度改名为CIFS呢?那都是源于微软面对Sun公司的NFS(Network File System)协议面向Web服务的扩张(WebNFS),而进行的一次失败的IETF网络文件系统标准化尝试[6],对此本文不多作细说。不过这一次改名导致了人们现在有时也会以CIFS来称呼SMB协议,而在Linux平台的SMB客户端甚至一直保持了CIFS的命名。”
“随着互联网产业的快速发展,SMB堪忧的安全性和愈发跟不上时代的性能使得微软不得不对SMB协议进行大刀阔斧的修订,并在2007年发布了SMB 2.0。仔细观察就会发现,SMB 2.X和SMB 3.X带来的众多新特性基本都是是围绕着增加安全性和提升性能这两个主题来设计的。”
“细心的读者可能会好奇,为什么SMB3没有独立的协议文档呢?一则SMB2和SMB3在报文格式上并没有太大差异,并不需要单独开一篇文档;二则,其实SMB 3.0在WIndows 8测试版阶段还是命名为SMB 2.2的,但微软工程师们经过再三考虑,认为以SMB3新增的代码之多、新特性之丰富,一个单独的主版本号才是理所应当的。”
各大知名产品或项目如何做SMB OS探测
由于时间原因我们并未从详细研究微软官方发布的与SMB相关的文档入手,而是选择从学习各大知名产品或项目开始,一窥他们是如何进行SMB OS探测的。下表是我们总结的它们的SMB OS探测方式,如有错误欢迎指正:
image-1661839889937
关键项说明:
强制SMBv1探测: 不使用与Server协商的Server偏好SMB版本,而是强制使用SMBv1进行探测,相较于SMBv2,SMBv1的响应中包含Server操作系统的明文字符串
SMBv1 OS探测: SMBv1请求有多种,并非每种请求都能得到OS版本信息,这里专指进行了SMBv1的OS探测
SMBv1 OS探测请求类型为NTLMSSP:若发送一般的 AndX Request 而非包含 NTLMSSP 的 AndX Request的SMBv1请求,则可能无法探测到 Windows Server 2012以上版本的操作系统,即使对方支持SMBv1
SMBv2探测结果包含ntlmssp.version: 对不支持SMBv1而只支持v2的Server,虽然不能直接使用 ntlmssp.version 来断定其操作系统,但在结合其他信息(如响应中ServerDNSDomainName中包含 WIN- 和 Desktop-等)确定其是Windows而非Unix/Linux后,即可使用 ntlmssp.version 来确定具体的Windows Name(Windows Edition)
SMBv2响应解析详细程度:是否解析了SMBv2响应,并列出了关键的字段值,如最为重要的 ntlmssp.version 和 ServerDNSDomainName
扫描共享目录: 该项不作为SMB OS扫描是否完善的标准,而是根据产品/工具的具体使用场景而定
下面一一具体分析。

  1. Nmap
    https://github.com/nmap/nmap
    Nmap的SMB OS识别是使用nse脚本实现的 nmap/scripts/smb-os-discovery.nse
    根据nse脚本注释,使用方法如下:
    image-1661839956182
    或者使用如下命令也能达到同样的效果
    image-1661839968615
    通过观察发包可以发现两种方法的不同之处,图中红框标出的即为包含操作系统信息的响应包
    445/tcp
    image-1661839976756
    137/udp 及 139/tcp
    image-1661839982964
    但在测试中我们发现,对有些目标Shodan可以通过SMB探测出OS,而我们调用Nmap却探测不到。这种情况的数据包如下图所示,目标是我们的一台Windows Server 2016:
    image-1661839991162
    经确认,smb-os-discovery.nse 无法识别 Windows Server 2016及以上的操作系统,而对2016以下版本的操作系统偶尔也无法识别。此外,它无法对仅支持SMBv2的主机进行探测。
    从上述截图中可以看到,Nmap成功识别出 另一台Windows Server 2012,并且有发送 Session Setup AndX Request, NTLMSSP_NEGOTIATE 请求。
    对比看一下识别 Windows Server 2016 的数据包,Nmap会先发送 Session Setup AndX Request, User: \guest请求,而非 NTLMSSP 请求,若认证失败,是不会继续发送NTLMSSP请求的,这导致它无法识别出 Windows Server 2016,而如果直接对该主机发送 SMBv1的 Session Setup AndX Request, NTLMSSP_NEGOTIATE 请求,是可以得到操作系统的明文字符串的,如下图 osfp-smb 的的数据包:
    image-1661840018278

  2. Zoomeye
    https://www.zoomeye.org/
    Zoomeye 从组件信息中的 microsoft-ds 字符串可知,Zoomeye使用的是Nmap的-sV命令而非 smb-os-discovery.nse 进行SMB探测,且未对banner进行解析。在Nmap中445上运行的协议(Nmap中称为service)被称为 microsoft-ds,而非 SMB。
    image-1661840031444
    具体示例如下:
    image-1661840037234
    通过 -sV 选项,很多时候无法得到操作系统的详细版本信息,上例我们的测试目标为 Windows Server 2012,Nmap得到的结果是 Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: DEMO)。此外还存在误报的情况,我们的Windows Server 2016也被Nmap识别为 Microsoft Windows Server 2008 R2 - 2012 microsoft-ds

  3. Goby
    https://gobies.org/
    Goby 针对SMB进行资产探测,应该使用的是自研的方式,发送的数据包如下:
    image-1661840045794
    可以看到 Goby 发送的 SMBv2 的 NTLMSSP 请求,结果可以得到 ntlmssp.version 为 Version 6.3 (Build 9600); NTLM Current Revision 15
    这个字段不一定可以确定目标使用的就是Windows,至少在SMB协议中是这样的,因为运行在Unix主机上的Samba服务,也会返回这个字段。参考 #2 wikipedia - NT LAN Manager - Compatibility with Linux
    (https://en.wikipedia.org/wiki/NT_LAN_Manager)
    NTLM implementations for Linux include Cntlm[33] and winbind (part of Samba).[34] These allow Linux applications to use NTLM proxies.FreeBSD also supports storing passwords via Crypt © in the insecure NT-Hash form.[35]
    这一观点可以通过Shodan中的如下目标来测试,通过观察Shodan中该IP的端口及banner,基本可以确定该目标是Ubuntu主机(而非存在port mapping且表现出多种操作系统属性的公网出口网关)。
    image-1661840063680
    使用Goby v1.8.239 beta 对该主机进行资产探测,结果被标记为Windows,这里存在误报:
    image-1661840074344
    抓包结果如下(这里使用了SOCKS5代理因此IP为本地IP):
    image-1661840082575
    但是,如果能够用某种方式确认目标系统确实是Windows,就可以通过 ntlmssp.version(内核Build版本) 推断对应的Windows Name(或Windows Edition),本例中的version 6.1 对应的 Windows Name 为 Windows 7 或者 Windows Server 2008 R2。
    具体的推断方式可参考如下链接:
    #3 List of Microsoft Windows versions
    (https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions)
    #4 Windows 10 version history
    (https://en.wikipedia.org/wiki/Windows_10_version_history)
    #5 Windows Server release information
    (https://docs.microsoft.com/en-us/windows-server/get-started/windows-server-release-info)
    关于各类版本概念的区别,参考 #6 版本 Version, Release, Build 和 Edition 之间的区别
    (https://blog.csdn.net/jobschen/article/details/43736085)
    “Version – 软件的公开发行版本,强调功能性。通常在功能方面有一定的/重大改变、改进或增加,包括对一些重大bug的修复。例如:V1.0, V1.01, V2.0, V2.3…,Windows 2000, XP, Vista, 7 等。
    Release – 软件的公开发行版本,强调软件由调试/内测阶段转为正式发布/发行阶段。
    Build – 对程序源代码做任何修改并重新编译后生成的版本,可能发生在软件公开发行前的调试、优化、测试阶段,也可能发生在软件正式发布后。同release相比,其发生较为频繁,每编译一次,即会产生一个 build。例如:SDL Trados 8.3.0.863 (Build 863)
    Edition – 通常表示按特定对象、特定群体进行分类的软件版本,强调软件的目标受众。例如:Trados 6.5 Freelance Edition, LSP Edition; Windows XP Home Edition, BussIness Edition。
    【示例】Official Release of PocketWeather Ver. 2.0.7 Enterprise Edition (Build 326)”

  4. Fofa
    https://fofa.so/
    Fofa 与 Goby 出自同一家公司,但两者似乎在 SMB OS探测中有些差异,不同于Goby在资产探测时只发送SMBv2,Fofa的结果揭示其有发送 SMBv1的请求并得到一些操作系统版本的明文字符串,如下图:
    image-1661840098365
    与Goby的问题相同,图中 122.70.157.10 的主机也被标记成了Windows。
    此外与 Goby 类似,Fofa中也存在某些目标未得到操作系统明文字符串,在Shodan中是可以得到的情况。
    Fofa的结果为:
    image-1661840106922
    Shodan的结果为:
    image-1661840115335
    从Shodan的结果可以看到,目标主机支持SMBv1,而上面提到Fofa也有做SMBv1探测,那么造成最终结果差异的原因就在于探测方法的差异上。Fofa在SMBv1探测时,发送的应该是 Session Setup AndX Request, User: \ 请求,而非 NTLMSSP请求。

参考链接
#1 SMB小传 —— SMB网络文件系统协议介绍
(https://developer.aliyun.com/article/675647)
#2 wikipedia - NT LAN Manager - Compatibility with Linux
(https://en.wikipedia.org/wiki/NT_LAN_Manager)
#3 List of Microsoft Windows versions
(https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions)
#4 Windows 10 version history
(https://en.wikipedia.org/wiki/Windows_10_version_history)
#5 Windows Server release information
(https://docs.microsoft.com/en-us/windows-server/get-started/windows-server-release-info)
#6 版本 Version, Release, Build 和 Edition 之间的区别
(https://blog.csdn.net/jobschen/article/details/43736085)