이번 글부터 진행하는 InjuredAndroid APK는 CTF 형식을 통해 버그 바운티, 안드로이드 취약점에 대한 공부에 도움을 줄 수 있도록 제작된 애플리케이션이다.
해당 앱은 github, Google Play에서 확인할 수 있다.
사전 준비
APK 설치
가장 먼저 애플리케이션 설치부터 진행한다.
설치는 github를 통해 다운로드하여 진행할 수 있지만 가장 쉬운 Google Play에서 다운을 받아 진행한다.
디컴파일
다운로드가 끝났다면 분석을 진행할 수 있도록 해당 애플리케이션을 분석 환경으로 가져와야 하는데 이를 위해서 먼저 해당 애플리케이션의 설치 경로를 알아내야 할 필요가 있다.
이는 안드로이드에서 사용 가능한 pm 명령어를 이용하여 알아낼 수 있다.
- pm list packages -f | grep "injured"
- lsit packages : 패키지 목록을 출력할 때 사용한다.
- -f : 패키지명과 연관된 애플리케이션 파일 경로를 보여준다.
경로를 알아내었다면 adb의 pull 명령어를 사용하여 애플리케이션을 가져온다.
- adb pull "/data/app/b3nac.injuredandroid-DmAWFt_h2YLScauxbhrQJA==/base.apk"
애플리케이션을 가져온 후 APK Easy Tool을 실행하여 다음 그림과 같이 디컴파일을 진행한다.
정상적으로 디컴파일이 끝났다면 다음과 같이 디컴파일된 파일이 저장된 폴더를 확인할 수 있다.
분석/변조
MainActivity 분석
smali변조를 위해 가장 먼저 호출되는 MainActivity에서 호출하는 함수를 확인한다.
이를 위해 jadx를 통해 추출된 어플리케이션을 열어준다.
MainActivity를 찾는 방법은 간단하다 인텐트 필터의 action에 해당하는 값이 MAIN인 액티비티를 확인하면 된다.
실제 AndroidManifest.xml에서 확인해보면 다음과 같은 코드를 확인할 수 있다.
<activity android:name="b3nac.injuredandroid.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
여기서 각 코드는 다음과 같은 의미를 가지고 있다.
- activity
- android:name = 액티비티를 구현하는 클래스의 이름
- intent-filter : 액티비티, 서비스 또는 Broadcast Receiver가 응답할 수 있는 인텐트 유형을 지정
- action : 인텐트 필터에 작업을 추가하기 위해 사용(인텐트 필터에는 하나 이상의 action요소가 포함되어 있어야 한다.)
- android:name = 수행되어야 할 작업의 이름
- android.intent,action.MAIN = MainActivity의 스타트 액션을 의미
- 이외의 값은 여기서 확인할 수 있다.
- android:name = 수행되어야 할 작업의 이름
- category : 인텐트 필터에 카테고리 이름을 추가하기 위해 사용
- android:name = 카테고리 이름
- android.intent.category.LAUNCHER = 가장 먼저 실행되는 액티비티를 의미
- android:name = 카테고리 이름
- action : 인텐트 필터에 작업을 추가하기 위해 사용(인텐트 필터에는 하나 이상의 action요소가 포함되어 있어야 한다.)
MainActivity를 구현하는 클래스를 따라가면 다음과 같은 코드를 확인할 수 있다.
코드 중 onCreate함수를 확인할 수 있는데 해당 함수는 무조건 Activity가 실행될 때 가장 먼저 호출이 됨으로 기존의 목적이었던 smali변조를 해당 부분으로 진행한다.
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView((int) R.layout.activity_main);
F();
}
smali code 변조
smali코드를 변조하기 위해서는 변조할 MainActivity.smali 파일을 찾아야 한다.
해당 파일은 이전에 디컴파일한 폴더에서 "smali\b3nac\injuredandroid"를 따라 가면 확인할 수 있다.
해당 파일을 에디터를 통해 열어준 후 다음과 같이 onCreate() 코드를 수정한다.
.method public onCreate(Landroid/os/Bundle;)V
.locals 1
invoke-super {p0, p1}, Landroidx/appcompat/app/c;->onCreate(Landroid/os/Bundle;)V
const p1, 0x7f0b0031
invoke-virtual {p0, p1}, Landroidx/appcompat/app/c;->setContentView(I)V
invoke-direct {p0}, Lb3nac/injuredandroid/MainActivity;->F()V
const-string p1, "mug test"
const/4 v0, 0x1
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p0
invoke-virtual {p0}, Landroid/widget/Toast;->show()V
return-void
.end method
추가/변경한 코드는 다음과 같은 의미를 가지고 있다.
- . locals 0~15 : 해당 메서드에서 사용할 로컬 레지스터의 개수로 값이 1 이상일 경우 v0, v1, v2, ... 등의 레지스터를 사용할 수 있다.
- const-string vAA, string@BBBB : 지정된 문자열을 지정된 레지스터에 저장한다.
- const/4 vA, #+B : 제공된 값을 32bit로 확장하여 지정된 레지스터에 저장한다.
- invoke-static : static 메서드를 호출하는 데 사용한다.
- move-result-object vAA : 가장 최근 invoke-kind의 객체 결과를 지정된 레지스터에 저장한다.
- invoke-virtual : 일반 가상 메서드(private, static 또는 final도 생성자도 아닌 메서드)를 호출하는데 사용한다.
간단하게 요약하면 mug test라는 문자열 박스를 출력하는 함수를 추가해 주었다.
수정이 끝났다면 저장 후 APK Easy Tool의 Compile 기능을 사용하여 컴파일을 해준다.
컴파일이 끝난 후 Compiled APK directory를 눌러주면 다음과 같이 애플리케이션 파일을 확인할 수 있다.
마지막으로 정상적으로 변조가 되었는지 확인하기 위해 adb를 이용하여 애플리케이션을 설치해준다. (이전에 설치된 정상적인 어플리케이션을 삭제 후 진행해야 된다)
- adb install base.apk
이후 설치된 어플리케이션을 실행하면 다음과 변조된 코드가 정상적으로 실행되는 것을 확인할 수 있다.
Reference
- Activity, intent, ...
https://developer.android.com/guide/components/activities/intro-activities?hl=ko - smali 문법 (dalvik-bytecode
https://hyeonbell.tistory.com/m/1
https://source.android.com/devices/tech/dalvik/dalvik-bytecode
'Android > InjuredAndroid' 카테고리의 다른 글
FLAG FOUR - Login 2 (0) | 2021.09.21 |
---|---|
FLAG THREE - RESOURCES (0) | 2021.09.21 |
FLAG TWO - EXPORTED ACTIVITY (0) | 2021.09.21 |
FLAG ONE - Login (0) | 2021.09.21 |
XSSTEST (0) | 2021.09.13 |