研究本地服务系列文章:
几个小问题想改进一下:
用 JavaScript 写个非常简单:
function Scanner(host = "127.0.0.1") {
this.host = host;
this.ports = [];
this.probe = (port) => {
return fetch(`http://${this.host}:${port}`, {
method: 'HEAD',
mode: 'no-cors',
}).then(resp => { this.ports.push(port); }).catch(e => { /*do nothing*/try { } catch (e) { } });
};
this.scan = (start, end) => {
const promises = [];
for (let port = start; port < end; port++) {
promises.push(this.probe(port));
}
return Promise.all(promises)
}
}
s = new Scanner();
s.scan(8000, 8100).then(() => {
s.ports.forEach(item => {
console.log("Opened Port:", item);
});
});
还没结束,得控制异步并发数量,不然浏览器直接跑崩…
抄网上的代码添加异步并发数量控制:
function Scanner(host = "127.0.0.1", limit = 10) {
this.host = host;
this.limit = limit;
this.ports = [];
this.probe = (port) => {
return fetch(`http://${this.host}:${port}`,
{
method: 'HEAD',
mode: 'no-cors',
}).then(resp => {
this.ports.push(port);
}).catch(e => {
const err = e.message;
if (err.includes("exceeded while awaiting") ||
err.includes("ssl") ||
err.includes("cors") ||
err.includes("invalid") ||
err.includes("protocol")) this.ports.push(port);;
try {/*do nothing*/ } catch (e) { }
});
};
this.scan = async (start, end) => {
const resultList = [];
const executing = [];
for (let port = start; port < end; port++) {
const p = this.probe(port);
resultList.push(p);
if (this.limit <= end) {
const e = p.then(() => {
return executing.splice(executing.indexOf(e), 1);
});
executing.push(e);
if (executing.length >= this.limit) {
await Promise.race(executing);
}
}
}
return Promise.all(resultList);
}
}
s = new Scanner();
s.scan(8000, 8100).then(() => {
s.ports.forEach(item => {
console.log("Opened Port:", item);
});
});
对扫出来的端口进行 url fuzz 测试,把 fetch mode no-cors
移除即可,其他逻辑一样。
在线测试地址:https://ac0d3r.github.io/webportscan/
源码:https://github.com/ac0d3r/webportscan