패스트터틀

안드로이드 Malware 분석 (19.5.15) 본문

Cyber Security(undergraduate)/mobile security

안드로이드 Malware 분석 (19.5.15)

SudekY 2019. 5. 15. 16:39

Android APK Overview

 

안드로이드는 윈도우즈와 다르게 APK라는 파일 묶음으로 되어있고

- DEX(Dalvik Executable) : 달빅 코드

- .so(Naitve Library) : 네이티브 코드

(안드로이드 이전에 만들었던 라이브러리는 c로만든것이 많았는데 그런것들을 잘 활용하고 싶어서 자바에서 기본적으로 c에 있는것들을 호출할수있게끔 하는 형식인데 이런거랑 비슷)
- AndroidManifest.xml : App metadata, Service, Activity

(권한)

 

DEX

 

Dalvik VM에서 실행되는 Bytecode

명시적인 class, Method 형태

명시적인 Method별 코드구역

Easier to Decompile( vs native)

(자바만의 특징 : Decompile = 우리가 어떤 실행코드를 분석한다고 할때 Assembly로 바꾼다라고 하면 disa셈블리 라고하는데 , 어셈블리형태는아니지만 소스수준으로 올라가는것이라고 생각하면됨,

윈도우즈용 악성코드는 인텔 cpu의 어셈블리로 표현되기 때문에 쉽지만 c언어로 바꾸는건 어려움 => IDS가 개발)

 

 

.so library Overview

 

안드로이드 같은 경우는 안에 들어가는 os가 리눅스로 되어있기 때문에 ELF파일 포멧을 쓰고있다.

자바에서 c로만들어진 코드를 호출할때 규약

 

자바는 native로 함수를 선언하면 자바가 실행할때 자바쪽에서 함수를 찾는것이 아니고 SO쪽에서 찾음

 

AndroidManifest.xml

 

앱 권한, Activity 목록 및 Intent-filter, Service 목록 및 Intent-filter

Intent는 머나햐면은 우리가 프로그램 , A라는 프로그램 B라는 프로그램... IOS가 더 잘되어있긴하지만... 서로 영역에 침범할수없는데 필요에 따라서 그런일을 해야함 그런일을 하는것이 Intent임

예를들어 주소록을 알려달라고할때 Intent로 통신하는것임, 서로다른 프로그램간,서비스간에 Intent를 주고받음

자기 프로그램내에서도 Intent를 주고받을수있음

 

그래서 뭐 인텐트 모습을 보면은

요딴식으로 되어있다.

ART, Dalvik, Native 

 

Native에 정의된 Method는 JNI를 통하여 호출

 

자바가 여러 os 구분안하고 실행될수있는 이유는 각자의 os에서 자바 VM을 지원하기때문에

안드로이드에서도 이 VM을 Dalvik이라고 정의하고 제공하는것임

기존에는 자바를 그대로 실행했다면 아트는 자바를 C로 바꾸고 실행하는형태로 바꿈

(홍보 차원에서는 속도가 빨라질거라고 했음)

그런데 c같은경우는 메모리를 alloc할때는 개발자가 스스로 정의하지만 최근에는 언어가 스스로 메모리를 스스로 할당 했는데... 불라불라 머라는지 모르겠고

여하튼 

 

Standard libraries는 기본적인 라이브러리

 

 

Static Analysis

 

분석가가 하는것은 소스코드가 있는것이 아닌 바이너리만 있는것임

그래서 이런 리버싱(이런거를 리버싱이라고함)을 하는것이 중요하다고 함

실제로 악성코드를 분석하는 과정은 정적,행위,동적분석등 크게 나누어지는데

정적분석 = 바이너리를 실행하지않고 분석하는것,

동적분석 = 실행을 해서 나온결과를 가지고 분석하는것을 의미,

행위분석 = 동적과 정적사이에 위치해서 동적분석이긴 한데 어떤 행위를 하는지 빨리 알고싶을때 그런 정보를 빨리 알고싶을때 행위분석이라고 함

 

우리가 어떤 프로그램이 있는데 아무것도 모르고 분석할려고 하면 매우매우 (디버거를 사용한다는것자체가 하나하나하나 나아가야하는게 굉장히 오래걸림)

그런데 만약에 어떤 프로그램이 어떤 파일을 접근한다는사실을 알았을때 이 파일에 콘피그가있나 지우려고하나? 이런것들을 breakpoint걸고 하면은 쉽게 할수있음

 

동적분석 정적분석을 왜하느냐라고 물어본다면 

정적 = 코드전체를 봐서 힘듦, 머리가 아픔, 추측해야함 // 동적은 = 실행을 해야함, 실행이 되는것만 분석을 할수있음

그렇기때문에 정적,분석,행위분석 다해야함

우선 행위분석을 하는것을 보고 (대충여기서 보면 머하는지 알음), 그리고 동적, 정적으로 진행함

그러면 여기서 부족한것은 정적 또 부족한것을 동적으로 서로를 왔다갔다하면서 필요한것을 꺼내서 사용하면서

분석하면됨

 

일단 가장 기본이 되는것을 정적분석이 됨

 

안드로이드 정적분석에 필요한것

 

Dalvik Instructons , Dalvik Registers, Calss & Method Signatures, Java

 

자바나 c나 c++이나 파이썬 이나 c#이나 f#이나 굉장히 많은 언어들이 있는데

생각하기에는 그중에 하나의 언어를 알면은 다른언어를 공부하는것은 어렵지 않다고 볼수있다.

언어는 우리가 실제 생활에서도 한국말이 있고 중국말이있고 그런것들처럼 언어는 내 생각을 표현하는수단

내 생각을 한국말로 표현할수있으면 영어로도 표현할수있다. 물론 이것보다 복잡한것이긴 하지만

컴퓨터 언어도 기본적인 문법만 알면은 개념적인것만 알면은 언어로 표현만 할수있는것임

그래서 이언어 공부 저언어 공부하는것은 큰관점에서는 그렇게 의미가 있다고는 말할수없음 ... 

 

Dalvik Instructions

 

기본적으로 Move Instructions가 있어서 얘는 메모리혹은 레지스터에서 이쪽으로 옮기는것을말함

Return Instructions는 리턴하는구나

Move Return value Instructions는 자바 VM에 특징인데 함수를 만들면 그 결과가 있는데 그 결과를 항상 어디에 저장해놓고 그니까 함수를 호출한 본체쪽에 저장해놓는?? ... 뭐지?

Const Instructions 리스트에 값을 넣을때?,

 

Read & Write Instructions 

메모리에서 put 쓰는것 get 가져오는것

Control flow instructions

이것을 절로가고 저것은 저기로가고 예를들어 goto같은것?

Call Method

Invoke라는것을 통해서 호출을 하게되고 그뒤에 virtual(논 static), dircet( private,) ....기타등등 나중에 해보면서 알게됨

 

Dalvik Register(smali syntax)

누군가가 smali 를 만든것임 (실제로 이런식으로 되어있는것은 아님) 

 

Parameter Register (파라미터)

- p0(this), p1, p2 

(this는 자기자신을 객체의 일부분으로 취급하는것을 뜻함, 자바 해보면은 알음, 일단 나는 알음, 그니까 내 자신의 객체의 메모리를 뜻하는것임, 그니까 내가 나를 가르키는것임, 손꾸락으로 나를 가르키는것으로 표현하는 수단이 this임)

Local Register (변수)
– v0, v1, v2, …
Instance Method의 Register Table Example 
– Parameter가 3개, Local Register 3개

Static Method의 Register Table Example
– Parameter가 2개, Local Register 1개

 

Class Signature

우리가 개발할때 class를 만들떄 상속하고 상속해서 여러가지것들을 선언하는데

어셈블리에서는 이런것들을 계층적으로 상속할수없는데 이런것들의 심볼을 가지고있는 Signature라고 생각하면됨

Lcom/example/myapp/Myclass(이런식으로 슬래쉬(/),점(.)으로 경우에따라서 달라짐 , 따옴표(;)까지가 클래스를 의미함)

 

StringBuilder sb = new stringbuilder("str")

만약에 이런식으로 개발자가 작성했다고하면은

 

Smali에서는 아래와같이 바꿔줌

 

new-instance v1, Ljava/lang/StringBuilder;
const-string v2, “str”
invoke-direct {v1, v2}, Ljava/lang/StringBuilder;->(Ljava/lang/String;)V

 

자바를 했을때 위와같은 상속과 같이 보이지만 사실 내부적으로 보면은 두번호출하는것임

 

 

Method Signature

 

메소드는(아래는 smali를 표현한것)

.method (메소드를 표현하기위한 지시사) protected onCreate(Landroid/os/Bundle;)V

.locals 1

.param p1, "saved"savedInstanceState" # Landroid/os/Bundle;

 

.locals 숫자 : 메소드에서 사용된 로컬 변수 개수
– 로컬 변수 이름은 v0, v1 과 같이 사용됨

.param p숫자 : 메소드 파라미터
– p0는 this(메소드의 객체)를 의미함(p1부터 사용함)

 

Method 호출

 

invoke-direct {파라미터 값} method_name(파라미터 타입)
return_type

– invoke-direct: 해당 메소드를 그대로 호출
– invoke-super: 부모 메소드 호출 (얘가 상속이 되었을경우)
– invoke-virtual: 동적 연결, 객체의 메소드 호출
객체 생성
– new-instance: 새로운 객체 생성 
바로 이어서 을 호출함, 은 constructor
– const-string: 상수 문자열 선언

 

Class & Method Signature

 

객체일경우에는 

primitive파일이라고 해서 개발자에의해서 정의된것이 아닌 내부적으로 가진 파일이기 때문에

 

 

 

SMALI 010

 

어떤 사람이 만들었다고 얘기했는데 이것은 APKTool과 AndroGuard등 다양한 도구들이 사용함

APK또는 DEX를 넣으면 SMALI로 싹 뽑아서 만들어줌

 

Main에 printf Hell world찍는 기본적인것

 

위의 형태

apktool

 

https://bitbucket.org/iBotPeaches/apktool/downloads/

 

iBotPeaches / Apktool / Downloads — Bitbucket

 

bitbucket.org

apktool 은 여기서 다운로드

https://drive.google.com/open?id=1Ef4yDUd5HW2dqKS9IAfqflkxgQvugijT

 

교육자료.zip

 

drive.google.com

 

 

 

 

 

 

apktool압축해제(왼쪽), 단순 zip변환(오른쪽)

 

Java에 있는것을 dex로 바꾸고 자바로 보는 귀찮을것을

 

bytecode는 이것을 간편하게 바꾸는것임

 

 

 

samli로 바뀐것
smali랑 bytecode분석

 

 

Where to analyze 분석을 어디에서 시작을 할것인가

 

Entry Points(진입점) - Activity Life Cycle 

 

어떤 엑티비티가 뜨면 러닝을 하다가 Pause가 된다던지 Destory가 된다던지 이럴수있고 그러다가 다시 러닝상태로 오거나 그런식으로 되어있음

 

Entry Points - Service LIfe Cycle

 

서비스도 마찬가지로 

 

– onCreate
– onStartCommand
– onBind
– onHandleIntent
– …

 

요런식으로 위와 비슷하기는한데 

 

이것을 SMALI코드로 보면은

이런식인데 

 

Android Studio(Crackme1.apk 파일 해독)

 

 

 

 

이 Crackme1.apk 파일의 Free Version을 Bytecode로 분석하여서 Pro Version으로 바꿔보자

 

초등학생도 가능한수준이다.

매우수준으로 변수를 코드에 직접 드러낸 멍청한 작성이다.

 

안드로이드는 Load Dex를 별도로 둘수있음

그렇게해서 예를들어서 체크가 안되면 실행안되게끔 만든것임

 

 

간다히 IF를 지워버리거나 안에 GJ를 쳐넣어버려서 그냥 확인해버릴수있음 ( 예측가능 )

 

SMALI로 실행하기 MAINACTIVITY 확인한다음에

 

 

if 문을 삭제해버림

 

그리고 이제 SMALI로 풀고 변경한파일을 다시 DEX로 만들어야됨

 

이제 빌드하는과정을 볼껀데

 

 

이런식으로 java -jar apktoo b (폴더명)

 

하면 풀리고 안에 새롭게 생긴 폴더를 보면 되어있음

그런데 서명이안되어서 설치를 할수없음 왜냐하면 인증이 안되있기 때문에 ( 리패키징여부 파악때문에 )

 

그렇기 때문에 앱의 서명이 다르다 -> "아 이노무시키 악성이구나" 라를 알수있다.

 

서명값은 APK필드안에 별도로있는데 이따가한다고함 하여튼 다른도구들로 볼수있음

 

Apksigner를 이용한 APK 재서명

 

$ jarsigner

  $ jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore
  ~/.android/debug.keystore ./sample/dist/app-debug.apk androiddebugkey
  – Password 입력
Keystore 위치는 OS 환경에 따라 다름
  – 윈도우의 경우 Users/사용자이름/.android/ 밑에 있음
안드로이드 스튜디오의 디버그용 키를 사용함
  – 디버그용 키가 아니라 새로 만들고 싶다면 keytool을 이용하면 됨
– $ keytool -genkey -v -keystore my-releasekey.keystore -alias
    alias_name -keyalg RSA -validity 10000
    alias_name은 위에서 androiddebugkey 라는 부분에 들어가는 키 이름임
 명령줄에서 앱 서명 참조 (하단링크)


jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore
~/.android/debug.keystore ./sample/dist/app-debug.apk androiddebugkey
https://developer.android.com/studio/publish/app-signing.html?hl=ko

 

앱 서명  |  Android Developers

Android는 모든 APK를 설치하기 전에 인증서로 디지털 서명을 하도록 요구합니다. 또한 Android 앱 번들을 Play Console에 업로드하기 전에 서명부터 해야 합니다. 이 문서에서는 인증서 생성 및 저장, 각각 다른 인증서를 사용한 여러 빌드 구성 서명, APK에 자동으로 서명하도록 빌드 프로세스 구성 등, Android Studio를 사용하여 APK나 앱 번들에 서명하는 방법에 대해 설명합니다. 인증서 및 키스토어 디지털 인증서 또는 ID

developer.android.com

 

 

android studio - build - Generate불라불라~~ - 아래 APK 선택 - create new...  - 폴더선택후 아무거나 대충 입력후

 

 

여기까지만 해서 jks파일을 생성하면됨 NEXT 누르는거아님

후에 apksinger( apk 싸이너 ) 로 할수있는데 이것은 

 

C:\Users\[이름]\AppData\Local\Android\Sdk\build-tools\[version]> (sdk 파일경로에서)

 

요기에있음

 

그리고나서 해당경로에서 CMD 후

 

Apksigner sign –ks (test.jks) (test.apk) 

 

를하면 우리가만든 test.jks(안드로이드스튜디오에서 만든)에다가 test.apk(기존꺼)

 

이유는 키가 다르니까 머가 맞는지 모르니까 UNINSTALL(기존파일)하고 해야됨 

 

이렇게하면 되야되는데 안됬음 ㄷㄷ ㅜㅜ ( 되긴 된다고함 )

 

지금까지 한 툴들은 전부 무료임(근데 막 귀찮음)

 

유료툴로는 jeb android 라고 있음

 

https://www.pnfsoftware.com/

 

JEB Decompiler by PNF Software

 

www.pnfsoftware.com

 

이거 trial version으로 실행시켜서

 

 

서명한파일을 실행시켜보면은 이런식으로 분석을 할수있음

 

앱 역공학/코드 삽입 과정

 

APK 압축 풀기
classes.dex 역어셈블 (apktool) -> .smali 코드 [lab01]
코드 분석/삽입 [lab02]
다시 어셈블하여 classes.dex 생성 [lab03]
APK 압축/서명 [lab04]

 

DEX Decompile

 

-Object 파일이된 코드를 소스코드로 복원하는 기법

 

흐름

DEX Decompile은 x86, arm 등 PE/ELF파일의 디컴파일보다 쉬움

왜냐면 은 

DEX는 모든 Class, Method의 이름과 영역이 명시적으로 구분됨
기본적인 컴파일시 생략되는 정보가 적음

이고 하지만 완벽한 Decompile은 어려움

 

Limitation(한계성)

컴파일후 생략되는 정보가 여전히 존재하기 때문에, Bytecode로 실행카능 코드가 여전히 java가 지원하지 않는 경우가 존재함 

 

그리고 IDA등 디컴파일러들에 의해서 악성코드가 이런 도구들의 존재를 알기때문에 이런 IDA에 해석 불가능하게 (까지는아니지만) 하는 기법들이 존재하고 개발되고있는 실정임

 

JEB

 

- DE– “Commercial” Android 분석 도구
- DEX, Native 등 Anroid APK 분석을 위한 대부분의 기능제공

 

Decompile DEX using JEB

 

JEB 실행
– jeb_wincon.bat
Sharif_ctf.apk 파일 연후 Decompile 클릭

 

 

JEB를 모르면 어플리케이션 분석 ㄴㄴ할줄 하는놈 판단가능 (무조건 알아야됨 잘하진 못해도)

 

무료라서 다 안보여줌

 

VirusClicker.apk => 10000번을 클릭하면 넘어가는 apk ( 바이러스 생성과정 = 1만번의 비유 )

 

이거를 보면은 분석하기에 조금어렵기는하지만 

 

c엑티비티 보면은터치이벤트를 받아서 

 

이거를 어찌어찌해서 고치면은 고쳐진다는 그러한 것? 이라고 함(Touch부분고쳤음)

 

Dynamic Analysis(동적분석)

 

Android App Debugging for DEX

 

동적분석은 앱을 실행을 하면서 하는것임

그러면 디버깅은 Breakpoint걸고 분석을 하는것인데 안드로이드에서는 어떻게 할것이냐고 물어보면

source(.so)와 dex를 dex는 디셈블러하고 

pc는 디버깅할때 브레이크포인터를 걸때 인터럽트걸고 그냥 주면되는데 안드로이드에서는 이렇게하면 종료되기때문에

이벤트로 취급해서 이벤트에 넣어서 바꿀수있게 해줌

 

디버깅을 하기 위해서는 안드로이드 스튜디오에서 할수있게 누군가(천재) 플러깅(plugging)을 만들음

그래서 안드로이드 스튜디오에 플러그인을 설치해서 할꺼임

 

아래는 설치링크

 

https://bitbucket.org/JesusFreke/smali/downloads/smalidea-0.05.zip

불러오는 중입니다...

설치후에 File>Settings>Plugins>Install plugin from disk(Settings 창 내 오른쪽 상단 설정 아이콘)

후에 RESTART하면됨

이제 브레이크포인트걸고 어떻게 나오나 확인해보는 과정을 해볼꺼임

lab06에 Android_Crackme2_teamURET.apk 를 넣어보면 Licenced가 있지 않아 켜지지않을꺼임 

 

이젠 디버거가 붙을때까지 해줘야함 이제 휴대폰정보에서 정보 클릭몇번(개발자모드 ON하라는소리)

 

하면 개발자모드에서

 

 

이제 Android Studio
– File > Profile or Debug APK
– Android_Crackme2_TeamURET.apk 선택

 

 

 

Android Studio
– Set Breakpoints, Stepping

 

하라고하는데 이해는 잘안감 디버거상태에서 무엇을 어떻게 확인하는지는 잘모르겠다

 

crackme1 hackplayers.apk 파일의 로그인 비밀번호를 뚫어보자

 

우선 정적분석으로 분석해보니

 

 

입력을 두개를 받으니 ID랑 PW를 입력받는데

아이디는 admin3 면 되고 var3는 PB.. 어쩌구 있는데 컨버트 함수를 통해서 var3를 얻는다는것임

여기서 할수있는 방법은 var3를 우리가 디버거로 확인하면 쉽다는것임(결과값을)

 

(여기서부터 환경설정의 문제로 불가했음)

그래서 브레이크포인트 걸고서 실행을하면 v1에 값이 들어가있어서 컨버터한값을 획득할수있다고함

 

아니면 리패키징을 통해서 var3를 볼수있다고 함

Log cat이라는 log를 뿌려주는 그런 데몬같은것이 있는데 안드로이드가 d라는 함수를 불르고 원하는값을 넣어주면

"zzzzzzzz..." 해서 로그켓을 통해서 확인을 할수있다고함 (???)

 

그러니까 v1을 들어가게 해서 string값을 찍게 해서 log쪽에 찍게해서 볼수있다고 함(꼭 디버거일 필요 ㄴㄴ함)

 

여하튼 이렇게 하면은 EASY하게 느껴질수있지만 우리가 정적으로 본 DEX파일과 실제로 메모리상에 있는 DEX는 다를수있음

 

 

 

DEX파일을 로딩하면 코드가 아무것도없음 (빈코드로 보이는것)

제일 앞에 덱스파일 구조를 설명했지만 실제로 인덱스를 코드인덱스를 DEX파일에서는 깨트려냄 

코드 인덱스가 다르니까 눈으로 실제로 본 함수는 이거지만 실행할때 테이블의 인덱스를 다른곳에 가게끔할수있음

그러니까 실행시에는 다를수있음

메소드가 무엇이 있는지 안보이게 할수도 있고

 

Proguard

 

Android SDK에 기본적으로 포함된 난독화 도구

그리고 우리는 에뮬레이터 실행했지만 악성코드들은 디버깅, 에뮬, 변조탐지,환경탐지해서 분석 불가능하게 할수있음

 

 

CTF04는 시간상 관계로 설명으로하면은

 

루팅탐지와 Uncrackable 이여서 실행불가능하다고 뜨는데

BytecodeViewable에서 보면은 Oncreate할때 디버거확인 DEX를 빌드할때

또한 해쉬값 저장해놓고 DEX해쉬값이 바뀌어지면 실행 불가능하게 할수있음(물론 이것도 확인못해놓게 빼어놓으면 못하게 할수있음)

이밖에 슈퍼유저 디바이스정보 수상한 것들은 죄다 if문으로 걸어놓아서 악성코드의 분석을 방지할수 있게 만들어놓는

싸가지없는 악성코드들이다.

Comments