루팅(Rooting)?
루팅은 쉽게 말해 시스템 최고 권한(root)을 얻는 것이다. 안드로이드에서는 안정적인 기기의 동작을 보장하기 위해 루트 권한은 일반적인 사용자가 접근하지 못하도록 되어 있다. 시스템 내부 저장소 접근, 권한 변경 등 많은 작업을 수행할 수 있기 때문이다. 하지만 Frida를 이용한 후킹을 위해서는 루팅된 시스템이 필요하며, 이 때 루팅 탐지 기법이 적용된 애플리케이션은 동작이 어려울 수 있다.
- 슈퍼유저는 특권제어를 할 수 있는데, 앱에 설치된 모든 권한과 시스템 백업, 다른 버전 안드로이드 설치, ROM 컨트롤 등을 할 수 있다.
- 시스템 안전을 보장할 수 없다. 개인정보인 연락처, 이메일 등에 접근할 수 있고 자격증명 및 비밀번호에도 접근이 가능하다.
루팅 탐지 앱 분석
- 루팅 탐지 함수를 후킹해서 우회해야한다.
- 앱이 시작하자마자 루팅여부 확인해서 반환값을 반환하는데 실행 후에 수작업으로 frida code를 attach 하면 늦는게 아닐까? (frida에서 -f 옵션을 사용하면 된다.)
- 앱을 종료시키면 pid가 유효하지 않아 frida가 죽어버리는데 유지시키는 방법은? (—no-pause)앱이 실행되고 루팅 여부를 검사한 후 Message 창을 띄운다.애플리케이션 프로세스를 실행시키면서 자바 스크립트 삽입이 가능하다.
- 앱을 실행시키면서 frida 코드를 삽입하려면 -f 옵션을 사용한다.
frida -U —no-pause -f com.android.chrome -l ~.js
- 루팅을 어떻게 탐지할 것인지 알아야 한다.
- 개발자의 입장에서 루팅된 기기를 어떻게 탐지할까
- 루팅 탐지 함수에 무엇이 있는지 알아야 한다.
- 루팅시 변화하는 값이나 바이너리에 무엇이 있는지 알아야 한다.
루팅 탐지 기술
테스트키 확인
- 커널이 컴파일될 때 서명되는 방법과 관련있음
"su" 확인
- 슈퍼유저를 식별하기 위한 식별자
busybox binary check
- busybox는 루팅된 장치에 종종 설치되며 linux 명령어를 제공한다.
루팅여부를 숨겨주는 앱의 존재여부 확인
- 패키지 관리자를 이용하여 슈퍼유저와 루트 액세스 관리에 설치된 앱을 확인가능하다.
- 파일이름 기반 탐지
- su 파일이나 superuser.apk 등 루팅 시 생성되는 파일이름을 탐지
- 오탐이 가장 적고 탐지도 쉽지만 우회도 쉬움
"su" 명령 실행을 통한 탐지
- 일반 디바이스는 su 명령 자체가 존재하지 않는다.
- su 명령을 직접 실행시켜서 Exception이 발생하는지 여부를 통해 판단
나열한 기법 이외에도 수많은 기법들이 존재한다.
OWASP Uncrackable 1 앱의 루팅 탐지 우회
Frida Bypassroot
앱 : OWASP Uncrackable 1
PATH 환경변수를 가져와서, 환경변수 내에 "su" 문자열이 있는지 검사한다.
var rt = Java.use("java.lang.System");
rt.getenv.overload('java.lang.String').implementation = function(str){
console.log("[*] getenv Hooked");
send(str.toString());
var retval = this.getenv(str);
console.log(retval.toString());
return retval;
}
var first = Java.use("sg.vantagepoint.a.c");
first.a.implementation = function(){
console.log("[*] first Hooked");
var retval = this.a();
console.log(retval.toString());
return retval;
}
var first = Java.use("sg.vantagepoint.a.c");
first.a.implementation = function(){
console.log("[*] first Hooked");
var retval = this.a();
console.log(retval.toString());
return false;
}
var second = Java.use("sg.vantagepoint.a.c");
second.b.implementation = function(){
console.log("[*] second Hooked");
var retvals = this.b();
console.log(retvals.toString());
return false;
}
var third = Java.use("sg.vantagepoint.a.c");
third.c.implementation = function(){
console.log("[*] third Hooked");
var retvalq = this.c();
console.log(retvalq.toString());
return false;
}
반환값 전부 false로 해서 검사문 통과할 수 있다.
상용 앱의 루팅 탐지 우회
앱 이름 : 비공개
앱 실행 시 루팅된 앱의 검사 로직에 따라 "루팅된 폰입니다~" 메시지가 나오면서 앱이 종료된다.
권한 허가 여부에 상관없이 루팅 단말로 인식하여 앱을 종료한다.
루팅 여부를 체크하는 로직이 있는 클래스를 분석한다.
jd-gui를 이용하여 apk 파일을 분석하였다. 앱 실행시 루팅 여부를 확인할 것이라고 생각했고 앱의 시작점인 MainActivity 내에 관련 클래스를 import 하고 호출하는 부분을 확인하였다. 그 클래스를 따라간다.
this.b() 메소드의 결과값을 boolean으로 받아서 if 문으로 확인하고 루팅 관련 메시지를 출력하고 앱을 종료시키는 코드가 있다. 호출 스택의 상위 레벨에 있는 a 메소드를 후킹하여 반환값을 변조하면 된다.
setImmediate(function(){
console.log("[*] Load Successfully");
Java.perform(function(){
var rt = Java.use("APP_NAME_korea.activity.BaseFragmentActivity");
rt.a.implementation = function(){
console.log("[*] chk root Hooked");
var retval = this.a();
console.log(retval.toString());
return 0;
}
프리다로 후킹하면 앱이 정상적으로 실행된다.
일반화
소개한 방법들은 단일 앱에 대해서 정적으로 분석을 마친후 어떤 클래스, 메소드에서 루팅을 탐지하는 지 직접확인 후에 후킹 스크립트를 작성해야 한다.
역공학 방지 솔루션이 적용된 경우 클래스명이나 메소드 명을 식별할 수 없어 제대로 된 후킹 코드를 작성할 수 없을 수도 있다.
그러면 루팅을 탐지하는 앱에 대해 하나의 스크립트로 모두 우회가 가능하도록 작성할 수 있을까?
Frida codeshare에서 루팅탐지 기법 우회를 범용적으로 사용할 수 있는 코드도 작성되어 공유되고 있다.
codeshare.frida.re/@dzonerzy/fridantiroot/
자바 기본 함수들을 후킹하여 루팅과 관련한 문자열과의 일치 여부를 판단해서 루팅을 우회하고 있다. 더 하위 레벨인 libc 메소드까지 후킹해서 사용하고 있는 스크립트 였다.
하지만 이 스크립트를 적용함에도 우회가 제대로 되지 않는 앱들이 많았고 다음 포스트에서는 그에 대한 내용을 정리해보려 한다.
'Security > Mobile' 카테고리의 다른 글
[Frida] Android Permission 필요 동작 후킹하기 (0) | 2020.12.26 |
---|---|
[Frida] 안드로이드 루팅 탐지 우회하기 2 (0) | 2020.12.24 |
[Flutter][Reversing]Webview, JSInterface 통신 앱 분석 (0) | 2020.11.21 |
[Flutter] Webview, JSInterface 통신하기 (0) | 2020.11.20 |
[Flutter] URI Scheme 사용하는 앱 개발 (2) | 2020.11.17 |