分析app的登陆协议

APP抓取 2018-05-24 12:00:50 阅读(27440) 评论(0)

这是一篇逆向分析APP登陆流程的文章。

1. 抓包

(1) 抓包前将手机和电脑连接到同一WIFI,在手机设置好代理,装好证书,就可以开始抓包了。之前我遇到抓不到包的情况,换了几个代理工具也不行,最后是开着热点抓到包(一台开热点,另一台和电脑连接热点),或者换成手机抓包工具HttpCanary等也可以抓包。

(2) 抓包环境配置好后,在登陆界面随便填一个账号密码:

分析app的登陆协议1

(3) 点击登录,查看Fiddler中的数据包数据包中的参数:city=%E5%8C%97%E4%BA%AC%E5%B8%82&citycode=010&device=63ac32df-d1c2-3008-828e-ef9f1bb3a96d&device_model=google%20Pixel%202&device_name=google%20Pixel%202&device_os=Android%205.1.1&device_product=google&device_size=1080*1920&device_type=1&district=%E4%B8%9C%E5%9F%8E%E5%8C%BA&fake_id=37979341&interface_code=620&latitude=39.91640353732639&longitude=116.41024359809028&mobile=13426355456&password=EBEDF39355506FF1F42AAD7A20E1DB83&province=%E5%8C%97%E4%BA%AC%E5%B8%82&province_code=1582770774000&version=6.2.0&securitykey=41de91b2c71d0af71c7a71887e14b57d

一般需要抓两次包来对比数据包参数的变化,观察哪些参数是固定或者容易得到的,哪些是不能直观看出需要进一步分析:

分析app的登陆协议2

对比两个数据包可以看到,手机号没有加密,密码做了加密,还有一个参数securitykey也是加密的。这次逆向的重点也就是分析这两个参数的生成逻辑。

2. 脱壳

(1) 直接把apk用jadx反编译,发现做了加固,是legu的壳,相关逻辑代码没法直接看到:

分析app的登陆协议3

(2) 这里我使用了一个基于frida编写的脱壳工具:https://github.com/hluwa/FRIDA-DEXDump 原理是在内存中暴力搜索,根据dex文件的结构特征将其dump下来,启动frida-server,启动app,运行脚本就可以了。如果使用过程中报错,可以试试重启手机,或者杀死app进程并重启app。

3.分析加密参数securitykey

(1)之前抓到的包是分析的入口点,在jadx中反编译dump下来的dex,点击菜单栏的小魔法棒搜索securitykey这个参数:

分析app的登陆协议4

结果如下;第四个GLOBAL_PARAMS_KEY = “securitykey”比较显眼,双击打开看看,也可以把右边所有结果挨个点开分析:

分析app的登陆协议5

 

观察代码,securitykey参数应该是在其他位置被引用,右键GLOBAL_PARAMS_KEY,选择查找用例,看看哪些地方用了这个参数:

分析app的登陆协议6

根据经验推测,第二个stringBuffer.append一般是数据包参数构造的位置,双击打开它:

分析app的登陆协议7

GLOBAL_PARAMS_KEY的值就是securitykey参数,接着拼接了一个“=”和一个finalSecStr的变量

分析app的登陆协议8

双击这个finalSecStr变量,可以看到finalSecStr在代码中的处理逻辑,可以看到是经过getMD5Str这个方法处理得到的,看函数名感觉是计算MD5:

分析app的登陆协议9

 

继续看getMD5Str的参数secStr,发现是由this.paramMap处理得到:

分析app的登陆协议10

再往上分析,发现this.paramMap中值就是数据包那些参数:

分析app的登陆协议11

自此,securitykey这个参数的计算逻辑差不多出来了,把this.paramMap中的参数挨个拼接“|”变成secStr,再传给getMD5Str,返回的值就是数据包中securitykey的值。
按住Ctrl键,单击getMD5Str这个方法,可以看到就是MD5的计算:

分析app的登陆协议12

点击菜单栏中的向左小箭头返回上一层代码:

分析app的登陆协议13

我们可以通过hook getMD5Str方法,将其参数和返回值打印出来,验证我们的分析。这里涉及到一个问题,这个app加了壳,直接去hook会出现“ClassNotFoundError“的错误,这是因为getMD5Str这个方法不是一开始就在内存中的,它是被壳加载起来的。所以hook方法要有所改变。

4.加壳和MultiDex情况下如何hook

原理:所有的类都是通过ClassLoader的loadClass方法加载的,于是可以等我们要hook的这个方法所在的类被加载后再去hook,这样就可以百发百中了,多个DEX的情况下也可以使用这个方法该方法出处:https://bbs.pediy.com/thread-225190.htm

分析app的登陆协议14

Hook getMD5Str方法后打印参数和返回值,编译安装xposed插件,重启手机,结果发现什么也没hook到,确认类名和方法名,参数都没问题。经过长时间的分析也没结论,最后是用ddms发现了问题:jadx反编译得到的类名,方法名不正确,与真实命名不一样。
%1. ddms的使用ddms是一个AndroidSDK自带的方法追踪工具(一般位于SDK的tools目录下),用于记录app执行过的方法。这里我们需要记录的是点击登陆按钮后app执行的方法。打开ddms后,先选中app对应的进程,然后选择菜单栏中的“开始追踪”

分析app的登陆协议15

 

选择第二个,记录所有方法

分析app的登陆协议16

接着以最快的手速点击登录按钮(因为ddms会记录系统中在运行的很多进程的方法),等到弹出“该账号不存在”(因为我们随便输入的),立即点击ddms的“停止追踪”按键(跟“开始追踪”是同一个,不过现在变灰了),就能得到从点击登陆按钮后到账号校验完期间app执行的所有方法:

分析app的登陆协议17
接着会弹出一个trace文件,就是记录下来的方法:
分析app的登陆协议18

在最下面find搜索栏中输入app的包名,按回车键挨个观察记录下来的方法,在其中找到了getMD5Str方法的正确类路径,而之前在jadx中反编译得到的是:com.XXXXXX.common.utils.encrtption.MD5Helper.getMD5Str所以用jadx中的类路径肯定是hook不到getMD5Str方法了。

分析app的登陆协议19

 

把类路径改成ddms记录的正确路径,重新编译hook插件,重启手机,运行app,输入账号密码,点击登录,在ddms的日志中可以发现,这次顺利的打印出了getMD5Str方法的参数和返回值:

分析app的登陆协议20

对比数据包参数:

分析app的登陆协议21

将getMD5Str方法的参数与数据包中参数对比,发现是一致的,返回值就是参数的MD5值,验证了我们之前的分析是对的:

分析app的登陆协议22

%1. password参数的分析分析完了securitykey这个参数,现在就分析password这个参数,可以发现,并没有在大量参数构造的地方发现password:

分析app的登陆协议23

在jadx中搜索也没有发现:

分析app的登陆协议24

 

观察上面的参数,他们都是带着双引号的,尝试给password加上双引号搜索,终于看到了:

分析app的登陆协议25

第二个看着像是AES加密有关的,双击进去看看,果然是:

分析app的登陆协议26

按住Ctrl,点开AesEncryptionHelper看看,是”AES/CBC/PKCS5Padding”的加密方法:

分析app的登陆协议27

验证一下:

分析app的登陆协议28

跟数据包中的password的值是一样的:

分析app的登陆协议29

自此,两个加密参数的分析就完成了。

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...