https://dreamhack.io/wargame/challenges/836
우리의 친구 아모가 미션을 주었습니다. "내가 원하는 결과가 나오도록 값을 입력해 줘!"
주어진 바이너리를 분석하고 알맞은 값을 입력하면 플래그가 출력됩니다. 플래그는 flag 파일에 있습니다.
플래그 형식은 DH{...} 입니다.
📜 문제 접속 가이드
본 문제는 리눅스에서 nc를 사용하여 접속할 수 있습니다.
nc 설치
터미널에서 sudo apt update && sudo apt install netcat 명령어 실행nc 사용
문제에서 접속 정보 보기 클릭 - 출력되는 nc [Host] [Port] 명령어 복사하여 터미널에서 실행
예시) nc host3.dreamhack.games 19809
sudo apt update && sudo apt install netcat 명령어 실행nc [Host] [Port] 명령어 복사하여 터미널에서 실행 예시) nc host3.dreamhack.games 19809nc로 접속하여 문제를 풀면 real flag가 출력됩니다! 🚩
※ 서버 통신에는 30초 타임아웃이 적용되어 있습니다. 30초 안에 문제를 해결하지 못할 시에 다시 nc로 접속하여 문제를 해결해 주세요!
chall 파일을 확인할 수 있었습니다. 리버싱 문제임으로 IDA 툴을 활용하여 열어주었습니다.F5 를 통해 디컴파일된 c 코드를 확인할 수 있습니다. 
fd = open("./flag", 0);
read(fd, buf, 0x45u);
flag 파일 내용을 buf에 저장.
get_rand_num(&v6);
printf("Random number: %#x\n", v6);
랜덤값(v6)을 화면에 출력.
scanf("%d", &v7);
입력값을 v7에 저장.
v11 = v6 ^ v7;
랜덤값 ^ 입력값 = v11
^ 기호는 XOR 연산을 뜻합니다. 즉, 랜덤값과 입력값을 XOR 연산하면, v11 값이 나와야 풀리는 문제입니다.
snprintf(s, "%08x", v6 ^ v7);
XOR의 결과를 %08x, 즉 8자리 16진수로 바꿉니다. 바꾼 문자열을 s에 저장합니다.
for (i = 0; i <= 7; ++i)
s1[i] = s[7 - i];
주의해야하는 부분입니다. s의 문자열을 거꾸로 뒤집어 그 결과를 s1에 저장합니다.
printf("Result: %s\n", s1);
if (!strcmp(s1, "a0b4c1d7"))
사용자의 입력을 Result로 받아 s1으로 받고, 만약 그 s1이 “a0b4c1d7”라면 플래그가 제공되는 코드임을 확인할 수 있었습니다.
즉, 랜덤한 값과 우리의 입력값의 XOR 연산 결과가, a0b4c1d7을 뒤집은 7d1c4b0a여야 합니다.
XOR의 성질은 다음과 같습니다.
a ^ b = c
→ a = c ^ b
→ b = c ^ a
따라서 주어지는 random값과 7d1c4b0a 를 XOR 연산하면 Result 값을 알 수 있고, 그 값을 입력한다면 플래그를 획득할 수 있습니다.

a ^ b = c
→ a = c ^ b
→ b = c ^ a