7주차
앱 후킹 도구 frida 사용하여 rooting 탐지 우회하기
frida ? DBI(Dynamic Binary Instrumentation) 프레임워크(도구들의 집합)
; A -> B 함수 호출하는 시점에 어떤 코드를 실행하고 싶어..! (바이너리 실행 중에 분석, 수정함)
어디까지 탐색했는지 알아야 하니까 -> 보통 함수 사이사이에 실행 주소를 측정함
앱 실행되는 사이사이에 자바스크립트 삽입 가능
+) DBI에 대한 추가 자료
https://code13.tistory.com/267
DBI(Dynamic Binary Instrumentation) 겉핥기로 알아보기
DBI (Dynamic Binary Instrumentation) printf("test %s", buf); 등과 같이 특정 시점에서의 변수값 등을 확인하거나 프로그램의 행위를 조사하는 일을 Instrumentation 라고 부른다 바이너리 분석을 할때 각종..
code13.tistory.com
[Frida 주요 기능]
-함수 후킹? 함수를 훔쳐간다/채간다
-> 함수 실행되는 시점에 잡아가서 원하는 코드 실행/함수 재작성
-adb(애플리케이션 디버깅 가능)
-힙 메모리 내 객체 인스턴스 검색 및 사용
-실시간 트래픽 스니핑 또는 암호 해독
-탈옥/루팅 되지 않은 단말기에서도 사용 가능. (ios, 맥os에서도 가능!)
[동작 방식]
host == me (frida server랑 연결되어있는 pc)
frida server == 에뮬레이터 안에서 돌고 있는 서버!
->drozer와 유사
+) host용은 pc에 설치, 서버용은 에뮬레이터에 설치
rooting 탐지를 하려면 rooting이 된 상태에서 해야 됨!
[Frida Tools]
- frida
- frida-ps (frida에 연결된 프로세스 목록 출력)
- frida-ls-devices (연결된 디바이스 목록 출력)
- frida-trace (함수 호출 동적으로 추적)
- frida-kill (프로세스 종료)
[frida-script ]
:frida에서 제공하는 스크립트 API(javaScript, C, SWIFT API)
-> 자바스크립트로 API 재정의하거나 우리가 원하는 방향으로 수정 가능
https://frida.re/docs/javascript-api/
JavaScript API
Inject JavaScript to explore native apps on Windows, macOS, GNU/Linux, iOS, Android, and QNX
frida.re
ㄴ> javascript API
-기본 뼈대 구조
java.perform(function() { /*
...
*/
} );
-Java.use(className)
var myClass = Java.use(com.mypackage.name.class)
//앱에서 사용하는 클래스와 연동되는 myclass 정의하기
var myClassInstance = myClass.$new()
//myClass를 통해 객체 인스턴스 생성 및 정의
var result = myClassInstance.myMethod("param")
//클래스 내부에 있는 메소드에 접근 -> 인자 값을 넘겨주고 해당 결과 값을 result에 받음
myClass.myMethod.implementation = function(param) {
//앱에서 정의된 메소드의 구현 내용을 재작성
}
**메소드 재구현시 주의점**
- 입력받은 인수가 없는 메소드
- 두 개의 바이트 배열 인수로 입력받는 메소드
- context, boolean 형태의 인수로 입력받는 메소드
-> 위 세 가지 경우에는 overLoad() 사용하여 재구현 필요!!
[Frida 실습]
#환경 구축
- 루트 권한 필요
- 디컴파일 도구 (apktool, dex2jar, bytecode-viewer, jd-gui, jadx 등)
- 테스트 대상 앱 : https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk
#rooting 탐지
테스트 앱 실행 -> "root detected" : 우회해서 정상적으로 실행하는 것이 목표!
루팅? 루트 권한을 가져가는 것
[루팅 탐지 7가지]
- su 탐지 ; su 명령어의 바이너리 파일 검색을 통해 검사
- 프로세스 리스트 탐지
- 설치된 패키지 목록 탐지
- 루팅 카운트 탐지
- busybox 및 명령어 탐지 ; 안드로이드 제공 커널 이외에, 원래 adb 쉘에서 제한적인 명령어가 루팅 후에는 가능한 명령어 많음
- build.prop 파일 기본값 확인
- 폴더 권한 확인
->이러한 탐지 방법들을 우회해야 함
; 루팅을 하면 바뀌는 파일이 있고, 파일 권한이 바뀌거나, 프로세스 생성함
==> 보통 smali 코드 패치 or 후킹으로 우회. ( 이번 실습에서는 코드는 그대로 두고 후킹으로 우회)
루팅 탐지 및 우회
안드로이드 루팅의 탐지와 루팅 탐지의 우회의 가능여부에 대해 요약하면 다음과 같다. 가능하지만 절대적이지 않고, 지금은 가능하나 차후에 막힐 수 있고, 지금은 막혔으나 차후에 가능할 수
blog.kinesis.kr
#실습과정
목표 : frida 활용하여 테스트 앱 루팅 탐지 기능 우회하기
1. 환경 구동 (frida 서버 실행)
$activate py3
$adb devices
$adb shell
2. 디컴파일 & 분석
>d2j-dex2jar.bat C:\Users\yoon2\Downloads\UnCrackable-Level1.apk
분석 : 우회할 부분을 가장 빨리 알 수 있는 것 -> Root로 검색!
mainActivity에서 발견
...
protected void onCreate(Bundle paramBundle) {
if (c.a() || c.b() || c.c())
a("Root detected!");
....
=> 후킹 지점
- 메시지가 떴을 때
- ok를 눌렀을 때(가장 최종적인 부분..?)
-> System.exit(0); 부분을 재정의해서 실행하기
3. 우회 스크립트 작성
setImmdeiate(function(){ //여기서 실행
Java.perform(function() {
/*
var exit_bypass = Java.use("android.content. DialogInterface.OnClickListener")
// android onclincklinstner 검색 -> android api dialogInterface onclickListener !!
exit_bypass.onClick.implementation = function(arg1, arg2) { //인수 타입은? js는 타입정의 없어서 알아서 맞춰줌
console.log("[*] Exit bypass");
}
*/
var exit_bypass = Java.use("android.content.DialogInterface.OnClickListener");
// 인터페이스를 받아와서 사용할 수 있는 Frida API가 존재하지 않음. 따라서 System.exit(0)을 사용
// (Java.lang.System의 exit 메소드를 재작성)
exit_bypass.onClick.implementation = function(arg, arg2) {
console.log("[*] Exit Bypass");
}
)}
)}
frida에서 인터페이스 받아오지 못한다. (onClickListener)
-> exit()을 재정의 해야 함!!
4. 결과 확인
>frida -U --no-pause -l [테스트 스크립트. js] -f [테스트 apk]
★★apk명 말고 패키지명!!!
-> UnCrackable-Level1 말고 owasp.mstg.uncrackable1 입력해야 한다. ★★
※ 패키지명 어떻게 알아내는지 ? adb로 들어가서 패키지명 검색하는 명령어 입력하기.
$pm list packages -f | grep crack
+) 자꾸 terminated 되는 현상?
frida.* 탐지해서 이름 바꿔서 실행 / nox 다운그레이드 / busybox 설치 확인 하기
과제
✔️ success 메시지 출력될 수 있는 입력 값 찾기
1. 환경 구동
에뮬레이터 구동 후 adb shell 명령어 입력 후 입력
2. 디컴파일 & 분석
MainActivity에서 입력 값 검증하는 함수 발견.
-> if문에서 a클래스에 있는 a함수를 호출한 뒤 반환 값에 따라 메세지를 출력하고 있다.
uncrackable1패키지의 a 클래스를 따라 살펴보면,
a 함수에서 입력 받은 값과 arrayOfByte를 equal 함수로 비교하여 boolaen 값을 리턴하고 있다.
b 함수는 arrayOfByte 값을 매핑하는 과정에서 포함되는 함수이다.
여기서 a 함수에 인자 두 개를 전달하고 있는데, this 클래스의 a 함수가 아님을 알 수 있다.
즉,
sg.vantagepoint.uncrackable1 패키지의 a클래스의 a 함수에서, (<-현재 분석중인 부분)
sg.vantagepoint.a 패키지의 a 클래스의 a 함수를 호출하고 있다.
a.a.a 함수를 찾아보면, 암호화 관련 함수로 보인다.
==> uncrackable1.a.a 함수의 리턴 값을 무조건 true로 후킹해주면 되지 않을까?
메소드를 어떻게 찾는지????????!!
-> API가 아닌 일반 메소드라서 따로 내부적으로 찾아야하는 줄 알았는데, 디컴파일한 패키지명+메소드명 그래도 입력해도 된다.
+) 다른 방법론은 찾다가 해본 작업 (후킹하는데는 필요없는 작업이었다.)
-> 저번 과제와 비슷한 과정으로 다시 앱 분석 해보기!
1) apk 내부 파일 추출>apktool.bat d UnCrackable-Level1.apk
2)\res\values에서 필요한 값 찾기
2130837505 -> 7F020001(hex값으로 변환)
\res\values public.xml 파일에서 해당 값 검색
\res\values strings.xml 파일에서 thanks 이름 가진 값 찾기
With special thanks to Bernhard Mueller for creating the app. Now maintained by the MSTG project. Want more? Check the MSTG playground!
3. 우회 스크립트 작성
[1] equals 함수 후킹 - 구글에 android api equals 검색! -> "java.lang.String"
argu 전달이랑 log에 argu 프린트
매개변수 잘 보기!!
but, log 너무 많아서 찾기 어려움 (하나하나 입력해야 됨)
[2] 복호화된 평문 프린트 하기 - sg.vantagepoint.a.a a함수 재정의하기
바이트 배열로 반환되기 때문에 아스키 코드 변환하여 출력 필요.
setImmediate(function() { // 바로 다음을 실행
Java.perform(function() { // 스레드가 연결되어 있으면 아래의 코드를 실행
var exit_bypass = Java.use("java.lang.System");
// 인터페이스를 받아와서 사용할 수 있는 Frida API가 존재하지 않음. 따라서 System.exit(0)을 사용
// (Java.lang.System의 exit 메소드를 재작성)
exit_bypass.exit.implementation = function() {
console.log("[*] Exit Bypass");
}
});
//[1]번방법
//equals 함수를 검색했을 때 처음에 -> java.lang.Object 로 나왔는데,
//java.lang.String가 맞다. String 객체 전달하고 있는 것을 코드에서 찾을 수 있다.
//이부분에 string 알아내는 코드 추가! setImmediate 안에만 넣어주면 된다.
// Java.perform(function() {
// var equalsFunc = Java.use("java.lang.String");
// equalsFunc.equals.implementation = function(arg1) {
// console.log(arg1);
// return true;
// }
// })
//[2]번 방법
Java.perform(function() {
var pw = Java.use("sg.vantagepoint.a.a");
pw.a.implementation = function(arg1, arg2) {
var secret_text = this.a(arg1, arg2);
var tmp = '';
console.log("\n[*]Decode before : " + secret_text);
for (var i=0; i<secret_text.length; i++) {
tmp += String.fromCharCode(secret_text[i]);
}
console.log("\n[*]Decrypted : " + tmp);
return secret_text;
}
})
});
스크립트 작성 완료 후에 cmd 창에 명령어 입력하기
$ frida -U --no-pause -l test.js -f owasp.mstg.uncrackable1
-> 콘솔 창에 평문이 출력된다.
'보안 > android' 카테고리의 다른 글
[앱][리버싱] 악성앱 분석 - InsecureBankv2 (1) (0) | 2021.10.28 |
---|---|
[앱][리버싱] 악성앱 분석 - InsecureBankv2 환경구축 (0) | 2021.10.28 |
[앱][리버싱] 앱 후킹 도구 frida 설치 (0) | 2021.10.28 |
[앱][리버싱] 6주차 정리 ; drozer로 앱 분석 (0) | 2021.10.28 |
[앱][리버싱] 4,5주차 정리 ; ADB로 앱 디버깅 (0) | 2021.10.28 |