오늘 제가 발표할 주제는 안드로이드 101입니다.

원래는 안드로이드 어플리케이션에서 어떻게 루팅을 탐지하는지에 대해서만 발표하려고 하였으나,
처음 안드로이드 공부할 때 많이 막막했던 것이 생각나기도 하고,
처음 하는 분들에게 조금이라도 도움을 드릴수 있고자 안드로이드에 대한 기본적인 내용을 추가하고,
루팅 탐지 부분의 비중을 낮춰서 안드로이드 101으로 발표 주제를 정했습니다.

 


목차는 크게 다음과 같습니다.

 - APK에 대한 기본적인 지식들

 - APK 분석 방법

 - 루팅 탐지 방법

 


아시다시피 요즘 날의 모바일 어플리케이션 생태계는 크게 안드로이드와 iOS로 나눌 수 있습니다.

그중에서 non-native code 인 달빅 바이트 코드를 사용하며,
상대적으로 디버깅하기 쉬운 안드로이드 어플리케이션에 대하여 이야기해보려고 합니다.

 


앞에서 non-native code에 대하여 언급했는데,
조금은 헷갈릴 수 있는 개념이라 간단하게 정리하고 넘어가겠습니다.
정확하게 까지는 아니더라도 대충 native 한 게 어떤 느낌인지 정도만 아셔도 괜찮을 것 같습니다.

 

우선은 managed code입니다.

 

이 managed code는 microsoft에서 2003년에 비주얼 스튜디오 2003을 출시하면서 발표한 개념입니다.
마이크로소프트 사의 C#이나 VB .NET 이 managed code에 포함되며,
그리고 많이들 사용하는 Python, Java 등도 여기에 포함됩니다.

 

소스코드가 실행되기까지의 과정에 대하여 간단하게 이야기해보면,
사용자가 작성한 소스코드는 IL 즉 중간 언어로 컴파일되는데,
이 IL 은 어셈블리어 정도로 생각하시면 될 것 같습니다.
그 후 IL 파일이 정상인지 확인한 후 runtime에 사용되는 메소드를 호출합니다.

 

이 지터에서 runtime 시에 사용되는 메모리나 예외 등을 처리해주기 때문에,
파이썬처럼 변수를 따로 할당하지 않아도 알아서 메모리를 할당해 주고 해제해줍니다.

 

다음으로는 unmanaged code입니다.

 

managed code에 반대되는 개념으로 예전부터 있던 전통적인 C 등이 여기에 포함됩니다.

 

소스코드는 각 환경에 맞게 바로 컴파일되어 기계어로 된 프로그램의 형식으로 실행되며,
C언어를 하면서 많이들 느꼈겠지만 필요한 메모리를 직접 할당(malloc) 및 해제를 해줘야 합니다.

 

참고로 알고리즘 할 때 많이 사용되는 C++ 은 managed code 가 될 수도, unmanaged code 가 될 수도 있습니다.

 

마지막으로 좀 모호하다고 생각되는 native code입니다.

 

보통은 native code를 unmanaged code의 동의어의 일종으로 생각해서,
크게 managed code와 native code로 나누기도 합니다.
이전 슬라이드에서 말한 것처럼 native code와 non-native code로 나눈 것처럼 말이죠.


하지만 native code는 unmanaged code 일 수도,
managed code의 산출물인 machine code 인 기계어도 될 수 있습니다.

 

이 부분에 대해서는 pwnwiz 님이 더 잘 아시니,
잘 모르겠다 싶은 것은 pwnwiz 님께 질문하면 잘 알려주실 겁니다.

 


apk 해킹? 이 맞는 말인지 모르겠지만,
apk 해킹에서 제가 가장 중요하다고 생각하는 것은

리패키징 방지 우회 및 루팅 탐지를 우회하는 것이라고 생각합니다.

 

왜냐하면 리패키징 방지와 루팅 탐지 2개에서 자유롭다면 분석의 난이도는 다르지만,
그래도 코드를 변조해서 무엇인가는 할 수 있기 때문입니다.

 


안드로이드 어플리케이션인 apk의 경우 iOS 어플리케이션인 ipa에 비하여 단순한 zip 구조로 구성되어 있으며,
별다른 절차(루팅) 없이도 개발자 도구 중 하나인 usb 디버깅 모드로 apk의 설치 및 삭제가 가능합니다.

 

그래서 사용자는 설치된 apk를 추출하거나 외부에서 apk를 구하여,
수정한 후 리패키징하여 다시 설치할 수 있습니다.


이렇게 되면 악의적인 사용자는 apk를 수정하여하고 싶은 것을 할 수 있게 됩니다.

 


apk의 구조를 조금 더 자세히 보자면,

소스코드는 dex 파일로 컴파일되며
여기에 apk에서 사용할 여러 리소스 파일들과 네이티브 코드들을 압축하여

apk를 생성합니다.

 

이 apk를 설치하면,

반대로 압축을 풀면서 설치가 되고 달빅이가 바이트코드를 해석하고 실행이 됩니다.

 


앞에서 말한 바와 같이 apk 해킹하는데 첫 번째로 중요하다고 생각하는 리패키징 방지입니다.

 

리패키징 과정은 apk 만드는 과정을 거꾸로 포함하고 있습니다.


정상적이라면 소스코드에서 컴파일을 한 후,
패키징 과정을 거친 후에 서명을 하고 배포를 합니다.


하지만 리패키징 과정은 apk를 언패킹 해서,
디컴파일을 거쳐 소스코드를 획득하고,
수정을 한 후에 다시 apk를 만듭니다.

 

따라서 이렇게 리패키징을 통해 소스코드를 수정할 가능성이 있기 때문에,
apk 가 리패키징되지 못하도록 방지해야 합니다.

 


이름은 밝힐 수 없는 한 게임이 있습니다.
물론 이 게임에서도 여러 보안 방식들로 자사의 어플리케이션을 보호하고 있습니다.


하지만 이렇게도 할 수 있다는 것을 보면서,
리패키징 방지의 중요성을 한번 더 생각해 봤으면 좋겠습니다.

 

우선 이러한 짓을 한 개요는 다음과 같습니다.
게임을 플레이하는 게 귀찮아서

“한 가지 색상으로만 나온다면 가만히 있어도 편하게 게임을 끝낼 수 있지 않을까?"

라는 생각으로,
파란색 캔디만 생성되도록 바꿔 보았습니다.
하지만 당연히 끝날 거라 생각했던 게임은 끝나지가 않았습니다,,

 


그다음으로 두 번째로 중요하다고 생각하는 루팅 탐지입니다.

 

여기서 루팅이란 정확히 뭘 말하는 것일까요?
루팅이란 최고 권한인 root를 획득하는 것을 말하며,
안드로이드 운영체제에서는 최고 권한인 superuser 권한을 획득하는 것을 말합니다.


이 권한으로는 일반적으로 할 수 없는 것들을 할 수 있게 해 줍니다.

예를 들면 접근이 불가능한 시스템 폴더 같은 곳에 접근해서 삭제 불가능한 좀비 어플을 삭제하거나,
어플리케이션이 사용하는 메모리에 접근해서 수정하는 것이 가능합니다.

 


초등학교, 중학교 때 게임을 많이 해보신 분들은 한 번은 써봤을 러키패처와 치트엔진입니다.


일반적으로 안드로이드에서는 각 어플리케이션별로 uid를 생성하고 각 uid 별로 관리되지만,
이 어플리케이션들은 루팅을 이용하여 다른 프로세스에서 사용하는 메모리를 수정할 수 있게 해 줍니다.

 

따라서 메모리 무결성 등이 중요한 금융이나 게임 어플리케이션의 경우 루팅이 되어 있는지를 확인해야 합니다.

 


앞에서 소개한 루팅을 탐지하는 것과 리패키징을 방지하는 것 외에도 여러 보호 기법들이 있습니다.


이 중에서 제가 가장 싫어하는 보호 기법을 하나 보여 드리면서 넘어가도록 하겠습니다.

 


이 어플리케이션은 제가 분석하면서 제일 싫었던 어플리케이션 이였습니다.

 

중간에 보면 메소드들이 a.a.a으로 되어 있는데 다시는 만나고 싶지 않은 친구입니다.

 

그러면 오늘의 진짜 주제였던 안드로이드에서 루팅 탐지 방법에 대하여 소개하겠습니다.

+ Recent posts