app entry reverse analysis --APP login request parameter


Environment Configuration:

Pyhton
the Java
dex2jar (the apk decompile java source code)
jd_gui (Source view)
jadx
have root Android phone or emulator
fiddler

analysis:

First, we use fiddler packet capture tool to be landed app capture, grab this app global agent package needs to open, or you'll catch data.

If you will not use the global proxy capture of friends, you can look at previous article, there are detailed packet capture tutorial.

Data capture follows:
               <ignore_js_op>

                    Sending a verification request parameter code

 

 

 

 


We can see a  token  parameter, experienced friends know that this is a server-generated background, and before sending the login verification code requests and no other data exchange! <ignore_js_op>


                 Login request parameters

 

 

 

 

 

This time we will go to app source code to find encryption of this parameter, then converted into  Python  code generation.
Next will take you step by step to crack this parameter.

Crack process:

We want to get app source code, it is necessary for the app to decompile, decompile way is very simple, straightforward tool to get.
There are two options for ways to decompile, reverse compile process is as follows:

1.将安卓app的后缀更改为可解密的包,并解压
<ignore_js_op>

2.将解压后生成的后缀为 .dex 复制到 dex2jar 安装目录中
<ignore_js_op> 


3.DOS命令行进入此文件夹,然后执行命令:dex2jar.bat   classes.dex

这个app有两个 *.dex *文件,所以两个* .dex* 文件都需要执行
执行完之后会生成两个对应的   .jar 文件,效果如下:
<ignore_js_op>

4. 生成.jar文件就是apk的源码了,我们使用 jd_gui 来查看源码 <ignore_js_op> 







幸运的是这个app并没有加固,有app进行了加固,像腾讯乐固,360加固等等
<ignore_js_op> 
<ignore_js_op> 

对于这种我们不能直接反编译,首先需要脱壳,然后再反编译

5.第二种反编译的方法是直接使用工具 jadx 打开 .apk 文件

剩下的事就是仔细阅读代码,分析其中的逻辑了。

6.根据请求或响应的参数去源码中搜索加密方式

需要注意的是,反编译的代码非常混乱,错误很多,并且apk经过混淆,变量名都消失了,这时一定要有有耐心,仔细研究代码。
根据前面请求、响应参数去搜索,或者请求的 url 地址去搜索,而且经验很重要


<ignore_js_op>
                              搜索结果
然后根据这些搜索到的结果慢慢去找。我们主要找到发送请求的时候定义参数的代码,然后往上追溯,
在查找的过程中要尽可能的多尝试,大胆猜测
最后我根据  keycode 找到了登录响应参数的生成函数
<ignore_js_op>
登录响应参数
其中有下划线的地方,我们可以直接点进去
<ignore_js_op>
加密方法
这部分代码就是加密的方法!

验证我们把源码拷贝出来,分析加密参数
private String c(String paramString)
  {
    Date localDate = new Date();
    Locale localLocale1 = Locale.CHINA;
    String str1 = new SimpleDateFormat("yyyyMMdd", localLocale1).format(localDate);
    Locale localLocale2 = Locale.CHINA;
    String str2 = new SimpleDateFormat("MMdd", localLocale2).format(localDate);
    StringBuilder localStringBuilder1 = new StringBuilder();
    String str3 = paramString.substring(7);
    StringBuilder localStringBuilder2 = localStringBuilder1.append(str3);
    StringBuilder localStringBuilder3 = localStringBuilder1.append(str2);
    String str4 = localStringBuilder1.toString();
    StringBuilder localStringBuilder4 = new StringBuilder();
    StringBuilder localStringBuilder5 = localStringBuilder4.append(paramString);
    StringBuilder localStringBuilder6 = localStringBuilder4.append("|");
    StringBuilder localStringBuilder7 = localStringBuilder4.append(str1);
    String str5 = localStringBuilder4.toString();
    try
    {
      str5 = zxw.data.c.b.a(str5, str4);
    }
    catch (Exception localException)
    {
      localException.printStackTrace();
      str5 = null;
    }
    return c.a(str5);
  }
其中生成了两个参数 str5str4 传到加密函数。
下面是 str5 的生成代码
String str1 = new SimpleDateFormat("yyyyMMdd", localLocale1).format(localDate);
StringBuilder localStringBuilder4 = new StringBuilder();
StringBuilder localStringBuilder5 = localStringBuilder4.append(paramString);
StringBuilder localStringBuilder6 = localStringBuilder4.append("|");
StringBuilder localStringBuilder7 = localStringBuilder4.append(str1);
String str5 = localStringBuilder4.toString();
str1 = 20190319,也就是今天的日期
str5 = 传过来的参数 + '|' + '20190319'
那么 str4 呢
String str2 = new SimpleDateFormat("MMdd", localLocale2).format(localDate);
StringBuilder localStringBuilder1 = new StringBuilder();
String str3 = paramString.substring(7);
StringBuilder localStringBuilder2 = localStringBuilder1.append(str3);
StringBuilder localStringBuilder3 = localStringBuilder1.append(str2);
String str4 = localStringBuilder1.toString();

java的  substring() 方法类似 python中的字符串切片,只是  substring() 方法返回字符串的子字符串。
那么我们可以推测, paramString 是一个长度大于7的字符串。这里大胆的猜测是我们提交的那个手机号码,因为我们请求的时候只提交了这个参数。
所以 str4 = '手机号码后四位' + 0319
如果不知道生成的方式,就用 java运行一波,将这两个参数打印出来,是最方便快捷的方法~~
既然知道加密参数了,接下来就是验证了
源码加密的方法如下:
<ignore_js_op>
下面是用 python 代码改造后的加密
<ignore_js_op>
运行之后的结果为 False,仔细看两者字母,数字基本都是一样的,感觉应该是对了,但还是有点差异!
再返回去看看源码,源码中最后将生成的加密数据再传给了某个函数再返回

return c.a(str5);

下面是这个 *c.a *的函数:

public class c
{
  public static String a(String paramString)
  {
    return paramString.replaceAll("\\+", "!");
  }
}

原来是将 "+" 替换成了 "!"
所以我们将之前运行出来的结果中的 "+"  替换成  "!" 就是完全正确了!
so, 我们就将这个 token 参数给破解了!

总结

1.对于app加密的要有耐心,尤其是在根据参数在源码中寻找加密方式的时候,更加需要耐心。
2.善于利用搜索引擎,碰到看不懂的方法,就去网上多搜索。
3.如果认识大佬,当然是要抱紧大佬的大腿啊,多问问大佬,会让你事半功倍!
当你解决的问题那一刻,你就会发现之前受的苦都是值得的!
 
更多技术资讯可关注:gzitcast

Guess you like

Origin www.cnblogs.com/heimaguangzhou/p/11388600.html