당신은 당신의 마음에 드는 오픈 소스 응용 프로그램 또는 라이브러리의 소스 코드를 읽을 수 또는 어쩌면 당신은 모임이나 스마트 폰 또는 태블릿에 인터뷰에서 자신의 프로젝트를 제시하고 싶어? Show 소스 코드 뷰어 하이라이트 : 이 응용 프로그램의 프로 버전은 추가 기능을 제공합니다 : 소스 리더에 의해 지원되는 언어 : 이 응용 프로그램 편집기 아님을 유의하시기 바랍니다. 대신, 그것은 매우 쉽게 파일을보기 및 읽기 위해 및 파일 브라우저에서 직관적 인 빌드에 최적화되어, 당신도 깊은 폴더 계층 구조 대형 프로젝트를 통해 빠르고 뛰어난 탐색 할 수 있습니다. 힌트 : 개발자들은 많은 시간을 들여 앱을 개발하고 있죠. 그렇다면 마지막으로 앱 하나를 분리해본 적은 언제인가요? 컴파일된 애플리케이션의 내부를 보는 과정을 간소화할 수 있다면, 업무에 적용하고 의문점을 해결할 수 있는 중요한 교훈을 더욱 잘 얻을 수 있을 겁니다. 이 강연은 간단한 실제 예제를 통해 안드로이드에 대한 리버스 엔지니어링 툴 세트를 사용해서 최대한 실질적인 이익을 얻을 방법을 보여줍니다. 어떤 것을 해부해보면 배울 수 있는 것이 정말 많습니다! 소개 (0:00)저는 Jon Reeve이고 이 강연은 “안드로이드 리버스 엔지니어링은 해커만을 위한 것이 아닙니다”라는 주제입니다. 포토 스톡을 제공하는 사이트에 가서 해킹을 검색하면 악성 또는 멀웨어 연구에 대한 이미지가 나오죠. 하지만 제가 말하고자 하는 내용은 이런 이미지의 해커를 위한 것이 아닙니다. 왜 앱을 해부해봐야 할까요? (1:19)세계에서 가장 큰 단일 머신인 유럽물리입자연구소의 강입자 가속기(LHC)를 생각해 보세요. 빅뱅을 재현하는 실험장치인 이 기계는 입자를 분리해서 내부를 볼 수 있게 합니다. 그것이 세탁기이든 최첨단 기술이든 분리해보는 것에서 많은 것을 얻을 수 있습니다. 애플리케이션도 마찬가지입니다. 소스 코드를 보기 위해서 꼭 소스 코드 자체가 필요하지는 않습니다. 예를 들어 왜 어떤 앱이 특정 권한을 요구하는지 궁금할 수 있습니다. 아마도 카메라로 희한한 일을 하거나 연락처를 모두 읽어서 어딘가로 보낼지도 모릅니다. SMS를 멋대로 보내서 비용이 나가게 할 수도 있습니다. 하지만 그 이유를 파악할 수는 없죠. 개발한 앱에 크래시가 난 경우를 생각해 볼까요? 우리 앱 때문일지도 모르지만 분석 도구나 광고 네트워크 같은 서드 파티 라이브러리 때문일 수도 있는데 이런 경우 소스가 없습니다. 혹은 크래시하는 앱이 직접 만든 앱이 아닐지라도, 개발자로서 새 안드로이드 OS 릴리즈를 사용하다가 맘에 드는 앱이 죽어버린다면 좀 더 많은 정보를 제작사에 줘서 좀 더 빠르게 버그를 픽스하도록 돕고 싶은 생각이 들 수도 있겠죠. 아니면 그 앱의 멋진 기능을 좀 더 들여다 보고 싶을 수도 있습니다. 프리랜서이자 전임 개발자로서 프로젝트를 참여할 때 다른 앱을 보고 비슷한 것을 만들고 싶다고 요청하는 경우가 많았습니다. 물론 앱을 카피할 생각은 없겠지만, 앱이 구성된 내용은 볼 가치가 큽니다. 좋은 시각적 효과가 있을 수도 있습니다. 어쩌면 가능하리라 생각하지도 못한 것을 해냈을지도 모르죠. 예를 들어 삼성 기기에서만 작동하는 카메라 API를 만들었을 수도 있습니다. 아니면 생각해왔던 그대로를 구현했을 수도 있습니다. 관련 라이브러리가 참 많은데, 가장 유명한 것은 무엇일까요? 사람들은 어떤 것을 사용하고 있을까요? 유명한 애플리케이션을 실제로 볼 수 있습니다. 앱을 열고 패키지 구조를 파악하고 어떤 라이브러리를 사용하는지 확인할 수 있죠. 다른 이들의 앱을 리버스 엔지니어링해서 훔치라는 뜻은 아닙니다. 하지만 직접 모든 것을 처음부터 다시 만들어내는 것보다 다른 사람들이 하고 있는 일을 참고하는 것은 유익할 수 있습니다. APK 얻기 (4:19)처음으로 해야할 일은 Android Package Kit, 즉 APK를 얻는 일입니다.
이 명렁어는 기기의 모든 패키지를 간단히 나열해 줍니다.
ADB 뉴라인 때문에 불편하고 해석이 필요하긴 하지만, 앞서 말한 명령어 대신 위 명령어를 사용하면 특정 애플리케이션의 APK를 가져올 수 있습니다. Bash Script 사용에 유용합니다. 다른 곳에서 APK를 가져올 수도 있습니다. 단, APK를 호스팅하는 사이트처럼 인터넷에서 받은 APK는 실제로 무엇이 설치될지 알 수가 없습니다. 구글 플레이 스토어와 같이 확실한 곳을 통하는 것이 좋습니다. APK가 사인 됐는지, 그리고 서비스 약관을 위반하지는 않는지 확인해야 합니다. AAPT (5:45)APK를 얻은 다음에는 안드로이드 SDK에 포함된
위와 같이 정말 많은 일을 할 수 있습니다. 특히 저게는 특히 AAPT Examples
badging과 같은 기본 정보를 알려주는 명령어입니다.
이 명령어로는 앞서 말씀드린 것처럼 흥미로운 스트링들을 볼 수 있습니다.
이 명령어는 전체 manifest를 XML 트리로 덤프합니다. manifest는 XML에서 바이너리 표현으로 바뀌므로 XML 트리를 다시 만들지만, 안드로이드는 이를 읽습니다. APK (7:17)APK에는 또 무엇이 들어 있을까요? 다음과 같은 공통 디렉터리도 있습니다.
META-INFMETA-INF 디렉터리에는 많은 것을 넣을 수 있습니다. 특히 APK의 서명을 나타내는 서명 파일이 위치하는 곳입니다. 여기서 재귀적인 문제가 발생합니다. 만약 APK를 서명하면 서명 파일을 이 디렉터리에 넣어야 하는데 이런 행동을 통해 APK의 서명이 다시 변경되면 곤란하겠죠. 따라서 이 디렉터리는 서명될 때 제외돼야 하죠. 즉, 이 디렉터리의 내용을 수정할 수 있지만 이것이 APK의 서명을 수정하지 않습니다. 서명을 무효로 하지 않고 이 디렉터리의 파일을 변경할 수 있습니다. 기본적으로 이 디렉터리는 서명을 포함하며 이를 통해 서드 파티 APK를 다운로드해서 제대로 된 것인지 확인할 수 있습니다. 다른 컨텐츠무엇이든 assets 이 될 수 있습니다. 멀웨어를 다루는 경우 실제로 코드처럼 보이지 않도록 조금 난독화되는데 거의 스테가노그래피(Steganography) 항목 수준의 것이 숨겨져 있을 수도 있습니다. 여기에 동적으로 코드를 불러오는 것이 있을 수도 있죠. 멀웨어가 종종 이런 형식을 취합니다. Classes.dex 에는 Dalvik 클래스로 바뀐 모든 Java 클래스가 포함됩니다. 최근에는 안드로이드 런타임(ART)와 미리 컴파일해주는 AOT(ahead-of-time) compilation으로 전체 전환되거나, 부분적으로 just-in-time(JIT) 방식을 사용하므로 이들 몇몇은 같은 방식으로 사용되지 않을 수도 있지만, 해당 형식이 고정돼 있으므로 모두 APK에 있어야 합니다. 그래서 실제로 이를 제거할 수는 없습니다. 비록 전체가 아니더라도 필요한 파일이며 리버스 엔지니어링을 하는 동안 계속 존재해야 합니다.
다른 도구 (10:30)이전에 저는 AAPT에 더해 다른 흥미로운 도구도 사용해 봤습니다.
명령어가 너무 복잡하죠? 예전에는 저런 명령어로 전체 코드 묶음을 돌렸는데 요즘은 제가 Java 1.5, Cupcake 등과 같은 초기 안드로이드 버전에서 작업한 이런 방식을 사용할 필요가 없습니다. 최근에는 Apktool을 사용하면 됩니다. Apktool다음과 같은 명령어로 실행할 수 있습니다.
Smali 에 대해 모르는 분을 위해 설명해 드리면 Dalvik 바이트 코드를 위한 어셈블리 언어입니다. 바이트 코드를 읽는 것보다 가독성은 높지만 바이트 코드와 거의 비슷하다고 볼 수 있습니다. 즉 아주 쉽게 Smali로 되돌릴 수 있죠. Baksmali 는 되돌려서 읽을 수 있는 형태로 바꿉니다. 이런 형태에 익숙해지는 데는 시간이 필요하지만, 점점 읽기 쉬워질 겁니다. 또한 이를 수정하고 다시 컴파일해서 앱을 다시 만들어내는 것도 가능합니다. 사실 Java 상에서 이런 변경을 하면 그 내용을 다시 앱으로 되돌리기에 한계가 있습니다. 리버스 엔지니어링을 하려면 앞서 말한 대로 Smali는 아주 가독성이 뛰어나지는 않지만, 필드와 상속 등을 볼 수 있습니다. 디버깅기본적으로는 왜 크래시가 나는지 보고 싶으실테죠. 그렇다면 이 방법이 효과있을지도 모릅니다. APK가 얼마나 엉망인지에 달려있고 제작자는 자신의 앱에 이런 디버깅을 하는 것을 원하지 않겠지만, 이 방법이 통한다면 놀라운 것들을 볼 수 있습니다. 디버그 버전이 아닌 버전으로 빌드된 앱을 가져와서 재빌드할 수 있습니다. Apktoll을 사용해서 다시 사인하고 자신의 디바이스에 설치해서 디버거를 붙여서 실행해볼 수 있습니다. 사인에는 기존 키가 아닌 자신의 키를 써도 됩니다. 여기까지 됐다면 아무 문제없이 마음껏 디버거를 쓸 수 있죠. 좀 사기같긴 하지만 여러분 앱의 릴리즈 버전이 이상하게 동작하는데 디버거를 붙일 수 없다면 디버깅이 가능한 릴리즈 버전이 필요할 수도 있습니다. 만약 쉽게 다시 만들 수 없는 예전 빌드라면 다음과 같은 것을 시도해볼 수도 있습니다.
Androguard (15:02)더 훌륭한 도구도 있습니다. 대화식 도구 모음인 Androguard입니다. Python 기반이므로 스트립팅이 가능하고 모듈화도 잘 돼 있으며 작은 도구의 라이브러리인 플러그 방식도 가능합니다. 또한 대화형 Python 셸 형식으로도 사용할 수 있습니다. 자체 Dalvik 디컴파일러를 포함하는 점도 인상적입니다. 사이트가 업데이트되지 않는 것 같지만 GitHub 프로젝트는 계속 업데이트되고 있으므로 API의 새 문제 등을 해결해줍니다. 이런 명령어로 대화식 작업을 시작할 수 있습니다.
APK를 나타내는 객체가 있고 이제 APK의 메인 액티비티가 뭔지 확인해 볼 수도 있습니다. 간단한 예제이지만 이런 방식으로 여러 가지를 확인해볼 수 있습니다.
좀 더 복잡한 예제의 경우
또한 권한을 표시하도록 할 수도 있고 이들 메서드의 다큐멘테이션을 얻을 수도 있습니다. 물음표는 매개 변수가 무엇인지 알려주고 어떤 매개 변수가 필요한지 알려주므로 대화식으로 편리하게 쓸 수 있습니다. 권한을 보는 경우 어디에 이들이 사용되는지도 알려줍니다. 소스 코드의 해당 위치로 가서 둘러볼 수도 있습니다. androquard는 구체적으로 보고 싶은 것이 있을 때 APK를 살펴보는 데도 유용합니다. 대화형 세션도 잘 돼 있습니다.
ClassyShark (17:49)최근에는 ClassyShark도 많이 쓰입니다. 구글 엔지니어가 배포한 유용한 도구인데 UI가 아주 멋지진 않지만 커맨드 라인 인터페이스가 있어서 편리합니다. 빌드 도구에서 사용할 수도 있고 그 안에서 스크립트를 작성해서 빌드 시점에 정보를 알 수도 있습니다. 자신의 프로젝트에서 사용할 수 있는데 APK를 열고 메서드 카운트가 무엇인지와 같은 기본적인 정보를 쉽게 볼 수 있습니다. 또한, 이 도구로 무엇이든 열 수 있다는 점도 편리합니다. APK 안의 raredare2 (19:20)Raredare2는 스크립트가 가능한 16진수 에디터입니다. 친숙하지는 않지만 많은 사람들의 기여로 전반적인 프레임워크로 진화했습니다. 거의 무엇이든 지원할 수 있으며 안드로이드뿐만 아니라 모든 종류의 아키텍처를 지원하는 오픈 소스 프로젝트입니다. 이 도구를 기기에서 실행해서 APK를 묶어서 만들어진 결과물을 확인할 수 있습니다. 분석을 담은 웹페이지 등 여러 웹 컨텐츠를 보여주므로 그다지 익숙한 모습은 아니지만 기기에서 사용할 수 있다는 점이 좋습니다. 추가 도구 (20:15)플레이 스토어에는 JaDX 등의 여러 도구가 있습니다. 좀 오래됐고 UI도 썩 훌륭하지는 않지만 유용한 도구입니다. 한편 Show Java 는 JaDX나 다른 자바 디컴파일러를 사용할 수 있습니다. Dexplorer 도 비슷한 일을 해줍니다. 이들 도구는 플레이 스토어에서 받을 수 있는 애플리케이션으로 APK를 노트북을 거칠 필요 없이 기기에서 열 수 있도록 해줍니다. 노트북 얘기로 돌아가서 Santoku라는 것도 있습니다. 이는 우분투의 더 가벼운 버전은 루분투를 기반으로 한 리눅스 배포판으로 안드로이드를 포함한 일반적인 프로그램들의 보안 점검 혹은 리버스 엔지니어링을 위한 여러 도구들이 미리 설치돼 있습니다. 따라서 Androguard와 같은 여러 도구가 미리 설치돼서 설정도 끝나 있어서 커맨드 라인에서 바로 실행할 수 있습니다. 자신의 기기에 여러 도구를 설치하지 않아도 좋다는 점이 편리하죠. VM이나 부팅 가능한 USB로 Santoku를 실행하고 필요한 도구 목록을 찾아서 실행하는 것만으로 직접 컴퓨터에 깔지 않고도 안드로이드 리버스 엔지니어링을 위한 훌륭한 도구를 사용할 수 있습니다. IDA와 같이 가격이 비싼 전문가용 도구도 있습니다. 리버스 엔지니어링을 심층적으로 하고 싶거나 큰 회사에서 일하면서 보안이 앱에 큰 이슈가 되는 경우라면 이런 도구를 사용하는 것도 좋습니다. IDA Pro는 안드로이드에서 뿐만이 아니라 여러 분야에서 사용됐으며, 디스어셈블리나 디버깅 도구의 제왕격으로 디스어셈블리를 위한 IDE와 같습니다. 따라서 노트를 만들고 변경하고 다시 작성할 수 있긴 하지만 아쉽게도 유료로 가격이 저렴하지는 않습니다. CodeInspect는 최근 알파 버전까지 무료였지만 현재는 유료이며 Jimple 이라는 것을 사용합니다. 앞서 Smali와 Baksmali가 Dalvik을 디스어셈블한다고 언급했는데, Jasmin 은 Java에서 널리 사용되는 유명한 어셈블러 언어입니다. CodeInspect는 Jimple이라는 것을 사용하는데 정적 분석을 위한 아이디어로 만들어졌으므로 Soot이라는 프레임워크를 사용해서 Jimple 내용을 분석해줍니다. 이론 상으로는 APK를 분석하는 도구를 플러그해서 특정 취약성이나 특정 패턴 등 코드를 정적으로 분석할 수 있습니다. 앱을 디버그할 수 있게 하고 런타임 상에 분석하거나 둘러보면서 필드나 메서드 등의 이름을 다시 지을 수 있으므로 앱이 난독화되는 경우 아주 유용합니다. 아쉽게도 Eclipse 기반이므로 예쁘지는 않습니다. 다른 유료 도구로 JEB / JEB2도 있습니다. Dalvik에서 Java로의 소스 디컴파일러로 대화형이므로 원하는 위치로 접근해서 이름을 다시 지정할 수 있습니다. 구독 기반 도구입니다. 보안 (25:08)보안에 대한 유명한 인용문을 먼저 소개하겠습니다.
앱을 완벽하게 보호할 수는 없습니다. 투입할 수 있는 시간의 양과 보안 정도와 공격자 수 사이에 절충해야 합니다. 앱에서 정말 보안이 필요한 것이 있다면 앱에 넣지 마세요. 자신의 앱을 포함해서 여러 앱을 리버스 엔지니어링을 해보는 것이 좋습니다. 많은 것을 배울 수 있고, 자신의 앱에서 다른 사람들이 어떤 정보를 볼 수 있는지도 알 수 있습니다. 뭔가 정말 보안이 필요한 것이 있다면 배포 이후에 되돌릴 방법이 없으니 앱에 있지 않는 것이 좋습니다. 적어도 보안을 신경 쓴다면 난독화와 사이즈 축소를 적용할 수 있습니다. 여기에는 실제로 큰 노력이 들어가지 않지만 때때로 결과를 확인하는 것이 좋습니다. 훌륭한 일을 했다고 생각해도 확인하지 않으면 생각보다 난독화가 성공적이지 않을 경우가 있기 때문입니다. 예산이 충분하고 중요한 이슈라면 특정 사안을 보호하기 위해 비용을 사용할 가치가 있습니다. DexGuard](https://www.guardsquare.com/en/dexguard)와 같은 경우 유료이지만 ProGuard 보다 높은 레벨을 제공합니다. DexGuard에 여러 트릭을 적용해서 APK를 리버스 엔지니어링하기 매우 어렵게 해줍니다. 물론 유명한 도구라서 이를 풀 도구가 생겨날지도 모르지만, 보통의 개발자들이 엿보는 것은 대부분 막을 수 있을 겁니다. SQLCipher는 데이터를 암호화하기 위한 도구로 내부를 보기 어렵게 만듭니다. 하지만 다시 강조하는데 정말 중요한 것이라면 앱에 넣지 마세요. 앱을 리버스 엔지니어링해서 어떤 것을 볼 수 있는지 확인해보고 쉽게 수행할 수 있는지 점검하세요. 사적인 것을 스트링에 넣는다면 누구나 쉽게 볼 수 있을 테니, 이를 남들보다 먼저 확인해 보시는 게 좋을 겁니다. 보안 예제위 이미지는 ProGuard로 난독화된 앱의 구조입니다. 액티비티와 액티비티의 전체 이름, 그리고 패키지를 유지해야 합니다. 이제 흔히 하는 것처럼 액티비티를 기능별 패키지로 묶을 수 있을 텐데, 그 경우 액티비티 이름을 유지하기 위해 전체 패키지 구조를 그대로 유지할 겁니다. 누군가 이 난독화된 앱을 열어보면 앱의 구조에 대해 꽤 많은 정보를 얻을 수 있고 어디서부터 둘러봐야 할지 알아차릴 수 있습니다. 예제는 아주 단순해서 모든 액티비티를 분리된 패키지에 넣었지만, 우선 순위에 따라 난독화되지 않을 것들이 전체 미러링 된 패키지 구조 안에 포함될 수도 있으니 알아둘 필요가 있습니다. 따라서 퍼블릭인 것은 완전히 다른 패키지 구조에 그룹화할 수 있습니다. 이렇게 할 경우 실제로 어떻게 보이게 되는지 직접 뜯어서 확인해보고 더 좋은 방법을 찾는 것이 좋습니다. 마무리 (29:58)Android Hacker’s Handbook에서 제가 말한 것 이외에도 많은 것을 배울 수 있습니다. Droidcon Berlin에서 제가 말한 CodeInspect 도구를 볼 수 있습니다. 어떤 것을 할 수 있는지 확인해 보세요. DEFCON23의 GitHub 링크에서는 리버스 엔지니어링에 대한 심화 내용을 볼 수 있습니다. Androguard 사용법은 문서에서 확인하세요. 감사합니다! 컨텐츠에 대하여 2017년 3월에 진행한 DroidKaigi 행사의 강연입니다. 영상 녹화와 제작, 정리 글은 Realm에서 제공하며, 주최 측의 허가 하에 이곳에서 공유합니다. |