이번 문제는 입력값이 FLAG가 되는 문제이다.
아무 문자열이나 입력하면 Wrong을 반환하는데,
“Wrong” 문자열을 역참조하면 FUN_140001120 함수에서 사용되는걸 알 수 있다.
void FUN_140001120(void) { ... FUN_1400011b0("Input : "); FUN_140001210("%256s",local_118); iVar1 = FUN_140001000(local_118); if (iVar1 == 0) { puts("Wrong"); } else { puts("Correct"); } ... }
문자열에서 Correct가 출력되기 위해서는
FUN_140001000 함수가 1을 반환시켜야 된다.
undefined8 FUN_140001000(longlong param_1) { uint local_18; local_18 = 0; while( true ) { if (0x17 < local_18) { return 1; } if ((uint)(byte)(&DAT_140003000)[(int)local_18] != (*(byte *)(param_1 + (int)local_18) ^ local_18) + local_18 * 2) break; local_18 = local_18 + 1; } return 0; }
FUN_140001000 함수를 살펴보면
입력받은 하나의 문자에 XOR 암호화시키는 것을 알 수 있다.
문자를 하나씩 비교하는데 하나라도 일치하지 않으면, 0을 반환시킨다.
DAT_140003000은 아래 값을 가지고 있었다.
\x49\x60\x67\x74\x63\x67\x42\x66\x80\x78\x69\x69\x7B\x99\x6D\x88\x68\x94\x9F\x8D\x4D\xA5\x9D\x45
그러니까 아래와 같이 한문자씩 계속 비교하며 반복한다.
0x4f != (0 ^ (입력받은 0번째 문자)) + 2 * 0 0x60 != (1 ^ (입력받은 1번째 문자)) + 2 * 1 0x67 != (2 ^ (입력받은 2번째 문자)) + 2 * 2 ...
XOR 연산은 (A ^ B) ^ B = A이므로
간단하게 역순으로 계산하고 XOR시키면 된다.
enc_str = b'\x49\x60\x67\x74\x63\x67\x42\x66\x80\x78\x69\x69\x7B\x99\x6D\x88\x68\x94\x9F\x8D\x4D\xA5\x9D\x45' dec_str = "" for i in range(len(enc_str)): dec_str = dec_str + chr((enc_str[i] - 2 * i) ^ i); print(dec_str)
ubuntu@WSL:~/CTF/dreamhack.io/chall3$ python3 chall3.py I_am_X0_xo_Xor_eXcit1ng