从 Android apk 或 .so 文件中提取机密

逆向工程 拆卸 二元分析 安卓 二进制 apk
2021-06-25 10:32:37

语境

作为练习,我正在研究在 android 移动应用程序二进制文件中隐藏秘密的所有方法......是的,我知道通过或多或少的努力,它们总是可以通过静态分析、运行时内省或 MITM 攻击提取出来。

在我隐藏秘密的研究中,我为 Android 找到的最好方法是使用 JNI/NDK,直到现在我还没有找到逆向工程的方法。

注意:我了解逆向工程师的高级概念,但我没有任何这样做的经验。

我的尝试

$ strings -aw lib/x86/libnative-lib.so | grep -C 1 -irn 'the-secret-api-key-goes-here' -
932-[^_]
933:the-secret-api-key-goes-here
934-cannot allocate __cxa_eh_globals

所以我在二进制文件中找到了 API 密钥,因为我知道它,但我希望能够通过搜索它关联的变量来找到它:

$ strings -aw lib/x86/libnative-lib.so | grep -C 1 -irn 'JNI_API_KEY' -
$

或者

$ strings -aw lib/x86/libnative-lib.so | grep -C 1 -irn 'SECRETS_API_KEY' -
$

这两个不返回任何结果......我试图也用hexdumpobjdump没有任何成功!

我也尝试过radare2retdec但我缺乏知识可能无法帮助我找到 API 密钥。

作为最后一次尝试我都去编译二进制MobSF和关注的smali代码JNI_API_KEYSECRETS_API_KEYthe-secret-api-key-goes-here没有任何成功。

在这一点上,我不想求助于 Frida 或 xPosed 来获取运行时逆向工程技术或 MITM 攻击方法......

所以现在我只想知道我是否可以使用其他二进制或反编译技术来找到 API 密钥?

注意:寻找开源工具,而不是商业工具。

代码

我用来在 Android 应用程序中使用 JNI 和 NDK 隐藏 API 密钥的代码如下...

文件:native-lib.cpp

#include <jni.h>
#include <string>
#include "api_key.h"

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_secrets_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {

    // To add the API_KEY to the mobile app when is compiled you need to:
    //   * copy `api_key.h.example` to `api_key.h`
    //   * edit the file and replace this text `place-the-api-key-here` with your desired API_KEY
    std::string JNI_API_KEY = SECRETS_API_KEY;

    return env->NewStringUTF(JNI_API_KEY.c_str());
}

文件:api_key.h

#ifndef SECRETS_API_KEY
#define SECRETS_API_KEY "the-secret-api-key-goes-here"

#endif / SECRETS_API_KEY

文件:CMakeLists.txt

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# orJNI_API_KEY SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        native-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
1个回答

如果 API 密钥是一个字符串,那么就像您在示例中所做的那样,只需运行strings就会显示它grep可能还有一些其他字符串,但更长的字符串似乎很突出,因此应该清楚地看到这是有意义的。有了那个 API 密钥,我可能会去使用常规的反汇编工具来查看它的使用位置和使用方式。

您无法按变量名称进行搜索,因为这些名称未保存在二进制文件 (.so) 中,对于 APK,它可能会有所不同。