如果端口范围太宽,节点中的端口扫描不起作用
Portscan in Node doesn't work if port range is too wide
我正在尝试用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
块中,但没有设法检测到任何错误。
您可能尝试一次打开太多连接并耗尽资源或在接收服务器上被阻止以使其泛滥。
由于所有套接字内容都是异步的,因此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();
这是我在带有节点 v4.0.0 的 Windows 10 上运行它时生成的输出:
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个端口探测器来"减慢速度"。
- 节点.js快速删除 req.body 不起作用
- ES2015“导入”在带有--harmony_modules选项的节点v6.0.0中不起作用
- 如果端口范围太宽,节点中的端口扫描不起作用
- “require”关键字在节点红色函数节点中不起作用
- 节点JS require不起作用
- 节点 Webkit 文本到语音 API 不起作用
- 默认条件在节点中不起作用
- 计算节点数不起作用
- 节点邮件不起作用,怎么了
- 节点要求()与ES6导入:为什么这个例子不起作用
- 节点.js正则表达式不起作用
- 节点.js:setInterval 函数不起作用
- 删除类后的添加类在选择同一节点时在剑道树视图中不起作用
- 节点.JS - 简单的 Socket.IO 示例不起作用.获取调试 - 提供静态内容/socket.io.js(Mac
- 使用节点发布回复.js不起作用
- 如果条件在节点 js 中不起作用
- 节点 Http 代理 - 基本反向代理不起作用 (404s)
- 通过猫鼬和节点_id进行简单查询.js不起作用
- DOM 附加文本节点的子节点不起作用
- 从角度到节点的 POST 数据不起作用