前言:前段时间遇到一个app做爬虫。这不是明显的欺负人吗?用赵四格的话来说:生死无足轻重,不服就服!那么接下来我就带大家分析破解一个app登录请求的加密参数,从而实现网络抓包密文到明文的转换。环境配置:PyhtonJavadex2jar(将apk反编译成java源码)jd_gui(查看源码)jadxroot手机或安卓模拟器fiddlerPS:公众号后台回复“decompile”获取反编译工具包分析:首先我们使用fiddler包捕获工具捕获应用程序的登录。本应用抓包需要开启全局代理,否则抓不到数据。如果你还不知道如何使用全局代理抓包,可以看之前的文章,里面有详细的抓包教程。抓取到的数据如下:我们可以看到一个token参数,有经验的朋友都知道这是服务器后台生成的,在发送登录验证码请求之前没有其他数据交换!这时候我们就得去查看app源码,找到这个参数的加密方式,然后转换成Python代码生成。接下来小编就带大家一步步破解这个参数。反编译流程:为了获取app源码,我们需要对app进行反编译。反编译的方法很简单,直接用工具就可以完成。有两种反编译方法可供选择。反编译过程如下:1.将Androidapp的后缀改为可解密包,并解压。2.将解压后生成的.dex后缀复制到dex2jar安装目录下。DOS命令行进入这个文件夹,然后执行命令:dex2jar.batclasses.dex。此应用程序有两个.dex文件,因此需要执行两个.dex文件。执行后会生成对应的两个.jar文件。效果如下:生成的.jar文件就是apk的源码。我们使用jd_gui查看源码还好这个app没有加固,有些app已经加固了,比如腾讯乐谷,360等,这种app不能直接反编译,需要先解包,然后反编译。5.第二次反编译编译的方式是直接使用工具jadx打开.apk文件。剩下的就是仔细阅读代码,分析其中的逻辑。6.根据请求或响应的参数查找加密方式的源码。需要注意的是,反编译后的代码非常混乱,错误较多,而且apk经过混淆后变量名已经消失。这个时候,你一定要有耐心,仔细研究代码。根据之前的request和response参数,或者请求的url地址来查找,经验很重要。我们将根据这些搜索结果慢慢搜索。我们主要是找到发送请求时定义参数的代码,然后在查找过程中尽可能往回走,大胆猜测,最后找到登录响应参数生成函数下划线部分根据keycode,我们可以直接点击进入,这部分代码就是加密方式!验证我们是否复制了源代码并分析了加密参数privateStringc(StringparamString){DatelocalDate=newDate();LocalelocalLocale1=Locale.CHINA;Stringstr1=newSimpleDateFormat("yyyyMMdd",localLocale1).format(localDate);LocalelocalLocale2=Locale.CHINA;Stringstr2=newSimpleDateFormat("MMdd",localLocale2).format(localDate);StringBuilderlocalStringBuilder1=newStringBuilder();字符串str3=paramString.substring(7);StringBuilderlocalStringBuilder2=localStringBuilder1.append(str3);StringBuilderlocalStringBuilder3=localStringBuilder1.append(str2);字符串str4=localStringBuilder1.toString();StringBuilderlocalStringBuilder4=newStringBuilder();StringBuilderlocalStringBuilder5=localStringBuilder4.append(paramString);StringBuilderlocalStringBuilder6=localStringBuilder4.append("|");字符串构建呃localStringBuilder7=localStringBuilder4.append(str1);字符串str5=localStringBuilder4.toString();尝试{str5=zxw.data.c.b.a(str5,str4);}catch(ExceptionlocalException){localException.printStackTrace();str5=空;}返回c.a(str5);}生成两个参数str5,str4传给加密函数下面是str5的生成代码Stringstr1=newSimpleDateFormat("yyyyMMdd",localLocale1).format(localDate);StringBuilderlocalStringBuilder4=newStringBuilder();StringBuilderlocalStringBuilder5=localStringBuilder4.append(paramString);StringBuilderlocalStringBuilder6=localStringBuilder4.append("|");StringBuilderlocalStringBuilder7=localStringBuilder4.append(str1);Stringstr5=localStringBuilder4.toString();str1=20190319,即今天的日期str5=传递的参数+'|'+'20190319'那么str4Stringstr2=newSimpleDateFormat("MMdd",localLocale2).format(localDate);StringBuilderlocalStringBuilder1=newStringBuilder();Stringstr3=paramString.substring(7);StringBuilderlocalStringBuilder2=localStringBuilder1.append(str2);Stringstr4=localStringBuilder1.toString();java的substring()方法类似于python中的字符串切片,只不过substring()方法返回的是字符串的子串。也可以推测paramString是一个长度大于7的字符串,这里大胆猜测是我们提交的手机号,因为我们请求的时候才提交了这个参数。所以str4='手机号后四位'+0319不知道怎么生成的就用java跑一波,把这两个参数打印出来,这样最方便快捷~~现在知道加密参数,接下来就是验证源码加密的方法如下:用python代码修改后的加密运算结果为False。仔细看两者的字母,数字基本一致。应该是对的,但是还是有一些区别!回去看看源码。在源码中,生成的加密数据最后传递给一个函数,然后返回returnc.a(str5);以下是这个c.a的函数:publicclassc{publicstaticStringa(StringparamString){returnparamString.replaceAll("\\+","!");}}原来是“+”换成了“!”所以我们把“+”换成“!”在前面运行的结果中,这是完全正确的!那么,我们就破解这个token参数吧!小结1、APP加密要有耐心,尤其是在源码中根据参数寻找加密方式时,更需要耐心。2、善于使用搜索引擎。遇到不懂的方法,多去网上搜索一下。3、认识大佬,当然要抱紧大佬的大腿。问大佬,会让你事半功倍!当你解决问题的那一刻,你会发现之前所有的苦都是值得的!更多内容请关注我公众号,Python编程与实战