-2

我目前正在用 bash 做扫描仪。
这个想法是接收一个网络作为输入,并在遍历它的同时,ping IP 并探测端口以查看它们是否打开。

Var说明(示例):
输入->要扫描的网络:192.168.1.0/24

起始IP:192.168.1.0 -> $i1.$i2.$i3.$i4
最后IP:192.168.1.255 -> $m1.$m2.$m3.$m4

for oct1 in $(seq $i1 1 $m1); do
    for oct2 in $(seq $i2 1 $m2); do
        for oct3 in $(seq $i3 1 $m3); do
            for oct4 in $(seq $i4 1 $m4); do
                 ping -c 1 $oct1.$oct2.$oct3.$oct4 | grep "64 bytes" | cut -d" " -f4 | tr -d ":" >> scan.txt
                 nc -nvz $oct1.$oct2.$oct3.$oct4 80 2>&1 | grep succeeded | cut -d" " -f4 >> scan.txt
             done
         done
     done
done

文件scan.txt类似于:

192.168.1.1
80
192.168.1.2
192.168.1.4
192.168.1.5
192.168.1.7
80
192.168.1.9
(...)

我唯一的问题是,这个解决方案虽然有效,但需要太多时间。
扫描 192.168.1.0/24 网络,我发现脚本可以正常启动,但在扫描了大约 10 个 IP 后,它开始变慢,几乎卡住了。

我想这与 ping 和 nc 命令使作业在后台运行有关。如果我添加& disown到 ping 和 nc 命令的末尾,它会运行得更顺畅,但会导致输出混乱。

而不是从 .1 到 .254,它开始看起来像:

192.168.1.6
80
192.168.1.10
80

80
192.168.1.1
192.168.1.5
192.168.1.3
(...)

可以优化(或以不同方式完成)此代码以更快地运行吗?

4

1 回答 1

2

ping -c 1 $oct1.$oct2.$oct3.$oct4 | grep "64 字节" | 剪切-d" "-f4 | tr -d ":" >> scan.txt

当 ping 不产生“64 字节”消息时会发生什么?您的脚本停止了很长一段时间。在我的系统上,失败需要 10 秒,但我不确定该超时是否有任何特别标准。

$ time ping -c1 192.168.0.123
PING 192.168.0.123 (192.168.0.123) 56(84) bytes of data.

--- 192.168.0.123 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms


real    0m10.004s
user    0m0.000s
sys     0m0.000s

目前大多数 Linux 发行版都包含超时(1),因此您可以限制脚本等待的时间:

$ timeout 2 ping -c1 192.168.0.123 || echo no
PING 192.168.0.123 (192.168.0.123) 56(84) bytes of data.
no

对于并发处理(一次 ping 多个主机),您可以考虑将make (1) 与该-j选项一起使用。使用脚本生成一组地址​​,每个地址都有一个文件名,然后定义一个 Makefile 规则来为每个输入生成一个输出文件。最后一步,将所有输出连接在一起。

如果您的输入文件是.ping并且您的输出文件是.pong,则遵循以下规则:

.ping.pong:
        ping -c 1 $^ \
        | grep "64 bytes" \
        | cut -d" " -f4 \
        | tr -d ":" > $@~
        nc -nvz $^ 80 2>&1 \
        | grep succeeded | cut -d" " -f4 >> $@~
        mv $@~ $@

会将每个 .ping 文件“编译”为 .pong 文件。(上述方法不太有效,因为您需要从文件名中删除后缀以用作命令行参数。)

最后一点建议:如果您发现自己在管道中使用 grep、cut、sed 和 tr,那么awk (1) 是您的朋友。有 100 个原因,但最好的一个可能是您可以轻松编写 awk 脚本,让意外输入“通过”您可以看到并处理它。使用 grep,所有意想不到的东西都会被丢弃,让您猜测(或询问)缺少什么。

于 2021-11-06T03:15:01.463 回答