BASH 脚本编程

优质
小牛编辑
120浏览
2023-12-01

BASH SCRIPTING

任何有自尊心的黑客都必须能够编写脚本。因此,任何自尊的 Linux 管理员都必须能够编写脚本。黑客经常需要自动化命令,有时需要多个工具,这可以通过他们自己编写的简短程序最有效地完成。

在本章中,我们构建了几个简单的 bash shell 脚本,以帮助您开始编写脚本。随着我们的进展,我们将添加功能和特性,最终构建一个脚本,该脚本能够在一系列 IP 地址中查找潜在的攻击目标。

要成为一名优秀的黑客,您还需要能够使用一种广泛使用的脚本语言编写脚本,例如 Ruby (Metasploit exploits 是用 Ruby 编写的)、Python(许多黑客工具都是 Python 脚本)或 Perl (Perl 是最好的文本操作脚本语言)。在第 17 章中,我将简要介绍 Python 脚本。

BASH 的速成班

shell 是用户和操作系统之间的接口,它允许您操作文件和运行命令、实用程序、程序等等。shell 的优点是,您可以直接从计算机执行这些任务,而不是通过 GUI 这样的抽象来执行这些任务,GUI 允许您将任务定制为 Z shell、C shell 和 Bourne Again Shell,也就是更广为人知的bash

由于 bash shell 几乎可以在所有 Linux 和 UNIX 发行版(包括 macOS 和 Kali)上使用,所以我们将只使用 bash shell。

bash shell 可以运行您通常的命令行可以运行的任何系统命令、实用程序或应用程序,但是它也包含一些自己的内置命令。本章后面的表 8-1 给出了对驻留在 bash shell 中的一些有用命令的引用。

在前面的章节中,您使用了cdpwdsetumask命令。在本节中,您将使用另外两个命令:echo命令(首先在第 7 章节中使用)和read命令(读取数据并将其存储在其他地方)。仅仅学习这两个命令就可以构建一个简单但功能强大的工具。

您将需要一个文本编辑器来创建 shell 脚本。您可以使用任何您最喜欢的 Linux 文本编辑器,包括 vi、vim、emacs、gedit、kate 等等。在这些教程中,我将使用 Leafpad,就像在前几章中一样。使用不同的编辑器不会对脚本或其功能造成任何影响。

你的第一个脚本:“HELLO, HACKERS-ARISE!”

对于您的第一个脚本,我们将从一个简单的程序开始,该程序将向屏幕返回一条消息,该消息说:“你好,黑客——站起来!”打开文本编辑器,开始吧。

首先,您需要告诉您的操作系统您想为脚本使用哪个解释器。为此,输入一个开头标识符,它是哈希符号和感叹号的组合,如下所示:

#!

然后按照指示的 (#!/bin/bash)操作系统使用 bash shell 解释器。正如您将在后面的章节中看到的,您还可以使用标识符(#!)来使用其他解释器,如 Perl 或 Python。在这里,您希望使用 bash 解释器,因此输入以下内容:

#! /bin/bash

接下来,输入echo命令,它告诉系统简单地将命令后面的内容重复(或回显)到监视器。

在这种情况下,我们希望系统向我们回送“Hello, Hackers-Arise!”如清单 8-1 所示。注意,要回显的文本或消息必须使用双引号。

#! /bin/bash

# This is my first bash script. Wish me luck.

echo "Hello, Hackers­Arise!"

清单 8-1: “Hello, Hackers­Arise!”脚本

在这里,您还可以看到前面有一行散列标记(#)。这是一个注释,是您留给自己或任何阅读代码的人来解释您在脚本中所做的事情的注释。程序员在每种编码语言中都使用注释。这些注释不是由解释器读取或执行的,因此您不必担心代码混乱。它们只对人类可见。bash shell 知道,如果一行以#字符开头,那么它就是一个注释。

现在,将该文件保存为 HelloHackersArise,不带扩展名,并退出文本编辑器。

设置执行权限

默认情况下,新创建的 bash 脚本甚至您(所有者)也无法执行。让我们在命令行中查看新文件的权限,方法是使用cd移动到目录中,然后输入ls -l。它应该是这样的:

kali >ls -l

­­snip­­

­rw­r­­r­­ 1 root root 42 Oct 22 14:32 HelloHackersArise

­­snip­­

如您所见,我们的新文件具有rw-r--r--(644)权限。正如您在第 5 章中学到的,这意味着这个文件的所有者只有读(r)和写(w)权限,而没有执行(x)权限。组和所有其他用户只有读权限。为了运行这个脚本,我们需要给其执行权限。我们使用 chmod 命令更改权限,如第 5 章所示。要授予所有者、组和所有其他执行权限,请输入以下命令:

kali >chmod 755 HelloHackersArise

现在,当我们对文件以长列表形式列出时,像这样,我们可以看到我们有执行权限:

kali >ls -l

­­snip­­

­rwx r­x r­x 1 root root 42 Oct 22 14:32 HelloHackersArise

­­snip­­

脚本现在可以执行了!

运行 HelloHackersArise

要运行我们的简单脚本,输入以下命令:

kali >./HelloHackersArise

文件名前的./告诉系统我们希望在 HelloHackersArise 所在的当前目录文件中执行此脚本。它还告诉系统,如果在另一个名为 hellohackersrise 的目录中有另一个文件,请忽略它,只在当前目录中运行 hellohackersrise。在您的系统上似乎不太可能有另一个具有此名称的文件,但是在执行文件时使用./是一个很好的实践,因为这会将文件执行定位到当前目录,并且许多目录将具有重复的文件名,例如 start 和 setup。

当我们按下回车 ENTER 时,我们非常简单的脚本将我们的消息返回给监视器:

Hello, Hackers­Arise!

恭喜成功!您刚刚完成了第一个 shell 脚本!

添加带有变量和用户输入的功能

现在我们有了一个简单的脚本。它所做的只是将消息回显到标准输出。如果希望创建更高级的脚本,可能需要添加一些变量。

变量是一个可以在内存中存储某些东西的存储区域。“某物”可能是一些字母或单词(字符串)或数字。它被称为变量,因为其中包含的值是可变的,这对于向脚本中添加功能非常有用。

在下一个脚本中,我们将添加一些功能来提示用户输入他们的名字,将他们输入的任何内容放入一个变量中,然后提示用户输入他们在这本书中的章节,并将键盘输入放入一个变量中。在此之后,我们将向用户回显一条包含其姓名和章节的欢迎消息。

在文本编辑器中打开一个新文件,并输入清单 8-2 所示的脚本。

➊ #! /bin/bash

➋ # This is your second bash script. In this one, you prompt /

# the user for input, place the input in a variable, and /

# display the variable contents in a string.

➌ echo "What is your name?"

read name

➍ echo "What chapter are you on in Linux Basics for Hackers?"

read chapter

➎ echo "Welcome" $name "to Chapter" $chapter "of Linux Basics for Hackers!"

清单 8-2:使用变量的简单脚本

我们从#!/bin/bash 开始,告诉系统要使用这个脚本 ➊bash 解释器。然后添加一个注释描述脚本 ➋ 及其功能。之后,我们提示用户输入他们的名字,➌ 问解释器我们的名字,读取输入并将其转换成一个变量name。然后我们提示用户输入他们目前正在这本书中的所在章节,➍ 我们再次读取键盘输入一个变量,这个章节叫chapter

在最后一行中,我们构造一个输出字符串,➎ 欢迎读者(他们的名字)在此书的所在章节。我们使用 echo 命令,并用双引号提供要在屏幕上显示的文本。然后,为了填写用户输入的名称和章号,我们将变量添加到消息中应该出现的位置。如第 7 章所述,要使用变量中包含的值,必须在变量名前面加上$符号。

将此文件保存为 WelcomeScript.sh 文件。其中.sh扩展名是脚本文件的约定。您可能已经注意到,我们没有包含前面的扩展名,这并不是严格要求的,如果您关闭扩展名,该文件将默认保存为 shell 脚本文件。

现在,让我们运行这个脚本。不要忘记先用chmod给其执行权限,否则,操作系统会用权限拒绝的消息(Permission denied)斥责你的。

kali >./WelcomeScript.sh

What is your name?

OccupytheWeb

What chapter are you on in Linux Basics for Hackers?

8

Welcome OccupytheWeb to chapter 8 of Linux Basics for Hackers!

如您所见,您的脚本从用户那里获取输入,将其放入变量中,然后使用这些输入为用户发出问候语。

这是一个简单的脚本,但它教你如何使用变量并从键盘输入。这些都是脚本中的关键概念,您将来需要在更复杂的脚本中使用它们。

您的第一个黑客脚本:扫描打开的端口

现在您已经掌握了一些基本的脚本编写技巧,接下来让我们来学习一些更高级的脚本编写技巧,它们具有实际应用的黑客应用程序。我们将使用黑帽子黑客世界的一个例子。“黑帽子黑客”指的是那些怀有恶意的黑客,比如盗取信用卡号码或篡改网站。白帽黑客是那些有良好意图的人,比如帮助软件开发人员或系统管理员使他们的系统更加安全。“灰帽黑客”是那些倾向于在这两个极端之间游走的人。

在继续之前,您需要熟悉一个名为nmap的简单但必要的工具,该工具默认安装在 Kali 上。您可能听说过nmap这个名称,它用于探测一个系统,以查看它是否连接到网络,并查明哪些端口是打开的。通过发现的开放端口,您可以推测在目标系统上运行哪些服务。这对于任何黑客或系统管理员来说都是一项至关重要的技能。

最简单的形式是,运行 nmap 扫描的语法如下所示:

nmap \ \ \

这不太困难。最简单、最可靠的 nmap 扫描是 TCP connect 扫描,在 nmap 中使用-sT参数选项进行指定。因此,如果想用 TCP 扫描 IP 地址 192.168.181.1,可以输入以下命令:

nmap -sT 192.168.181.1

更进一步,如果您想对地址 192.168.181.1 执行 TCP 扫描,查看端口 3306 (MySQL 的默认端口)是否打开,您可以输入以下命令:

nmap -sT 192.168.181.1 -p 3306

这里,-p指定要扫描的端口。现在就在您的 Kali 系统上尝试它吧。

我们的任务

在撰写本书时,有一名黑客在美国联邦监狱服刑时间名为 Max Butler,在整个黑客世界中也被称为 Max Vision。Max 是一个灰帽子黑客。白天,他是硅谷的 IT 安全专业人员,到了晚上,他在黑市上偷窃和销售信用卡号码。有一段时间,他经营着全球最大的信用卡黑市 CardersMarket。现在,Max 正在服刑 13 年,同时协助匹兹堡的计算机应急响应小组(CERT)防御黑客。

在 Max 被抓住的几年前,他意识到许多小餐馆使用的 Aloha 销售点(POS)系统都内置了技术支持后门。在这种情况下,后门启用了技术支持来帮助他们的客户。Aloha 技术支持可以通过端口 5505 访问最终用户的系统,以在用户寻求帮助时提供帮助。Max 意识到,如果他发现一个系统通过 Aloha POS 系统连接到互联网,他可以通过端口 5505 访问具有 sysadmin 权限的系统。Max 可以进入许多这样的系统并窃取数以万计的信用卡号码。

最终,Max 想要找到每个有 5505 端口打开的系统,这样他就可以从窃取数千个信用卡号码变成窃取数百万个。Max 决定编写一个脚本,扫描数百万个 IP 地址,寻找端口 5505 打开的系统。当然,大多数系统端口 5505 没有打开,所以,如果它们被打开了,很可能它们正在运行注定的 Aloha POS。他可以在白天工作时运行这个脚本,然后在夜间入侵那些被识别为打开端口 5505 的系统。

我们的任务是编写一个与 Max 的脚本几乎相同的脚本,但不是像 Max 那样扫描端口 5505,我们的脚本将扫描连接到无处不在的在线数据库 MySQL 的系统。MySQL 是一个在数百万个网站背后使用的开源数据库(现在 MySQL 属于 Oracle 旗下,但依然保留有社区版,原开源分支变为 MariaDB),我们将在第 12 章中使用 MySQL。默认情况下,MySQL 使用端口 3306。数据库是几乎每个黑帽子黑客都在寻找的“金羊毛”,因为它们经常包含在黑市上非常有价值的信用卡号和个人身份信息(PII)。

一个简单的扫描器

在编写在互联网上扫描公共 ip 的脚本之前,让我们先完成一个小得多的任务。让我们先编写一个脚本,以扫描局域网上的端口 3306,而不是扫描全球,以查看脚本是否实际工作。如果有,我们可以很容易地编辑它来完成更大的任务。

在文本编辑器中,输入清单 8-3 所示的脚本。

➊ #! /bin/bash

➋ # This script is designed to find hosts with MySQL installed

nmap ➌­sT 192.168.181.0/24 ➍­p 3306 ➎>/dev/null ➏­oG MySQLscan

➐ cat MySQLscan | grep open > MySQLscan2 ➑

cat MySQLscan2

清单 8-3:简化的扫描程序脚本

➊ 我们使用标识符#!开始。➋ 让我们遵循这个注释来解释脚本的用途。

现在,让我们使用 ➌nmap 命令 TCP 扫描局域网,寻找端口 3306➍。(请注意,您的 IP 地址在您的终端中可能不同,请使用 Linux 上的 ifconfig 命令或 Windows 上的 ipconfig 命令来确定您的 IP 地址。) 为了保持隐秘,我们还发送通常会出现在屏幕上的标准 nmap 输出到 Linux 的一个特殊的地方 ➎,一个特殊的地方在 Linux 中消失。我们在本地机器上做这个,所以这并不重要,但如果要远程使用脚本,则需要隐藏 nmap 输出。然后,我们将扫描的输出发送到一个名为 MySQLscan 的文件 ➏,格式为 grep 格式,这意味着 grep 可以处理的格式。

下一行显示我们存储输出的 MySQLscan 文件,➐ 然后输出到 grep 的管道,以过滤包含关键字 open(端口开放)的所在行。然后我们把这些字符行放到一个命名为 MySQLscan2 的文件中 ➑。

最后,显示文件 MySQLscan2 的内容。此最终文件应仅包含 nmap 的输出行,其中包含端口 3306 打开的主机。将此文件另存为 MySQLscanner.sh 并使用 chmod 755 为自己赋予执行权限。

执行脚本,如下所示:

kali >./MySQLscanner.sh

host: 192.168.181.69 () Ports: 3306/open/tcp//mysql///

我们可以看到,这个脚本能够识别局域网内运行 MySQL 的唯一的 IP 地址。当然,您的结果可能会有所不同,具体取决于是否有任何端口在本地网络上运行 MySQL 服务。

改进 MySQL 扫描器

现在,我们希望修改这个脚本,使其不仅适用于您自己的本地网络。如果该脚本能够提示用户想要扫描的 IP 地址范围和要查找的端口,然后使用该输入,那么该脚本将更容易使用。请记住,您在此章节前一小节页的“添加带有变量和用户输入处理功能”中学习了如何提示用户并将其键盘输入内容输入到变量中。

让我们看看如何使用变量使这个脚本更加灵活和高效。

在黑客脚本中添加提示和变量

在文本编辑器中,输入清单 8-4 所示的脚本(或直接创建MySQLscannerAdvanced文件并打开输入以下内容)。

#! /bin/bash

➊ echo "Enter the starting IP address : "

➋ read FirstIP

➌ echo "Enter the last octet of the last IP address : " read LastOctetIP

➍ echo "Enter the port number you want to scan for : " read port

➎ nmap ­sT $FirstIP­$LastOctetIP ­p $port >/dev/null ­oG MySQLscan

➏ cat MySQLscan | grep open > MySQLscan2

➐ cat MySQLscan2

清单 8-4:高级 MySQL 端口扫描器

我们需要做的第一件事是用 IP 地址范围替换指定的子网。我们将创建一个名为FirstIP的变量和另一个名为LastOctetIP的变量来创建这个范围,并为端口号创建一个名为port的变量(最后一个八位体是 IP 地址中第三段(以.分割的 IP)之后的最后一组数字。在 IP 地址 192.168.1.101 中,最后一个字节是 101)。

我们还需要提示用户输入这些值。我们可以使用清单 8-1 中使用的 echo 命令来实现这一点。

FirstIP变量的值,对应“Enter the starting IP address :” ➊,向用户询问他们想扫描第一个 IP 地址。在屏幕上看到这个提示时,用户将输入第一个 IP 地址,因此我们需要从用户那里获取该输入。

➋ 我们可以读取命令后跟变量的名称我们想在存储输入。这个命令将把用户输入的 IP 地址放入变量FirstIP中。然后我们可以在整个脚本中使用FirstIP中的值。

我们将做同样的为变量LastOctetIP➌ 和port➍ 通过提示用户输入信息,然后使用一个读命令来捕获它。

接下来,我们需要在脚本中编辑 nmap 命令,以使用刚刚创建和填充的变量。要使用存储在变量中的值,只需在变量名前面加上$,例如在$port中。所以,➎ 我们扫描一系列 IP 地址,从用户输入第一个 IP 到用户输入第二个 IP 开始,并查找用户输入的特定端口。我们使用变量代替子网来扫描,使用端口来决定扫描什么。重定向符号(>)告诉标准的 nmap 输出(通常显示在屏幕上)转到/dev/null (/dev/null 只是一个发送输出的地方,以便它消失)。然后,我们将输出以 grep 标准格式发送到名为 MySQLscan 的文件。

下一行与我们的简单扫描器中相同:它输出 MySQLscan 文件的内容,将其传输到 grep,在那里对包含关键字的行进行筛选过滤,然后将该输出发送到名为 MySQLscan2 的新文件 ➏。最后,我们打印展示 MySQLscan2 文件内容 ➐。

如果一切正常,此脚本将扫描从第一个输入地址到最后一个输入的 IP 地址,搜索输入端口,然后仅使用指定端口打开的 IP 地址进行报告。将脚本文件保存为MySQLscannerAdvanced,记住要给其执行权限。

一个运行示例

现在我们可以使用变量来运行我们的简单扫描程序脚本,这些变量确定要扫描的 IP 地址范围和端口,而不必在每次要运行扫描时编辑脚本:

kali >./MySQLscannerAdvanced.sh Enter the starting IP address : 192.168.181.0

Enter the last IP address :

192.168.181.255

Enter the port number you want to scan for :

3306

Host: 192.168.181.254 ()Ports:3306/open/tcp//mysql//

脚本提示用户输入第一个 IP 地址、最后一个 IP 地址,然后输入要扫描的端口。在收集这些信息之后,脚本执行 nmap 扫描,并生成具有指定端口的范围内所有 IP 地址的报告。正如您所看到的,即使是最简单的脚本也可以创建强大的工具。在第 17 章中,您将学习更多关于脚本的知识。

常用内置 BASH 命令

如前所述,表 8-1 提供了 bash 中内置的一些有用命令的列表。

表 8-1:内置 Bash 命令

命令功能
返回 0 或true
.执行 shell 脚本
b将作业放在后台
break退出当前循环
cd改变目录
continue执行当前循环
echo显示命令参数
eval计算以下表达式
exec在不创建新进程的情况下执行以下命令
exit退出 shell
export使变量或函数对其他程序可用
fg将工作放在前台
getopts解析 shell 脚本的参数
jobs列出后台(bg)执行的工作
Pwd显示当前目录
Read从标准输入读取一行
Readonly将变量声明为只读
set列出所有变量
shift将参数向左移动
test评估参数
[执行条件测试
times打印用户和系统时间
trap追踪一个信号
type显示如何将每个参数解释为一个命令
umask更改新文件的默认权限
unset从变量或函数中删除值
wait等待后台进程完成

总结

脚本是任何黑客或系统管理员的基本技能。它使您能够通常需要花费几个小时的任务变得自动化,并且一旦保存为脚本,就可以反复使用它。Bash 脚本是脚本的最基本形式,在第 17 章中,您将使用更多的功能进一步学习 Python 脚本。