【问题标题】:Why does this port scanner code sometimes miss open ports?为什么此端口扫描程序代码有时会错过打开的端口?
【发布时间】:2012-02-26 21:57:43
【问题描述】:

我正在尝试编写一个简单的连接端口扫描器。我正在 scanme.nmap.org 上针对前 10K 端口对其进行测试。它应该看到端口 22、80 和 9929。如果我扫描 1 - 10000,它会找到 22 和 80,但看不到 9929。如果我先扫描 9900 到 10000,然后是 1-10000(如下例所示),它会看到 9929 ,但通常看不到端口 80 或 22。

我知道我可以尝试通过 .NET 包装器使用 WinPcap 并进入较低级别,但无论如何,是否有一个简单的 TCP 连接端口扫描程序在没有 WinPcap 的情况下可靠地工作?

注意:我目前以 100 个批次进行扫描,因为如果以更大的块进行扫描,结果会更差。

using System;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace ps
{
internal class Program
{
    private const int batchSize = 100;

    public static void Main(string[] args)
    {
        int minPort = Convert.ToInt32(args[0]);
        int maxPort = Convert.ToInt32(args[1]);

        int loops;

        if (maxPort < batchSize)
        {
            loops = 1;
        }
        else
        {
            loops = maxPort/batchSize;
        }

        // If I look for 9929 in the inital 100 - I can find it
        Parallel.For(9900, 10000, port =>
                                      {
                                          string host = "scanme.nmap.org";
                                          bool res = TryConnect(host, port, 5000);

                                          if (res)
                                          {
                                              Console.WriteLine("\nConnected: " + port + "\n");
                                          }
                                      });

        // now loop through all ports in batches
        // should see 22, 80 & 9929 but normally doesn't
        for (int i = 0; i < loops; i++)
        {
            minPort = 1 + (i*batchSize);
            if (loops != 1)
            {
                maxPort = batchSize + (i*batchSize);
            }
            Console.WriteLine("minPort:" + minPort + " maxPort:" + maxPort);
            Parallel.For(minPort, maxPort, port =>
                                               {
                                                   string host = "scanme.nmap.org";
                                                   bool res = TryConnect(host, port, 5000);

                                                   if (res)
                                                   {
                                                       Console.WriteLine("\nConnected: " + port + "\n");
                                                   }
                                               });
        }

        // Can see port 22 and 80 still?
        Parallel.For(1, 100, port =>
                                 {
                                     string host = "scanme.nmap.org";
                                     bool res = TryConnect(host, port, 5000);

                                     if (res)
                                     {
                                         Console.WriteLine("\nConnected: " + port + "\n");
                                     }
                                 });
    }


    private static bool TryConnect(string strIpAddress, int intPort, int nTimeoutMsec)
    {
        Socket socket = null;
        bool retval = false;

        try
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IAsyncResult result = socket.BeginConnect(strIpAddress, intPort, null, null);
            bool success = result.AsyncWaitHandle.WaitOne(nTimeoutMsec, true);
            retval = socket.Connected;
        }
        catch
        {
            Console.WriteLine("error: " + intPort);
            retval = false;
        }
        finally
        {
            if (null != socket)
                socket.Close();
        }
        return retval;
    }
}

}

【问题讨论】:

  • 你尝试过更高的超时时间吗?
  • @sh4nx0r 刚把它调到 15 秒 - 它看到 9929,但不是 80 或 22。
  • @Andrew Barber 正在检查所有端口,只是它只可靠地连接到检查的前 100 个端口。如果我先扫描 1-100,它总是会看到 22 和 80。而如果我先扫描 9900 到 10000,它经常会错过 80 或 22,但并非每次都如此。
  • @FunLovinCoder,对不起,伙计,我真的很想测试该代码,但我现在远离我的电脑。顺便说一句,我已经收藏了你的问题,所以当我回来时,如果你还没有找到答案,我会看看。
  • 也许防火墙认为它是一个邪恶的 portscan™ 并在前几个端口之后阻止它。

标签: c# networking tcp network-programming


【解决方案1】:

我认为你在计算循环方面有一个不一样的地方,如果它甚至没有出来的话。

请注意您在最后一遍中的所有失败情况。

【讨论】:

  • 谢谢,但这并不能解释为什么它有时会错过端口。我感兴趣的那些,即 22 80 和 9929 它总是尝试连接。
  • @FunLovinCoder:如果您尝试扫描的端口数不能被您的块大小整除,则部分块中的端口将不会运行,甚至不会尝试。给你带来麻烦的端口号总是在最后一个块中。
  • 给我带来麻烦的并不都在最后一个区块 - 22 和 80 在我扫描 9900-10000 之后的第一个区块中。您的观点是正确的,但对于缺少这些特定端口的代码来说,这是一个红鲱鱼。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多