본문 바로가기
4. 모바일 앱 취약점 진단/Android

[Android] 1.3. 디바이스 임의 개조 탐지 취약점

by Robert8478 2024. 6. 19.

개요

디바이스 임의 개조 탐지는 루팅이나 탈옥과 같은 작업이 된 디바이스 여부를 앱에서 감지하는 것이다.

이것이 취약한 이유는 루팅되거나 탈옥된 기기의 경우 권한이 더 높아지고 다양한 악성 트윅 등을 사용할 수 있게 되기 때문에 앱의 변조, 앱 내 정보 탈취 등의 행위를 수행할 우려가 높아진다.

 

점검 방법

루팅은 기본적으로 루팅된 기기를 통해 앱에 접근했을 때 정상 접근이 되는지 여부만 파악하면 된다.

취약한 경우에는 그냥 접근이 되거나 루팅 탐지 관련 메시지만 출력시키고 정상 접근이 되는 경우들이 존재했다.

루팅 탐지 로직이 존재하지 않는 경우 앱 정상 접근

루팅 탐지 로직이 적용되어 있어 기본적으로는 루팅된 기기에서 접근이 불가능한 경우에는 양호라고 볼 수 있지만, 만약 1.1 소스코드 난독화 및 암호화 취약점과 1.2 무결성 검증 취약점이 존재하는 경우에는 이러한 루팅 탐지 로직을 우회할 수 있어서 취약한 상태가 될 수 있다.

루팅 탐지 로직 우회는 앱의 코드단인 Smali 코드를 변조하여 우회하거나 Frida Script를 통해 Hooking 하여 우회하는 방식이 존재한다.

 

1. Smali 코드를 통한 루팅 탐지 로직 우회

Smali 코드를 통한 루팅 탐지 로직 우회는 앱을 디컴파일하고 내부의 코드를 변조하는 방식이다.

우선적으로 JEB나 JD-GUI 툴을 통해 루팅 탐지 로직을 분석하고 해당 부분을 smali 코드에서 찾아

조건문 로직을 변경하는 방식으로 이루어진다.

루팅 탐지되었을때 메시지

기본적인 우회 순서는 아래와 같다. 보통 루팅 탐지가 되면 루팅 탐지 관련 메시지가 출력되는 경우가 많은데 이 메시지를 Astrogrep 툴을 사용해 디컴파일한 폴더의 res 폴더에서 검색해본다.

res 폴더에서 루팅 탐지 관련 메시지 검색

검색해보면 strings.xml에서 루팅 탐지 관련 메시지를 확인할 수 있다.

이제 해당 string 값의 name인 rooting을 검색해보자

res 폴더에서 rooting을 검색한 결과

검색을 해보니 public 태그의 rooting 속성에 id값을 확인할 수 있다. 이 id 값을 긁어서 smali 폴더에 검색하게 되면 루팅 탐지 로직 위치를 찾을 수 있다.

검색을 해보니 MainActivity.smali에 루팅 탐지 코드가 존재한다는 것을 알았다.

MainActivity 관련 로직을 쉽고 자세히 보기 위해서 JEB를 사용해 관련 로직을 분석해본다.

JEB에서 rooting 관련 id 값 검색

MainActivity에 직접 들어가 다시 루팅 관련 메시지 등을 검색하는 방법도 있지만 단순히 아까 찾았던 id 값을 JEB에서 검색해도 바로 해당 로직을 찾을 수 있다.

로직을 자세히 보면 위 if문의 조건을 통해 아래 v 부분에서 rooting 탐지 로직이 수행되는 것을 볼 수 있다. 그렇다면 if 문의 조건문만 반대로 변조해준다면 루팅 탐지 로직을 우회할 수 있을지 모른다.

그래서 해당 코드의 어셈블리어를 보면 if-eqz 부분을 확인할 수 있는데 이 부분이 바로 조건문 로직이다. Smali 코드는 이렇게 어셈블리어 코드를 변경하는 방식으로 진행된다.

해당 smali 파일을 연 후 eqz 로직을 nez 로직으로 변조하고 리패키징한다.

참고로 eqz, nez같은 경우는 equal zero, not equal zero와 같은 뜻인데 보통 쓰이는건 아래와 같다

eq - equal (같다)
ne - not equal (같지 않다)
eqz - equal zero (같거나 0)
nez - not equal zero (같지 않거나 0)

즉, 로직이 eq로 되어있으면 ne로 변조하면 반대로 되는것이고, nez로 되어있으면 eqz로 변조하면 마찬가지로 반대로 되는것이다.

그 후 리패키징을 하면 앱이 정상적으로 실행되었다. 전반적인 방식은 이런식으로 진행되지만 아예 메시지가 출력되지 않고 바로 꺼지는 경우도 있다. 이럴떈 finish 함수 등을 검색하여 로직을 판단하는데 이게 쉽지 않을 경우 2번쨰 방법인 Frida를 통해 루팅 우회를 진행한다.

 

2. Frida를 활용한 루팅 탐지 로직 우회

먼저 프리다(Frida)란, Ole에서 개발한 DB(Dynamic Binary Instrumentation)프레임워크로 Windows, MacOS, Linux, Android, iOS 등의 다양한 플랫폼 기반의 네이티브(Native) 애플리케이션을 대상으로 메모리 인젝션(Memory Injection) 기능을 제공하는 파이썬(Python) 라이브러리다

Frida를 통해서는 후킹 기능 이외에도 디버그, 트래픽 스니핑, 암호 해독 등의 작업이 가능하다.

Frida를 사용하기 위해서는 모바일 기기에서는 Frida-Server가 실행되고 있어야 하며 공격자 PC에선 FridaTools가 설치되어 있어야 하며 아래 명령어 및 링크에서 설치 가능하다.

Frida-tools 설치

# pip install frida-tools

 

Frida-Server 설치

https://github.com/frida/frida/releases/

페이지에서 클라이언트 Frida 버전에 맞는 Frida-Server 설치 후 /data/local/tmp 경로로 이동, chmod 777로 권한을 준 후 ./frida-server & 명령어로 백그라운드에서 실행시켜주면 된다.

만약 Frida 환경을 별도로 구성하여 사용하고 싶다면 Python anaconda 환경을 사용하도록 한다.

🐍 아나콘다 설치 - https://www.anaconda.com/download

설치 후 conda activate frida15와 같은 방식으로 별도의 Frida 환경을 사용한다.

 

모바일 앱에서 루팅 탐지를 하는 방식은 보통 루팅된 기기가 가진 파일이나 패키지 등이 단말에 존재하는지 여부를 파악하는 경우가 많다.

// Runtime에서 which, su를 잡아서 루팅탐지를 하고있는 경우에 사용

Java.perform(function() {
    // which, su를 InputSTreamReader에서 Runtime으로 받고 있는 경우
    // java.lang.Runtim.exec(java.lang.String[]) : java.lang.Process
    const Runtime = Java.use('java.lang.Runtime')   // java.lang.Runtime 클래스 정보를 Runtime 변수에 반환
    const exec = Runtime.exec.overload('[Ljava.lang.String;')   // [L 은 배열을 의미, Frida 오류 메시지의 overload에서 복사함

    // implementation이 함수 후킹 최종 구문
    exec.implementation = function(arg){

        console.log("\n[*] is Call!")
        if(/which|su/gi.test(arg)){
            const fakeArray = Java.array('java.lang.String', ['fake', 'fake'])  // which, su를 fake array로 변조해주는것

            console.log("[*] Bypass Success! ")
            return exec.call(this, fakeArray)
        }

        return exec.call(this, arg)  // 원본함수 호출
    }
})

위는 which나 su를 잡아서 루팅 탐지를 하고 있는 경우에 Frida 메모리 후킹을 통해 우회하는 코드다.

which, su 파일을 Fake Array로 전달함으로써 가짜 반환 값을 보내는 방식으로 이루어진다.

보통 루팅 탐지 우회 시 검색하는 문자열은 아래와 같다.

* 루팅 탐지 우회시 검색 할 문자열 *

which, /system/bin, system, su, bin, /system/xbin/, busybox, magisk, KingoUser, SuperSu, vendor, sbin, etc 등

Frida에서 위와 같은 Script를 실행하기 위해서는 아래의 명령어를 사용한다.

# frida -U -F com.playground.anditer -l "스크립트 경로" // 패키지 대상으로 Attach 방식으로 USB에 연결된 앱에 붙는다.
# frida -U -f com.playground.anditer -l "스크립트 경로" // 패키지 대상으로 Spawn 방식으로 USB에 연결된 앱에 붙는다.

모바일 앱에서 탐지하는 방식은 which, su 뿐만 아니라 루팅 시 설치되는 cydia나 sileo 등의 파일을 검증하는 경우도 존재하므로 이러한 로직을 확인하여 우회하는 방식으로 진행하게 된다.