Bash脚本
Bash脚本(程序)可以单批次地执行数条计算机命令。Bash脚本又称作shell脚本,是一种由多条终端命令构成的脚本程序。所有可以直接在终端界面里运行的命令,都可以通过脚本来执行。

1.ping
首先编写写一个名为 pingscript.sh的脚本程序,旨在通过ICMP(Internet Control Message Protocol)的ping命令对局域网进行扫描,以探测那些能够回复消息的主机地址。

换句话来讲,要编写一个基于ping命令且能探测互联网主机的程序。但是并非所有的互联网主机都会回复ping命的请求,但是ping命令完全作为初级扫描工具。默认情况下,使用ping命令扫描主机时需要指定目标主机的IP。
例如:

root@kali:~/ # ping 192.168.1.100
PING 192.168.1.100 (192.168.1.100): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.067 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.086 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.082 ms
--- 192.168.1.100 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.065/0.075/0.086/0.009 ms

根据回显可知,ping的目标主机在线,而且回复了ICMP协议的ping请求。摁住Ctrl-C退出ping命令。

2.脚本编程
现在写一个对整个网段进行ping扫描的Bash脚本程序。大多数的计算机程序都能通过帮助信息来完成一个程序的使用方法。因此首先完成程序的提示功能。

#! /bin/bash    
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"

脚本程序的第一行会让终端界面调用Bash解释器,其后的两行echo命令将提示用户“在使用这个程序时,请在命令行里提供所需的参数。 例如,请指定程序扫描的网段信息(例如:192.168.20网段)”其中的echo命令可把那些放在双引号的内容显示在屏幕上。

这里这个程序默认对C类网段进行扫描,即网段就是IP地址前3个八位组

保存该文件,再使用chomd命令赋予它执行权限。

(base) MacBook-Pro:掌控者安全 macbook$ chmod 744 Bash脚本.sh 

3.运行程序
Linux系统使用环境变量PATH记录内置命令所在的目录以及Kali Linux的渗透工具所在的目录。环境变量PATH为Linux系统提供了“在哪些目录下寻找可执行的命令”的关键信息。可以直接通过“echo $PATH”命令查看它的值.如果当前目录没有被环境变量PATH收录,则不能直接通过命令调用刚刚写好的脚本,设置后如图所示:
显示

4.if语句
下面通过if语句完善这个程序的功能

#! /bin/bash    
if [ "$1" == "" ] (1)
then (2)
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
fi (3)

通常情况下,脚本程序只有在命令有误的情况下才有必要显示使用说明。就本例而言,这个程序需要用户在命令行中指定网段参数。如果用户没有启动命令指定的网段信息,那么希望这个程序能够通过提示信息告诉用户正确的使用方法。
为此,使用if语句判断上述条件是否成立。通过if语句,脚本程序就能够在特定条件下显示帮助信息。

脚本程序首先判断命令行的第一个参数(1)是否为空(null)。符号$1代表命令行传给Bash脚本程序的第一个参数。双等号(==)是逻辑符号。在if语句之后,有一个then语句(2)。当且仅当if条件判断表达式的值为真(true)时----就程序而言,当且仅当命令行传入的第一个参数为空时---程序将执行介于then语句和fi语句(if的反写)语句(3)之间的全部命令.

5.for循环
即使传递了一个命令行参数,这个程序也不具备相应的处理能力,下面继续完善它的功能。

#!/bin/bash    
if [ "$1" == "" ]
then
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
else (1)
for x in `seq 1 254`; do (2)
ping -c 1 $1.$x
done (3)
fi

在then后面追加了一个else语句(1),令程序在if表达式不成立的情况下------也就是用户传入了正确的参数之后,执行的相应代码。鉴于这个程序是为了探测某个C类网站的全部在线主机,所以需要以循环的方式ping那些末位为1~254(IPv4地址的最后一个8位组)的全部IP。
因此,程序还需要在循环的同时调用迭代次数的序列号。在这种情况下,for循环语句(2)就符合需要,程序中的
“for x in seq 1 254; do”
可以让脚本程序把x变量从1逐次迭代到254,与此同时它还会执行254次循环体。可见使用循环体语句之后,就不必把各个示例(x取每个值时的全部语句全部展开),另外要在循环体尾部添加done命令(3)
我们希望程序在for循环语句的每次迭代之中都ping一个IP地址。根据相关的使用说明可知,ping命令的-c选项可以限定它ping某台既定主机的探测次数。因此把-c选项设定为1,让程序对每个IP只ping一次。
在for语句迭代的过程中,还要让程序能够命令行传入的参数(IP地址的前3个八位组)自行设定目标主机的IP。为此使用了
"ping -c 1 $1.$x"命令。其中的$1代表命令行传入的第一个参数,而$x则是for循环语句使用的循环变量。在逐次迭代时,它首先会ping192.168.20.1,然后是ping 192.168.20.2 ........最后执行ping 192.168.20.254。在循环变量取值为254并执行一次迭代之后,for语句的循环迭代就会结束。
在通过命令号参数指定IP网段的前3个八位组时,这个脚本程序就会ping指定网段的每个IP地址
测试

6.提取数据
上述返回的信息不够直观,面对这么多的结果,应该有一定的筛选才行,确定哪些主机是在线的。
尝试使用grep命令来筛选特定的关键词。可以利用grep命令的功能对脚本程序的输出内容进行初步筛选。

ping -c 1 $1.$x | grep "64 bytes"

若远程主机恢复ping的扫描请求,就会收到这样的ICMP回复。对脚本程序进行上述的改动之后,屏幕就只会显示含有"64 bytes"的信息。

(base) MacBook-Pro:掌控者安全 macbook$ ./Bash脚本.sh 127.0.0
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.059 ms

这里测试本地,当然是可以ping同的,我没有实际去测试,毕竟我周围大概也许没有这个网段的主机,测了也是没有用,只要用本地测试证明它是可行的即可。

上面的内容其实还有改进的余地,我们进行ping扫描时,是为了获取在线主机的IP清单。这里可以使用cut命令对上述信息二次处理,直接获取IP信息,把其他数据都过滤了。
修改如下:

ping -c 1 $1.$x | grep "64 bytes" | cut -d" " -f4 
运行结果:
(base) MacBook-Pro:掌控者安全 macbook$ ./Bash脚本.sh 127.0.0
127.0.0.1:

但是我们发现,这样后面会跟着一个":"这样还是不够美观,这时候可以使用sed命令。

cut s/.$//

这个命令可删除每行最后面的冒号,修改如下:

ping -c 1 $1.$x | grep "64 bytes" | cut -d" " -f4 | sed 's/.$//'

这样这个程序就彻底修改完成,完整代码如下:

#!/bin/bash    
if [ "$1" == "" ]
then
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
else
for x in `seq 1 254`; do
ping -c 1 $1.$x | grep "64 bytes" | cut -d" " -f4 | sed 's/.$//'
done
fi
最后修改:2021 年 12 月 14 日 11 : 16 AM
如果觉得这篇文章不错,不妨赏我碎银几两。