gpt4 book ai didi

javascript - 如果端口范围太宽,Node 中的端口扫描将不起作用

转载 作者:太空宇宙 更新时间:2023-11-04 03:07:06 25 4
gpt4 key购买 nike

我正在尝试在nodejs 中编写一个简单的portscan 脚本。您可以针对 scanme.nmap.org 运行此脚本。通过运行 nmap 本身,我知道该主机有四个开放端口:22、80、9929、31337。

我的脚本是:

var net = require('net');
var host = 'scanme.nmap.org';
var max = 35000;

function scanPort(port) {
try {
var c = new net.Socket();
c.setTimeout(5000);
c.connect({
port: port,
host: host
})

c.on('connect', function () {
console.log(port);
})

c.on('error', function (err) {
c.destroy();
})

c.on('timeout', function () {
c.destroy();
})
} catch (err) {
console.error(err);
}
}

for (i = 1; i<=max; i++) {
scanPort(i);
}

如果我从i = 1开始循环,脚本将检测端口22和80,之后,它将以退出代码0退出。它不会检测其他两个端口。如果我使用变量i,即跳过第一个端口并设置i = 9500,它将正确检测端口9929。如果我设置 i = 31000,也会发生同样的情况,检测到端口 31337。

我真的不明白为什么它没有按预期工作。我怀疑某些系统限制导致了一些错误,但我尝试将扫描功能包装在 try block 中,但未能检测到任何错误。

最佳答案

您可能尝试一次打开太多连接,导致资源耗尽,或者因接收服务器泛滥而被阻止。

因为所有套接字内容都是异步的,所以您的 for 循环会立即尝试打开 35,000 个套接字。虽然可以配置服务器来执行此操作,但它需要非常特殊的配置,并且使用每个套接字都需要低内存方案(这里没有)。

因此,一个简单的解决方案是将一次打开的套接字数量限制为某个合理的数量。

以下代码最初打开固定数量的套接字,然后当每个套接字完成时,它会打开另一个,从而维护固定数量的打开和事件套接字。当前设置为一次打开 100 个套接字。您可以在特定环境和操作系统中进行实验,看看在不出现问题的情况下可以将这个数字提高到多高:

var net = require('net');
var host = 'scanme.nmap.org';
var low = 1;
var high = 35000;

var maxInFlight = 100;


function scanPort(port) {
return new Promise(function(resolve, reject) {
var c = new net.Socket();
c.setTimeout(5000);
c.connect({
port: port,
host: host
})

c.on('connect', function () {
console.log(port);
c.destroy();
resolve(port);
})

c.on('error', function (err) {
c.destroy();
reject(err);
})

c.on('timeout', function () {
c.destroy();
reject({code: "Timeout", port: port});
})
});
}

var cntr = low;
var inFlightCnt = 0;

function run() {
while (inFlightCnt < maxInFlight && cntr <= high) {
++inFlightCnt;
scanPort(cntr++).then(function(port) {
--inFlightCnt;
run();
}, function(err) {
--inFlightCnt;
run();
});
}
}

run();

注意:当一次设置为 100 时,需要一段时间才能运行最多 35,000 个端口。它确实找到了您提到的四个开放端口。

<小时/>

而且,这是另一个版本,它收集有关每个端口及其失败/成功方式的信息,以便您在最后得到转储。它还在控制台中显示进度,以便您可以查看它是否仍在运行以及距离完成有多近:

var net = require('net');
var host = 'scanme.nmap.org';

var low = 1;
var high = 35000;

var maxInFlight = 200;


function scanPort(port) {
return new Promise(function(resolve, reject) {
var c = new net.Socket();
c.setTimeout(15000);
c.connect({
port: port,
host: host
})

c.on('connect', function () {
c.destroy();
resolve(port);
})

c.on('error', function (err) {
c.destroy();
reject(err);
})

c.on('timeout', function () {
c.destroy();
reject({code: "timeout", port: port});
})
});
}

var cntr = low;
var inFlightCnt = 0;

var openPorts = [];
var timeouts = [];
var refused = [];
var otherErrors = [];

function run() {
while (inFlightCnt < maxInFlight && cntr <= high) {
++inFlightCnt;
scanPort(cntr++).then(function(port) {
--inFlightCnt;
openPorts.push(port);
console.log(openPorts);
run();
}, function(err) {
if (err.code === "timeout" || err.code === "ETIMEDOUT") {
timeouts.push(err.port);
} else if (err.code === "ECONNREFUSED") {
refused.push(err.port);
} else {
otherErrors.push(err.port);
}
console.log(err.code + ": " + err.port);
--inFlightCnt;
run();
});
}
// if we are all done here, log the open ports
if (inFlightCnt === 0 && cntr >= high) {
console.log("open: " + JSON.stringify(openPorts));
console.log("timeouts: " + JSON.stringify(timeouts));
console.log("otherErrors: " + JSON.stringify(otherErrors));
}
}

run();

这是我在 Windows 10 上使用 Node v4.0.0 运行它时生成的输出:

open: [22,80,9929,31337]
timeouts: [25,135,136,137,138,139,445,974,984,972,965,963,964,978,985,980,975,981,987,971,960,977,1000,992,990,986,991,997,1391,1384,7455,7459,7450,7506,7512,23033,23736,33635,33640,33638,33641,33634,33636,33633]
otherErrors: []

我不知道为什么有些端口会超时。大多数会得到 ECONNREFUSED ,这正是您对未打开的端口所期望的情况,少数会从 net 库中得到 ETIMEDOUT ,还有一些会因代码中的超时而超时(我将其增加到 15 秒)。

另外,请注意我在连接后添加了销毁。您将这些套接字保持打开状态,当只有几个连接时,这可以正常工作,但如果连接大量端口,则可能会出现问题。

<小时/>

注意事项:在测试这个程序时,我运行了它很多很多次,大约在第 20 次运行它之后,我的互联网连接中断了一段时间,并且需要重新启动我的电缆调制解调器才能让一切恢复正常。我怀疑电缆调制解调器内部的某些东西无法在测试时一遍又一遍地处理这种快速的请求。但是,也可能是康卡斯特由于异常事件(大量端口请求)而关闭了我的连接。

当然,这可能只是巧合,我的小故障可能与我正在做的事情没有任何关系,但时间似乎太相关了,我不认为这只是一个巧合。

可以进一步修改该程序,通过每秒计量不超过 N 个端口探头来“减慢速度”。

关于javascript - 如果端口范围太宽,Node 中的端口扫描将不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36814081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com