콘텐츠로 건너뛰기

HateIntel

File

seohyun-gyu@MacBook-Pro-2 Downloads % file ./HateIntel/HateIntel
./HateIntel/HateIntel: Mach-O executable arm

arm 아키텍처 iOS에서 돌아가는 실행 파일이다.

sub_2224

int sub_2224()
{
  char __s[80]; // [sp+4h] [bp-5Ch] BYREF
  int v2; // [sp+54h] [bp-Ch]
  int v3; // [sp+58h] [bp-8h]
  int i; // [sp+5Ch] [bp-4h]

  v2 = 4;
  printf("Input key : ");
  scanf("%s", __s);
  v3 = strlen(__s);
  sub_232C((signed __int32)__s, v2);
  for ( i = 0; i < v3; ++i )
  {
    if ( __s[i] != byte_3004[i] )
    {
      puts("Wrong Key! ");
      return 0;
    }
  }
  puts("Correct Key! ");
  return 0;
}

사용자로부터 입력받은 key를 sub_232C에서 변환 과정을 거쳐
__s[i] != byte_3004[I]에서 각각 한 문자씩 확인한다.

sub_232C

signed __int32 __fastcall sub_232C(signed __int32 result, int a2)
{
  char *__s; // [sp+4h] [bp-10h]
  int i; // [sp+8h] [bp-Ch]
  signed __int32 j; // [sp+Ch] [bp-8h]

  __s = (char *)result;
  for ( i = 0; i < a2; ++i )  // a2=4
  {
    for ( j = 0; ; ++j )
    {
      result = strlen(__s);
      if ( result <= j )
        break;
      __s[j] = sub_2494((unsigned __int8)__s[j], 1);
    }
  }
  return result;
}

각 문자의 변환을 sub_2494 함수를 통해 총 4번 반복시킨다.

sub_2494

int __fastcall sub_2494(unsigned __int8 a1, int a2)
{
  int v3; // [sp+8h] [bp-8h]
  int i; // [sp+Ch] [bp-4h]

  v3 = a1;  // a1 = __s[j]
  for ( i = 0; i < a2; ++i )  // a2 = 1
  {
    v3 *= 2;
    if ( (v3 & 0x100) != 0 )
      v3 |= 1u;
  }
  return (unsigned __int8)v3;
}

여기 함수에서는 2번째 매개변수인 a2가 1이 들어가므로 딱 1번만 작동한다.

각 하나의 문자인 v3에 2를 곱하고

그 곱한 값을 0x100으로 AND 연산했을때 0이 아니면 v3에 OR 연산한다.

그리고 최종적으로 v3를 반환한다.

Example

이를 테면, 32바이트인 key가 다음과 같다면

ABCDEFGHIJKLMNOPQRSTUVWXYZ123456

A = 0x41
v3 = 0x41
v3 = v3 * 2 = 0x41 * 2 = 0x82
v3 & 0x100 = 0x82 & 0x100 = 0 이므로,
-> v3 = 0x82

v3 = 0x82
v3 = v3 * 2 = 0x82 * 2 = 0x104
v3 & 0x100 = 0x104 & 0x100 = 0x100 이므로
-> v3 = v3 | 1 = 0x104 | 1 = 0x105
v3 = 0x105 & 255 = 5 (unsigned __int8 범위)

v3 = 5
v3 = v3 * 2 = 5 * 2 = 0xa
v3 & 0x100 = 0x104 & 0x100 = 0 이므로
-> v3 = 0xa

v3 = 0xa
v3 = v3 * 2 = 0xa * 2 = 0x14
v3 & 0x100 = 0이므로,
-> v3 = 0x14

따라서 A인 0x41을 나타내는 한 문자는 0x14가 된다.

따라서 변환하는 코드를 작성하면 다음과 같다.

str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"
str = [ord(char) for char in str]
# str = list(str)
# print(str)
# print(len(str))


for i in range(len(str)):
    for j in range(4):
        k = str[i]
        k = k * 2
        if((k & 0x100) != 0):
            k = k | 1
        if(k > 255):
            k = k & 255
        str[i] = k

# print(str)

str = [hex(char) for char in str]
print(str)
seohyun-gyu@MacBook-Pro-2 HateIntel % python3 enc.py
['0x14', '0x24', '0x34', '0x44', '0x54', '0x64', '0x74', '0x84', '0x94', '0xa4', '0xb4', '0xc4', '0xd4', '0xe4', '0xf4', '0x5', '0x15', '0x25', '0x35', '0x45', '0x55', '0x65', '0x75', '0x85', '0x95', '0xa5', '0x13', '0x23', '0x33', '0x43', '0x53', '0x63']

Solution

byte_3004 = [0x44, 0xF6, 0xF5, 0x57, 0xF5, 0xC6, 0x96, 0xB6,\
             0x56, 0xF5, 0x14, 0x25, 0xD4, 0xF5, 0x96, 0xE6,\
             0x37, 0x47, 0x27, 0x57, 0x36, 0x47, 0x96, 0x03,\
             0xE6, 0xF3, 0xA3, 0x92, 0x00, 0x00, 0x00, 0x00]

k = 0
str = [0] * 32
# str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"
# str = [ord(char) for char in str]
# str = list(str)
# print(str)
# print(len(str))

for i in range(len(str)):
    for guess in range(255):
        for j in range(4):
            k = str[i]
            k = k * 2
            if((k & 0x100) != 0):
                k = k | 1
            if(k > 255):
                k = k & 255
            str[i] = k

        if k == byte_3004[i]:
            # guess = 0
            str[i] = guess
            break
        else:
            str[i] = guess + 1
    


# print(str)

str = [chr(char) for char in str]
# print(str)
for i in range(len(str)):
    print(str[i], end='')

0~254 범위 사이의 문자를 하나씩 때려맞추는 방법으로 풀었다.

seohyun-gyu@MacBook-Pro-2 HateIntel % python3 solve.py
Do_u_like_ARM_instructi0n?:)%

KEY

Do_u_like_ARM_instructi0n?:)

태그:

답글 남기기