어플리케이션 공부를 위해 UnCrackable-Level1.apk 후킹 연습을 해보았다.

 

1. 앱 실행

이번에도 그냥 냅다 켜봤다. 그런데 루팅이 탐지 되었다고 앱을 종료 시켜버렸다..

일단 이거 우회부터 시도 해봐야지

 

 

2. jadx-gui 툴로 디컴파일

자세하게는 모르지만 onCreate 메소드에서 첫번째 if가 true가 되면 루팅이 탐지됐다고 판단하고 a 의 onClick에서 종료가 되는 구나! 라고 분석해보았다.

 

그럼 간단하게 onClick쪽에서 앱이 안꺼지게끔 하면 되지 않을까?

 

바로 onClick을 후킹하는 코드를 짜서 돌렸다.

 

 

3. 후킹 코드 작성 후 돌리기

Java.perform(function() {
	console.log("[+] Hooking System.exit");

  var exitClass = Java.use("sg.vantagepoint.uncrackable1.MainActivity");	//hooking 할 메소드의 class 명
  exitClass.onClick.implementation = function() {      //class명.method명.implementation = funtion(argv[])
    console.log("[+] clicked");
  }
})

UnCrackable-Level1.js로 저장하고 후킹... 어라? 근데 후킹이 안된다.

삽질한 결과 onClick은 DialogInterface.OnClickListener()라는 익명 클래스에 속해있어서 못 불러오는거였다..
익명 클래스를 지정해주기 위해서는 간단한 작업이 필요한데

 

jadx-gui > file > preferences > Inline anonymous classes 체크 해제

 

이렇게 하면 위에 코드가 아래 코드처럼 바뀐다.

 

우리가 후킹할 메소드는 AnonymousClass1에 들어있는걸 확인 할수있다.

그렇다면 코드를 이렇게 바꾸도록 하자.

 

Java.perform(function() {
	console.log("[+] Hooking System.exit");

  var exitClass = Java.use("sg.vantagepoint.uncrackable1.MainActivity$1");	//hooking 할 메소드의 class 명
  exitClass.onClick.implementation = function() {      //class명.method명.implementation = funtion(argv[])
    console.log("[+] clicked");
  }
})

간단하다.

var exitClass = Java.use("sg.vantagepoint.uncrackable1.MainActivity"); 뒤에 $1 붙였을 뿐이다.

두번째 익명클래스를 지정하고 싶다면 $2를 썼겠지

 

 

4. 수정한 코드 돌리기

frida -U -f  owasp.mstg.uncrackable1 -l UnCrackable-Level1.js --no-pause

똑같이 alert 창은 뜨지만 ok를 눌러도 앱이 꺼지지 않았다.

하지만 여기서 끝이아니다. 이제 루팅우회만 했을 뿐

 

 

5. 성공 메시지 뜨게하기

아무값이나 입력해보니 틀렸다고 나왔다. 당연하겠지..

이것도 마찬가지로 디컴파일해서 봐봐야겠다.

 

 

어찌되었든 a.a(obj) 저 값만 true가 되면 되는거 잖아? 그래서 a 클래스를 봤다.

 

 

막줄보니까 결국 내가 입력한 값이랑 복잡한 계산을 거친 bArr이 같으면 통과, 즉 true를 리턴한다는 소리인듯?

그런건 난 모르겠고 a.(obj)가 무조건 true를 리턴하면 되는거 아닌가??

 

Java.perform(function() {
	console.log("[+] Hooking System.exit");

	var exitClass = Java.use("sg.vantagepoint.uncrackable1.MainActivity$1");	//hooking 할 메소드의 class 명
	exitClass.onClick.implementation = function() {      //class명.method명.implementation = funtion(argv[])
	console.log("[+] clicked");
  }
	var callClass = Java.use("sg.vantagepoint.uncrackable1.a");	//hooking 할 메소드의 class 명
	callClass.a.implementation = function() {      //class명.method명.implementation = funtion(argv[])
  	return true;
	}
})

그래서 이렇게 짜보았다.

UnCrackable-Level1_2.js 로 저장을 한 뒤 프리다 돌려보기로 했다.

 

 

6. 결과

이게 되네;;

 


 

7. (여담) 실제 값을 구해서 푸는 방법

인터넷 찾아보니 실제로 값을 구해서 푸는 방법이 있길래 가져와보았다.

Java.perform(function() {
	console.log("[+] Hooking System.exit");

  var exitClass = Java.use("sg.vantagepoint.uncrackable1.MainActivity$1");	//hooking 할 메소드의 class 명
  exitClass.onClick.implementation = function() {      //class명.method명.implementation = funtion(argv[])
    console.log("[+] clicked");
  }

	var aClass = Java.use("sg.vantagepoint.a.a");	//hooking 할 메소드의 class 명
  	aClass.a.implementation = function(test1,test2) {
		var keyval_low=this.a(test1,test2);
		var keyval=""
		for(var i=0;i<keyval_low.length;i++){
			keyval+=String.fromCharCode(keyval_low[i])
		}
		console.log(keyval);
		return keyval_low;
	}
})

 

역시 나는 한참 멀었다.

복사했습니다!