[dreamhack] rev-basic-3

Monitor In Secure☃️·2024년 5월 22일

wargame_rev

목록 보기
9/11

문제 파일 ida로 열기)

디컴파일한 결과(F5))

int __fastcall main(int argc, const char **argv, const char **envp)
{
  char v4[256]; // [rsp+20h] [rbp-118h] BYREF

  memset(v4, 0, sizeof(v4));
  sub_1400011B0("Input : ", argv, envp);
  sub_140001210("%256s", v4);
  if ( (unsigned int)sub_140001000(v4) )
    puts("Correct");
  else
    puts("Wrong");
  return 0;
}

변수 v4는 크기가 256인 배열로 이루어져 있다.
함수 sub_140001000(v4)와 비교하여 맞으면 'Correct'라고 문구가 출력되는 것을 알 수 있다.

sub_140001000 디컴파일한 결과)

__int64 __fastcall sub_140001000(__int64 a1)
{
  int i; // [rsp+0h] [rbp-18h]

  for ( i = 0; (unsigned __int64)i < 0x18; ++i )
  {
    if ( byte_140003000[i] != (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i )
      return 0LL;
  }
  return 1LL;
}

디컴파일 결과를 보면 0x18(24)번 반복하며

byte_140003000[i] == (i ^ a1[i]) + (2 * i)

위 조건을 성립해야 Correct가 출력된다.

❗^(XOR) 연산 의미❗
XOR의 특징 : 피연산자 둘이 같으면 0 출력
ex) A ^ B = 0 (A = B)
     A ^ B = C => C ^ B = A

때문에 역연산을 했을 때의 식인 (byte_140003000[i] - (2 * i)) ^ i = i 도 가능해야 한다.

byte_140003000함수 디컴파일 결과)

따라서 들어있는 값은,

0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66, 0x80, 0x78, 0x69, 0x69, 0x7B, 0x99, 0x6D, 0x88, 0x68, 0x94, 0x9F, 0x8D, 0x4D, 0xA5, 0x9D, 0x45, 0x00

이다.


이를 역연산하기 위해 c코드를 이용해보았다.

#include <stdio.h>

int main() {
    
    int list[50] ={ 0x49, 0x60 , 0x67 , 0x74 , 0x63 ,0x67, 0x42 , 0x66 , 0x80 , 0x78 ,0x69 , 0x69 , 0x7B , 0x99 , 0x6D ,
    0x88 , 0x68 , 0x94 , 0x9F , 0x8D ,0x4D , 0xA5 , 0x9D , 0x45 };
    
    for (int i = 0; i < 24; i++) {
        printf("%c", (list[i]-(2*i))^i);
    }
    
}

플래그값이 잘 출력되었다.

0개의 댓글