【发布时间】: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