哈哈,TCP泄露了操作系统信息~
扫描二维码
随时随地手机看文章
HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Fri, 23 Aug 2019 01:02:08 GMT
Accept-Ranges: bytes
ETag: "e65855634e59d51:0"
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Fri, 23 Jul 2021 06:02:38 GMT
Content-Length: 1375
还有人说,可以通过URL路径来判断,如果大小写敏感就是Linux,不敏感就是Windows。于是,我进一步提高了难度,如果连Web服务也没有,只有一个TCP Server呢?这时又有人说,可以通过ping这个IP,查看ICMP报文中的TTL值,如果是xxx就是xx系统,如果是yyy就是yy系统···(不过,有些情况下也不是太准确)从TCP重传说起
今天,想跟大家探讨的是另外一种方法。这个方法的思路来源于前几天被删掉的那篇文章。就是日本网络环境下访问不了极客时间的问题,当时抓包看到的情况是这样的:cat /proc/sys/net/ipv4/tcp_retries1
cat /proc/sys/net/ipv4/tcp_retries2
tcp_retries1
默认值是3,tcp_retries2
默认值是15。但需要特别注意的是,并不是最多重传3次或者15次,Linux内部有一套算法,这两个值是算法中非常重要的参数,而不是重传次数本身。具体的重传次数还与RTO
有关系,具体的算法,有兴趣的朋友可以看看这篇文章:聊一聊重传次数(http://perthcharles.github.io/2015/09/07/wiki-tcp-retries/)总体来说,在Linux上重传的次数不是一个固定值,而是不同的连接根据tcp_retries2
和RTO
计算出来的一个动态值,不固定。而在Windows上,也有一个变量来控制重传次数,可以在注册表中设定它:键值路径:
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
键值名:
TcpMaxDataRetransmissions
默认值:5
我手里有一份Windows XP的源码,在实现协议栈的驱动tcpip.sys
的部分中,也印证了这个信息:TCP之SYN ACK的重传
就在我想要放弃的时候,我再一次品读了《TCP/IP详解·卷1》中的那段话,发现另一个信息:TCP的重传在建立连接阶段和数据传输阶段是不一样的!上面说到的重传次数限制,针对的是TCP连接已经建立完成,在数据传输过程中发生超时重传后的重传次数情况描述。而在TCP建立连接的过程中,也就是三次握手的过程中,发生超时重传,它的次数限定是有另外一套约定的。Linux:cat /proc/sys/net/ipv4/tcp_syn_retries
cat /proc/sys/net/ipv4/tcp_synack_retries
tcp_syn_retries
限定作为客户端的时候发起TCP连接,最多重传SYN的次数,Linux3.10中默认是6,Linux2.6中是5。tcp_synack_retries
限定作为服务端的时候收到SYN后,最多重传SYN ACK的次数,默认是5。重点来关注这个tcp_synack_retries
,它指的就是TCP的三次握手中,服务端回复了第二次握手包,但客户端一直没发来第三次握手包时,服务端会重发的次数。我们知道,在正常情况下,TCP的三次握手是这个样子的:tcp_synack_retries
实际上规定的就是上面这种情况下,服务端会重传SYN ACK的次数。为了进一步验证,我使用Python写了一段代码,用来手动发送TCP报文,里面使用的发包库是scapy。下面的这段代码,我向目标IP的指定端口只发送了一个SYN包:def tcp_syn_test(ip, port):
# 第一次握手,发送SYN包
# 请求端口和初始序列号随机生成
# 使用sr1发送而不用send发送,因为sr1会接收返回的内容
ans = sr1(IP(dst=ip) / TCP(dport=port, sport=RandShort(), seq=RandInt(), flags='S'), verbose=False)
用上面这段代码,向一台Linux的服务器发送,抓包来看一下:Windows
前面说过,在注册表HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
目录下有一个叫TcpMaxDataRetransmissions
的参数,可以用来控制数据重传次数。不过,那是限定的数据传输阶段的重传次数。根据MSDN
上的介绍,除了这个参数,还有另一个参数用来限制上面SYN ACK重传的次数,它就是TcpMaxConnectResponseRetransmissions
。Linux上,SYN ACK默认重传5次。Windows上,SYN ACK默认重传2次。
总结
如果一个IP开启了基于TCP的服务,不管是不是HTTP服务,都可以通过向其发送SYN包,观察其回应来判断对方是一个Linux操作系统还是一个Windows操作系统。当然,这种方法的局限性还是挺大的。首先,本文只介绍了一些默认的情况,但TCP的重传次数是可以更改的,如果网络管理员更改了这个数值,判断的结果就不准确了。其次,对于有些网络服务器开启了防DDoS功能,测试发现,其根本不会重传SYN ACK包,比如我用百度的IP测试就得到了这样的结果。最后,没有测试其他操作系统上的情况,比如Unix和MAC OSX,为什么呢?END
作者:轩辕之风O来源:编程技术宇宙版权归原作者所有,如有侵权,请联系删除。
▍