安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解

1.准备工作及运行环境

1.1 系统环境:Mac
1.2 抓包工具:Charles v4.2.8
1.3 安卓模拟器:MuMu模拟器 v1.6.5
1.4 Java环境:Java 8
1.4 反编译工具:jadx  (github链接地址:https://github.com/skylot/jadx)
1.5 某个app包:******.apk

 

2. 抓包分析

在安卓模拟器中安装好******.apk, 首先打开Charles,然后配置好安卓模拟器中的Charles证书。打开该app, 进行下拉页面操作,在Charles中看到了该接口所对应的请求。
请求参数如下:

deviceId	008796752342119
appVersion	2.2.1
location	%E6%9D%AD%E5%B7%9E%E5%B8%82
phoneType	MuMu
currentTime	1559974834660
phoneVersion	6.0.2
version	2.2.1
pageIndex	1
pageSize	15
appChannel	channelvalue
phoneSystem	A
appName	creditSteward

请求header头如下:
安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第1张图片
事实证明,当我pageIndex参数发生变化时,对方服务器会提示签名验证错误。所以必须得知道 _nsign参数是怎么计算得到的,不然的话,无法爬取下一页的数据。
 

3. apk反编译及分析

这里得利用jadx工具对该apk进行反编译。

首先去我上述的github地址下载jadx工具包,然后解压并进入到bin目录下, iterm终端执行这个命令: nohup ./jadx-gui >/dev/null &

然后会打开图形化的界面,然后导入被反编译的apk。稍微等待1-2分钟,该apk就被反编译出来了。

然后全局搜索(shift + command + f)“queryOrderList.json”,就能够定位到具体的代码块了。

安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第2张图片
这里,它首先new了一个HashMap类型的hashMap对象,然后首先添加了 pageSize和pageIndex这两个键值对,这两个参数刚好和Charles抓包分析相对应。再之后作为参数传给 OkHttpUtil.b的b方法。

然后继续分析,按住 control键的同时,单击 OkHttpUtil.b的b方法,会跳转到b方法被定义的代码处
安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第3张图片
差不多可以看出个大概来,首先 map参数 参与了 167行 xNApplication.a方法的运行,然后也参与了168行 xNApplication.a方法的运行。

继续在 167行单击该方法,会跳转到该方法被定义的代码处
安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第4张图片
分析到这里的时候,其实请求的参数差不多一目了然了,刚好和前面Charles抓包分析的参数一一对应起来。此刻,我的内心有一丝丝的兴奋。

继续在 168行单击该方法,同样也会跳转到该方法被定义的代码处
安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第5张图片
其实,这里的时候,就差不多已经看到了 _nsign参数是如何产生的了。继续分析 SignAlgorithm.a方法
安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第6张图片
安卓逆向 -- 某个金融类app自动抢单接口的nsign参数校验破解_第7张图片
其实它这个加密算法,本质上就是把url中的那些请求参数按照key做升序排序,然后以 "key1=value1&key2=vaule2…"的形式再加上 salt值,进行一次md5的散列摘要,不过它这个md5最终输出是转大写的。
 

以下是我用python3实现它这个加密算法

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from hashlib import md5


def _md5(str):
    m = md5()
    m.update(str.encode('utf-8'))
    return m.hexdigest().upper()

def create_sign(query, salt):
    """
    :param query: 类型是字典类型
    :param salt: 加密的盐值
    :return: 返回加密后的字符串
    """
    _d = sorted(query.items())
    sign_str = '&'.join([key + '=' + value.replace(" ", "") for key, value in _d])
    sign_str = (sign_str + "&v__s_k_=" + salt).replace(" ", "")
    return _md5(sign_str)

哈哈,匆匆写的,没做异常处理啥的。

4. 总结

4.1 首先利用Charles抓包分析该请求,明确该请求的方式,该请求的参数构造规律,该请求的header所携带的字段,然后重点分析所加密的请求参数字段或者请求头字段。

4.2 得善于利用apk相关的反编译工具(jadx能够对付一般的apk,但是那种加固、加壳的apk就得用别的工具了)

4.3 巧用url中的关键词,header中的关键字段去全局搜索代码,进行代码定位。

4.4 分析代码,进行代码回溯。得有耐心!得有耐心!!得有耐心!!!

总之,安卓逆向也是一条不归路,且行且珍惜!

你可能感兴趣的:(安卓逆向)