美文网首页
app逆向入门分析——破解某APP登陆请求参数

app逆向入门分析——破解某APP登陆请求参数

作者: GoPython | 来源:发表于2019-03-19 20:51 被阅读0次

    前言:

    微信搜:Python编程与实战

    前段时间做爬虫遇到一个app,里面的数据需要登录之后才能拿到,而且登录不能用密码,只能通过验证码登录。
    这不是明摆着欺负人么,按赵四哥那句话来说就是:

    生死看淡,不服就干!

    所以接下来手把手带大家就某个app登陆请求的加密参数进行分析破解,
    从而实现从网络抓包的密文到明文的转换。

    环境配置:

    Pyhton
    Java
    dex2jar(将apk反编译成java源码)
    jd_gui(源码查看)
    jadx
    已root的手机或者安卓模拟器
    fiddler
    PS:公众号后台回复 "反编译" 即可获取反编译工具包

    分析:

    首先我们用fiddler抓包工具对app的登陆进行抓包,这个app抓包需要开启全局代理,不然会抓不到数据。

    如果还不会使用全局代理抓包的朋友,可以看下前面一篇文章,里面有详细的抓包教程。

    抓包的数据如下:


    发送验证码请求参数

    我们可以看到有个 token 的参数,有经验的朋友知道,这是服务器后台生成的,而且在发送登陆验证码请求之前并没有其它的数据交换!

    登录请求参数

    这时候我们就要去看app源码找到这个参数的加密方式,然后用转换成 Python 代码生成。

    接下来就带大家就一步一步来破解这个参数。

    破解过程:

    我们要获取app源码,就要对app进行反编译,反编译方式很简单,直接用工具搞定。
    有两种反编译方式可供选择,反编译过程如下:

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

    解压生产.dex

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

    解压生产.dex

    3.DOS命令行进入此文件夹,然后执行命令: dex2jar.bat classes.dex
    这个app有两个 .dex 文件,所以两个 .dex 文件都需要执行

    执行完之后会生成两个对应的 .jar 文件,效果如下:

    反编译生成.jar文件
    1. 生成.jar文件就是apk的源码了,我们使用 jd_gui 来查看源码
    查看源码

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

    腾讯加固 360加固

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

    5.第二种反编译的方法是直接使用工具 jadx 打开 .apk 文件
    剩下的事就是仔细阅读代码,分析其中的逻辑了。

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

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


    搜索结果

    我们就要根据这些搜索到的结果慢慢去找了。我们主要找到发送请求的时候定义参数的代码,然后往上追溯
    在查找的过程中要尽可能的多尝试,大胆猜测

    最后根据 keycode 找到了登录响应参数的生成函数

    登录响应参数
    其中有下划线的地方,我们可以直接点进去 加密方法

    这部分代码就是加密的方法!

    验证

    我们把源码拷贝出来,分析加密参数

    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);
      }
    

    其中生成了两个参数 str5, str4 传到加密函数。
    下面是 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运行一波,将这两个参数打印出来,是最方便快捷的方法~~

    既然知道加密参数了,接下来就是验证了
    源码加密的方法如下:


    源码加密

    用 python 代码改造的加密


    python改造的加密

    运行之后的结果为 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.如果认识大佬,当然是要抱紧大佬的大腿啊,多问问大佬,会让你事半功倍!

    当你解决的问题那一刻,你就会发现之前受的苦都是值得的!

    相关文章

      网友评论

          本文标题:app逆向入门分析——破解某APP登陆请求参数

          本文链接:https://www.haomeiwen.com/subject/dcpwmqtx.html