본문 바로가기
Reversing/CTF

[HackCTF] Static

by L3m0n S0ju 2021. 10. 17.

 

 

 

 

파일을 IDA로 열면 오류가 발생한다. syms2elf 플러그인을 다운로드 받아서 실행하면 symbol 오류가 사라지고 아래와 같이 디컴파일 가능하다.

 

 

 

 

 

__int64 __fastcall sub_87C(char *a1, const char *a2)
{
  char v3; // dl
  size_t v4; // rax
  char *v5; // [rsp+8h] [rbp-68h]
  char v6[32]; // [rsp+10h] [rbp-60h] BYREF
  char v7[24]; // [rsp+30h] [rbp-40h] BYREF
  int v8; // [rsp+48h] [rbp-28h]
  int v9; // [rsp+50h] [rbp-20h]
  int v10; // [rsp+54h] [rbp-1Ch]
  int v11; // [rsp+58h] [rbp-18h]
  int i; // [rsp+5Ch] [rbp-14h]

  v5 = a1;
  v11 = 0;
  v10 = 0;
  strcpy(v7, "1617181926381617919194");
  if ( strlen(a2) != 22 )
    return 0LL;
  for ( i = 0; i < strlen(v5); ++i )
    v11 += v5[i];
  v8 = 0;
  v11 /= 30;
  while ( v10 != 22 )
  {
    if ( (v10 & 1) != 0 )
      v3 = a2[v10] - 4;
    else
      v3 = a2[v10] + 4;
    v6[v10] = v3;
    v6[v10++] ^= v11;
  }
  v9 = 0;
  for ( i = strlen(v6) - 1; i >= 0; --i )
  {
    v4 = strlen(v6);
    if ( v6[v4 - i - 1] != v7[i] )
      return 0LL;
  }
  return 1LL;
}

 

 

 

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *s1; // [rsp+20h] [rbp-10h]

  s1 = getenv("team_name");
  if ( s1 && !strncmp(s1, "bi0s", 4uLL) )
  {
    if ( argc == 2 )
    {
      if ( (unsigned int)sub_87C(s1, argv[1]) == 1 )
        sub_830(argv[1]);
      else
        printf("Better luck next time!");
    }
    else
    {
      printf("usage: chall <input>");
    }
  }
  else
  {
    printf("Nope.");
  }
  return 0;
}

 

 

 

 

 


코드를 살펴보면 (unsigned int)sub_87C(s1, argv[1]) == 1) 라는 조건이 참이면 플래그가 출력되는 것을 예상할 수 있다. sub_87C(s1, argv[1])의 결과가 1이면 된다.  해당 함수를 거꾸로 역연산하면 첫번째로 아래 코드를 역연산해야한다.

 

for ( i = strlen(v6) - 1; i >= 0; --i )
  {
    v4 = strlen(v6);
    if ( v6[v4 - i - 1] != v7[i] )
      return 0LL;
  }

 

해당 연산은 간단하게 한번 더 하면 역연산 가능하다. 즉, 1617181926381617919194을 거꾸로 뒤집으면 원래 상태가 된다.

 

-> 4919197161836291817161

 

 

 

 

 


다음으로 역연산해야 할 코드는 아래와 같다.

 

 while ( v10 != 22 )
  {
    if ( (v10 & 1) != 0 )
      v3 = a2[v10] - 4;
    else
      v3 = a2[v10] + 4;
    v6[v10] = v3;
    v6[v10++] ^= v11;
  }

 

 

v11은 계산하면 12인것을 알 수 있고 이진수로 111이다. 조금 더 보기 편하게 수정하겠다.

 

int i = 0

 while ( i != 22 ){
    if ( (i & 1) != 0 )          // 홀수면
        result[i] = flag[i] - 4;
    else                          // 짝수면
        result[i] = flag[i] + 4;
    result[i++] ^= 12;       // 최종 result는 위에서 구한 4919197161836291817161
  }

 

 

 

 


이제 역연산을 진행하면 xor을 한번 더 하면 원래 값이 되고 +4 -4를 해도 짝수 홀수는 변하지 않으므로 아래와 같이 파이썬 코드를 작성한다.

 

result='4919197161836291817161'
flag=''
for i in range(22):
    if(i % 2==0):
        flag+=chr((ord(result[i])^12) - 4)        
    else:
        flag+=chr((ord(result[i])^12) + 4)

print(flag)

 

 

 

 

 


결과는 아래와 같다. 처음에 여기서 아스키코드 변환이랑 여러가지를 해보았지만 해결되지않았다. 찾아보니 그냥 아래 값이 플래그였다....

 

4999997A6A0C6B1A0A7A6A

'Reversing > CTF' 카테고리의 다른 글

[HackCTF] Keygen  (0) 2021.10.09
[HackCTF] Strncmp  (0) 2021.09.12
[HackCTF] Handray  (0) 2021.09.11
[HackCTF] Reversing Me  (0) 2021.09.10
[HackCTF] Welcome_REV  (0) 2021.09.10

댓글