misakikata.github.io/2019/05/%E5%9F%BA%E4%BA%8EdvmDexFileOpenPartial%E7%9A%84%E5%8A%A8%E6%80%81%E8%84%B1%E5%A3%B3/

Android Nougat 보안 정책

https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html

Android Nougat(API Level 24) 이상 버전부터 설치되는 앱은 기본적으로 사용자가 또는 관리자가 추가한 CA를 신뢰하지 않습니다. 그로인해 이전 버전과 동일하게 버프 프록시를 세팅할 경우 패킷이 안잡히는 경우를 보셨을 겁니다.

해결 방안 #1

아래 링크를 참조

https://blog.ropnop.com/configuring-burp-suite-with-android-nougat/

해결 방안 #2

https://techblog.mediaservice.net/2018/11/universal-android-ssl-pinning-bypass-2/

Frida로 해당 코드를 이용하여 해결이 가능하다.

http://comsecuodj.tistory.com/21?category=199091 포스팅 이후로 1년 7개월 만에 Frida에 대한 글을 써봅니다. 저 글을 쓸 당시 Frida Major 버전이 9였는데, 이제 12까지 업데이트 됐네요.

버전이 업데이트 되면서 설치 방법부터 조금씩 바뀐것 같습니다. 예전에는 pip install frida 로 설치가 가능했던 것 같은데 실제로 해당 명령어로 설치해봤더니 설치는 되나 frida-ps 라던지 그 이외의 툴들이 설치 되지 않는 것을 확인했습니다. 앞으론 아래 명령어처럼 설치해야겠습니다.



또 당시만 해도 Nox 앱 플레이어에 프리다 서버를 실행시켜봤지만 실행되지 않았는데 올해  초 저랑 똑같은 질문을 한 사람이 있었나 봅니다. 이런 답변이 있었네요. (ARM 기반의 Frida 서버가 아닌 x86서버로 해도 frida-ps -U 명령어는 됐지만 후킹이 잘 안됐던걸로 기억합니다. 내가 잘못한건가..?)

결론적으로 이제는 잘 됩니다. 테스트 폰이 없어졌는데 이제 굳이 안사도 되겠네요. 크크


후킹 포인트는 2곳이며 소스코드는 아래 처럼 작성했습니다. 이상 ㄲ ㅡ ㅌ.


import frida, sys
 
pacage_name = "com.djoh.memory";
 
def on_message(message, data):
    if message['type'== 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)
 
 
jscode = """
Java.perform(function () {
console.log('[+] Hooking Start!');
console.log("");
    var MainActivity = Java.use('com.djoh.memory.MainActivity');
    MainActivity.isDebuggable.overload('android.content.Context').implementation = function (str) {
        console.log("***********isDebuggable***********");
        console.log("[+] Method Hooking Start!");
        return false;
        console.log("[+] Method Hooking Finish!");
        console.log("**************************");
        console.log("");
        
    };
    MainActivity.showMsg.overload('java.lang.String').implementation = function (str) {
        console.log("***********showMsg***********");
        console.log("[+] Method Hooking Start!");
        console.log("[-" + str);
        console.log("[+] Method Hooking Finish!");
        console.log("****************************");
        console.log("");
        
    };
});
"""
 
process = frida.get_usb_device().attach("com.djoh.memory")
script = process.create_script(jscode)
script.on('message', on_message)
print('[+] Frida Attached!')
script.load()
sys.stdin.read()






https://blog.netspi.com/four-ways-bypass-android-ssl-verification-certificate-pinning/

Four Ways to Bypass Android SSL Verification and Certificate Pinning

이 블로그에서는 Android에서 SSL 인증서 확인을 우회하는 데 사용할 수 있는 4 가지 기술을 살펴 보겠습니다.

  • 신뢰할 수 있는 인증서 저장소에 사용자 지정 CA 추가
  • 패키징된 CA인증서에 커스텀 CA 인증서로 덮어 쓰기
  • Frida를 사용하여 SSL 인증서 검사를 후킹하고 우회
  • 커스텀 인증서 코드 리버싱

SSL MITM – Why?


Technique 1 – Adding a Custom CA to the User Certificate Store

SSL오류를 피하는 가장 간단한 방법은 신뢰할 수 있는 인증서를 사용하는 것입니다. 새롭고 신뢰할 수 있는 인증서를 디바이스에 설치할 수 있으면 비교적 쉽습니다. Android에는 운영 체제에서 신뢰하는 CA(사전 설치된 CA) 및 사용자 저장소(사용자가  설치한 CA)를 추적하는 두 가지 내장 인증서 저장소가 있습니다. 

기본적으로 모든 애플리케이션의 보안 연결(TLS 및 HTTPS와 같은 프로토콜 사용)은 사전 설치된 시스템 CA를 신뢰하고 Android 6.0 (API Level 23)이하를 타겟팅하는 어플리케이션은 기본적으로 사용자가 추가한 CA 저장소를 신뢰합니다. 앱은 base-config(for app wide customization) 혹은 domain-config(for per-domain customization)를 사용하여 자체 연결을 커스터마이징해 사용할 수 있습니다.

이것은 우리에게 무엇을 의미합니까?  MITM을 대상으로 하는 애플리케이션이 Android 6.0이하를 대상으로하는 경우 CA를 user-added CA 저장소에 추가하기만 하면 됩니다. 애플리케이션에서 사용자 커스텀 인증서에 대한 트러스트 체인의 유효성을 검사하면 사용자 커스텀 CA가 trust 저장소에서 발견되고 인증서가 신뢰될것입니다. 그러나 6.0이후의 Android 버전을 대상으로 하는 애플리케이션은 사용자가 추가한 CA저장소를 신뢰하지 않습니다. 이 문제를 해결하기 위해 애플리케이션의 Manifest파일을 수정해 Android 6.0을 대상으로 할 수 있습니다. 타겟 API레벨은 AndroidManifest.xml파일의 'manifest' 요소의 'platformBuildVersionCode' 속성에 지정됩니다. 

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.app" platformBuildVersionCode="25" platformBuildVersionName="7.1.1">

위의 manifest 요소는 ‘platformBuildVersionCode=25'을 대상으로 하며, 23으로 변경해댜 합니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.app" platformBuildVersionCode="23" platformBuildVersionName="6.0">
 


이 업데이트된 매니페스토로 애플리케이션을 다시 리패키징하면 사용자가 추가 한 CA 저장소가 신뢰됩니다.


특정 플랫 버전을 실행해야하는 경우 APK의 '/res/xml/network_security_config.xml' 구성 파일에 특정 트러스트 앵커를 정의할 수 있습니다. 예를 들어 다음 파일은 /res/raw/my_ca(from https://developer.android.com/training/articles/security-config.html)에 저장해야하는 신뢰할 수 있는 CA를 정의합니다.

<?xml version="1.0" encoding="utf-8"?
<network-security-config
<base-config
<trust-anchors
<certificates src="@raw/my_ca"/
</trust-anchors
</base-config
</network-security-config>


애플리케이션에 제시된 인증서가 유효한지만 확인하는 경우이 기술을 사용하면 성공적인 MITM 조건을 설정할 수 있습니다.


Technique 2 – Overwrite Packaged CA Certificate with Custom CA Certificate

사용자가 추가한 CA 저장소에 인증서를 성공적으로 설치하고 애플리케이션 Android 6.0을 대상으로하고 다른 SSL로 보호 된 자원을 시도하고 찾아 볼 때 인증서가 유효한 것으로 나타나지만 SSL 오류로 인해 애플리케이션이 여전히 정지되면 어떻게됩니까? 개발자가 애플리케이션에서 신뢰하는 CA 집합을 제한하기 위한 추가 단계를 수행했을 수 있습니다.  technique 1에서 커스텀 사용자 앵커를 정의하고 CA 인증서 경로를 제공했습니다. 이것은 개발자가 응용 프로그램을 SSL interception으로부터 보호하기 위해 사용할 수 있는 기능입니다.

애플리케이션과 함께 커스텀 인증서 체인을 배포하는 경우 APK를 추출하고 제공된 CA를 우리의 커스텀 CA로 덮어 쓰는 것만으로도 상호 수신 인증서를 신뢰할 수 있는 원인이 되기에 충분합니다. 경우에 따라 트러스트 체인의 추가 확인이 진행될 수 있으므로 이 방법은 여러 가지 결과를 초래할 수 있습니다.

APK Studio와 같은 도구로 APK를 열면 배포 된 애플리케이션과 함께 번들로 제공되는 인증서가 있음을 알 수 있습니다. 위 이미지에서 인증서는 'assets'디렉토리 아래에 있습니다. 적절히 이름 붙여진 'UniversalRootCA'인증서를 사용자 지정 CA로 덮어 쓰면 애플리케이션을 속여서 인증서를 수락 할 수 있습니다.


Technique 3 – Frida Hook

자체 CA를 설치하여 SSL 트랙픽을 프록시하는것이 충분하지 않은 경우 애플리케이션이 SSL Pinning이나 추가적으로 SSL 유효성 검사를 수행할 가능성이 있습니다. 일반적으로 이러한 유효성 검사를 우회하려면 애플리케이션의 코드를 후킹하거나 유효성 검사 프로세스를 방해해야합니다. 이러한 유형의 우회는  루팅/탈옥된 단말기에서만 진행할 수 있지만 Frida Gadget을 이용해 루팅하지 않고도 가능합니다.

모바일 애플리케이션 침투 테스트를 수행한 경함이 있다면 Frida 프레임 워크에 익숙할 것입니다. Frida의 전체 기능을 설명하는 것은 이 블로그의 범위를 벗어나지만 Frida는 런타임시 애플리케이션의 코드를 조작할 수 있는 프레임워크입니다. 일반적으로 프리다는 stand-alone 프로그램으로 운영체제에서 실행되지만 디바이스를 루팅해야합니다. 이를 피하기 위해 Frida Gadget을 대상 APK에 삽입할 수 있습니다. Frida Gadget은 Frida의 기능 대부분을 포함하지만 런타임에 타겟 애플리케이션에 의해 로드되는 동적 라이브러리에 캠슐화되어 타겟 애플리케이션의 코드를 수정할 수 있습니다.

Frida Gadget을 로드하려면 APK를 추출, 동적 라이브러리를 삽입, smali코드를 편집하고 동적 라이브러리를 애플리케이션 시작 시 호출 될 첫 번째 항목으로 만든 다음 APK를 리패키징하고 디바이스에 설치해야합니다. 이 전체 과정은 John Kozyrakis에 의해 문서화 되어 있습니다. 그러나 시작을 절약하기 위해 사용할 수 있는 또 다른 툴인 Objection이 있습니다. Objection은 앞서 이야기했던 전체 프로세스를 자동화하며 커맨드라인에 타겟 APK만 제공하면 됩니다. 

C:\ >objection patchapk -s test_app.apk
No architecture specified. Determining it using `adb`...
Detected target device architecture as: armeabi-v7a
Github FridaGadget is v10.6.28, local is v10.6.13. Updating...
Downloading armeabi-v7a library to C:\.objection\android\armeabi-v7a\libfrida-gadget.so.xz...
Unpacking C:\.objection\android\armeabi-v7a\libfrida-gadget.so.xz...
Cleaning up downloaded archives...
Using Gadget version: 10.6.28
Unpacking test_app.apk
App already has android.permission.INTERNET
Reading smali from: C:\Temp\tmp8dxqks1u.apktemp\smali\com/test/app/TestMainActivity.smali
Injecting loadLibrary call at line: 10
Writing patched smali back to: C:\Temp\tmp8dxqks1u.apktemp\smali\com/test/app/TestMainActivity.smali
Creating library path: C:\Temp\tmp8dxqks1u.apktemp\lib\armeabi-v7a
Copying Frida gadget to libs path...
Rebuilding the APK with the frida-gadget loaded...
Built new APK with injected loadLibrary and frida-gadget
Signing new APK.
jar signed.
Signed the new APK
Performing zipalign
Zipaling completed
Copying final apk from C:\Users\cwass\AppData\Local\Temp\tmp8dxqks1u.apktemp.aligned.objection.apk to current directory...
Cleaning up temp files...


이 과정을 거치면 작업 디렉터리에 'test_app.objection.apk'라는 파일이 생성될 것 입니다. 기본적으로 objection은 원래 APK의 이름에 '.objection'을 추가합니다.  이 APK는 다른 APK와 마찬가지로 설치할 수 있습니다. adb install test_app.objection.apk 명령어를 이용해 디바이스에 설치해봅시다. objection을 통해 변경된 APK가 디바이스에 설치된 후에 앱을 실행하면 시작 화면에서 중지되는 것을 확인할 수 있습니다. 이 시점에서 우리는 Frida 서버에 연결할 수 있습니다.

C:\>frida-ps -U
PID  Name
----  ------
6383  Gadget
 
C:\>frida -U gadget
____
/ _ | Frida 10.3.14 - A world-class dynamic instrumentation framework
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at http://www.frida.re/docs/home/
 
[Motorola Moto G (5) Plus::gadget]-> Java.available
true
 
Alternatively, Objection supports interaction with the listening Frida server by using the ‘explore’ command:
 
C:\>objection explore
 ___| |_  |_|___ ___| |_|_|___ ___
| . | . | | | -_|  _|  _| | . |   |
|___|___|_| |___|___|_| |_|___|_|_|
        |___|     (object)inject(ion) v1.2.2
 
Runtime Mobile Exploration
by: @leonjza from @sensepost
 
[tab] for command suggestions
com.test.app on (motorola: 7.0) [usb] # android hooking search classes TrustManager
android.security.net.config.RootTrustManager
android.app.trust.ITrustManager$Stub$Proxy
android.app.trust.ITrustManager
android.security.net.config.NetworkSecurityTrustManager
android.security.net.config.RootTrustManagerFactorySpi
android.app.trust.TrustManager
android.app.trust.ITrustManager$Stub
com.android.org.conscrypt.TrustManagerImpl
com.android.org.conscrypt.TrustManagerImpl$ExtendedKeyUsagePKIXCertPathChecker
com.android.org.conscrypt.TrustManagerImpl$TrustAnchorComparator
com.android.org.conscrypt.TrustManagerFactoryImpl
javax.net.ssl.TrustManagerFactory$1
javax.net.ssl.TrustManager
javax.net.ssl.TrustManagerFactory
javax.net.ssl.X509TrustManager
javax.net.ssl.TrustManagerFactorySpi
javax.net.ssl.X509ExtendedTrustManager
[Ljavax.net.ssl.TrustManager;


이 시점에서 내장된 SSL 피닝 우회 기능을 활용해야 합니다.

com.test.app on (motorola: 7.0) [usb] # android sslpinning disable
Job: 2f633f86-f252-4a57-958e-6b46ac8d69d1 - Starting
[6b46ac8d69d1] [android-ssl-pinning-bypass] Custom, Empty TrustManager ready
Job: 2f633f86-f252-4a57-958e-6b46ac8d69d1 – Started


Technique 4 – Reversing Custom Certificate Validation Code

마지막으로, 개발자가 시스템 라이브러리에 의존하지 않고 SSL 인증서 유효성 검사를 처리하는 대신 자신이 개발한 SSL 라이브러리를 사용할 수 도 있습니다. 이 경우 APK를 추출하여 smali를 Java로 변환하여 인증서 유효성 확인을 처리하는 코드를 찾을 수 있습니다.



https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05a-Platform-Overview.md

Android Platform Overview

이 섹션에서는 아키텍쳐 관점에서 안드로이드 플랫폼을 소개합니다. 다음과 같은 네 가지 핵심 영역에 대해 논의합니다.

  1.  Android security architecture
  2. Android application structure
  3. Inter-process Communication (IPC)
  4. Android application publishing

Android 플랫폼에 대한 자세한 내용은 공식 Android 개발자 문서 웹 사이트를 참조하십시오.


Android Security Architecture

안드로이드는 Google이 모바일 운영체제 (OS)로 개발 한 Linux 기반 오픈 소스 플랫폼입니다. 현재 이 플랫폼은 휴대 전화, 태블릿, 웨어러블 기술, TV 및 기타 "Smart"디바이스와 같은 다양한 최신 기술의 기반이됩니다. 일반적인 Android 빌드는 미리 설치된 다양한("stock")앱과 함께 제공되며 Google Play 스토어 및 기타 마켓을 통해 third-party 앱 설치를 지원합니다.

Android의 소프트웨어 스택은 여러 가지 레이어로 구성됩니다. 각 계층은 인터페이스를 정의하고 특정 서비스를 제공합니다.

가장 낮은 레벨에서 안드로이드는 Linux Kernel의 변형을 기반으로합니다. 커널 위에 존재하는 HAL (Hardware Abstraction Layer)은 기본 제공 하드웨어 컴포넌트와 상호 작용할 수 있는 표준 인터페이스를 정의합니다.  이는 애플리케이션이 장치의 하드웨어와 상호 작용할 수 있도록 하는 기반입니다. 예를 들어 스톡 전화 애플리케이션에서 장치의 마이크와 스피커를 사용할 수 있습니다.

안드로이드 애플리케이션은 일반적으로 Java로 작성되고 Dalvik 바이트 코드로 컴파일됩니다. 이는 전통적인 Java 바이트 코드와 다소 다릅니다. Dalvik 바이트 코드는 먼저 Java 코드를 .class 파일로 컴파일 한 다음 dx 도구를 사용하여 JVM 바이트 코드를 Dalvik .dex 형식으로 변환하여 만듭니다.

현재 Android 버전은 Android 런타임 (ART)에서 이 바이트 코드를 실행합니다. ART는 Android 오리지널 런타임  Dalvik Virtual Machine의 후속 제품입니다. Dalvik과 ART의 주요 차이점은 바이트 코드가 실행되는 방식입니다.

Dalvik에서 바이트 코드는 JIT (Just-In-Time) 컴파일로 알려진 프로세스에서  실행시점에  machine code로 변환됩니다. 컴파일은 앱이 실행될 때마다 수행되기 때문에 JIT 컴파일은 성능에 나쁜 영향을 줍니다. 성능 향상을 위해 ART는 AOT (ahead-of-time) 컴파일을 도입했습니다. 이름에서 알 수 있듯이 앱은 처음 실행되기 전에 미리 컴파일됩니다. 이 사전에 컴파일 된 machine code는 모든 후속 실행에 사용됩니다. AOT는 전력 소모를 줄이면서 성능을 2배 향상시킵니다.

Android 앱은 하드웨어 리소스에 직접 액세스 할 수 없으며 각 앱은 자체 샌드 박스에서 실행됩니다. 이렇게하면 리소스와 앱을 정밀하게 제어 할 수 있습니다. 예를 들어, 충돌하는 앱은 기기에서 실행중인 다른 앱에는 영향을 미치지 않습니다. 동시에 Android 런타임은 앱에 할당 된 시스템 리소스의 최대 개수를 제어하여 하나의 앱이 너무 많은 리소스를 독점하지 못하게합니다.

Android Users and Groups

안드로이드 운영체제는 리눅스 기반이지만 다른 유닉스 계열 시스템처럼 사용자 계정을 구현하지 않습니다. 안드로이드에서는 샌드 박스 애플리케이션으로 리눅스 커널의 다중 사용자를 지원 합니다. : 몇 가지 예외는 있지만 각 애플리케이션은 다른 Linux 사용자와 마찬가지로 실행되며 다른 애플리케이션 및 나머지 운영 체제와 효과적으로 격리됩니다.

system/core/include/private/android_filesystem_config.h 파일 에는 시스템 프로세스가 할당 된 사전 정의 된 사용자 및 그룹 목록이 포함됩니다. 자세한 내용은 Bin Chen의 Android sandboxing 블로그 게시물을 확인하십시오.

예를 들어, Android Nougat는 다음 시스템 사용자를 정의합니다.

     #define AID_ROOT             0  /* traditional unix root user */

    #define AID_SYSTEM        1000  /* system server */

...

    #define AID_SHELL         2000  /* adb and debug shell user */

...

    #define AID_APP          10000  /* first app user */

...

Android Application Structure

Communication with the Operating System

안드로이드 애플 리케이션은 안드로이드 프레임 워크, 높은 수준의 자바 API를 제공하는 추상화 계층을 통해 시스템 서비스와 상호 작용합니다. 이러한 서비스의 대부분은 일반적인 Java 메소드 호출을 통해 호출되며 백그라운드에서 실행중인 시스템 서비스에 대한 IPC 호출로 변환됩니다. 시스템 서비스의 예는 다음과 같습니다.

  - Connectivity (Wi-Fi, Bluetooth, NFC, etc.)

  - Giles

  - Cameras

  - Geolocation (GPS)

  - Microphone

프레임 워크는 또한 암호화와 같은 일반적인 보안 기능을 제공합니다.

새로운 Android 버전이 출시 될 때마다 API 사양이 변경됩니다. 중요한 버그 수정 및 보안 패치는 일반적으로 이전 버전에도 적용됩니다. 작성 당시에 지원 된 가장 오래된 Android 버전은 4.4 (KitKat), API 레벨 19, 현재 Android 버전은 7.1 (Nougat), API 레벨 25입니다.

주목할만한 API 버전 :
  • 2012년 11월 Android 4.2 Jelly Bean (API 16) (SELinux 소개)
  • 2013년 07월 Android 4.3 Jelly Bean (API 18) (SELinux 기본적으로 사용)
  • 2013년 10월 Android 4.4 KitKat (API 19) (몇가지 새로운 API 및 ART 도입)
  • 2014년 11월 Android 5.0 Lollipop (API 21) (ART는 기본적으로 사용되며 다른 많은 기능이 추가됨)
  • 2015년 10월 Android 6.0 Marshmallow (API 23) (many new features and improvements, including granting; detailed permissions setup at run time rather than all or nothing during installation)
  • 2016년 08월 Android 7.0 Nougat (API 24-25) (ART의 새로운 JIT 컴파일러)
  • Android 8.0 O (API26) 베타 (주요 보안 수정 예정)

App Folder Structure

설치된 Android 앱은 /data/app/[package-name]에 있습니다. 예를 들어 YouTube 앱의 위치는 다음과 같습니다.

   /data/app/com.google.android.youtube-1/base.apk

Android Package Kit(APK) 파일은 앱을 실행하는데 필요한 코드와 리소스가 포함된 아카이브 파일 입니다. 이 파일은 개발자가 만든 서명된 원본 앱 패키지와 동일합니다. 실제로 다음 디렉토리 구조를 가진 ZIP 아카이브 입니다.

$ unzip base.apk

 $ ls -lah

  -rw-r--r--   1 sven  staff    11K Dec  5 14:45 AndroidManifest.xml

  drwxr-xr-x   5 sven  staff   170B Dec  5 16:18 META-INF

  drwxr-xr-x   6 sven  staff   204B Dec  5 16:17 assets

  -rw-r--r--   1 sven  staff   3.5M Dec  5 14:41 classes.dex

  drwxr-xr-x   3 sven  staff   102B Dec  5 16:18 lib

  drwxr-xr-x  27 sven  staff   918B Dec  5 16:17 res

  -rw-r--r--   1 sven  staff   241K Dec  5 14:45 resources.arsc

  • AndroidManifest.xml : 앱의 패키지 이름, 대상 및 최소 API 버전, 앱 구성, 컴포넌트, 사용자가 부여한 권한 등의 정의를 포함합니다.
  • META-INF : 앱의 metadata를 포함 합니다.
  1. MANIFEST.MF : 앱 리소스의 해시를 저장합니다.
  2. CERT.RSA : 앱의 인증서
  3. CERT.SF : MANIFEST.MF 파일의 해당 라인에 대한 리소스 목록 및 SHA-1 다이제스트
  • assets : AssetManager가 검색할 수 있는 app asset (XML 파일, JavaScript 파일 및 그림과 같은 Android 앱 내에서 사용되는 파일)을 포함하는 디렉터리
  • classes.dex : Dalvik virtual machine / Android Runtime이 처리할 수 있는 DEX파일 형식으로 컴파일 된 class. DEX는 Dalvik Virtual Machine용 Java Bytecode입니다.
  • lib : APK의 일부인 라이브러리가 들어있는 디렉토리입니다. (예 : Android SDK에 포함되지 않은 타사 라이브러리)
  • res : resources.arsc로 컴파일되지 않은 자원을 포함하는 디렉토리
  • resources.arsc : 레이아웃을위한 XML 파일과 같은 미리 컴파일 된 리소스를 포함하는 파일

아카이브를 unzip 유틸리티로 압축을 풀면 일부 파일을 읽을 수 없게됩니다. AndroidManifest.XML은 텍스트 편집기로 읽을 수없는 바이너리 XML 형식으로 인코딩됩니다.













중요한 작업 (암호화, 민감한 정보가 포함 된 서버 응답 구문 분석 등)이 끝날 때마다 가비지 컬렉션garbage collection을 요청해야 한다. 정보의 일부 사본이 제대로 정리되지 않은 경우 이를 통해 (아래 설명 참조)복사본을 메모리에서 사용할 수 있는 시간을 줄이는 데 도움이 된다.
중요한 정보를 메모리에서 적절하게 정리하려면 중요정보 저장 시 바이트 배열 (byte []) 또는 char 배열 (char [])과 같은 원시 데이터 형식을 사용하는 것이 가장 좋다.
중요한 개체가 더 이상 필요 없으면 내용을 덮어 쓴다. 간단하고 인기있는 방법 중 하나는 내용을 0으로 덮어 쓰는 것이다.

 


How to get current foreground activity context in android?

안드로이드 앱 진단 시 가끔 현재 Activity가 궁금해질때가 있습니다. 친절하게도 Android에서 제공하는 ActivityManager 클래스를 통해 확인할 수 있습니다. 역시나 제가 필요한건 누군가 먼저 만들었네요

 

What is the ActivityClass?

ActivityManager

public class ActivityManager 

extends Object 


This class gives information about, and interacts with, activities, services, and the containing process.


Script

아래 스크립트는 로그를 이용해서 현재 액티비티를 출력 해줍니다. 간단한 소스코드라 따로 설명이 필요없을 듯 하네요!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.bignerdranch.android.test;
 
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
 
import java.util.List;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        ActivityManager activity_manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> task_info = activity_manager.getRunningTasks(9999);
        for(int i=0; i<task_info.size(); i++) {
            Log.d("XXXXXXXXXX""[" + i + "] activity:"+ task_info.get(i).topActivity.getPackageName() + " >> " + task_info.get(i).topActivity.getClassName());}
    }
}
 
cs


참고

https://developer.android.com/reference/android/app/ActivityManager.html

http://stackoverflow.com/questions/11411395/how-to-get-current-foreground-activity-context-in-android

http://stackoverflow.com/questions/3873659/android-how-can-i-get-the-current-foreground-activity-from-a-service

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

Adnroid# Platform-Overview  (0) 2018.02.08
Android@Memory# 메모리 중요정보 노출  (0) 2017.08.15
Android@Frida#Rooting Bypass(1)  (0) 2017.02.27
Android@SSL Pinning# Android SSL Pinning Bypass  (0) 2017.01.27
Android@Frida# Frida  (0) 2017.01.25

Rooting Bypass


Rooting Check Script

BuildTag를 이용한 Rooting Check Script입니다. 이외에 루팅 체크 하는 방식은 많지만 간단하게 BuildTag를 이용해 루팅 체크를 해보겠습니다.

BuildTag를 확인하고 싶을 경우 모바일 기기에 adb shell로 접근 하여 cat /system/build.prop | grep ro.build.tags 해당 명령어를 입력 합니다. 

모바일 기기가 루팅 되어 있을 경우 ro.build.tags=release-keys, 루팅 되어 있지 않을 경우 ro.build.tags=test-keys 결과를 확인할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.bignerdranch.android.rootcheck;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
public class RootCheck extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_root_check);
        Button b =(Button)findViewById(R.id.button);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isPhoneRooted()){
                    Toast.makeText(getApplicationContext(),"Phone Not Rooted", Toast.LENGTH_LONG).show();
                }else {
                    Toast.makeText(getApplicationContext(),"Phone Rooted", Toast.LENGTH_LONG).show();
                }
            }
        });
    }
    public static boolean isPhoneRooted() {
        // get from build info
        String buildTags = android.os.Build.TAGS;
        if (buildTags != null && buildTags.contains("test-keys")) {
            return true;
        }
        return false;
    }
}
 

루팅 되어 있는 모바일 기기에서 RootCheck 버튼 클릭 시 Phone Rooted 메세지를 출력 하며 루팅 여부를 확인할 수 있습니다.




Rooting Bypass Script

Frida를 이용하여 Rooting Check를 우회 하도록 해보겠습니다. isPhoneRooted()메소드 호출 시 return 값을 True로 변경 하여 우회를 시도 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import frida, sys
 
package_name = "com.bignerdranch.android.rootcheck"
 
def get_messages_from_js(message, data):
    if message['type'== 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)
 
def instrument_root_checks():
 
        hook_code = """
        console.log('Start');
        setTimeout(function(){
        Java.perform(function () {
            var TM = Java.use("com.bignerdranch.android.rootcheck.RootCheck");
            TM.isPhoneRooted.implementation = function () {
                send("Called - isPhoneRooted()");
                return true;
            };
        });
    },0);
        """
 
        return hook_code
 
process = frida.get_device_manager().enumerate_devices()[-1].attach(package_name)
script = process.create_script(instrument_root_checks())
script.on('message',get_messages_from_js)
script.load()
sys.stdin.read()
              
cs


Rooting Check Bypass 스크립트를 저장 후 실행 합니다. 정상적으로 실행 시 콘솔 창에 아래 그림과 같은 메세지가 출력 되며 Rooting Check 버튼 클릭 시 Phone Not Rooted 메시지를 통해 후킹이 정상적으로 이루어졌음을 확인할 수 있습니다.



+ Recent posts