티스토리 뷰
안녕하세요.
광주아이입니다.
3버전의 설명을 드리기 앞서
정말 죄송하지만 이 글은 연구 용도로만 작성하였으며,
개인의뢰 및 소스코드는 드릴 수 없는점 이해좀 부탁드립니다.
저 쇠고랑차고 쇠철창 들어갑니다. ㅠㅡㅠ
............
............
............
아무튼 개인의뢰는 받지도 하지도 않고 있으니 이해해주시리라 믿고
그렇지 않으신 분들은 Command + w 누르셔서 이 페이지를 닫아주시면 감사하겠습니다.
이번 #3에서는 이미지가 없을 것 같습니다.
지난번 iOS 트윅을 이용하여 탈옥폰을 정상폰처럼 보이게끔 하는 작업을 했습니다.
탈옥우회탐지 100% 방법은 있냐?
없다고 말씀드렸습니다.
그럼 Android는 할 수 있냐?
100%는 없다고 미리 말씀드리겠습니다.
Android도 iOS처럼 100%는 막을 수 없습니다.
이유는 IDA, GDB(lldb), Frida 와 같은 강력한 디버깅(후킹 포함) 툴까지는 막을 수 없다고 봅니다.
다만, Android는 최근 루팅 탐지 기술이 워낙 발달이 되었고,
난독화 제품도 출시가 되어 우회가 많이 힘들어진건 사실입니다.
그럼 도대체 어떻게 루팅 탐지 우회를 하냐?
보통 대부분 금융거래가 이루어지는(금융기관, 은행, 개인정보취급 기관) 앱은 첫 번째로
루팅폰인지 확인을 합니다.
Class a {
private boolean Exists(String cmd) {
try {
out = Runtime.getRuntime().exec("su");
return true;
} catch(Exception e) {
return false;
}
}
}
와 같은 소스가 있다고 가정하겠습니다.
su를 실행해보고 익셉션이 일어나면 정상폰, 그렇지 않으면 루팅폰이라고 판단하면 되지요.
하지만 이 함수 자체는 엄청난 오류를 범하고 있다는걸 아실텐데요.
루팅폰에 su 바이너리를 삭제해버리면 루팅폰임에도 불구하고 익셉션이 일어나 루팅폰이 아니다 라고 판단을 할 수 있죠.
Android에서 알려져 있는 루팅 탐지 기법이 여러 가지가 있습니다.
1. test-key
2. Known Binary
3. Known Packages
4. Manage Root Apps
5. Dangerous Apps
6. Dangerous Props
7. BusyBox
8. RW System Directory
눈으로 살펴 보셔도 충분히 이해하시리라 생각하고 넘어가겠습니다.
위와 같은 방법으로 루팅탐지를 하고 있는데요.
한마디로 구식(?) 입니다.
21세기에 저 방법으로 루팅 탐지 했다가는
해당앱을 hide 시킬 수 있는 아주 강력한 SuperSU, Magisk 툴이 있기 때문에 다른 방법을 강구해야 할 것입니다.
저는 막는자가 아닌 뚫는 자 이기 때문에 탐지 방법에 대해서는 굳이 설명을 드리지는 않겠습니다.
자 그럼 어떻게 루팅 탐지 우회를 할 것이냐에 대해서 설명드리겠습니다.
루팅폰에서 금융앱을 실행할 때
루팅이 탐지되었습니다. 루팅폰입니다. 루팅이 탐지되어 이용할 수 없습니다. 라는 구문을 자주 보실 것입니다.
그러고는 앱이 종료가 되죠.
Android 분석을 할 때
반드시 필요한 도구가 있습니다.
Android는 기본적으로 JAVA 기반으로 앱이 구동이 되기 때문에
1. 설치 돼 있는 앱 apk로 추출하기
2. apk 압축풀기
3. dex 파일 디컴파일 하기
4. 디컴파일된 jar 파일 분석하기
난독화로 인하여 디컴파일이 되지 않으면 좀 난감합니다.
그럼 어떻게 해야하지...........
방법이 문득 생각은 안나네요.
사실 iOS보다 Android 루팅탐지우회가 더 몇배 아니 몇백배 더 어렵습니다.
우선은 dex 파일을 IDA로 끌어옵니다. (이미지가 없어서 죄송합니다.)
AhXXXXX, Rooting, CheckRoot 등 루팅 관련된 스트링을 죄다 검색해봅니다.
그럼 반드시 1개는 나옵니다.
머든 안나온다 싶으면 gdb(lldb)로 노가다를 하셔야 합니다.
위에서 말씀드린 1~8까지의 작업을 순 삽질(?) 노가다로 하나하나 Hooking 하셔야합니다.
Hooking은 가장 쉬운 방법이 Frida를 이용하는것입니다.
하지만 앱이 Hooking 을 잡는다?
점점 머리가 복잡해지고 무의식에서 IDA, jd-gui 프로그램을 종료한다는 것이지요.
이처럼 Android는 엄청난 노가다와 시간과 노력이 필요합니다.
Frida를 이용하여 해당앱을 Attach만 돼도 50%는 성공한 것과 다름없습니다.
Frida Tool을 이용하여 MainActivity가 되는 onCreate() 함수를 후킹할 수 있으니깐요.
물론 implements BaseActivity가 있다면 도루묵이긴 하지만요.
50% 성공된 작업으로 method list를 뽑아올 수 있으며
특이하게 생겨먹은 method를 후킹할 수 있다는 점에서 성공했다라고 판단할 수 있다는거죠.
이해되셨나요?
이해가 안되셔도 상관없습니다.
이미 성공하셨으니깐요.
특이한 method 를 파악하셨다면
xposed framework를 이용하실 차례입니다.
물론 Java의 기본 클래스의 특정함수도 Hooking 해야할 경우도 생깁니다.
다음과 같은 소스를 보시죠.
위의 소스는 Android 디바이스 ADB 가 활성화 돼 있으면
리턴값을 0으로 세팅해주는 Hooking 소스입니다.
특정 금융기관의 앱에서 adb 가 활성화 돼 있는것도 탐지를 해서
기본적으로 물고 들어가는 Hooking 소스입니다.
이와 같이 System 관련 클래스의 특정 method 도 후킹이 가능하게 돼 있습니다.
자 그러면 눈치 채셨나요?
Settings.Global.class의 getInt 라는 매개변수에 3가지가 들어가는데요.
Hooking과정에서 이 함수에 진입할 때 나갈 때를 후킹 할 수 있습니다.
void 함수는 result가 없으니 null 이 되겠죠.
자..... 그럼 Runtime.getRuntime().exec(매개변수) 함수도 Hooking 이 가능하겠죠?
if(매개변수 != null) 아니면 param.args[0] 의 값을 Frida로 쫙 뽑아보면?
여기까지 성공하셨으면 90% 성공하신겁니다.
어떠어떠한 명령어를 실행하는지 뽑아올 수 있다는거죠.
Good Job!!
매개변수에 개발자가 입력해놓은 값 대신 garbage 명령어를 넣는다면? 익셉션이 발생하게 된다는거죠.
위 그림에서 보시다시피 before, after Override 함수가 있습니다.
이 함수를 이용하여 진입 시 또는 함수 나갈 때 Hooking이 가능하며,
return 값이 없는 void에서도 가능하니 다만, void 함수에서 레이아웃을 꾸미거나 데이터 넣어주는 작업과 같이 할 경우 null 보내시면
앱이 뻗을 수 있겠죠?
이 점만 유념하신다면 앱 내 모든 함수는 Hooking이 가능합니다.
여기까지 #3에 대해서 이야기를 해보았습니다.
실제 앱을 토대로 보여드리고 싶지만
쇠고랑차고 철창살에 들어가고 싶지는 않습니다.
이해가 안되신다면 처음부터 다시 보시거나
저보다 글재주가 좋으신 분의 글을 먼저 보시고
제 글을 보신다면 이해가 되실 수(?) 있겠습니다.
그럼 #4에서 뵙죠 ^^