이번 포스팅에서는 간혹 악성코드에서 사용되는 dex 파일을 DES 암호화 한 후, 이를 복호화하여 dex를 load하는 방법인 DES 암호화 패킹에 대한 복호화 방법을 설명한다.


흔히 이 방법은 다음과 같은 형태의 클래스 형태를 띄고 있다.

 

 

NoApp 클래스를 분석하면, 아래 그림과 같이 Assets 폴더 내부에 ns 파일을 DES key인 gjaoun을 이용하여 복호화하는 것을 알 수 있다.

 

 

해당 코드를 바탕으로 Assets 폴더 내부의 ns 파일을 복호화하는 코드는 아래와 같다.

 

 

복호화된 dex파일을 디컴파일을 이용하여 열면 다음과 같이 기존 dex파일과 다른 구조의 실제 악성행위를 하는 dex 파일을 확인할 수 있다.

 

 

이번 포스팅에서는 가장 흔하게 배포되고 있는 안드로이드 스미싱 악성코드인 CJ대한통운 택배 사칭 앱에 대한 악성코드 분석을 한다. 분석 방법은 AndroidManifest.xml 분석과 코드 정적 분석 그리고, 직접 실행하여 유출되는 패킷을 분석하는 동적 분석을 진행할 예정이다.


해당 악성 앱은 실제 구글 앱 스토어에 있는 앱과 아이콘이 유사하기 때문에, 일반 사용자들은 이를 CJ대한통운 택배 앱으로 착각하고 설치하게 되었을 때, 피해를 입게 된다. 다음과 같이 CJ대한통운 택배 앱을 사칭하며, 실제 정상 앱과 유사한 아이콘으로 일반 사용자들을 속이고 설치를 유도한다.

 

 

해당 악성코드를 Virustotal 사이트에서 확인해보면, 다음과 같이 많은 백신 엔진에서 이를 탐지하고 있음을 알 수 있으며, 탐지명은 대다수가 Android.Trojan.SmsSpy 명칭을 사용하는 악성코드로 SMS 정보를 탈취하는 행위를 하는 것을 가늠할 수 있다.

 

 

 

1. AndroidManifest.xml 분석

​Apktool를 이용하여 AndroidManifest.xml를 열어보면, 해당 악성 앱은 다음과 같은 권한을 요구한다.

 

 

  - 네트워크 사용 권한 (INTERNET)

  - 폰 상태 정보 읽기 권한 (READ_PHONE_STATE)

  - SMS 읽기 권한 (READ_SMS)

  - SMS 보내기 권한 (SEND_SMS)

  - 부팅 완료 시, 브로드캐스트를 받을 수 있게 하는 권한 (RECEIVE_BOOT_COMPLETED)

  - SMS 수신 권한 (RECEIVE_SMS)

  - 환경설정 변경 권한 (WRITE_SETTINGS)

  - 전화 수신 관련 권한 (CALL_PHONE)

  - 폰 상태 변경 권한 (MODIFY_PHONE_STATE)

 

최초로 수행되는 Entry Point는 MainActivity로 등록되어 있으며, 그 밖에 1개의 Activity와 1개의 Service, 2개의 Receiver로 구성되어 있음을 확인할 수 있다.


 

 

2. 소스 코드 정적 분석

소스 코드 정적 분석의 경우 JEB Decompiler를 이용하였으며, 이전 포스팅에서 JEB Decompiler에 대한 설명을 하였다.

JEB Decompiler : 2017/05/02 - [Analysis/Android] - 안드로이드 디컴파일러 (JEB Decompiler)

 

최초 앱이 실행되면 아래 그림처럼 실행과 동시에 애플리케이션 목록에서 해당 앱의 아이콘을 은폐시킨다. 또한, 앱 디렉토리 내에 shared_prefs에서 perf.xml 파일에 접근하여 해당 정보를 가져오며, PreodicService​RegDPMActivity​를 각각 인텐트로 Service와 Activity 형태로 실행하게 된다.


 

http://goncp.ucmkb.net/ DNS 주소를 확인할 수 있다.

 

 

다음으로 Intent를 이용하여 Service로 등록시킨 PreodicService​를 분석해보면, 해당기기의 전화번호를 http 프로토콜의 파라메타 형태로 전송한다.

 

 

RegDPMActivity​ 경우, Intent를 이용하여 Activity 형태로 실행시키며 앱이 실행되면 기기 관리자 정보를 요구한다.

 

 

 

 

다음으로 Receiver로 등록된 CallStateReceiverSMSBroadcastReceiver​의 경우, 기기의 상태를 체크하여 해당 기기의 정보를 탈취하려는 의도를 확인할 수 있다.

 

 

 

 

3. 네트워크 동적 분석

다음으로 Tcpdump를 이용하여, 해당 악성 앱을 동작시켜 실제 유출지로 기기의 정보를 전송하는지 분석한다.

안드로이드 환경에서의 Tcpdump 사용 방법은 이전 포스팅에서 설명하였다.

안드로이드 환경에서의 Tcpdump 사용 방법 : 2017/05/03 - [Android] - 안드로이드 환경에서의 Tcpdump 사용 방법

 

해당 기기에서 악성 앱을 동작시키고 덤프 받은 pcap 파일을 분석하면 다음과 같이 기기의 정보를 전송하는 것을 확인할 수 있다.

 

 

또한, 유출 도메인을 nslookup 명령어를 실행하여 해당 DNS 정보를 조회할 수 있는데, 이를 조회할 경우 다음과 같은 IP를 확인할 수 있다.

 

 

해당 IP를 whois를 이용하여 유출 국가를 확인할 수 있는데, 다음과 같이 홍콩으로 해당 정보가 유출되는 것을 확인할 수 있다.

 

 

 

 

4. 악성 앱 제거 방법

해당 앱을 삭제하기 위해서는 다음과 같이 기기 관리자 정보에서 기기 관리자 권한을 해제한 후, 제거가 가능하다.

 

 

 

 

 

 

흔히 구글 플레이와 같은 공식 스토어에서 제공하는 앱 스토어 이외의 유료 앱의 경우 사용자가 이에 대한 금액을 지불하지 않고, 블랙마켓과 같은 사이트에서 무료로 제공하는 앱들을 받아서 사용하는 경우가 많다.

 

기본적으로 안드로이드 앱의 구성요소는 iOS에 비해 단순하며(DRM, 암호화, 인증 등등), iOS 탈옥처럼 안드로이드에서는 루팅 절차를 거치지 않고 USB 디버깅 모드를 통하여 콘솔로 apk 파일을 설치하고 지우는것이 가능하다.

 

그래서 유료 앱을 결제하여 설치를 하더라도 해당 앱을 다운 받은 기기에서 apk 추출이 손쉽게 가능하며, 이를 이용해서 유료 앱을 블랙마켓과 같은 스토어 사이트나 커뮤니티 사이트에서 재 업로드 하여 무료로 배포하는 사이트들이 무수히 많이 성행하고 있다.

 

단순히 무료로 사용하기 위해 이와 같은 방법을 사용하여 앱을 사용함에 있어서 도덕적인 문제의 소지는 있을수도 있겠으나 정상적인 원본 앱이라면 사용자에게 미치는 영향은 없다고 무방하다.

 

하지만 안드로이드 앱의 특성상 앱의 위/변조가 손쉬우며, 이와 같이 안드로이드의 개방성과 앱의 위/변조의 쉬운점으로 인해 사용자에게 일반 유료 앱을 위/변조하여 악의적인 행위를 수행한 리패키징 앱을 제공할 가능성도 존재하게 된다.


이번 글에서는 이와 같은 리패키징앱에 대한 위험성과 발생할 수 있는 가능성에 대한 내용을 설명하고자 한다.

 

앞서 설명한 포스팅 글처럼(2017/05/02 - [Analysis/Android] - Apktool을 이용한 안드로이드 apk 파일 디컴파일 및 리패키징) apk는 디컴파일 및 리패키징을 위한 방법을 설명하며, 그 절차가 까다롭지 않다.


다음과 같이, 리패키징 과정을 거쳐 보여줄 예시의 샘플 앱을 선정하였다. 일단, 심플하면서도 변조하기 손쉬울 앱으로 선정하였기 때문에 설명할 내용은 간단하겠지만, 그 위험성에 대한 잠재력은 방대한 응용에 있다고 보여진다.


다음의 앱은 구글 플레이 스토어에서 무료로 설치할 수 있는 안드로이드용 메모장 앱이다.
 

Notepad for Android : https://play.google.com/store/apps/details?id=com.blogspot.logpedia.note2

 

다음과 같은 앱은 말그대로 단순히 메모장 기능만 제공하며, 기입한 내용들을 단순 저장하는 방식으로 동작한다.

 

 

이번 포스팅에서는 이 메모장 앱을 디컴파일하여 해당 앱에서 저장되는 시점에 Log.e() API를 호출하고 Eclipse에서 사용자에 의해 저장되는 문자를 Logcat으로 출력하도록 변조하는 과정에 대해 설명할 것이다.

 

먼저, 안드로이드용 메모장 앱을 디컴파일 도구를 이용하여 소스를 분석한다.

 

 

다음과 같이 저장하는 시점은 onPause()가 수행될 때인 것을 확인할 수 있다. 또한 이 변수는 최종적으로 String을 Byte형으로 변형하여 저장한다. 따라서, 이 시점 사이에 Log.e() API를 호출하는 기능을 넣어 editText1에 있는 문자열을 Logcat으로 찍을 수 있는 기능을 추가해야 할 것이다.

 

앞서 설명한 Logcat으로 문자열을 찍어낼 수 있는 기능을 추가하기 위해서는 Log.e()을 호출하는 Smali 코드를 얻어야 할 것이다.
Log.e()의 Smali 코드를 얻기 위해 간단한 Project를 생성하여 Log.e() API를 호출하는 코드를 추가하고 이를 컴파일한 후, 다시 디컴파일을 하여 Smali 코드를 얻어 낸다.

 

 

다음으로, 안드로이드용 메모장 앱을 디컴파일하여 Smali 코드를 분석한다. 실제 원본코드와 비교해 보면, 다음과 같이 Smali 코드가 흘러 가는 것을 확인할 수 있다. 또한, 여기서 사용자가 작성한 내용에 대한 내용을 담는 변수는 v1이라는 것이 유추 가능하다.

 

 

다음과 같이 디컴파일된 이 2개의 Smali 코드를 적절히 버무려서 저장하는 시점에 Log.e() API를 호출하도록 기능을 수정한다.

v1 변수는 이미 메모장 앱에서 사용자가 입력한 내용을 저장하기 위한 용도로 사용 중이다. 따라서 변수명을 변경해주고, Byte를 String형으로 바꿔주는 부분에서는 이 v1을 삽입하여 사용자가 입력한 내용의 Byte 변수가 String형으로 변환하는 흐름을 타도록 한다.

 

 

수정이 완료되면 이를 저장하여 다시 리패키징을 진행한다. 그리고 리패키징된 apk를 디컴파일 도구를 이용하여 제대로 소스코드가 삽입되었는지 확인한다.

 

 

이제 리패키징된 apk를 설치하여 실제 Eclipse환경에서 사용자가 입력하고 저장되는 내용이 Logcat에 정상적으로 Log가 남겨지는지 확인해본다.

 

 

 

다음과 같이 정상적으로 Log가 찍힌것을 확인할 수 있다.


지금까지 Smali 코드 수정으로 리패키징을 통해 간단히 보여준 사례 예시는 다른 방법으로도 응용이 가능하다. 예를 들어 Log.e() API를 호출하는 지점에 E-mali이나 특정 서버에 해당 메시지를 전송하게 한 Class를 생성하고 호출 하는 코드를 삽입하여, 리패키징된 앱을 배포를 한다면 그에 따른 정보는 고스란히 넘어가게 될 것이다. 따라서 이러한 리패키징 앱에 대한 위험성을 염두하고 있어야 하며 앱 사용시 각별히 주의를 해야할 것이다.

Android의 앱은 apk이라는 파일로 되어 있으며 이것은 압축형태로 되어 있다.

apk를 압축 프로그램으로 열어보면 크게 AndroidManifest.xml, resources.arsc, classes.dex의 정보에 의해 앱이 실행되며, 때에 따라서는 Asset, lib 폴더도 존재하여 ndk를 이용한 Native Code나, Java Library, 그 밖의 리소스와 같은 부가적인 사용이 가능하다.

 

 


이 중, 가장 핵심적인 소스코드의 정보는 classes.dex 파일에 담겨져 있다.

이번 글에서는 apktool를 이용하여 apk를 디컴파일하고, 디컴파일된 Smali 코드와 실제 Java 코드를 간략하게 비교를 한다.
그리고 다시 apk로 리패키징하는 방법에 대해 간략히 설명한다.

 

apktool을 다운받는 URL은 다음과 같다.

APKTool : http://ibotpeaches.github.io/Apktool/

 

apktool은 Java기반으로 만들어졌으며, jar 형태로 배포하고 있다.

apktool를 이용하여 test.apk를 디컴파일을 수행하면 아래와 같은 절차를 따라 디컴파일이 수행된다.
명령어는 다음과 같다.

$ java -jar apktool_2.0.3.jar d 디컴파일할 앱.apk 


 


아래는 apk 파일을 apktool을 이용하여 디컴파일 후 생성되는 파일들이다. 이 중 smali 폴더가 생성된 것을 확인할 수 있는데 이는 classes.dex를 디스어셈블링한 결과의 파일들이며 Android 환경에서 Java 기반의 소스코드가 dalvik 가상 머신 환경에서 동작하기 위한 코드이며, 마치 형태가 C언어 기반의 Assembly와 비슷한 형태의 코드를 얻을 수 있다.

 

 


smali 폴더 내부로 들어가면 class 단위의 smali 코드로 된 파일들을 확인할 수 있으며, 이를 열어보면 다음과 같은 형태의 코드가 존재한다. C언어 기반의 Assembly 코드보다 가독성은 좋지만 기존의 Java 코드와는 동떨어진 코드 형태를 보여준다.

 

 


Smali 코드와 원본 Java 코드를 비교한 그림이 아래에 있다. 일반 Java 코드에 비해 Smali는 그 양이 많은 것을 알 수 있다. 또한, 이 Smali 코드를 이용하여 수정하는 것이 가능하며, 이는 기존의 원본 apk의 기능을 사용자의 목적에 맞게 조작이 가능하다는 것을 의미한다.

 



리패키징 방법은 아래와 같다.

 $ java -jar apktool_2.0.3.jar b 디컴파일한 apk 폴더 Path -o 리패키징할 파일 이름.apk

 

 

리패키징이 완료되고 파일이 생성되었지만, 해당 파일을 서명없이 바로 설치를 하게 되면, 다음과 같은 에러 메시지와 함께 패키지 설치가 실패된다.

 

 

signapk.jar 를 이용하여 리패키징 앱을 Test키로 서명하자. signapk.jar는 아래의 URL에서 다운 받을 수 있다.
signapk : https://github.com/appium/sign

 

서명 방법은 아래와 같다.

 - java -jar signapk.jar 서명키.pem 서명키.pk8 리패키징.apk 서명된 리패키징 이름.apk

 

 


다음과 같이 서명 절차를 거치면 해당 앱이 정상적으로 기기에 설치되며, 앱 실행시 문제 없이 동작하는 것을 확인할 수 있다.

 

 


마지막으로 원본 앱과 Test키를 이용한 리패키징 앱에 대한 서명을 비교하여 서명 값이 변경된 것을 확인할 수 있는 방법을 소개한다.
해당 파일은 설치된 jdk의 bin 폴더에 존재하며, 앱의 서명 정보를 보는 명령어는 아래와 같다.

$ jarsigner -verbose -verify -certs 앱.apk

 

  - 리패키징 전, 서명 값

 


 

  - 리패키징 후, 서명 값

 

 


원본의 서명 키를 원본 앱을 만든 개발자에게서 구하지 않는 이상 동일한 키를 이용하여 리패키징 된 앱을 서명할 수는 없을 것이며, 따라서 원본 앱과 리패키징 앱을 구분 시, 다음과 같이 서명 값을 확인해서 비교하는 방법으로도 앱의 리패키지 여부를 알 수 있는 방법이 된다.

 

 

기본적으로 Manifest, Resource, Certificate, Assembly, Decompiled Java, Strings, Constants, Notes 기능을 제공하며, 자체적으로 만든 dex 디컴파일 엔진을 이용해서인지, 일부 dex파일에 대한 바이너리 난독화에서도 에러 없이 디컴파일이 된다.

파이썬을 응용한 다양한 난독화 플러그인을 지원한다.

 

 

 

 

 

 

 

 

JEB Decompiler : https://www.pnfsoftware.com

 

 

 

안드로이드 apk 분석을 위한 무료 디컴파일 도구 중에 가장 막강한 기능을 제공한다.

기본 지원하는 파일 포맷은 jar, class, apk, dex 이며, 다양한 디컴파일러의 결과에 대한 비교 분석이 가능하다.


다음과 같이 여러 종류의 Decompiler 및 Smalicode, Bytecode, Hexcode Viewer 기능을 제공하며, 분할 창을 이용하여 서로 다른 디컴파일 결과나 Java 소스코드와 Smali 소스코드의 비교도 가능하다.


 

스트링 난독화에 대한 복호화 및 다양한 플러그인 기능

 

 

코드 흐름에 대한 시퀀스 다이어그램 기능

 

 

BytecodeViewer : https://github.com/konloch/bytecode-viewer/releases

 

 

안드로이드 apk 분석 디컴파일러인 jadx-gui 디컴파일러는 기존 jd-gui의 불편한 점(dex2jar를 이용한 dex→jar 변환)을 개선하여, dex2jar 도구의 없이도 apk 디컴파일이 가능하다.

또한, 소스코드 뿐만 아니라 리소스 부분도 확인이 가능하도록 기능을 확장하였다.

 

jadx-gui : https://github.com/skylot/jadx/releases

 

안드로이드 앱은 Java 언어 기반으로 프로그래밍되며, 작성된 소스는 Dalvik 가상 머신 기반에 동작하도록 컴파일 된다.

즉, jd-gul 도구에서 apk 앱을 분석을 하기전에 apk 내부의 dex 파일을 dex2jar 도구를 이용하여 class 파일로 전환하기만 한다면, Java 처럼 원본 코드와 흡사한 디컴파일이 가능하기 때문에 분석에 용이하다.

 

 

아래 그림에서 왼쪽은 Eclipse를 이용한 실제 원본코드이고, 오른쪽은 dex2jar와 dj-gui를 이용하여 디컴파일한 결과를 보여주는 코드이다.

 

 

dex2jar : https://github.com/pxb1988/dex2jar

jd-gui : http://jd.benow.ca

 

 

안드로이드의 앱은 기본적으로 .apk라는 파일 확장자 명을 가진다. 하지만, 사실상 이 파일의 Magic Number을 보면 다음과 같이 zip 형태의 파일 포맷을 가지는 것을 확인할 수 있다.

 

 

apk 파일의 압축을 해제하면 아래와 같은 구조를 확인할 수 있는데, 간단하게 3가지로 구분된다.

 

 

 

1. AndroidManifest.xml

  - 안드로이드 앱의 속성들을 주로 다루게 되는데 Activity, Service, Receiver, Persmission 등의 속성은 이 파일에서 정의된다. apk 파일을 단순히 압축을 해제 하였을 때 AndroidManifest.xml은 바이너리 형태의 xml로 인코딩 되어 형태를 알아보기 어렵지만, 이를 apktool과 같은 디컴파일러를 통하여 확인하면 디코딩된 xml 정보를 얻을 수 있다. 아래의 그림은 AndroidManifest.xml에 대해 디컴파일 전과 후의 xml 파일에 대한 정보를 비교한 그림이다.

 

 

 

2. Resource

  - 안드로이드의 Image, Style 등과 같은 정보는 Resource에서 관리하게 된다. 이것 또한 Apktool을 통하여 확인 가능하다.

 

 

 

3. DEX (Dalvik EXecutable)

  - Dex는 안드로이드에서 앱이 구동하기 위한 핵심적인 파일 포맷이다. dex 포맷형식에 대한 내용은 차후 포스팅에서 자세히 다루도록 하겠다. dex의 포맷형식에 대한 문서는 Android Source 사이트에 있으며 주소는 다음과 같다.

Dex Format : https://source.android.com/devices/tech/dalvik/dex-format.html


 

+ Recent posts