Tcp 侦听应用程序(winsock2)对端口扫描(Syn扫描)的行为

Tcp 侦听应用程序(winsock2)对端口扫描(Syn扫描)的行为,tcp,server,behavior,winsock2,difference,Tcp,Server,Behavior,Winsock2,Difference,侦听端口的服务器应用程序是否应该能够检测并记录Syn扫描所做的任何连接尝试 测试场景 我写了一个windows程序,我简单地称之为“simpleServer.exe”。 这个程序只是一个非常基本的服务器应用程序的模拟。 它侦听端口,并等待传入消息。 侦听套接字被定义为TCP流套接字。 这就是这个项目所做的一切 我在两台不同的机器上部署了完全相同的程序,都运行在Windows7 professional 64位上。 这台机器将充当主机。 而且他们都驻扎在同一个网络区域 然后,使用程序“nmap”,

侦听端口的服务器应用程序是否应该能够检测并记录Syn扫描所做的任何连接尝试

测试场景

我写了一个windows程序,我简单地称之为“simpleServer.exe”。 这个程序只是一个非常基本的服务器应用程序的模拟。 它侦听端口,并等待传入消息。 侦听套接字被定义为TCP流套接字。 这就是这个项目所做的一切

我在两台不同的机器上部署了完全相同的程序,都运行在Windows7 professional 64位上。 这台机器将充当主机。 而且他们都驻扎在同一个网络区域

然后,使用程序“nmap”, 我使用同一网络上的另一台机器作为客户端。 使用“nmap”上的“-sS”参数,我对两台机器上侦听simpleServer的IP和端口进行Syn扫描(一次尝试一次)

(请注意,这两台主机已经启动了“wireshark”,并且正在监视从客户端IP到侦听端口的tcp数据包。)

在这两台机器上的“wireshark”条目中,我看到了用于Syn扫描的预期tcp数据包:

client ----(SYN)----> host

client <--(SYN/ACK)-- host

client ----(RST)----> host
旁注: 是的,因为它只是一个简单的程序,所以流程可能有点滑稽,比如while循环中没有中断。所以请不要介意这个简单而有缺陷的设计

进一步调查

在“simpleServer”进入侦听状态之后,我还将getsockopt()放在了“simpleServer”中,以检查侦听套接字的SOL_套接字选项的差异

我发现这两台主机之间有一个显著的区别,就是SO_MAX_MSG_大小。 检测传入连接的主机的十六进制值为0x3FFFFFFF(1073741823),而另一个没有日志的主机的十六进制值为0xFFFFFF(-1)。不确定这是否相关,但我只是对我在测试环境中发现的任何差异进行了垃圾邮件处理。SOL_套接字的其他值大致相同

旁注:我在另一台机器上进行了测试,其中包括另一台Windows7专业版、WindowsServer2008R2和WindowsServer2003。我不确定这是否是巧合,但机器上有SO_MAX_MSG_SIZE==-1,它们都没有检测到Syn扫描的连接。但也许这只是巧合。我没有什么可以证明的

我需要的帮助

  • 为什么在具有相同操作系统的不同机器上,同一应用程序的2个相同操作的不同行为
  • 什么决定了SO_MAX_MSG_SIZE的值?考虑两个相同的操作系统,但有两个不同的值

如果从未建立连接,
accept()
将永远不会返回。这就解决了你90%的问题

“新传入连接”(或“recv a connection”或其他任何内容)消息的唯一解释是其他连接


所以\u MAX\u MSG\u SIZE对于TCP套接字没有意义,更不用说侦听TCP套接字了。所以你经历的任何变化都是毫无意义的

嗨,EJP,谢谢你的回复。顺便问一下,还有什么可能与之相关?如果我正确跟踪wireshark上的跟踪,则只有来自客户端的数据包。只有在客户端上的上运行nmap时,跟踪才会出现。必须有SYN-SYN/ACK-ACK序列才能返回
accept()
。这就是我试图找出我的计算机上发生了什么的原因。我看到一个SYN-SYN/ACK-RST(在wireshark跟踪中从未找到SYN-SYN/ACK-ACK),但
accept()
以某种方式返回一个值。并且还打印了客户端的IP。它只发生在特定的机器上(包括我的笔记本电脑)。顺便说一句,如果我在问题中使用了不正确的术语/句子,我很抱歉。
// 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);
}