练习概述
本次练习来自 Dolev Farhi 与 Nick Aleks 合著的《Black Hat Bash》一书的第五章:漏洞扫描与模糊测试。我们将解决其中的一个挑战性练习。
本章介绍了一些渗透测试过程中的关键工具:
- Nuclei
- Nmap NSE 脚本
- GitJacker(用于发现网站端点上配置错误的 Git 仓库)
- Wfuzz 与 ffuf(用于向网站发送半随机负载以发现隐藏信息,常用于寻找隐藏的 Web 路径、目录和文件)
- nikto(用于 Web 漏洞扫描)
在章节末尾,按照惯例,我们将面临一个具有挑战性的练习。
让我们运用所学知识和技能尝试解决这个练习,即使最终结果可能存在瑕疵,但至少我们做出了尝试,并且可以不断改进!
练习:组合工具发现 FTP 问题
“本练习的目标是编写一个脚本,该脚本能够调用多个安全工具,解析它们的输出,并将这些输出传递给其他工具以执行后续操作。以这种方式编排多个工具是渗透测试中的常见任务,因此我们鼓励你熟练掌握此类工作流的构建。
你的脚本应实现以下功能:
- 在命令行中接受一个或多个 IP 地址。
- 对 IP 地址运行端口扫描器(使用何种端口扫描器完全由你决定)。
- 识别开放端口。如果其中存在 FTP 端口(21/TCP),脚本应将该地址传递给第 4 步中的漏洞扫描器。
- 使用 Nuclei 扫描 IP 地址和端口。尝试应用专门用于查找 FTP 服务器问题的模板。在 Nuclei 模板文件夹
~/.local/nuclei-templates/中搜索与 FTP 相关的模板,或使用 Nuclei 的-tags ftp标志。- 使用 Nmap 扫描 IP 地址。利用能够发现 FTP 服务器漏洞的 NSE 脚本,你可以在
/usr/share/nmap/scripts/目录中搜索这些脚本,例如ftp-anon.nse。- 将结果解析并写入一个文件,格式自定。该文件应包含漏洞描述、相关的 IP 地址和端口、发现漏洞的时间戳以及检测到该问题的工具名称。对数据呈现方式没有硬性要求;一种选择是使用 HTML 表格,也可以将结果写入 CSV 文件。”
我的脚本解决方案
#!/usr/bin/env bash
if [[ "$#" == 0 ]]; then
echo "你必须提供一个 IP 作为参数。"
exit 1
fi
for TARGET in $@; do
if ! nc -w 1 ${TARGET} 21; then
echo "[!] 目标 ${TARGET} 上未检测到 FTP"
continue
fi
while read -r line; do
ftp_port=$(echo "${line}" | grep "tcp" | awk -F '/' '{print $1}' | grep 21)
if [[ $ftp_port -eq 21 ]]; then
echo "[!] 在目标 ${TARGET} 上发现 FTP"
echo "[!] 正在运行 nuclei…"
nuclei_result=$(nuclei -tags ftp -target "${TARGET}")
echo "[!] 正在运行 NSE…"
nse_result=$(nmap --script=ftp-anon.nse "${TARGET}")
echo "[!] 正在写入日志文件: opfile.txt…"
echo -e "# 如果某个目标的结果未在此处显示,则表示该目标未使用 FTP,但脚本会保存端口扫描输出。\n\n目标: ${TARGET}\n工具: Nuclei\n发现结果:\n$nuclei_result\n\n工具: Nmap NSE\n\n发现结果:\n\n$nse_result\n" >> opfile.txt
fi
done < <(nmap -sS $TARGET)
done
脚本运行演示
脚本显示了未检测到 FTP 的目标。通过手动对端口 21(FTP)进行 Nmap 端口扫描验证。
脚本显示了检测到 FTP 的目标。
opfile.txt 的输出内容。
解释说明
如您所见,脚本首先检查是否有任何参数传递给了命令行。$# 是一个特殊的 Bash 变量,它以整数形式返回传递给脚本的参数总数。
我们使用一个 for 循环来遍历所有参数。$@ 是一个特殊的 Bash 变量,它包含了传递给脚本的所有参数(类似于数组形式)。
对于传递给脚本的每个参数(即目标的 IP 地址),我们运行一个标准的 Nmap SYN 端口扫描。
我们通过使用 Netcat 连接到目标端口 21 来专门检查该端口是开放还是关闭。这里使用了 if command; then <expr> fi 格式的命令成功评估。
如果 FTP 端口关闭,它会打印“FTP 未检测到”,并使用 continue 命令跳过当前迭代。
如果端口开放,它会运行循环的后续代码块:
只有当目标上的 FTP 端口开放时,才会运行 while 循环的剩余部分。否则我们只打印“FTP 未检测到”。
我们使用带有进程替换(下文解释)的 while 循环来格式化工作流程。
我们通过命令替换过滤出所需的特定端口(21/ftp),并将值赋给 ftp_port 变量。
然后我们使用整数运算符 -eq(代表 equals to,即“等于”)检查 ftp_port 的值是否等于 21。
如果存在值,它会打印“发现 FTP 端口”。
它使用 -tags ftp 和 -target 标志运行 Nuclei,并将输出追加到 nuclei_result 变量。
接着它运行 NSE 脚本,并将输出追加到 nse_result 变量。
然后使用带有 -e 标志的 echo 命令,该标志允许我们将反斜杠解释为转义序列,从而以专业、易于解析的格式将输出打印到 opfile.txt 文件中。
done < <(nmap -sS ${TARGET}) 是一个 Bash 进程替换指令,它允许我们将一个命令当作文件来使用。它在一个流上运行命令,该流由一个整数的文件描述符表示。例如,假设我们的 nmap -sS 扫描在 /dev/fd/3/ 流上运行,它看起来像一个目录。命令的输出保留在 /dev/fd/3/ 目录中,循环从该流中读取数据,就像从文件中读取一样。
结语
亲自尝试一下吧!目标不是构建一个零错误的完美专业级脚本,而是理解工作流程,并使其足够语义化,以便你能够在无需外部帮助的情况下自行编排。 CSD0tFqvECLokhw9aBeRqhu8+HKTh/2RSSRVwf75o4HAONYzpbYkCeYXW65N31x9X/8tC5F8MBuHE8UkKjB5Yaie+qjXi0Gd/cZQcCXpNepOPts5oD3jjtnd1g2sU9gj