https://dreamhack.io/wargame/challenges/17
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.
예시) 입력 값이 Apple_Banana일 경우 flag는 DH{Apple_Banana}
제공된 chall0.exe파일을 실행하면 input : 이라는 문자열이 출력되며 사용자의 입력을 받는 프로그램임을 알 수 있습니다. 플래그 값을 입력하면 "Correct"가 뜨는 구조입니다.
x64dbg을 이용해 chall0.exe 파일을 열어봅니다.
우클릭 후 다음을 찾기 > 모든 시스템 모듈 > 문자열 참조 을 통해 "Correct" 문자열을 검색합니다.

"Correct" 문자열이 출력되는 코드 근처에서 다음과 같은 흐름을 확인할 수 있었습니다.

input : 을 출력합니다.[rsp+20] 주소에 저장합니다.[rsp+20]을 검사합니다.eax == 0 라면 wrong, 같다면 correct을 출력합니다.입력한 값이 정답인지 검사하는 함수인 00007FF6689C114E | call chall0.7FF6689C1000 이 핵심함수임을 알 수 있었습니다.
더블클릭해 그 함수에 들어가 보았습니다. 하지만 드림핵의 앞선 리버싱 문제인 rev-basic-0 같이 플래그 값이 바로 나오지 않았습니다.
코드의 흐름을 확인하기 위해 우클릭 > 그래프 를 선택하여줍니다.


그래프의 화살표 색이 파란색, 녹색, 빨간색임을 확인할 수 있습니다. x64dbg에서 색은 점프 조건의 방향을 의미합니다.
위 그래프에서는 녹색, 빨간색 화살표가 보이고, 파란 화살표가 한 바퀴를 돌면 다시 위로 올라가는 것을 보면 조건문과 반복문을 이용하였다고 확인할 수 있습니다.
chal 13. 00007FF7E1E7101A 부터 확인해봅니다.cmp rax, 18 : cmp= 비교 명령어입니다. rax와 18 비교합니다. 0x18번째, 즉 24(10진수)번을 반복합니다.jae chall3.7FF7E17E71053 : jae = Jump if Above or Equal. 즉, 비교 결과에서 rax ≥24 면 chall3.7FF7E17E71053 주소로 이동합니다.24번동안 반복할 반복문을 확인해 보았습니다.
lea rcx, qword ptr ds:[7FF7E1E73000] : LEA (Load Effective Address) = “메모리 내용을 읽지 않고, 주소값(포인터)만 계산해서 레지스터에 넣어라.” → rcx = 0x7FF7E1E73000 이라는 뜻입니다.0x7FF7E1E73000 에 있다는 뜻입니다.비교할 문자열이 있는 0x7FF7E1E73000 에 더블클릭하여 이동하였습니다.

덤프를 확인해보니 16진수 24글자가 있었습니다. 어셈블리어 변환기로 변환 해 보았더니 I`gtcgBfxii{mhM¥E 라는… 알 수 없는 문자가 나왔습니다. 반목문에 추가적인 조건이 있음을 알 수 있었습니다. 이어서 확인해 보겠습니다.
⇒ table[i] == (flag[i] ^ i) + (2*i) 가 최종 식입니다.
# 주어진 table 값 (16진수)
table_hex = [
0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66,
0x80, 0x78, 0x69, 0x69, 0x7B, 0x99, 0x6D, 0x88,
0x68, 0x94, 0x9F, 0x8D, 0x4D, 0xA5, 0x9D, 0x45
]
flag_bytes = []
for i, val in enumerate(table_hex):
# 역연산: flag[i] = (table[i] - 2*i) ^ i
calc = (val - 2*i) & 0xFF # 0~255 범위 유지
flag_val = calc ^ i
flag_bytes.append(flag_val)
flag = bytes(flag_bytes)
print("Flag bytes:", flag_bytes)
print("Flag string:", flag.decode(errors="ignore"))
실행하면 결과가 Flag string: I_am_X0_xo_Xor_eXcit1ng 로 나옵니다.
DH{I_am_X0_xo_Xor_eXcit1ng} 을 입력하였더니 해결할 수 있었습니다.

"Correct" if it matches the expected flag."Correct" string reference led to the check function at call chall0.7FF6689C1000.0x7FF7E1E73000.table[i] == (flag[i] ^ i) + (2*i).flag[i] = (table[i] - 2*i) ^ i.I_am_X0_xo_Xor_eXcit1ng.DH{I_am_X0_xo_Xor_eXcit1ng}.