#####0x01.准备工具
#####0x02.抓包
手机连上`wifi`,与电脑处于同一局域网,然后设置好Fiddler,具体步骤不详述。
打开`宝宝树孕育6.2.1`版本,进入`登陆`窗口,输入账号密码点登陆,在电脑查看封包。
可以得到请求`URL`:
方式:`POST`
参数:
分析可知:
`phone_number`,`password`,`email`,`secret`四个参数为加密,其他参数均为固定或者地理位置信息等参数。
所以此次目标就为这`4`个参数
#####0x03分析调试1. 先把apk拖入AndroidKiller进行分析,可知无壳。
2. 根据先前分析,可在AndroidKiller中搜索相应字符串查找我们感兴趣的函数
搜索`muser\login`,可知登陆的函数在`com.babytree.platform.api.muser`中的`login.smali`中。
由图可知
Login.java的父类是ApiBase,可以猜想,所有Api的请求所公共的函数都会在此类中生成。
关键地方找一个就行,本次分析主要还是以动态调试为主.
3. 用baksmali将apk反编译成.smali文件
4. 然后打开IntelliJ IDEA,创建一个java工程.将上一步反编译出的smali文件导入到src文件夹中。如图:
5. 然后打开eclipse,切换到DDMS视图,选中手机,查看其端口,如图:
图上可以看到,目标应用的端口为8631.
6. 切换到IntelliJ IDEA,选择Run-Configurations.
7. 然后新建一个Remote,填写端口为8631,然后选择source using module's classpath为我们之前创建的项目,点击OK
8. 接下来在IntelliJ IDEA中打开Login.smali,快速浏览一下,选择一个感兴趣的地方下断点,这里我选择.method protected a()Ljava/lang/String;
在函数起始处下断点后,在手机中输入账号密码,点击登陆,可以看到断点成功断下,如图所示:
从图中可以看到,左下角为函数的调用堆栈,从 登陆按钮 按下(OnClick),到api.user.login整个的调用过程。
展开右下角的p0,可以看到此时已经生成了3个参数,
说明在断点之前,参数已经生成好了。
所以我们按照函数的调用栈,挨个查看调用过的函数。
查阅一番后可以发现。Login对象是在
LoginActivity中的.method public a(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V方法创建的。
在new-instance v0, Lcom/babytree/platform/api/muser/Login;处下断点,重新点击登陆按钮,如图:
此时v1.v2.v3寄存器分别出现了加密的结果,由上可知,分别对应`phone_number`,`password`,`email`三个参数。
所以加密的函数应该就在上面。
往上下断点,重新来一次观察一下加密的过程。
可知:
iget-object v0, p0, Lcom/babytree/apps/pregnancy/activity/LoginActivity;->u:Ljava/lang/String;
这一句函数调用之后,v0是一串固定字符串。
invoke-static {p1, v0}, Lcom/babytree/apps/pregnancy/h/a;->a(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
调用之后,v1为加密结果。查看a函数:
为RSA加密,所以之前的v0就是RSA的pubKey了。
在a函数中下断点,看一看加密的参数是什么:
一切尽收眼底。由此可知`phone_number`,`password`,`email`三个参数的算法。
9. 接下来找`secret`的算法。
回到AndroidKiller搜索关键字,定位到com/babytree/platform/api/ApiCommonParams;
大致看一下,这个是API通用参数生成的类。且加载了一个so:api_encrypt.so
在`secret`关键字附近看一下,调用了so的invoke-static {v1, v2}, Lcom/babytree/platform/api/ApiCommonParams;->nativeGetParam(Landroid/content/Context;Ljava/util/List;)Ljava/lang/String;方法。
我们先在这句上面下个断点,看看传给so函数的是什么参数。
断点断下后,看到传递给so的参数是一个List,POST参数中除`secret`之外的所有参数。
参数知道了,调用点知道了。分析一下so,看看需不需要动态调试。
载入ida,找到调用的nativeGetParam函数。大致看一下,发现又调用了java的md5函数,好了,调试so的步骤剩下了。
回到IntelliJ IDEA,在getMD5Str处下断点,继续调试:
很快我们可以知道,p0中就是进行md5的参数啦。
分析一下可知,`secret`就是 MD5(时间戳+所有参数排序+&asdf12341dfas!@#$%()(Ujjlasdflasdfj;asjdf23412313kljajsdflasjdflasjdflajsdf;lajsdf2342234sdfsdfffds)
#####0x04.总结
动态调试apk的方式让我们了解apk运作的过程,通过动静结合的分析方式,快速找到想要的东西~
#####0x02.抓包
手机连上`wifi`,与电脑处于同一局域网,然后设置好Fiddler,具体步骤不详述。
打开`宝宝树孕育6.2.1`版本,进入`登陆`窗口,输入账号密码点登陆,在电脑查看封包。
可以得到请求`URL`:
方式:`POST`
参数:
分析可知:
`phone_number`,`password`,`email`,`secret`四个参数为加密,其他参数均为固定或者地理位置信息等参数。
所以此次目标就为这`4`个参数
#####0x03分析调试1. 先把apk拖入AndroidKiller进行分析,可知无壳。
2. 根据先前分析,可在AndroidKiller中搜索相应字符串查找我们感兴趣的函数
搜索`muser\login`,可知登陆的函数在`com.babytree.platform.api.muser`中的`login.smali`中。
由图可知

Login.java的父类是ApiBase,可以猜想,所有Api的请求所公共的函数都会在此类中生成。
关键地方找一个就行,本次分析主要还是以动态调试为主.
3. 用baksmali将apk反编译成.smali文件
4. 然后打开IntelliJ IDEA,创建一个java工程.将上一步反编译出的smali文件导入到src文件夹中。如图:

5. 然后打开eclipse,切换到DDMS视图,选中手机,查看其端口,如图:

图上可以看到,目标应用的端口为8631.
6. 切换到IntelliJ IDEA,选择Run-Configurations.
7. 然后新建一个Remote,填写端口为8631,然后选择source using module's classpath为我们之前创建的项目,点击OK
8. 接下来在IntelliJ IDEA中打开Login.smali,快速浏览一下,选择一个感兴趣的地方下断点,这里我选择.method protected a()Ljava/lang/String;
在函数起始处下断点后,在手机中输入账号密码,点击登陆,可以看到断点成功断下,如图所示:

从图中可以看到,左下角为函数的调用堆栈,从 登陆按钮 按下(OnClick),到api.user.login整个的调用过程。
展开右下角的p0,可以看到此时已经生成了3个参数,

说明在断点之前,参数已经生成好了。
所以我们按照函数的调用栈,挨个查看调用过的函数。
查阅一番后可以发现。Login对象是在
LoginActivity中的.method public a(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V方法创建的。
在new-instance v0, Lcom/babytree/platform/api/muser/Login;处下断点,重新点击登陆按钮,如图:

此时v1.v2.v3寄存器分别出现了加密的结果,由上可知,分别对应`phone_number`,`password`,`email`三个参数。
所以加密的函数应该就在上面。
往上下断点,重新来一次观察一下加密的过程。
可知:
iget-object v0, p0, Lcom/babytree/apps/pregnancy/activity/LoginActivity;->u:Ljava/lang/String;
这一句函数调用之后,v0是一串固定字符串。
invoke-static {p1, v0}, Lcom/babytree/apps/pregnancy/h/a;->a(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
调用之后,v1为加密结果。查看a函数:

为RSA加密,所以之前的v0就是RSA的pubKey了。
在a函数中下断点,看一看加密的参数是什么:

一切尽收眼底。由此可知`phone_number`,`password`,`email`三个参数的算法。
9. 接下来找`secret`的算法。
回到AndroidKiller搜索关键字,定位到com/babytree/platform/api/ApiCommonParams;
大致看一下,这个是API通用参数生成的类。且加载了一个so:api_encrypt.so
在`secret`关键字附近看一下,调用了so的invoke-static {v1, v2}, Lcom/babytree/platform/api/ApiCommonParams;->nativeGetParam(Landroid/content/Context;Ljava/util/List;)Ljava/lang/String;方法。
我们先在这句上面下个断点,看看传给so函数的是什么参数。
断点断下后,看到传递给so的参数是一个List,POST参数中除`secret`之外的所有参数。
参数知道了,调用点知道了。分析一下so,看看需不需要动态调试。
载入ida,找到调用的nativeGetParam函数。大致看一下,发现又调用了java的md5函数,好了,调试so的步骤剩下了。

回到IntelliJ IDEA,在getMD5Str处下断点,继续调试:

很快我们可以知道,p0中就是进行md5的参数啦。
分析一下可知,`secret`就是 MD5(时间戳+所有参数排序+&asdf12341dfas!@#$%()(Ujjlasdflasdfj;asjdf23412313kljajsdflasjdflasjdflajsdf;lajsdf2342234sdfsdfffds)
#####0x04.总结
动态调试apk的方式让我们了解apk运作的过程,通过动静结合的分析方式,快速找到想要的东西~