이번 문제는 입력값이 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

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다