Root권한이 허용된 단말기에 앱 설치 후 실행할 경우 루팅이 탐지되며 강제종료 되는 것을 확인

이번에 루팅을 해제한 상태에서 실행할 경우


비밀키를 입력하라는 메시지가 출력된다. 틀린 비밀키 입력 시 다시 시도하라는 문구가 출력
2. 목표
1. 비밀키 검증 우회
2. 비밀키를 찾아서 입력
두 가지 방법으로 좁힐 수 있다.
3. 풀이
1) JEB3 Decompiler를 사용하여 Manifest부터 확인

Manifest 확인 시, 패키지명은 owasp.mstg.uncrackable1, 메인 액티비티 이름은 sg.vantagepoint.uncrackable1.MainActivity이다.
2) 메인 액티비티 sg.vantagepoint.uncrackable1.MainActivity 확인

루팅 탐지로직과 비밀키 입력 시 성공여부를 판단하는 로직이 보이며 각각 onCreate, verify 메서드라는 이름을 가지고 있다.
3) 루팅탐지 로직 분석

이 루팅을 탐지하는 로직이며, sg.vantagepoint.a 패키지 안의 c 클래스의 a, b, c 메서드를 모두 false를 만족하여야 루팅 탐지가 안되는 것을 확인할 수 있다.

c 클래스의 내부를 확인한 결과 a, b, c 메서드가 각각 무슨 일을 하는지 확인 할 수 있다.
a 메서드는 su의 PATH를 탐지하여 단말기에 su 경로가 존재하는지 확인
b 메서드는 test-keys라는 문자열이 있는지 확인
c 메서드는 su 바이너리들이 있는지 탐지
4) 루팅탐지 우회를 위한 Frida 코드 작성 후 실행
Java.perform(function(){
// 콘솔로그로 정상 동작하는지 테스트 수행
console.log("[*] passed!");
// Rooting 우회
var ByPassRooting=Java.use("sg.vantagepoint.a.c");
console.log("[*] Rooting Detect_hook!!");
ByPassRooting.a.implementation = function(param){return false;}
ByPassRooting.b.implementation = function(param){return false;}
ByPassRooting.c.implementation = function(param){return false;}
console.log("[*] Rooting Bypass!!");
});

5) 루팅 우회 후, 비밀키 입력할 경우 다시 입력하라는 문구 출력

6) 비밀키를 알아내어 검증 우회 시도
UnCrackable에서 사용하는 모든 String 문자열을 모두 Console.log로 출력하는 후킹 코드 작성
Java.perform(function(){
// 콘솔로그로 정상 동작하는지 테스트 수행
console.log("[*] passed!");
// Rooting 우회
var ByPassRooting=Java.use("sg.vantagepoint.a.c");
console.log("[*] Rooting Detect_hook!!");
ByPassRooting.a.implementation = function(param){return false;}
ByPassRooting.b.implementation = function(param){return false;}
ByPassRooting.c.implementation = function(param){return false;}
console.log("[*] Rooting Bypass!!");
// 사용하고 있는 텍스트 출력하기
var HookString = Java.use("java.lang.String");
HookString.equals.implementation = function(param){
console.log(param);
return true;
}
});

실행 결과, 사용하고 있는 모든 문자열이 출력되고 있어서 비밀키로 의심되는 문자열만 필터링한다.
이를 위한, 후킹코드를 재작성한다.
Java.perform(function(){
// 콘솔로그로 정상 동작하는지 테스트 수행
console.log("[*] passed!");
// Rooting 우회
var ByPassRooting=Java.use("sg.vantagepoint.a.c");
console.log("[*] Rooting Detect_hook!!");
ByPassRooting.a.implementation = function(param){return false;}
ByPassRooting.b.implementation = function(param){return false;}
ByPassRooting.c.implementation = function(param){return false;}
console.log("[*] Rooting Bypass!!");
// 사용하고 있는 텍스트 출력하기
var HookString = Java.use("java.lang.String");
HookString.equals.implementation = function(param){
// 키 값이 아닌 항목 추가
if (param == "ko-KR" | param == "owasp.mstg.uncrackable1" | param == "android.view.Display$HdrCapabilities" | param == "SEC_FLOATING_FEATURE_MESSAGE_CONFIG_PACKAGE_NAME" | param == "sg.vantagepoint.uncrackable1.MainActivity" | param == "value" | param == "_track_generation" | param == "android.content.res.Configuration" | param == "0x4f4c" | param == "user" | param == "android.graphics.Rect" | param == "SEC_FLOATING_FEATURE_COMMON_SUPPORT_ULTRA_POWER_SAVING" | param == "SEC_FLOATING_FEATURE_COMMON_SUPPORT_SAFETYCARE" | param == "time_12_24" | param == "java.io.tmpdir" | param == "package" | param == "/data/app/owasp.mstg.uncrackable1-Qm86DR0g7jzG1URJA_qGOA==/base.apk" | param == "_generation" | param == "android.util.MemoryIntArray" | param == "sans-serif" | param == "sans-serif-medium" | param == "v30" | param == "android.os.ParcelFileDescriptor" | param == "settings" | param == "_generation_index" | param == "_generation_index" | param == "window" | param == "KRW" | param == "0"){
}
else{
console.log(param);
}
return true;
}
});

비밀키 값으로 의심되는 문자열 중 “I want to believe”가 보이며, 루팅 해제 후, 키 값 확인