书旗app字符串加密分析

本文案例是对书旗app搜索接口的请求密文进行逆向分析。

案例环境:书旗app (安卓11.5.4.152)、Frida、夜神、Jadx


@


抓包分析接口

在这里插入图片描述

'https://ocean.shuqireader.com/sqan/render/render/search/native?_reqid=1ce4c18035'

在这里插入图片描述

脱壳反编译

查壳
在这里插入图片描述

脱壳
在这里插入图片描述

在这里插入图片描述

可以把非常小的删除掉,把非常大的单独拿出来分析一下。我先把最大的文件(47MB)单独用Jadx打开。


data定位

看到请求内容或者响应内容加密的,就直接搜加解密关键词 decrypt和encrypt 。
另外请求中data的格式很像被base64过,然后再aes加密(猜的)。
在这里插入图片描述
搜完并没有发现特别合适的。(我这里调试了好一会儿,最终发现几个都不是)

于是换了个关键词,搜索表单中的 "data" 。 最后的 params.put("data", n.encrypt(jSONObject.toString()));
非常像
在这里插入图片描述

点进去后,可以看到encrypt相关的方法
在这里插入图片描述
用frida打印一下看看。


Frida hook

启动frida
在这里插入图片描述

HOOK代码:

import frida, sys
def on_message(message, data):
    print("[%s] => %s" % (message, data))

session = frida.get_usb_device().attach('com.shuqi.controller')

js_code = '''
    Java.perform(
        function(){
                console.log("1. start hook");
                var ba = Java.use("com.shuqi.common.l");
                if (ba != undefined) {
                    console.log("2. find class");
                    ba.c.implementation = function(a1){
                        console.log("3. hook method");
                        console.log(a1);
                        var res = ba.c(a1);
                        console.log(res);
                        return res
                        }
                }
        }
    )
'''
script = session.create_script(js_code)
script.on('message', on_message)
script.load()
sys.stdin.read()

打印内容:
在这里插入图片描述

可以发现加密的是一些RequestParams 参数。

{
    "query": "遮天3",
    "page": "liteAppSearchResult",
    "pagination": "{'page':'1','pageSize':'10'}",
    "mod": "LIO-AN00",
    "sdk": "25",
    "umidtoken": "vZhLXf1LOhBiGzV9+qvRixj8ptIK2Wg+",
    "utdid": "WVc0ZjZRRndmVllEQUFRQU9CUnIxY0Fy",
    "first_placeid": "src1011",
    "vc": "75ec",
    "subVer": "sqrelease2",
    "manufacturer": "HUAWEI",
    "utype": "pre_vip",
    "aak": "4d1fe5",
    "permissionType": "3",
    "net_env": "4",
    "net_type": "wifi",
    "sn": "1640587766920775",
    "contentRecom": "1",
    "net": "4",
    "platform": "an",
    "scene_code": "",
    "enc": "182121640596695489",
    "wh": "900x1600",
    "brand": "HUAWEI",
    "placeid": "1038",
    "appVer": "11.5.4.152",
    "msv": "3",
    "soft_id": "1",
    "sqUniqDeviceId": "ODYzMDY0NDI1NjQ0Mzky",
    "personalized": "1",
    "ver": "211208",
    "user_id": "3120839143",
    "isTeenMode": "0",
    "sqSv": "1.0",
    "key": "sq_app_gateway",
    "sign": "b8669a96b48e6ceb07d34d7eee2df0ac"
}

经过多次测试,参数中的enc和sign还是一个动态的。

先不管这俩参数是怎么计算的,我们先看看data是如何加密的。

主要方式是 n.encrypt 。 但是跳不进去,方法在其他的dex文件中。

我把原apk丢Jadx后,找到了 com.shuqi.common.n类,并且有 encrypt方法。

在这里插入图片描述

再次用Frida hook分析:

import frida, sys
def on_message(message, data):
    print("[%s] => %s" % (message, data))

session = frida.get_usb_device().attach('com.shuqi.controller')

js_code = '''
    Java.perform(
        function(){
                console.log("1. start hook");
                var ba = Java.use("com.shuqi.common.n");
                if (ba != undefined) {
                    console.log("2. find class");
                    ba.encrypt.implementation = function(a1){
                        console.log("3. hook method");
                        console.log(a1);
                        var res = ba.encrypt(a1);
                        console.log(res);
                        return res
                        }
                }
        }
    )
'''
script = session.create_script(js_code)
script.on('message', on_message)
script.load()
sys.stdin.read()

打印内容:
在这里插入图片描述

现在加解参数和结果都有了。参数和之前分析的一样,不过参数中的enc和sign是动态的。

其实到这里就可以了,用frida来调用生成密文。

快下班了,字符串加密分析暂时到这。回头再看 cqT.staticSafeEncrypt(3, "23011413", str);


Sign 分析

在全局搜了一下,发现在CommonSignUtils中。
在这里插入图片描述

简单看一下生成流程,是把he进行UrlEncode,he是RequestParams请求的参数,去掉cBG中的key,然后m49290a 后再md5一下。

cBG = {"sign", "key", "_public", "_reqid", "beta", "", "X-NEBULAXMLHTTPREQUEST", "callbackUrl"};
在这里插入图片描述
m49290a:
在这里插入图片描述

m49308h:
在这里插入图片描述
可以看到m49308h是一个md5的实现。


enc 分析

全局搜索 enc

在这里插入图片描述
查看 m10070br
在这里插入图片描述
可以看出来enc是一个由时间戳控制和计算的随机值。

_reqid 分析

请求时的params中有一个 _reqid参数。全局搜索 _reqid
在这里插入图片描述
此处很合理
在这里插入图片描述
_reqid = aBW
在这里插入图片描述
aBW = aBV()
在这里插入图片描述

参数太多了,就不再还原了,大家可自行尝试。

点赞

发表回复