LineCTF 2022 Rolling

Osori·2022년 3월 27일
0

Write-up

목록 보기
1/3

LineCTF 2022에 출제된 리버싱 문제이다.
아쉽게도 이번 CTF에서는 이거 한문제 풀었다.
대부분의 안드로이드 리버싱 문제가 그렇지만 폰으로 앱을 다운받아서 켜서 버튼을 누르면 종료되서 뭔가 문제가 있다 싶었다.

jadx 같은 안드로이드 앱 디컴파일러로 분석하면 액티비티 한개를 가지고 있고, 플래그 검사는 native 코드에서 하는 것을 알 수 있다.
그래서 그 네이티브 라이브러리를 IDA로 까보면 아래와 같은 플래그 검사 루틴이 존재했다.

strlen 으로 구한 문자열 길이로 반복문이 돌아가는 것을 통해서 1바이트 씩 플래그 검사를 한다고 추측할 수 있었고 저 코드를 직접 재구현주기로 했다.
핸드폰에서 앱이 안돌아 갔기 때문에 해당 코드를 정상적인 방법으로 실행이 불가능했다... 만약 가능했으면 frida 를 통해서 조금 더 쉽게 풀 수 있었을 것이다.
다행인 것은 termux 라는 안드로이드 앱을 통해서 핸드폰에 리눅스 쉘 환경을 구축할 수 있었고, arm64 명령어 실행이 네이티브로 가능했기 때문에 해당 library 를 dlopen 해서 플래그 검증과 관련된 메모리 값들은 심볼로 가지고 올 수 있어서 노가다를 좀 덜해도 됐다.

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
int main()
{
        void* handle = dlopen("/data/data/com.termux/files/home/rolling/libnative-lib.so",RTLD_NOW );
        if(!handle)
        {
                puts("dlopen error");
                exit(0);
        }
        printf("pid : %d\n", getpid());
        puts("dlopen success");
        printf("handle addr : %p\n", handle);
        int len = 0;
        unsigned int* (*meatbox)(char*) = dlsym(handle, "_Z7meatboxPc");
        unsigned int* (*soulbox)(char*) = dlsym(handle, "_Z7soulboxPc");
        unsigned int* (*godbox)(char*) = dlsym(handle, "_Z6godboxPc");
        char* asc_box = (size_t)meatbox + (0x30e0);
        printf("meatbox addr : %p\n",meatbox);
        printf("soulbox addr : %p\n",soulbox);
        printf("godbox addr : %p\n",godbox);
        printf("asc_box addr : %p\n",asc_box);
        char flag[0x100] = {0};
        char* ch = flag;
        int idx = 0;
        int while_flag = 1;
        while(while_flag)
        {
                //brute force
                for(int i = 0x20; i<=0x7f; i++)
                {
                        *ch = i;
                        unsigned int* res_meatbox = meatbox(ch);
                        unsigned int* res_soulbox = soulbox(ch);
                        unsigned int* res_godbox = godbox(ch);
                        //printf("%p\n", asc_box+4*idx);
                        if(*((unsigned int*)(asc_box+4*idx)) == *res_meatbox)
                        {
                                if(*((unsigned int*)&asc_box[4*(idx+1)]) == *res_soulbox)
                                {
                                        if(*((unsigned int*)&asc_box[4*(idx+2)]) == *res_godbox)
                                        {
                                                printf("%c",i);
                                                if(i == '}')
                                                        while_flag = 0;
                                                break;
                                        }
                                }

                        }
                }
                ch++;
                idx += 3;
        }


}

위 코드를 arm64 환경에서 컴파일 하고 돌리게 되면 플래그가 나온다.

profile
해킹, 리버싱, 게임 좋아합니다

0개의 댓글

관련 채용 정보