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?:)