吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5369|回复: 23
收起左侧

[Android 原创] 某药品监管app——安卓端脱壳+RPC服务调用参数生成方法

[复制链接]
loushimin 发表于 2023-8-18 15:16
本帖最后由 loushimin 于 2023-8-22 14:13 编辑

前言:
本篇帖子是在我爬虫笔记里的的记录
只是操作记录,代码量少
主要记录了脱壳、调试、objection hook、frIDA hook注入,最后调用注入的方法获取加密参数


一、环境准备:
1、某药品监管apk:v5.3.2


2、安卓端脱壳工具——BlackDex:无版本要求,最新的即可
github : https://github.com/CodingGay/BlackDex/releases
脱壳环境要求
  • 一台普通手机
  • 无需Xposed
  • 无需Frida
  • 无需Magisk
  • 无需Root
  • 无需定制系统


安卓端脱壳工具——BlackDex

安卓端脱壳工具——BlackDex
   
3、Frida  
frida                   15.2.2
frida-tools             11.0.0


4、objection
objection github:https://github.com/sensepost/objection
pip install objection
pip安装最新的即可,无版本要求


5、jadx



6、安卓真机或模拟器
安卓 7
逍遥模拟器



7、Android Studio

8、python 3.7



二、开始
1、抓包分析
通过对app的抓包可知app端就一个加密参数 tzRgz52a签名
headers:
[JavaScript] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
Accept-Language: zh-CN,zh;q=0.8
User-Agent: Mozilla/5.0 (Linux; U; Android 7.1.2; zh-cn; HD1910 Build/N2G48H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Connection: close
Host: mobile.nmpa.gov.cn
Accept-Encoding: gzip
tzRgz52a: BlRnN9IbxigK7nqPZitab6KNJ5oaPyiKKmPOSV-k_6JsT7bS0ywp0DhUwx7pDVsvshj5S5Mj26SqTg6YK_jc81sahiH4oH86rAotrTjoK8I3NYzEGP_wDWlJtGolNxD8XgDZr0z3hoyGzTI7dCuL2RI5e_uNwyIuD-yUEWz9TrTEKVO9Po1iWTPGbgfns9xN7bgjDYfbmHxiXi0IRWmBNZY2uNZ6I7b2iI2GeR2lLN_Zj42B2UP_oClQv5jdPxENikZ8GOa8UoJM4Slja0hY2k-FT6RWtjDoL6IvXIYy40WdnM0pYvMWxE2kkczs_WuN7nuFPKjZplGDwJYABG5R4qSchFSoIt_95rLa3N9OtgRvWMur9qQM3rHVZa16WqRKcYJqHwIrxiOncUS-udOLYfFtQlCLsxe0RlFpVxn0ykiw1O0ualP2_2r-mY7VoOKS0wDCM6aaWynDAfVdNQJonnRv1SjS9MjgJ0BgAMGdPwENNTUn_cAkwFK-HVZpw35H7PGqAk0DoMhNfQ9vR0XQ7p3eUkyc1Lp3bdDXL94AHZb3lVSEUicex9BumrwnkNGM3F3s4B1zjdetUk3tZZlj8u3v_Fj48wDC7zsR8-KOBkrGMBj-t2rOahfGk1PXqK8_epWVIysgbLlXInHP35587M0
Connection: close
Cache-Control: no-cache



2、frida-server
下载与frida版本对应的 frida-server,模拟器就下载 x86版本的(红框),安卓真机就下载arm版本的(蓝框),也可以adb shell 进入手机终端,执行以下命令查看内核版本,再下载相应的frida-server
[Shell] 纯文本查看 复制代码
1
2
adb shell
getprop ro.product.cpu.abi


截图2.png

截图3.png


将下载的frida-server-15.2.2-android-x86_64.xz解压,将文件夹中的 frida-server-15.2.2-android-x86_64 push到安卓目录 /data/local/tmp/ 下,并给该文件添加权限,然后并启动
[Shell] 纯文本查看 复制代码
1
2
3
4
5
6
7
adb shell
cd /data/local/tmp
su
#添加权限
chmod 777 frida-server-15.2.2-android-x86_64
#启动frida-server
./frida-server-15.2.2-android-x86_64



新建cmd窗口开启端口转发
[Shell] 纯文本查看 复制代码
1
2
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043



在cmd窗口中输入 frida-ps -U命令后输出模拟器进程,说明frida安装成功
[Shell] 纯文本查看 复制代码
1
frida-ps -U


截图4.png


3、app脱壳
在手机上安装 药监局app 和 BlackDex app
对于BlackDex 64位的和32位的都要安装,如果一个脱壳失败,就换另一个版本
截图5.png


根据提示将脱壳后的dex文件提取出来


截图6.png

截图7.png


4、调试
使用jadx打开dex文件


截图8.png


先在jadx中全局搜索tzRgz52a 结果是搜不到的
如果经验多的话 这时候就应该知道,先搜索与header有关的
搜索 getheader 结果如下

截图9.png


可以发现,搜索到了很多,重点观察com开头的节点,发现两个可以的方法com.msec.MSecClient 的 _ts_getHeaderKey, _ts_getRequestHeader


截图10.png


下一步就可以根据上面的结果进一步调试hook看能否拿到我们想要的数据

调试方法有很多
1、objection hook
2、python 写脚本 hook
3、fridamanager 注入 js hook
4、xposed 插件注入 js hook
5、aosp 内置 frida hook
都可进行尝试,这里用的是objection



三、objection hook
1、查找app及其包名


cmd窗口执行  
[Shell] 纯文本查看 复制代码
1
frida-ps -Uai



结果如下
截图16.png

com.hxzk.android.hxzksyjg_xj  即是包名


2、objection hook
cmd执行 ,进入objection
[Shell] 纯文本查看 复制代码
1
objection -g com.hxzk.android.hxzksyjg_xj explore


截图12.png


根据二、4的结果  搜索msec相关的类
[Shell] 纯文本查看 复制代码
1
android hooking search classes msec


截图13.png


hook com.msec.MSecClient 类,查看类中的方法,找到要hook的方法
[Shell] 纯文本查看 复制代码
1
android hooking watch class com.msec.MSecClient


截图14.png


hook以上两个方法


[Shell] 纯文本查看 复制代码
1
2
3
android hooking watch class_method com.msec.MSecClient._ts_getH
eaderKey --dump-args --dump-backtrace --dump-return
android hooking watch class_method com.msec.MSecClient._ts_getRequestHeader --dump-args --dump-backtrace --dump-return



去app中请求接口,即可看到hook结果
截图15.png


根据hook结果可知 _ts_getRequestHeader()方法的返回值 即是 tzRgz52a签名

3、使用frida hook并注入,hookjs如下:
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function get_yjj_tzRgz52a() {
    console.log('script 加载成功')
    Java.perform(function () {
        console.log('hook test')
        var MainActivity = Java.use('com.msec.MSecClient');
        MainActivity._ts_getRequestHeader.implementation = function (x, y, z) {
            // 这里开始是原函数的逻辑
            console.log(x)
            console.log(y)
            console.log(z)
 
            // 这里对原函数的参数重新赋值
            var vaule = this._ts_getRequestHeader(x, y, z);
 
            // 返回原函数的结果
            console.log(vaule);
            return vaule
 
        }
    })
}
 
setTimeout(get_yjj_tzRgz52a)



使用 以下命令注入:
[Shell] 纯文本查看 复制代码
1
frida -U -l 1.js 中国药品监管


注意:这里注入后面写的是name 而并非包名



如图所示,注入成功
截图17.png


在app中重新请求 接口,hook结果如下
截图18.png


0 0 http://mobile.nmpa.gov.cn/datasearch/QueryList?tableId=25&searchF=Quick%20SearchK&pageIndex=4&pageSize=15
分别对应方法的参数 x y z,多次请求后发现 0 0是固定的,即只有参数z是变量,z就是 请求的数据接口链接



4、RPC主动调用
确定方法的参数后即可使用RPC将被动调用 改为主动调用
稍微改动下hook的js
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
function getYjjTzRgz52a(x, y, z) {
    var vaule;
    Java.perform(function () {
        Java.choose('com.msec.MSecClient', {
            onMatch: function (instance) {
                vaule = instance._ts_getRequestHeader(x, y, z);
            },
            onComplete: function () {
                console.log('_ts_getRequestHeader()调用完成')
            }
        })
    })
    return vaule
}
 
rpc.exports = {
    getyjjtzrgz52a: getYjjTzRgz52a
}



RPC使用python实现,代码如下:
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
42
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 LouShimin, Inc. All Rights Reserved
#
# @version : 1.0
# @AuThor  : LouShimin
# @Time    :
# @FileName: yjj.py
# @desc    :
import frida
 
def on_message(message, data):
    if message['type'] == 'send':
        print(message['payload'])
    elif message['type'] == 'error':
        print(message['stack'])
 
 
device = frida.get_usb_device()
process = device.attach('中国药品监管')
with open('./yjj_end_rpc.js', encoding='utf-8') as f:
    jscode = f.read()
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
def get_yjj_rpc():
    rpc = script.exports
    return rpc
 
def get_yjj_tzRgz52a(page):
    rpc = get_yjj_rpc()
    a1 = rpc.getyjjtzrgz52a(0, 0,
                             'http://mobile.nmpa.gov.cn/datasearch/QueryList?tableId=25&searchF=Quick%20SearchK&pageIndex={}&pageSize=15'.format(
                                 page))
    print(a1)
 
if __name__ == '__main__':
    while True:
        page = input('请输入页码:')
        print(page)
        get_yjj_tzRgz52a(page)



运行程序后输入页码,返回值即为tzRgz52a 签名
截图19.png


5、Sanic+RPC远程调用
接口文件如下:
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 LouShimin, Inc. All Rights Reserved
#
# @Version : 1.0
# @Author  : LouShimin
# @Time    :
# @FileName: sanic_app.py
# @Desc    :
from sanic import Sanic
from sanic.response import json as response_json
 
from commons.frida_rpc.yjj_rpc import get_yjj_rpc
 
app = Sanic(__name__)
 
yjj_rpc = get_yjj_rpc()
 
 
@app.route("/getSignFromJni", methods=['POST'])
async def req_proxy_data(request):
    res = request.json
    yjj_url = res['yjj_url']
 
    tzRgz52a = yjj_rpc.getyjjtzrgz52a(0, 0, yjj_url)
    print(tzRgz52a)
    res_data = {
        'msg': 'success',
        'code': 200,
        'tzRgz52a': tzRgz52a,
        'yjj_url': yjj_url
    }
    return response_json(res_data)
 
 
if __name__ == '__main__':
    app.run("0.0.0.0", port=16383, debug=True, workers=30)



改造并引入三、4中的 getyjjtzrgz52a()方法接口通过接口形式调用:
截图20.png


安卓端脱壳工具——BlackDex

安卓端脱壳工具——BlackDex
截图16.png

免费评分

参与人数 5吾爱币 +4 热心值 +4 收起 理由
zhouzheng1201 + 1 热心回复!
junjia215 + 1 + 1 用心讨论,共获提升!
天空宫阙 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
027rainguai + 1 我很赞同!
oogo + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| loushimin 发表于 2023-11-21 14:47
嘛哩嘛哩轰 发表于 2023-11-12 20:38
怎么现在 5.3.2的apk 打开直接弹 禁止root 设备安装apk了。。。。

在面具中对该应用隐藏面具,再使用JsHook app对该应用hook,过掉root检测。如图:

面具隐藏

面具隐藏

JsHook

JsHook
8b7432c8203312fafc266a96e196752.jpg
2d6e93904b24a31ed2384b0b6ea9b04.jpg

成功进入

成功进入

5.3.2

5.3.2
 楼主| loushimin 发表于 2023-11-21 15:09
天空宫阙 发表于 2023-11-11 11:58
rpc调用确实很方便,就是感觉不能大量调用,加密参数可能包含了设备的信息

这个我个人觉得不是太大的问题,web端可以用指纹浏览器,安卓端可以用“应用伪装”等app去修改设备的信息,所以我认为设备信息对于rpc来说只是个小坎,稍微做点改动就过去了

应用伪装 app

应用伪装 app

伪装设备信息1

伪装设备信息1

伪装设备信息2

伪装设备信息2

指纹浏览器-设置指纹1

指纹浏览器-设置指纹1

指纹浏览器-设置指纹2

指纹浏览器-设置指纹2

指纹浏览器-设置指纹3

指纹浏览器-设置指纹3

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
天空宫阙 + 2 + 1 牛啊牛啊

查看全部评分

zhouzheng1201 发表于 2023-11-17 11:35
嘛哩嘛哩轰 发表于 2023-11-3 16:28
不错不错,支持一下
wantwill 发表于 2023-11-3 16:47
不错不错,支持一下
中原一点红 发表于 2023-11-4 22:26
过来看看
mcby 发表于 2023-11-7 09:31
再学习一下大脑的技术。
Mist520 发表于 2023-11-7 11:25
感谢分享 谢谢大佬
天空宫阙 发表于 2023-11-11 11:58
rpc调用确实很方便,就是感觉不能大量调用,加密参数可能包含了设备的信息
嘛哩嘛哩轰 发表于 2023-11-12 20:38
怎么现在 5.3.2的apk 打开直接弹 禁止root 设备安装apk了。。。。
closeai 发表于 2023-11-13 11:56

不错不错,支持一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-15 17:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表