【frida逆向开发】frida-rpc远程调用某安app方法获取token

目录

        • 一、使用fiddler对app进行抓包
        • 二、反编译app定位关键代码
        • 三、frida-rpc调用相关方法


一、使用fiddler对app进行抓包

【frida逆向开发】frida-rpc远程调用某安app方法获取token_第1张图片
通过抓包可以看到请求参数中X-App-Token: e8f1c71569a7166b6aa9723342923606edc38cb9-c72d-3bc4-8e82-6fd9212d77a00x5fdb0663每次请求都是变化的,这里需要反编译app进行进一步的分析。

二、反编译app定位关键代码

直接使用jadx反编译app并通过搜索相关参数定位相关代码

【frida逆向开发】frida-rpc远程调用某安app方法获取token_第2张图片
【frida逆向开发】frida-rpc远程调用某安app方法获取token_第3张图片

private String[] createHeaders() {
     
        Locale locale = Locale.getDefault();
        String valueOf = String.valueOf(VERSION.SDK_INT);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(locale.getLanguage());
        stringBuilder.append(Constants.ACCEPT_TIME_SEPARATOR_SERVER);
        stringBuilder.append(locale.getCountry());
        String stringBuilder2 = stringBuilder.toString();
        String as = AuthUtils.getAS(this.appContext, this.deviceId);
        StringBuilder stringBuilder3 = new StringBuilder();
        stringBuilder3.append(getAndroidId());
        stringBuilder3.append("; ");
        stringBuilder3.append(getImeiOrMeid());
        stringBuilder3.append("; ");
        stringBuilder3.append(getImsi());
        stringBuilder3.append("; ");
        stringBuilder3.append(getMacAddress());
        stringBuilder3.append("; ");
        stringBuilder3.append(Build.MANUFACTURER);
        stringBuilder3.append("; ");
        stringBuilder3.append(Build.BRAND);
        stringBuilder3.append("; ");
        stringBuilder3.append(Build.MODEL);
        String replaceAll = new StringBuilder(Base64.encodeToString(stringBuilder3.toString().getBytes(), 0)).reverse().toString().replaceAll("\\r\\n|\\r|\\n|=", "");
        String str = "0";
        if (AppHolder.getAppTheme().isNightTheme()) {
     
            str = "1";
        } else if (AppHolder.getAppTheme().isAmoledTheme()) {
     
            str = "2";
        }
        return new String[]{
     HttpHeaders.USER_AGENT, this.userAgent, "X-Requested-With", "XMLHttpRequest", "X-Sdk-Int", valueOf, "X-Sdk-Locale", stringBuilder2, "X-App-Id", BuildConfig.APPLICATION_ID, "X-App-Token", as, "X-App-Version", this.appVersionName, "X-App-Code", String.valueOf(this.appVersionCode), "X-Api-Version", EntityListFragment.APK_TYPE_DYH, "X-App-Device", replaceAll, "X-Dark-Mode", str};
    }

分析代码得出as的值赋给X-App-Token,as = AuthUtils.getAS(this.appContext, this.deviceId);

【frida逆向开发】frida-rpc远程调用某安app方法获取token_第4张图片
【frida逆向开发】frida-rpc远程调用某安app方法获取token_第5张图片
【frida逆向开发】frida-rpc远程调用某安app方法获取token_第6张图片
提示:frida-rpc远程调用某个方法时,如果该方法需要传参,需要自己手动组装正确的参数。

如上图所示调用getAS需要传递两个参数contextstr

context上下文组装方式如下:

//拿到context上下文
var currentApplication = Java.use('android.app.ActivityThread').currentApplication();
var context = currentApplication.getApplicationContext();

str这个参数是我们不知道的,我们可以对getAS进行普通的hook操作,来得到str的值。

import frida  #导入frida模块
import sys    #导入sys模块

jscode = """
    Java.perform(function(){  
        var AuthUtils = Java.use('com.coolapk.market.util.AuthUtils') // 类的加载路径
        
        AuthUtils.getAS.implementation = function(a,b){   // str为getAS的参数,原getAS需要几个参数就写几个
            send(a);  
            send(b);  // 这里的b就是str的值

            var as = this.getAS(a,b);  // 源函数有返回值 这里我们也将得到的返回值return
            return as 
        };
        
    });
"""

def on_message(message,data): #js中执行send函数后要回调的函数
    if message["type"] == "send":
        print("[*] {0}".format(message["payload"]))
    else:
        print(message)
    
process = frida.get_usb_device().attach('com.coolapk.market') # app包名
script = process.create_script(jscode) #创建js脚本
script.on('message',on_message) #加载回调函数,也就是js中执行send函数规定要执行的python函数
script.load() #加载脚本
sys.stdin.read()

注意:这种调用方式需要我们手动触发api调用getAS这个方法才会执行我们对应的脚本。

在这里插入图片描述

str为固定值edc38cb9-c72d-3bc4-8e82-6fd9212d77a0

三、frida-rpc调用相关方法

通过这种调用方式去主动调用相关方法来生成加密的token

import codecs
import frida
import os

def adbforward():
    os.system("adb forward tcp:27042 tcp:27042")
    os.system("adb forward tcp:27043 tcp:27043")

hook_code = '''
rpc.exports = {
    // 函数名gethello
    gethello: function(str){
        send('heelo');
        Java.perform(function(){

            //拿到context上下文
            var currentApplication = Java.use('android.app.ActivityThread').currentApplication();
            var context = currentApplication.getApplicationContext();

            // use 加载的类路径
            var AuthUtils = Java.use('com.coolapk.market.util.AuthUtils');
            //f = tt.$new();
            var sig = AuthUtils.getAS(context, str);  // context,str组要自己组装
            send(sig);
        }
    )
    }
};
'''

def on_message(message, data):
    if message['type'] == 'send':
        print(message['payload'])
    elif message['type'] == 'error':
        print(message['stack'])

process = frida.get_usb_device().attach('com.coolapk.market')
script = process.create_script(hook_code)
script.on('message', on_message)
script.load()

script.exports.gethello('edc38cb9-c72d-3bc4-8e82-6fd9212d77a0')

在这里插入图片描述

token对比

# rpc调用生成的
4bdc740d8fff25d577ed9b28cca6b34cedc38cb9-c72d-3bc4-8e82-6fd9212d77a00x5fdb2185       

# 抓包得到的
e8f1c71569a7166b6aa9723342923606edc38cb9-c72d-3bc4-8e82-6fd9212d77a00x5fdb0663

根据这种主动的调用方式我们可以搭建一个web服务,来对外使用。

正常的hook方式需要我们手动触发执行到相关方法才会执行对应脚本,rpc这种方式可以主动调用方法不需要我们手动触发。

你可能感兴趣的:(移动APP安全,android,python,js,java,app逆向)