2020 SuSecCTF wp

web0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1function sha1(s) {
2 return crypto.createHash("sha1")
3 .update(s)
4 .digest("hex");
5}
6
7app.post("/flag", (req, res) => {
8 const {first, second} = req.body;
9 const salt = "pepper";
10
11 if (!first || !second || first.length !== second.length) {
12 res.send("bad input");
13 return;
14 }
15
16 if (first !== second && sha1(salt + first) === sha1(salt + second)) {
17 res.send(flag); // have some flag
18 return;
19 }
20
21 res.send("access denied");
22});

方法一

js 特性

方法二

让first等于[1],second等于1,即POST:

first[]=1&second=1

那么服务端获取到[ '1' ]1,它们不相等,且与字符串pepper相加后,都会等于pepper1,从而得到相同的sha1值

本地复现源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var express = require('express');
var bodyParser = require('body-parser');
var crypto = require('crypto');

var app = express();
app.use(bodyParser.urlencoded({extended:true})); // for parsing application/x-www-form-urlencoded

function sha1(s) {
return crypto.createHash("sha1")
.update(s)
.digest("hex");
}
app.post("/flag", (req, res) => {
const {first, second} = req.body;
const salt = "pepper";
console.log(first.length);
if (!first || !second || first.length !== second.length) {
res.send("bad input");
return;
}
if (first !== second && sha1(salt + first) === sha1(salt + second)) {
res.send("flag"); // have some flag
return;
}

res.send("access denied");
});


var server = app.listen(9999, function(){})

Secure note

题目是一个粘贴板,可以通过curl注册用户,并可将文本内容粘贴到页面上,之后便可查看粘贴的文本

admin粘贴的记录:

那么关键就是要查看那条private的信息,仔细观察,其他的信息的path是有规律的:

Xkva4KrqXd6tZvrT

(private)

XkvawqrqXd6tZvrH

Xkvav6rqXd6tZvrE

Xkvau6rqXd6tZvrC

Xkvat6rqXd6tZvrB

Xkva{}{}rqXd6tZvr{}

处了用括号括起来的三个地方字符不一样,其他地方的都一样,那么可以考虑爆破,这三个地方的字符其实是有规律的,比如第一个括号位置和最后一个括号位置按字母顺序递增;

最后得到存储flag的路径:

Xkva2arqXd6tZvrP

Microservice

只能以guest身份登录,并且登录后会返回一个jwt的信息,解码得到:

{
  "typ": "JWT",
  "alg": "HS256"
}

{
  "iat": 1584618391,
  "nbf": 1584618391,
  "jti": "cbd382e1-02e9-475a-9b5d-342587ebac3e",
  "identity": "guest",
  "fresh": false,
  "type": "access"
}

将alg改为none发现被拦截了,爆破也没用,那么肯定要通过某种方式获得secret-key来伪造jwt

这题比较坑的是,在404页面存在ssti:

虽然可以通过ssti getshell,但flag不在当前docker环境中,所以还是乖乖伪造jwt吧~