Write_Up/REV

[HKCERT_CTF_2024] Baby Cracker, Yet another crackme Writeup

90mapt4 2024. 11. 18. 15:31
Reverse_Baby Cracker

 

가장 먼저 바이너리 파일을 IDA로 열어주면 main함수가 보이는데, main함수만 보면 되는 간단한 문제였다.

 

 

로직을 확인해보면 크게 3단계 조건문으로 나눌 수 있다.

 

1. 첫번째 조건문

- 사용자가 입력한 문자열에 'hkcert24{' 가 포함되어있는가?

 

2. 두번째 조건

 

- 사용자가 입력한 문자열의 끝이 '1}' 로 끝나는가?

- 그리고 뒤에서 3번째 4번째 5번째 문자열에 대한 방정식이 존재 

 --> 해당 방정식에서는 4번째 문자열은 'h' 이고, 3번째 + 5번째 = 196임을 알아낼 수 있다.

 

3. 세번째 조건

- '*((char *)off_4058 + i) ^ haystack[i + 9]) == byte_2123[i]' 해당 조건을 만족하는가?

 

세번째 조건에서 haystack[i + 9]는 사용자가 입력한 문자열의 'hkcert24{' 뒤의 문자열이고, for문은 28번 돌고 끝나는 것을 볼 수 있다.

 

사용자가 입력한 문자열을 구하기 위해서는 off_4058과 byte_2123을 xor해야한다. 각 값들을 가져와서 코드를 통해 xor해준다.

 

#include <stdio.h>

int main() {
    unsigned char off_4058[] = {
        0xCE, 0x21, 0xDB, 0x64, 0xD1, 0x50, 0xE0, 0x1B, 0x0D, 0x3E, 0xFB, 0x0A,
        0x52, 0x2F, 0x94, 0x9D, 0xAF, 0xB1, 0x58, 0x6B, 0x8A, 0xEE, 0xC1, 0xF0,
        0xFC, 0x19, 0x0A, 0xE3, 0xE9
    };

    unsigned char byte_2123[] = {
        0xBD, 0x10, 0xB6, 0x50, 0xBD, 0x35, 0xBF, 0x78, 0x7F, 0x0A, 0x98, 0x61,
        0x1F, 0x1C, 0xCB, 0xA9, 0xF0, 0xD9, 0x6C, 0x05, 0xEE, 0xAC, 0xB8, 0x98,
        0x9D, 0x77, 0x3C, 0xBC
    };

    unsigned char haystack[28];

    for (int i = 0; i < 28; i++) {
        haystack[i] = off_4058[i] ^ byte_2123[i];
        printf("%c", haystack[i]);
    }

    printf("\n");
    return 0;
}

 

flag : hkcert24{s1m4le_cr4ckM3_4_h4ndByhan6_cha1}

 


Reverse_Yet another crackm

 

 

본 문제 파일을 다운로드 해보면, .apk확장자 파일이 나온다. 

- apk 파일은 무엇일까?

.apk가 붙은 파일인 android 패키지에는 런타임에 필요한 android 앱의 콘텐츠가 포함되어 있으며 android 기반 기기에서 앱을 설치하는 데 사용하는 파일이다.

 

apk확장자를 가진 파일을 올리면 소스코드를 다 볼 수 있도록 해주는 도구인 jadx-gui를 통해 열어보면, 중점으로 볼 파일은 .DEX확장자를 가진 파일이다.

.DEX 파일은 무엇일까?

DEX에는 android 런타임에서 궁극적으로 실행되는 코드가 포함 되어 있다. 즉 기계어로 되어있다. 이를 디컴파일 하면 smail 코드가 된다.

그치만 .DEX 확장자를 봐도 그렇다 할 내용을 얻을 수 없었기 다른곳을 보니 maui와 xamarin을 주목할 수 있었다. 

 

이것들을 봐서 알 수 있는 것은 .NET MAUI 프레임워크로 개발되었을 거라 추측할 수 있다. 

 

이제 Xamarin/MAUI를 리버싱 하면 된다. \assemblies 디렉토리에서 dll을 복구할 수 있으니 pyxamstore를 이용해 복구해준다.

 

복구하면 CrackMe.dll을 찾을 수 있는데 해당 로직만 분석하면 바로 flag를 찾을 수 있다.

 

from struct import pack

array = [
    9, 10, 11, 12, 13, 32, 33, 34, 35, 36,
    37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
    47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
    57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
    77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
    87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
    107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
    117, 118, 119, 120, 121, 122, 123, 124, 125, 126
]

array2 = [
    58, 38, 66, 88, 78, 39, 80, 125, 64, 106,
    48, 49, 98, 32, 42, 59, 126, 93, 33, 56,
    112, 120, 60, 117, 111, 45, 87, 35, 10, 68,
    61, 77, 11, 55, 121, 74, 107, 104, 65, 63,
    46, 110, 34, 41, 102, 97, 81, 12, 47, 51,
    103, 89, 115, 75, 54, 92, 90, 76, 113, 122,
    114, 52, 72, 70, 50, 94, 91, 73, 84, 95,
    36, 82, 124, 53, 108, 101, 9, 13, 44, 96,
    67, 85, 116, 123, 100, 37, 43, 119, 71, 105,
    118, 69, 99, 79, 86, 109, 62, 83, 40, 57
]

array3 = [
    16684662107559623091,
    13659980421084405632,
    11938144112493055466,
    17764897102866017993,
    11375978084890832581,
    14699674141193569951
]

num = 14627333968358193854
num2 = 8

reverse_dictionary = {array2[i]: array[i] for i in range(len(array))}

def reverse_verify_flag(array3: List[ulong]) -> str:

    ulongs = [num ^ item for item in array3]
    
    padded_text = ''.join(
        pack("<Q", item).decode('ascii') for item in ulongs
    )
    
    original_text = padded_text.rstrip(chr(1))
    
    original_chars = [chr(reverse_dictionary[ord(char)]) for char in original_text if ord(char) in reverse_dictionary]
    
    return ''.join(original_chars)

flag = reverse_verify_flag(array3)
print(flag)

 

flag : hkcert24{f0r3v3r_r3m3mb3r_x4m4r1n_2024-5-1}

'Write_Up > REV' 카테고리의 다른 글

[ISITDTU_CTF_2024] re01, animal Writeup  (1) 2024.11.08