Nmap OS指纹识别的工作原理是向目标机器的已知打开和关闭端口发送最多16个TCP,UDP和ICMP探针。这些探针专门用于利用标准协议RFC中的各种模糊性。然后Nmap侦听响应。 分析并组合这些响应中的许多属性以生成指纹。如果没有响应,则每个探测包都被跟踪并重新发送一次。所有数据包都是具有随机IP ID值的IPv4。如果未找到此类端口,则会跳过针对开放的TCP端口的探测的步骤。对于关闭的TCP或UDP端口,Nmap将首先检查是否找到了这样的端口。如果没有,Nmap将随机选择一个端口。
下图是icmp echo 请求或应答头部格式(ICMP echo request or reply header layout)
下图是icmp 目的地不可达头部格式(ICMP destination unreachable header layout)
2.Probe Sent:
2.1Sequence generation (SEQ, OPS, WIN, and T1)
发送一系列六个TCP探针来生成这四条测试响应线(test response line)。探测器精确间隔100毫秒发送,因此总时间为500毫秒。精确定时非常重要,因为我们检测到的一些序列算法(初始序列号、IP标识和TCP时间戳(initial sequence numbers, IP IDs, and TCP timestamps))依赖于时间。选择该定时值需要500毫秒,以便我们能够可靠地检测常用的2 Hz TCP时间戳序列。
每个探针都是检测远程机器上开放端口的TCP SYN 数据包。序列号sequence和确认号acknowledgment是随机的(但是保存起来以便Nmap可以区分响应)。检测精度要求探针的一致性,因此即使用户使用–data-length选项,也没有数据有效载荷。
这些数据包在使用的TCP选项和TCP窗口字段值方面有所不同。下表提供了所有六个数据包的选项和值。列出的窗口字段值不反映窗口缩放因子(window scaling)。EOL是选项列表的末尾选项,默认情况下,许多嗅探工具不会显示它。
Packet #1: window scale (10), NOP, MSS (1460), timestamp (TSval: 0xFFFFFFFF; TSecr: 0), SACK permitted. The window field is 1.
Packet #2: MSS (1400), window scale (0), SACK permitted, timestamp (TSval: 0xFFFFFFFF; TSecr: 0), EOL. The window field is 63.
Packet #3: Timestamp (TSval: 0xFFFFFFFF; TSecr: 0), NOP, NOP, window scale (5), NOP, MSS (640). The window field is 4.
Packet #4: SACK permitted, Timestamp (TSval: 0xFFFFFFFF; TSecr: 0), window scale (10), EOL. The window field is 4.
Packet #5: MSS (536), SACK permitted, Timestamp (TSval: 0xFFFFFFFF; TSecr: 0), window scale (10), EOL. The window field is 16.
Packet #6: MSS (265), SACK permitted, Timestamp (TSval: 0xFFFFFFFF; TSecr: 0). The window field is 512.
这些测试的结果包括四个结果类别行。 第一个SEQ包含基于探测包的序列分析的结果。 这些测试结果是GCD,SP,ISR,TI,II,TS和SS。 下一行,OPS包含为每个探测器接收的TCP选项(测试名称为O1到06)。 类似地,WIN行包含探测响应的窗口大小(名为W1到W6)。 与这些探测器相关的最后一行T1包含数据包#1的各种测试值。 这些结果用于R,DF,T,TG,W,S,A,F,O,RD和Q测试。这些测试仅针对第一个探针报告,因为它们对于每个探针几乎总是相同的。
2.2
ICMP echo (IE)
IE测试向目标发送两个ICMP echo request包.第一个设置了IP DF位,服务类型(type-of-service)(TOS)字节值为0,代码(code)为9(即使它应该为0),序列号295,随机IP ID和ICMP请求标识符(request identifier) ,以及数据有效负载的120字节的0x00。
第二个ping查询类似,除了使用四个TOS(IP_TOS_RELIABILITY),代码(code)为0,发送150个字节的数据,并且ICMP request ID和在先前的查询值基础上加1d的sequence number。
将这两种探针的结果组合成含有R,DFI,T,TG和CD测试集的IE行。 如果两个探针都引出响应,则R值仅为真(Y)。 T和CD值仅用于对第一个探针的响应,因为它们极可能相同。 DFI是针对这种特殊双探针ICMP 例子的定制测试。
这些ICMP探测(ICMP probes )在TCP序列探测(TCP sequence probes )之后立即进行,以确保共享的IP ID序列号测试的结果有效
2.3
TCP explicit congestion notification (ECN)
此探针测试目标TCP堆栈中的显式拥塞通知(explicit congestion notification)(ECN)支持。 ECN是一种通过允许路由器在开始丢弃数据包之前发出拥塞问题来提高互联网性能的方法。它在RFC 3168中有记录.Nmap通过发送一个SYN数据包来测试它,该数据包也设置了ECN CWR和ECE拥塞控制标志。对于不相关(对于ECN而言)测试,即使未设置紧急标志(urgent flag),也使用0xF7F5的紧急字段值(urgent field value)。 确认号(acknowledgment number )为零,序列号(sequence number)是随机的,窗口大小字段(window size field)是3,并且紧接在CWR位之前的保留位被置位。TCP选项(option)是WScale(10),NOP,MSS(1460),允许SACK,NOP,NOP。探针被发送到开放端口.
如果收到响应,则执行并记录R,DF,T,TG,W,O,CC和Q测试。
2.4
TCP (T2–T7)
六个T2到T7测试每个发送一个TCP探测包。在一个例外的情况下,每种情况下的TCP选项数据是(十六进制)03030A0102040109080AFFFFFFFF000000000402。那20个字节分别对应window scale(10),NOP,MSS(265),timestamp(TSval:0xFFFFFFFF; TSecr:0),然后是SACK permitted。例外情况是T7使用的window scale为15而不是10.每个探针的变量特征如下所述:
T2 sends a TCP null (no flags set) packet with the IP DF bit set and a window field of 128 to an open port.
T3 sends a TCP packet with the SYN, FIN, URG, and PSH flags set and a window field of 256 to an open port. The IP DF bit is not set.
T4 sends a TCP ACK packet with IP DF and a window field of 1024 to an open port.
T5 sends a TCP SYN packet without IP DF and a window field of 31337 to a closed port.
T6 sends a TCP ACK packet with IP DF and a window field of 32768 to a closed port.
T7 sends a TCP packet with the FIN, PSH, and URG flags set and a window field of 65535 to a closed port. The IP DF bit is not set.
在每种情况下,指纹中都会添加一行,并显示R、DF、T、TG、W、S、A、F、O、RD和Q测试的结果
2.5
UDP (U1)
此探针是发送到关闭端口的UDP数据包。在数据字段(data field),字符“C”(0x43)重复300次。对于允许我们这么设置的操作系统,IP ID值设置为0x1042。如果端口真正关闭且没有防火墙,则Nmap期望收到ICMP端口不可达消息(unreachable message)。 然后该响应进行R,DF,T,TG,IPL,UN,RIPL,RID,RIPCK,RUCK和RUD测试
3.Response Tests
上一节描述了Nmap发送的探测器,这一部分通过描述对响应执行的一连串测试。短名称(例如DF,R和RIPCK)是nmap-os-db指纹数据库中用于节省空间的名称。除非另有说明,否则所有数值测试值均以十六进制表示法给出,不带前导零。tests大致按照它们在指纹中出现的顺序记录。
3.1
TCP ISN greatest common divisor (GCD)
SEQ测试将六个TCP SYN数据包发送到目标机器的开放端口,并收集返回的SYN / ACK数据包。每一个SYN / ACK数据包包含32位初始序列号(initial sequence number)(ISN)。 此测试尝试确定目标主机增加这些值的最小数量。例如,许多主机(尤其是旧主机)总是以64,000的倍数递增ISN。
计算此问题的第一步是在探测响应之间创建一系列差异。 第一个元素是第一和第二探测响应ISN之间的差异。第二个元素是第二个和第三个响应之间的差异。 如果Nmap收到对所有六个探测的响应,则有五个元素。由于接下来的几个部分引用了这个数组,我们将其称为diff1。 如果一个ISN低于前一个ISN,Nmap会查看它必须从第一个值中减去以获得第二个值的值的数量,以及它必须计数的值的数量(包括将32位计数器归零)。这两个值中较小的一个存储在diff1中。因此0x20000后跟0x15000之间的差异是0xB000。0xFFFFFF00和0xC000之间的差值是0xC0FF。 然后,该测试值记录所有这些元素的最大公约数(greatest common divisor,GCD)。该GCD也用于计算SP结果
3.2
TCP ISN counter rate (ISR)
此值报告返回的TCP初始序列号的平均增长率。回想一下,每两个连续的探测响应之间存在差异并存储在先前讨论的diff1阵列中。这些差异除以发送产生它们的两个探针之间经过的时间量(以秒为单位 - 通常约为0.1)。结果是一个数组,我们称之为seq_rates,其中包含每秒ISN计数器增加的速率。 该数组对每个diff1值都有一个元素。 取数组值的平均值。 如果该平均值小于1(例如,使用恒定的ISN),则ISR为零。否则,ISR是该平均值的二进制对数(log base-2)的八倍,四舍五入到最接近的整数。
3.3
TCP ISN sequence predictability index (SP)
虽然ISR测试测量初始序列号增量的平均速率,但该值也测量ISN的变化率。它粗略估计从六个探测响应的已知序列预测下一个ISN是多么困难。计算方案使用上一节中讨论的差异数组(seq_rates)和GCD值。
只有在看到至少四个响应时才执行此测试。如果先前计算的GCD值大于9,则先前计算的seq_rates数组的元素除以该值。我们不对较小的GCD值进行除法,因为这些值通常是由偶然性引起的。然后获得所得值的阵列的标准偏差。如果结果为1或更小,则SP为零。否则计算结果的二进制对数,然后将其乘以8,四舍五入到最接近的整数,并存储为SP。
请记住,此测试仅用于OS检测目的,并不是对目标ISN生成器的全面审核。 即使SP值很高,也有许多算法缺陷导致易于预测。
3.4
IP ID sequence generation algorithm (TI, CI, II)
有三个测试检查响应的IP头ID字段。 TI基于对TCP SEQ探测的响应。CI来自对发送到关闭端口的三个TCP探测的响应:T5,T6和T7。 II来自ICMP对两个IE ping探测器的响应。对于TI,必须至少收到三个响应才能包含测试; CI,至少需要两个回复; 对于II,必须收到ICMP响应。
对于这些测试中的每一个,目标的IP ID生成算法基于以下算法进行分类。注意到测试之间的细微差别。请注意,差值假定计数器可以换行。因此,IP ID为65,100,后跟值700之间的差异为1,136。 2,000之后是1,100的差异是64,636。 以下是计算详情:
1.如果所有ID号都为零,则测试值为Z.
2.如果IP ID序列增加至少20,000,则该值为RD(随机)。 不可能是II的结果,因为没有足够的样本来支持它。
3.如果所有IP ID都相同,则将测试设置为十六进制的该值。
4.如果两个连续ID之间的任何差异超过1,000,并且不能被256整除,则测试的值为RI(随机正增量)。如果差异可被256整除,则必须至少为256,000才能产生此RI结果。
5.如果所有差异都可以被256整除并且不大于5,120,则将测试设置为BI(broken increment)。这种情况发生在Microsoft Windows等系统上,其中IP ID以主机字节顺序而不是网络字节顺序发送。 它工作正常,并不是任何类型的RFC违规,但它确实泄露了对攻击者有用的主机架构细节。
6.如果所有差异小于10,则值为I(incremental)。我们在这里允许差异达到十(而不是需要顺序排序),因为来自其他主机的流量可能导致序列间隙。
7.如果前面的步骤都没有识别生成算法,则从指纹中省略测试。
3.5
Shared IP ID sequence Boolean (SS)
此布尔值记录目标是否在TCP和ICMP协议之间共享其IP ID序列。 如果我们的六个TCP IP ID值是117,118,119,120,121和122,那么我们的ICMP结果是123和124,很明显,这两个序列不仅是增量的,而且它们都是相同序列的一部分。另一方面,如果TCP IP ID值是117-122但ICMP值是32,917和32,918,则使用两个不同的序列。
仅当II为RI,BI或I且TI相同时才包括此测试。如果包含SS,则如果序列是共享的,则结果为S;如果不是,则结果为O(other)。通过以下算法确定:
令avg为最终的TCP序列响应IP ID减去第一个TCP序列响应IP ID,除以探测数的差异。如果探测器#1返回的IP ID为10,000而探测器#6返回20,000,则avg将为(20,000 - 10,000)/(6 - 1),等于2,000。
如果第一个ICMP echo response IP ID小于最终TCP序列响应IP ID加上3倍的avg,则SS结果为S.否则为O.
3.6
TCP timestamp option algorithm (TS)
TS是另一个尝试根据它如何生成一系列数字来确定目标OS特性的测试。它查看对SEQ探测的响应中的TCP时间戳选项(如果有的话)。它检查TSval(选项的前四个字节)而不是回显的TSecr(最后四个字节)值。它取每个连续TSval之间的差异,并除以Nmap发送生成这些响应的两个探测器之间经过的时间量。结果值给出了每秒时间戳增量的速率。Nmap计算所有连续探测的每秒平均增量,然后按如下方式计算TS:
1.如果任何响应都没有时间戳选项,则TS设置为U(不支持)。
2.如果任何时间戳值为零,则TS设置为0。
3.如果每秒的平均增量落在0-5.66,70-150或150-350的范围内,则TS分别设置为1,7或8。 这三个范围得到特殊处理,是因为它们对应于许多主机使用的2 Hz,100 Hz和200 Hz频率。
4.在所有其他情况下,Nmap记录每秒平均增量的二进制对数,四舍五入到最接近的整数。 由于大多数主机使用1,000 Hz频率,因此A是常见结果
3.7
TCP options (O, O1–O6)
此测试记录数据包中的TCP 头部选项。它保留了原始顺序,并提供了有关选项值的一些信息。因为RFC 793不需要任何特定的排序,所以实现通常会提供独特的排序。有些平台没有实现所有选项(当然,它们是可选的)。当你将所有这些排列与实现使用的不同选项值的数量组合在一起时,此测试提供了一个真实的信息库。此测试的值是表示正在使用的选项的字符串。有几个选项会在角色后面立即生成参数。支持的选项和参数都显示在表8.1中。
例如,字符串M5B4NW3NNT11表示该数据包包含MSS选项(值0x5B4),后跟NOP。 接下来是一个窗口缩放选项,其值为3,然后是两个NOP。 最后一个选项是时间戳,它的两个字段都不为零。 如果响应中没有TCP选项,则测试将存在,但值字符串将为空。如果未返回探测,则省略测试。
虽然该测试通常被命名为O,但是为了序列生成目的而发送的六个探测器是特殊情况。这些被插入到特殊的OPS测试行中,并采用名称O1到O6来区分它们所涉及的探测包。“O”代表“选项”。 尽管名称不同,但O1到O6每个测试的处理方式与其他O测试完全相同.
3.8
TCP initial window size (W, W1–W6)
此测试仅记录接收数据包的16位TCP窗口大小。它非常有效,因为至少一台已知的主机发送超过80个值。不利的一面是,某些操作系统本身具有十几种可能的值。在我们收集操作系统使用的所有可能窗口大小之前,这会导致错误的否定结果。
虽然此测试通常命名为W,但为序列生成目的而发送的六个探测器是一种特殊情况。它们被插入一个特殊的WIN测试行,并取名为W1到W6。记录所有序列号探测的窗口大小,因为它们在TCP MSS选项值上不同,这导致某些操作系统通告不同的窗口大小。尽管名称不同,但每个测试的处理方式完全相同。
3.9
Responsiveness ®
此测试仅记录目标是否响应给定探测。可能的值为Y和N.如果没有回复,则省略测试的剩余字段。
此测试的风险涉及防火墙丢弃的探测器。这导致受试者指纹中的R = N. 然而,如果目标OS通常回复,则nmap-os-db中的参考指纹可以具有R = Y. 因此,防火墙可能会阻止正确的OS检测。为了减少这个问题,参考指纹通常省略了IE和U1探测器的R = Y测试,这些探测器是最可能被丢弃的探测器。此外,如果Nmap缺少目标的关闭状态的TCP端口,即使它尝试的端口没有响应,它也不会为T5,T6或T7测试设置R = N. 毕竟,缺少一个封闭的端口可能是因为它们都被过滤掉了。
3.10
IP don’t fragment bit (DF)
IP报头包含一个禁止路由器分段数据包的位。 如果数据包对于路由器来说太大而无法处理,则只需丢弃它(理想情况下返回“目标无法到达,需要分片”响应)。如果该位被设置则该测试记录Y,如果不是则记录N.
3.11
Don’t fragment (ICMP) (DFI)
这只是DF测试的修改版本,用于特殊的IE探测。它比较了发送的两个ICMP回送请求探测的不分段位的结果。它有四个可能的值,在表8.2中列举。
3.12
IP initial time-to-live (T)
IP数据包包含一个名为生存时间(TTL)的字段,每次遍历路由器时都会递减。如果字段达到零,则必须丢弃该数据包。这可以防止数据包无休止地循环。由于操作系统它们开始的TTL不同,因此可用于OS检测。Nmap通过检查对U1探测器的ICMP端口不可达响应来确定它与目标的跳数。该响应包括目标接收的原始IP分组,包括已经减少的TTL字段。通过从我们发送的TTL中减去该值,我们可以了解机器的跳数。然后,Nmap将该跳跃距离添加到探测响应TTL,以确定发送ICMP探测响应数据包时的初始TTL。该初始TTL值作为T结果存储在指纹中。
尽管像TTL这样的8位字段永远不会保持大于0xFF的值,但此测试偶尔会导致值为0x100或更高。当系统(可能是源,目标或其间的系统)破坏或以其他方式无法正确递减TTL时,就会发生这种情况。它也可能由于不对称的路线而发生。
当跳距离(hop distance)为零(本地主机扫描)或一个(在同一网段上)时,Nmap还可以从系统接口和路由表中学习。当Nmap打印用户的跳距时使用此值,但它不用于T结果计算。
3.13
IP initial time-to-live guess (TG)
Nmap没有接收到对U1探测器的响应的情况并不罕见,这会阻止Nmap获取目标的跳数。 防火墙和NAT设备喜欢阻止未经请求的UDP数据包。但是由于常见的TTL值分散得很好,并且目标很少超过20跳,所以Nmap无论如何都可以做出相当不错的猜测。大多数系统发送初始TTL为32,60,64,128或255的数据包。因此,响应中收到的TTL值向上舍入到32,64,128或255中的下一个值.60不在该列表因为无法与64进行可靠区分。结果猜测存储在TG字段中。如果发现实际TTL(T)值,则不会在受试者指纹中打印此TTL猜测字段。
3.14
Explicit congestion notification (CC)
该测试仅用于ECN探针。该探测是一个SYN数据包,包括CWR和ECE拥塞控制标志。当接收到响应SYN / ACK时,检查那些标志以设置CC(拥塞控制)测试值,如表8.3所述。
3.15
TCP miscellaneous quirks (Q)
这测试是针对实现TCP堆栈过程中存在的quirk。第一个是TCP header中的保留字段(在header length之后)非零。这特别有可能发生在ECN测试中,因为它在探测中设置了保留位。如果在数据包中看到这种情况,则在Q字符串中记录“R”。
另一个quirk是当未设置URG标志时,Nmap对是非零紧急指针字段值的测试。这也特别有可能在ECN探测器中看到,该探测器设置非零紧急字段(non-zero urgent field)。当看到这个时,在Q字符串上附加“U”。
必须始终按字母顺序生成Q字符串。 如果没有quirk,则Q测试为空但仍显示。
3.16
TCP sequence number (S)
此测试检查TCP header中的32位序列号字段。它不是像其他测试那样记录字段值,而是检查它与引发响应的探测的TCP确认号的比较。 然后记录适当的值,如表8.4所示。
3.17
TCP acknowledgment number (A)
该测试与S相同,不同之处在于它测试响应中的确认号与相应探测中的序列号的比较.可能的四个值为:
3.18
TCP flags (F)
该字段记录响应中的TCP标志。每个字母代表一个标志,它们的出现顺序与TCP数据包相同(从左侧的高位到低位)。因此值AS表示设置的ACK和SYN位,而值SA是非法的(错误的顺序)。 可能的标志如表8.6所示。
3.19
TCP RST data checksum (RD)
某些操作系统返回ASCII数据,例如重置数据包(reset package)中的错误消息。 RFC 1122的4.2.2.12节明确允许这样做。当Nmap遇到此类数据时,它会执行CRC32校验和并报告结果。没有数据时,RD设置为零。可能在其重置数据包中返回数据的操作系统包括HP-UX和Mac OS X之前的Mac OS版本
3.20
IP total length (IPL)
此测试记录IP数据包的总长度(以八位字节为单位)。它仅用于U1测试引发的端口不可达响应。该长度因实现而异,因为只要它们满足最低RFC 1122要求,就可以选择原始探针中包含的数据量。该要求是包括原始IP头和至少八个字节的数据
3.21
Unused port unreachable field nonzero (UN)
ICMP端口不可达消息头长度为八个字节,但仅使用前四个。 RFC 792规定最后四个字节必须为零。一些实现(主要是以太网交换机和一些专用嵌入式设备)会以任意方式设置它。 最后四个字节的值记录在该字段中。
3.22
Returned probe IP total length value (RIPL)
ICMP端口不可达消息(作为对u1探测器的响应而发送)需要包括生成它们的IP头。此header应该在收到它时返回,但是由于在IP处理期间所做的更改,某些实现会发回一个损坏的版本。 此测试仅记录返回的IP总长度值。如果返回正确的值0x148(328),则存储值G(good)而不是实际值。
3.23
Returned probe IP ID value (RID)
U1探针的静态IP ID值为0x1042。如果在端口不可到达消息中返回该值,则为该测试存储值G. 否则,将存储返回的确切值。某些系统(如Solaris)会处理Nmap发送的原始IP数据包的IP ID值。在这种情况下,将跳过此测试。我们发现某些系统,特别是HP和Xerox打印机,会翻转字节并返回0x4210。
3.24
Integrity of returned probe IP checksum value (RIPCK)
IP校验和是在端口不可达消息中返回时我们不希望保持不变的一个值。毕竟,传输过程中的每个网络跳都会随着TTL的减少而改变校验和。但是,我们收到的校验和应该与封闭的IP数据包匹配。 如果是,则为该测试存储值G(good)。 如果返回值为零,则存储Z. 否则结果是I(invalid)。
3.25
Integrity of returned probe UDP checksum (RUCK)
UDP header校验和的值应该与发送时完全一样。如果是,则记录该测试的G. 否则记录实际返回的值
3.26
Integrity of returned UDP data (RUD)
此测试检查返回的UDP有效负载的完整性(可能已截断)。如果所有payload字节都是预期的’C’(0x43),或者如果payload被截断为零长度,则记录G; 否则,I(invalid)被记录下来。
3.27
ICMP response code (CD)
ICMP echo reply(type zero)数据包的代码值应该为零。但是一些实现错误地发送其他值,特别是如果echo请求具有非零代码(如IE测试之一那样)。两个探针的响应代码值组合成CD值,如表8.7所述。