第一次进行android逆向的过程记录

前言

要逆向的是一款叫shengqian快报的app,具体要分析sign签名的加密过程。

环境配置及工具

系统:macOS 10.14.1 

模拟器:mac版夜神模拟器 3.0.3.0

抓包工具:Charles

逆向工具:apk-tool、JD-GUI、frida、adb、dex2jar、objection

准备工作

从网上下载shengqian快报的apk保存到电脑上,打开夜神模拟器,将apk拖到夜神模拟器里面安装。

抓包分析

使用Charles对夜神模拟器进行抓包。(需要在夜神模拟器上安装好Charles的证书然后配置好代理)

打开shengqian快报app,对需要分析的页面进行抓包。

分析抓到的包,发现目标接口:

返回的json就是需要的数据:

ok。到这里目标接口就找到了,接下来要对这个接口进行分析。

分析发现这个接口接收一个post请求,包含了30多个参数,其中最重要的就是我们要分析的sign参数了。

我们可以先尝试用postman或者python脚本向这个接口发送一个post请求试试,结果返回的是{"status_code":-1,"message":"invalid sign"},可以证明在服务器端进行了sign的校验,所以我们想要得到这个接口的数据就需要将sign加密过程找到然后伪造一个合法的post请求。

逆向分析

用apktool反编译apk文件为smali

apktool d jz_dsp_ydcx_zcw17.apk

将反编译后的文件夹后缀名修改为zip,然后进行解压,解压后的文件夹里含有classes.dex的文件。最后使用dex2jar工具将classes.dex文件转换为classes-dex2jar.jar文件。

用JD-GUI打开最后的jar文件,发现代码是经过混淆的。

点开左上角的手电筒全局搜索sign,

发现一处比较可疑的地方,这个e函数猜测应该就是用parama来加密,

接下来进入e方法,可以确定这就是加密的方法了。stringBuilder创建了一个用&连接所有参数的字符串,最后又添加了一个32位的字符串,通过b.a()方法来加密。

接下来进入b类查看,可以看出来这就是md5加密,

确认完加密算法,就需要分析parama里面都是什么了。

打开夜神模拟器,adb shell进入命令行(模拟器的root启动要开启),运行frida-server。

模拟器里打开shengqian快报app,新开一个命令行输入下面命令查看进程,

frida-ps -U

找到对应进程就可以开始hook了。

输入下面命令进入objection,

objection -g com.****.coupon explore

watch一下e方法看看返回值、调用栈和传入参数的内容都是啥。

android hooking watch class_method com.****.coupon.httptask.a.a.e --dump-args --dump-backtrace --dump-return

点击进入详情页后,发现e方法被调用了很多次,返回值其实就是加密后生成的sign(调用栈就不截图了)

同时在Charles的抓到的目标接口中,发现sign和hook到的返回值一样。

因此可以确认接口的sign是通过e这里生成的了。

接下来就要去分析传入e的parama是什么了。

读一下e方法里面的代码,可以看出来parama.k()可以获得一个List类型的对象,然后遍历这个对象并且生成一个url参数格式的字符串(name1=value1&name2=value2……)

知道了这些就可以写一个简单的hook脚本来打印一下parama里面的内容了。

python脚本:

import sys
import frida

PACKAGE = 'com.****.coupon'


def hook():
	jscode = open('script.js', 'r').read()
	# 查找USB设备并附加到目标进程
	session = frida.get_usb_device().attach(PACKAGE)
	# 在目标进程里创建脚本
	script = session.create_script(jscode)
	print('[*] Start attach')
	# 加载创建好的javascript脚本
	script.load()
	# 读取系统输入
	sys.stdin.read()


if __name__ == '__main__':
	hook()

script.js:

function hook(){
    Java.perform(function(){
        var a = Java.use("com.****.coupon.httptask.a.a");
        a.e.implementation = function(parama){
            var result = this.e(parama);
            var l = parama.k().size();
            console.log("len:",l,"len:",l);
            // 随便打印几个参数
            console.log("parama1",parama.k().get(1));
            console.log("parama31",parama.k().get(31));
            console.log("parama34",parama.k().get(34));
            return result;
        }
    });
};

setImmediate(function(){
    setTimeout(hook, 2000);
});

hook好之后,发现加密的这些参数其实就是post里面提交的参数,到这里sign分析就结束了。

我们要实现sign加密算法的话,就保留关键的参数,然后将这些键值进行拼接,字符串的末尾要拼接"81f454ac98956541b195f2c7f9e53a06",最后再对字符串进行一次MD5就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章