들어가기 앞서
해당 게시글부터 제가 제작한 ANDITER를 활용해 안드로이드의 주요 보안 탐지 및 우회 방법에 대한 시리즈를 작성하려고 합니다. 원래 지금 재직 중인 회사에서 분석 글로 작성했던 거지만 블로그에도 정리를 하려고 합니다.
ANDITER 앱 같은 경우는 안드로이드 앱에서 루팅, 프리다, 피닝 등을 어떻게 탐지하고 또 이를 공격자의 관점에서 어떻게 우회할 수 있는지 배울 수 있는 좋은 학습 앱으로 모바일 보안을 처음 접하시는 분들에게는 큰 도움이 될 거라고 생각합니다. 실습하다가 모르는 부분이나 막히시는게 있다면 댓글 달아주시면 답변 드리겠습니다.
실습을 위해 ANDITER 앱 다운로드가 필요한 경우 아래의 링크에서 다운로드 가능하며, NoEncryption 버전을 다운로드 받으셔서 실습을 진행해주시면 됩니다. Encryption 버전은 난독화 적용 버전이고 NoEncryption은 난독화 미적용 버전으로 포스팅에서는 난독화 미적용 버전인 NoEncryption 버전이 사용되었습니다.
개요
디바이스 루팅 시 사용된 응용 프로그램 종류에 따라 다르겠지만, 디바이스 내부 저장소에는 특정 패키지들이 함께 설치된다. 이렇게 설치된 패키지들은 특정 동작 수행을 위해 관리자 권한을 획득하거나 또는 디바이스 정보를 변경하는데 사용된다. 설치되거나 또는 설치하는 대표적인 패키지들로는 Magisk(com.topjohnwu.magisk), Super Key(com.super.superkey) 등이 있다.
Bypass Packages 항목은 디바이스에 설치된 앱 패키지 목록을 검사해 루팅 시 사용되는 알려진 패키지 목록들이 존재하는지 검사하고 패키지 존재 시 루팅 디바이스로 판단해 탐지하게 된다.
※ 디바이스마다 사용하고 있는 루팅 관련 패키지 정보들이 다 상이하기 때문에 원활한 실습 진행을 위해 탐지를 원하는 경우 ANDITER를 다운로드 받았던 github에 AnditerRooting.apk를 다운로드 받으셔서 설치하시면 됩니다.
실습 환경
도구 | 버전 |
JEB | 4.2 |
APK Easy Tool | 1.60 |
갤럭시 Z(루팅 유) | Android 13.0 |
분석
해당 포스팅은 JEB 디컴파일러 도구를 통해 ANDITER 앱을 분석하며, 다운로드가 필요하신 분은 공식 홈페이지에 접속해 데모 버전을 다운로드 받을 수 있습니다. -> https://www.pnfsoftware.com/jeb/demo
[그림 2]의 isCheckRootingInstalled() 함수는 Bypass Packages 탐지 결과를 반환해 주는 역할을 한다. 코드를 보면 ①에서 [그림 1]의 rootingPackages에서 패키지 목록을 가져오고 있으며 ② getPackagesInfoCompat() 함수를 통해 가져온 패키지 정보를 반환받게 된다. 패키지 정보가 있을 경우 디바이스에 해당 패키지가 설치되어 있는 것으로 판단해 탐지하게 된다.
Bypass Packages 탐지를 우회하기 위한 포인트는 두 가지가 있다. 첫 번째는 [그림 1]의 검사하는 패키지 목록을 가지고 있는 rootingPackages 리스트 요소를 더미 값으로 변조하는 방법이고 두 번째는 isCheckRootingInstalled() 함수에서 사용되는 While문의 조건식을 변조해 While 구문이 동작되지 않도록 만드는 방법이다. 여기서는 리패키징 방식으로 두 번째 방법을 사용해 탐지를 우회해 보도록 하겠다.
리패키징이란?
앱을 디컴파일 후 실행 코드를 수정한 후 다시 실행 파일로 패키징하는 기법
우회 실습
코드 수정을 위해서는 classes.dex 파일이 필요하다. Dex 파일에는 Android 런타임에서 애플리케이션 실행에 필요한 코드가 포함되어 있으며, 애플리케이션 실행 파일인 apk 파일을 압축 해제하면 확인 할 수 있다. 하지만, Dex 파일의 경우 기계어로 작성되어 있어 사람이 읽고 또 그것을 수정하기에는 무리가 있다. 따라서, Dex 파일을 사람이 읽을 수 있도록 표현한 언어인 smali 코드로 변환해줘야 한다.
[그림 3]의 APK Easy Tool은 Dex 파일을 smali 코드로 변환해 주는 도구이다. 원래는 apktool이라는 도구의 콘솔 명령어를 이용해 직접 디컴파일 해줘야 하지만 APK Easy Tool을 사용한다면 클릭 한 번으로 쉽게 디컴파일된 smali 코드를 추출할 수 있다. 또한, APK Easy Tool은 디컴파일 기능 외에도 컴파일 기능과 자동 사이닝 기능이 있어 리패키징 과정을 빠르고 간편하게 만들어준다. 사용 방법은 Browse 버튼을 클릭해 추출을 원하는 apk 파일을 선택해 주고 Decompile 버튼을 클릭하면 된다.
디컴파일이 완료 되었다면 [그림 4]와 같은 산출물이 도출되고 이 중 smali 디렉터리를 확인해보면 추출된 smali 코드를 패키지 별로 확인할 수 있다.
smali 코드 추출이 완료되었다면 텍스트 편집기를 통해 코드를 수정하면 된다. 그런데 여기서 문제가 하나 있는데 smali 코드는 패키지, 클래스, 함수 별로 존재하고 있어 수정하려는 함수가 포함되어 있는 코드가 어떤 코드인지 찾기가 쉽지 않다는 것이다. 이를 위해 JEB 도구에서는 강력한 기능을 제공하고 있는데 바로 smali 코드와 Java 코드의 매핑 기능이다.
사용 방법은 간단하다. 사용자가 원하는 Java 코드 영역에 마우스를 클릭하고 Tab 버튼을 누르거나 마우스 오른쪽 버튼 클릭 후 출력되는 팝업 창에서 디컴파일 버튼을 클릭하면 된다. 반대로 smali 코드에서 Java 코드 매핑도 가능하다.
[그림 5]는 isCheckRootingInstalled() 함수명을 smali 코드랑 매핑한 결과이다. 추가로 코드에 마우스를 가져다 대고 잠시 기다리면 매개변수, 반환 값 등 코드에 대한 간략한 설명이 나오는데 그 중 Decscriptor에는 smali 코드 경로가 표시되어 있다. 해당 기능을 사용하지 않고도 패키지 명과 함수 명을 통해서 smali 코드를 찾을 수 있으나, 난독화 모듈이 적용된 코드에서는 함수명이 a,b,c 알파벳 또는 숫자 등의 의미 없는 문자열로 지정되어 있어 찾는데 시간이 오래 소요되기 때문에 위 기능을 활용할 경우 분석 시간을 단축 시킬 수 있다.
smali 코드 위치가 확인이 되었다면 smali 코드에서 변조 포인트를 찾아야 한다. JEB 도구로 돌아와 [그림 6]의 매핑된 코드를 살펴보면 ① smali 코드 구문이 Java 소스코드의 while문 조건 구문이며 v4, v2 레지스터리에 저장된 값을 비교해 v4 값이 v2 보다 클 경우 38로 분기된다. 반대로 v4 값이 v2 보다 작을 경우 0x00000014 ~ 0x0000004C 주소까지 구문들이 동작해 패키지 검사를 하게 된다. ② 분기문 38의 smali 코드를 살펴보면 함수를 호출한 곳으로 false 값이 반환된다. 따라서, 첫 번째 smali 코드 구문의 조건문을 참으로 만들어 분기문 38로 분기시킨 다음 false 값을 반환할 수 있도록 변조하면 된다.
조건문 | 설명 |
If-eq | A==B |
if-ne | A!=B |
If-lt | A<B |
If-le | A<=B |
If-ge | A>=B |
If-gt | A>B |
[표 1] smali 코드의 if 문법
[그림 7]의 표시된 구문이 [그림 6]에서 확인한 while문 조건 구문이다. 탐지 우회를 위해서는 해당 조건 구문을 참으로 만들어야 하기 때문에 [표 1]를 참고해 조건식을 수정해주면 된다. 여기서는 if-ge를 if-le로 수정했다.
samli 코드 수정이 완료되었다면 실행 파일인 apk 파일로 다시 만들어줘야 한다. smali 코드를 apk 파일로 만들기 위해서는 smali 코드를 컴파일해 Dex 파일로 변환하고 사이닝 및 리빌딩 과정을 거쳐야 한다. 이러한 일련의 과정들은 손도 많이 가고 각각의 과정에서 그에 맞는 도구들을 사용해야 하지만, APK Easy Tool를 사용하면 원 클릭으로 smali 코드를 다시 apk 파일로 리패키징 할 수 있다. 디컴파일 했던 apk 디렉터리를 다른 곳으로 이동시키지 않았다면 [그림 8]와 같이 Compile 버튼을 클릭하면 자동으로 컴파일 되어 apk 파일로 만들어진다.
컴파일 과정이 끝났다면 산출물인 apk 파일을 설치 후 ANDITER에서 Bypass Packages 항목을 체크하면 Success!가 출력되며 탐지가 우회된 것을 볼 수 있다.
참고
● 필자가 작성한 원본 분석 글은 아래의 링크에서 확인 가능하다.
'안드로이드 탐지 및 우회 > 루팅 탐지 및 우회' 카테고리의 다른 글
ANDITER를 활용한 시스템 속성 기반의 루팅 탐지 및 우회 방법 (0) | 2023.06.01 |
---|---|
ANDITER를 활용한 Writeable 기반의 루팅 탐지 및 우회 방법 (0) | 2023.05.31 |
ANDITER를 활용한 Build.prop 기반의 루팅 탐지 및 우회 방법 (0) | 2023.05.25 |
ANDITER를 활용한 명령어(which) 기반의 루팅 탐지 및 우회 방법 (0) | 2023.05.25 |
ANDITER를 활용한 Binary 기반의 루팅 탐지 및 우회 방법 (0) | 2023.05.24 |