ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Frida] Uncrackable 4 (r2pay) 풀이
    Learning/Android 2024. 1. 20. 23:38

    요번엔 r2pay로 돌아왔다!

    uncrackable 1 ~ 3단계를 풀었더니 uncrackable4가 아닌 r2pay가 나온 게 이상했는데 후에 찾아보니 r2pay v0.9는 OWASP에서 만들었고, r2pay v1.0은 R2con CTF를 위해 만들어졌다고 한다

     

    실행을 하는 순간 그냥 바로 꺼진다

     

    메인액티비티의 onCreate 부분을 보니 특정 클래스의 메서드 실행결과에 따라 숫자를 0으로 나눠버리는 악랄한 짓을 하는 것을 볼 수 있다

     

    0으로 나누면 당연히 에러가 발생할테니 우선 저기부터 후킹해봤다

     

    rb.1161()

    rb.1161 메서드이다 특정 함수들의 리턴값을 리턴해준다

     

    if문의 뒤쪽 로직은 rb.m1154() 혹은 rb.m1149() 중 하나만 false면 false이므로 rb.m1154()만 후킹했다

    rb.m1154()

    RootBeer를 사용한 루팅 탐지를 하는것으로 보인다 

    하지만 리턴값만 바꾸면 그만이긴 하다

     

    setImmediate(function() {
    	Java.perform(function() {
    		console.log("[*] Script start"); 
    
    		let C0282 = Java.use("\u266B.\u1D64");
    		
    		C0282["\u20A4"].implementation = function () {
    			console.log(`C0282.m1161 is called`);
    			return false;
    		};
    		
    		let C0282 = Java.use("\u266B.\u1D64");
    		C0282["\u03B8"].overload().implementation = function () {
    			console.log(`C0282.m1154 is called`);
    			return false;
    		};
    		
    		console.log("[*] Script finish");
    	});
    });

    그렇게 루팅 탐지 메서드의 리턴값을 false로 조작한 후 다시 실행시켜보았다

     

    똑같았다..

    그렇다면 onCreate 이전에 루팅이 탐지되고 종료된다는 뜻이다

     

    에러가 나며 종료될 때 backtrace가 찍히는데 뭔가... 뭔가 이상한 주소이다..

    우선 해당 apk가 어떤 라이브러리를 로딩하는지 알아보자

     

    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
      onEnter: function(args){
    	  console.log("\nlib: ", Memory.readUtf8String(args[0]));
    	  },
      onLeave: function(retval){
    	  }
    });

    android_dlopen_ext를 후킹하여 어떤 라이브러리가 로딩되는지 알아볼 것이다

     

    arm 라이브러리가 로딩된다

    녹스에서는 arm 라이브러리가 로딩될 때 libhoudini.so라는 라이브러리를 통해 arm 명령어를 x86으로 변환해준다

    당연히 다른 라이브러리를 통해 번역되므로 프리다로 후킹은 불가능하다.

     

    http://linforum.kr/bbs/board.php?bo_table=qa&wr_id=233

     

    에뮬레이터 환경에서 arm 라이브러리에 Frida attach (?)

    안녕하세요 ㅎㅎ frida 후킹에 대해 이제 막 공부를 시작한 뉴비입니다! 에뮬레이터 환경(x86)에서 frida를 사용해서 arm 라이브러리에 attach가 안되는 문제가 있어 질문드립니다. 질문에 앞서 저는 LD

    linforum.kr

    이 글을 참고해보자!

     

    lib 폴더를 확인해보니 arm과 x64 라이브러리가 있었다

    현재 환경은 x86이기 때문에 arm 라이브러리가 로딩되는 것이다

     

    녹스에 x64 환경을 새로 설치했다

     

    x64 에뮬레이터로 다시 프리다 코드를 돌려보니 x64 라이브러리를 가져오는 것과, backtrace가 이쁘게 찍히는 것을 볼 수 있다

     

    libnative-lib.so 라이브러리에서 프로그램이 종료되기 때문에 해당 라이브러리를 분석해보자

     

    으음... 저만한 함수들을 다 분석하기에는 빡세니 어떤 함수를 호출하는지 확인해서 루팅 탐지를 어떻게 할지 추측해보자

     

    수상하게 보이는 함수가 몇 개 있다.

    open, lstat, opendir, pthread_create, snprintf가 수상해보인다

     

    하나하나 후킹해가며 우회해보자

     

    우선 lstat을 후킹하여 인자값을 확인해보자

    //생략
    Interceptor.attach(Module.findExportByName("libc.so", "lstat"), {
    	onEnter : function(args) {
    		console.warn("lstat " + args[0].readUtf8String());
    	},
    	onLeave : function(retval) {
    	}
    });
    //생략

     

     /proc/self/fd/39 에서 터지는 것을 볼 수 있다.

    한 번 뭐가 들었는지 확인해보자

     

    R2pay 의 pid를 구해서 fd 폴더를 확인해보았다.

    그런데 39번 파일이 없다...?

    없는 파일을 인자로 넘겨서 터졌나보다. 넘어가는 인자를 항상 있는 /proc/PID/fd/0로 바꿔보자

    //생략
    Interceptor.attach(Module.findExportByName("libc.so", "lstat"), {
    	onEnter : function(args) {
    		console.warn("lstat ", args[0].readUtf8String());
    		var buf;
    		if(args[0].readUtf8String().indexOf("/fd/") > -1) {
    			buf = Memory.allocUtf8String('/proc/self/fd/0');
    			this.buf = buf;
    			args[0] = buf;
    			console.log("change to " + args[0].readUtf8String() + "\n");
    		}
    	},
    	onLeave : function(retval) {
    	}
    });
    //생략

     

     

    음... 그래도 똑같다. 우선 다른 함수들도 살펴보자

     

    다음은  snprintf를 살펴보자!

    //생략
    var tmp;
    Interceptor.attach(Module.findExportByName("libc.so", "snprintf"), {
    	onEnter : function(args) {
    		tmp = args[0];	
    	},
    	onLeave : function(retval) {
    		console.warn("snprintf ", tmp.readUtf8String());
    	}
    });
    //생략

    snprintf 를 살펴볼거다

    엥? snprintf랑 루팅 탐지랑 무슨상관이죠 싶을 수도 있지만

     

    snprintf의 활용법은 snprintf(buf, "/proc/self/%d/status", getpid()); 와 같은 형태로 현재 프로세스의 pid를 구해 proc 폴더에 접근할 수 있도록 한다.

     

    그렇기 때문에 args[0]의 주소를 저장해두고, snprintf의 실행이 종료되면 개발자가 원하는 값이 담겨있을테니 onLeave에서 결과물을 출력시켜줬다.

     

    9번째 status에서 크래시가 났다! 한 번 살펴보러 가자

    r2pay의 PID를 구해 task 폴더 밑의 9번째 status를 출력한 내용이다

    Name을 보면 gmain인데 gmain은 프리다를 실행시키고, 자바스크립트를 inject 할 때 생성되는 스레드이다

    이걸 탐지해서 앱을 종료시켰을 것이다

     

    그렇다면 멀쩡한 status 파일을 하나 복사하고, 인자를 해당 fakeStatus 파일 경로로 바꾸면 될 것이다

    //생략
    var tmp;
    Interceptor.attach(Module.findExportByName("libc.so", "snprintf"), {
    	onEnter : function(args) {
    		tmp = args[0];	
    	},
    	onLeave : function(retval) {
    		console.warn("snprintf ", tmp.readUtf8String());
    		if(tmp.readUtf8String().indexOf("/status") > -1) {
    			tmp.writeUtf8String("/data/local/tmp/fakeStatus");
    			console.log("change to " + tmp.readUtf8String() + "\n");
    		}
    	}
    });
    //생략

    이제  status 파일에서 크래시가 나지 않는 것을 볼 수 있다

     

    그렇다면 또 범인찾기를 시작해보자...

     

    이번엔 open 함수이다

    //생략
    Interceptor.attach(Module.findExportByName("libc.so", "open"), {
    	onEnter : function(args) {
    		console.warn("open ", args[0].readUtf8String());
    	},
    	onLeave : function(retval) {
    	}
    });
    //생략

     

    su 파일을 찾는다..

    이것도 인자를 바꿔버리자

     

    //생략
    Interceptor.attach(Module.findExportByName("libc.so", "open"), {
    	onEnter : function(args) {
    		console.warn("open ", args[0].readUtf8String());
    		var buf;
    		if(args[0].readUtf8String().indexOf("/su") > -1) {
    			buf = Memory.allocUtf8String('/su_is_not_here');
    			this.buf = buf;
    			args[0] = buf;
    			console.log("change to " + args[0].readUtf8String() + "\n");
    		}
    	},
    	onLeave : function(retval) {
    	}
    });
    //생략

    또.....

    일단 이정도로 하고 파트2로 돌아오겠다

    'Learning > Android' 카테고리의 다른 글

    몸캠피싱앱 분석  (0) 2024.11.11
    [Frida] Uncrackable 4 (r2pay) 풀이2  (0) 2024.03.15
    [Frida] Uncrackable level 3 풀이  (0) 2023.12.29
    [Frida] Uncrackable level 2 풀이  (0) 2023.12.18
    [Frida] Uncrackable level 1 풀이  (0) 2023.12.18

    댓글

Hi