들어가기 앞서
이전 "동적 디버깅 도구(JEB Decompiler) 탐지 방안과 우회 기법" 포스팅에 이어서 디바이스에 개발자 모드 옵션 허용 여부를 검사하여 동적 디버깅을 탐지하는 방안과 우회 기법을 다뤄보도록 하겠다.
실습 진행에 사용되는 ANDITER 앱은 아래의 GitHub에서 다운로드 가능하다.
개요
Android OS 기반의 모바일 디바이스에는 개발자 옵션이라는 히든 설정이 존재한다. 해당 설정은 개발자들이 애플리케이션 제작 시 하드웨어 렌더링, 애니메이션, 블루투스 등 관련 기능을 테스트 할 때 주로 사용되며 설정 중에는 디버그 사용을 위한 관련 항목도 존재한다.
[그림 2]는 개발자 옵션에서 디버깅 항목을 보여주고 있으며 이 중 USB 디버깅 설정은 애플리케이션 개발 시 사용되는 Android 스튜디오와 SDK 도구가 USB를 통해 디바이스를 인식할 수 있도록 도와주는 기능이다. 또한, 동적 분석을 위한 디버그 도구 사용 시에도 도구와 디바이스 연결을 위해서 사용된다.
Bypass Develop Mode 탐지 항목은 애플리케이션 기능 테스트를 위해 사용되는 개발자 옵션이 디바이스에서 사용 중인지 확인하고 사용 중일 경우 애플리케이션이 디버그 모드로 동작 중인 것으로 판단해 탐지하게 된다. 다만, 개발자 옵션의 경우 디버그 목적 외에도 다른 용도로 사용할 수 있기 때문에 실제 애플리케이션에서는 디버그를 탐지할 때 개발자 옵션 사용 유무만으로 판단하지 않고 추가로 다른 설정들과 함께 참고해 디버그 모드를 탐지한다.
실습 준비
개발자 옵션은 히든 메뉴로 별도의 방법을 통해서만 활성화 시킬 수 있다. 활성화 방법은 사용 중인 디바이스 기종과 제조사 별로 조금씩 차이가 있겠으나 큰 흐름은 똑같으며, [표 1]을 참고해 개발자 모드를 활성화시키면 된다. 만약 사용 중인 디바이스가 아래 목록에 포함되어 있지 않다면 디바이스 제조사 홈페이지의 매뉴얼을 통해 확인하면 된다.
제조사 | 디바이스 모델 | 설정 |
구글 | Pixel | 설정 > 휴대전화 정보 > 빌드 번호 5번 이상 터치 |
삼성 | Galaxy S8 이상 | 설정 > 휴대전화 정보 > 소프트웨어 정보 > 빌드 번호 5번 이상 터치 |
LG | G6 이상 | 설정 > 휴대전화 정보 > 소프트웨어 정보 > 빌드 번호 5번 이상 터치 |
HTC | U11 이상 | 설정 > 정보 > 소프트웨어 정보 > 더 보기 > 빌드 번호 또는 설정 > 시스템 > 휴대전화 정보 > 소프트웨어 정보 > 더 보기 > 빌드 번호 5번 이상 터치 |
OnePlus | 5T 이상 | 설정 > 휴대전화 정보 > 빌드 번호 5번 이상 터치 |
[표 1] 제조사별 개발자 모드 활성화 방법
분석
[그림 3-28]의 isCheckDevelopMode() 함수는 Bypass Develop Mode 탐지 결과를 반환해주는 역할을 한다. 코드를 보면 Settings 클래스가 사용 되었는데 해당 클래스는 디바이스에서 사용하는 설정에 관련된 정보들을 제공해 주며 내부 클래스인 Global를 통해 디바이스에 공통적으로 적용되는 설정 값을 참조할 수 있다. 그리고 인자로 전달되는 development_settings_enabled 설정 값을 getInt() 함수를 통해 반환 받게 된다. 값이 0이면 개발자 옵션이 비활성화 상태를 뜻하고 1이면 활성화 상태를 뜻한다. 따라서, 값이 1인 경우 디버그 모드가 동작 중인 것으로 판단해 탐지하게 된다.
Bypass Develop Mode 탐지를 우회하기 위한 후킹 포인트는 두 가지가 있다, 첫 번째는 함수 결과와 상관없이 무조건 False를 반환하도록 isCheckDevelopMode() 함수를 재 작성하는 방법이고 두 번째는 Settings.Global 클래스 getInt() 함수의 인자로 전달되는 설정 값을 변조하는 방법이다. 여기서는 두 번째 방법을 사용해 탐지를 우회해 보도록 하겠다.
우회 실습
[그림 5]는 getInt() 함수를 후킹하기 위해 필자가 작성한 Frida 스크립트이다. 코드를 보면 ①에서 getInt() 함수 사용을 위해 Settings 클래스 객체를 생성했고 isCheckDevelopMode()에서 getInt() 함수를 호출할 때 전달되는 인자의 데이터 타입에 맞춰 getInt() 함수를 오버로딩으로 구현한다. ②에서는 함수 호출 시 매개 변수 들어오는 설정 값이 development_settings_enabled일 경우 더미 값으로 변조하고 변조한 더미 값을 인저로 원본 getInt() 함수를 호출해 해당 결과 값을 반환하게 된다.
Frida를 통해 작성한 스크립트를 ADITER 애플리케이션에 어태치 하고 Bypass Develop Mode 탐지 항목을 체크하면 Success! 가 출력되며 탐지가 우회된 것을 볼 수 있다.
마무리
지금까지 앱 디버깅 시 디바이스 내에 설정되어야 하는 옵션인 개발자 모드 허용 여부를 검사하여 디버깅을 탐지하는 방안과 또, 이를 공격자의 관점에서 어떻게 우회할 수 있는지 살펴봤다. 다음 포스팅에서는 개발자 모드 옵션 중 하나인 USB 디버깅 옵션 허용 여부를 검사하여 동적 디버깅을 탐지하는 방안과 우회하는 기법을 다뤄보도록 하겠다.
'안드로이드 탐지 및 우회 > 디버깅 탐지 및 우회' 카테고리의 다른 글
USB 연결 검사를 통한 동적 디버깅 탐지 방안과 우회 기법 (0) | 2023.08.04 |
---|---|
USB 디버깅 옵션 검사를 통한 동적 디버깅 탐지 방안과 우회 기법 (0) | 2023.08.03 |
동적 디버깅 도구(JEB Decompiler) 탐지 방안과 우회 기법 (0) | 2023.07.28 |
ro.debuggable 값 검사를 통한 동적 디버깅 탐지 방안과 우회 기법 (0) | 2023.07.11 |
TracerPid 검사를 통한 동적 디버깅 탐지 방안과 우회 기법 (1) | 2023.07.10 |