侦听应用程序(winsock2)对端口扫描的行为(Syn Scan)
侦听端口的服务器应用程序应该能够检测并记录Syn扫描所做的任何连接尝试吗?侦听应用程序(winsock2)对端口扫描的行为(Syn Scan)
测试方案
我写了一个Windows程序,我只是把它叫做 “simpleServer.exe”。 这个程序只是一个非常基本的服务器应用程序的模拟。 它侦听一个端口,并等待传入的消息。 监听套接字被定义为TCP流套接字。 这就是这个程序正在做的。
我一直在2个不同的机器上部署这个完全相同的程序,都运行在Windows 7专业版64位。 此机器将充当主机。 和他们驻扎在同一个网络区域。
然后,使用程序“nmap”, 我在同一个网络上使用另一台机器来充当客户端。 使用“nmap”上的“-sS”参数,我做了Syn Scan,在两台计算机上一次尝试一次尝试侦听简单服务器的IP和端口。
(注意,2台主机已经有了“Wireshark的”启动,并从客户端的IP和侦听端口,监视TCP数据包。)
在“Wireshark的”条目,这两个机器上,我看到Syn Scan的预期tcp数据包:
client ----(SYN)----> host
client <--(SYN/ACK)-- host
client ----(RST)----> host
上述数据包交换表明连接未建立。
但是在“simpleServer.exe”中,其中只有一个在日志中打印了“新传入连接”,而另一个实例未收到任何新传入连接的警报,因此根本没有日志。
代码段
// socket bind and listen was done above this loop
while(TRUE)
{
sClient=accept(sListen,(SOCKADDR*)&remoteAddr,&nAddrLen);
if(sClient == INVALID_SOCKET)
{
printf("Failed accept()");
continue;
}
dwSockOpt (sListen);
printf ("recv a connection: %s\n", inet_ntoa(remoteAddr.sin_addr));
closesocket(sClient);
}
侧面说明: 是的,因为它只是一个简单的程序,流程可能有点好笑,比如在而循环中没有休息。所以请不要介意这个简单而有缺陷的设计。
进一步调查
我也把的getsockopt()在“SimpleServer来”后马上进入监听状态,同时检查监听套接字的SOL_SOCKET选项的差异。
我在两台主机之间发现了一个值得注意的区别,就是SO_MAX_MSG_SIZE。 检测到传入连接的主机的十六进制值为0x3FFFFFFF(1073741823),而没有日志的另一个为0xFFFFFFFF(-1)。不确定这是否相关,但我只是垃圾邮件我可能在我的测试环境中发现的任何差异。 SOL_SOCKET的另一个值或多或少是相同的。
备注:我在其他一些机器上测试过,它覆盖了另一个Windows 7专业版,windows server 2008 r2,windows server 2003.我不确定它是不是巧合,但机器的SO_MAX_MSG_SIZE == -1 ,他们都没有检测到Syn扫描的连接。但也许这只是一个巧合。我没有什么证明寿。
帮助,我需要
- 为什么是从2相同的不同的机器上相同的应用程序使用相同的操作系统的不同的行为?
- 什么决定了SO_MAX_MSG_SIZE的值?考虑两个相同的操作系统但有两个不同的值。
如果连接永远不会建立,accept()
永远不会返回。这解决了90%的问题。
'new incoming connection'(或'recv a connection'或其它什么)消息的唯一解释是其他连接。
SO_MAX_MSG_SIZE对TCP套接字没有意义,更不用说侦听TCP套接字了。所以无论你经历什么样的变化都没有意义
嗨EJP,感谢您的答复。顺便说一句,还有什么可以连接到它?如果我正确地在wireshark上跟踪我的踪迹,那么只有来自客户端的数据包。只有当我在客户端上运行nmap时才会出现这些跟踪。 – Hakim
“accept()”必须有一个SYN-SYN/ACK-ACK序列才能返回。 – EJP
这就是为什么我试图找出我的机器上发生了什么。我看到一个SYN-SYN/ACK-RST(从wireshark踪迹中找不到SYN-SYN/ACK-ACK),但accept()会返回一个值。并打印客户的IP。它只发生在某台机器上(包括我的笔记本电脑)。顺便说一句,对不起,如果我可能在我的问题中使用了不正确的术语/句子。 – Hakim