原文章发表在 https://www.jianshu.com/p/5cc402b67aaa 现在有了自己的静态博客,特意搬过来
1. 前言
此文章仅适用于兴趣研究,不可作为损坏他人或其他机构等利益之用,本文只是提出一个设想,并不保证具有普适性
2. 开题
对于安全来说,app是毫无安全性可言的。
不管您是用了proGuard来混淆app,还是用了360加固宝,腾讯加固,等加固产品,最终都会被以各种方法破解。
例如使用IDA Pro,来进行dump,很容易就可以进行还原未加固的.dex文件,源代码就会暴露出来
因为app要运行,总会把加固的东西还原进内存,总是会有一些工具可以做到脱壳。
所以与其想办法在前端做加密,不如使用SSL和安全的服务器端
本讲主要介绍如何利用手写xposed模块,hook(钩出我们想要的密码的盐值
注,此方法对于native method: C/C++代码编译的.so文件无解
3. 需求
3.1. 需求的出现
我学校有个查成绩的app,抓包发现使用的是RESTful风格的WebService,配合手机端的app
原理是
使用用户名和加密的密码登录,返回一个由时间和用户信息共同决定的token,以后的各种请求都由此token来确定请求者身份,可以很容易把此WebService搬到网页上面来,而不用为了安装一个一年只用2次的app而到处求包
于是决定搞清楚p字段(密码加密的原理
3.2. 分析p字段
p字段的长相
c98f9b47a56d685001b94a9827feef36
他的特点有:32位,最大字母是f
由此可以初步判断,他可能是使用了较为常见的MD5消息摘要算法进行的加密
利用站长工具MD5在线加密,对‘password’这个密码进行了测试,发现
与上文c98f9b47a56d685001b94a9827feef36
是不一样的
3.3. 对app进行反编译
由于第2步中的两次测试结果不一致,猜测app内部可能使用了盐(Salt
盐(Salt,在密码学中,是指在散列之前将散列内容(例如:密码的任意固定位置插入特定的字符串。这个在散列中加入字符串的方式称为“加盐”。其作用是让加盐后的散列结果和没有加盐的结果不相同,在不同的应用情景中,这个处理可以增加额外的安全性。
为了探寻加盐方式和加密逻辑,要对app进行反编译
这里使用apktool
apktool的下载地址:https://ibotpeaches.github.io/Apktool/
将app的apk安装包和apktool放在同一文件夹下
cd
到该目录 或 按住shift
键在该目录空白处右键,选择在此处打开cmd/powershell窗口
执行如下命令
java -jar .\apktool_【版本号】.jar d .\【apk名字】.apk
发现整个程序的入口被一个桩模块(stub)取代,再看到qihoo
,就知道是用了360加固
360加固宝加密了!:
在assets下发现360加固的内容so二进制文件:
这下就很棘手了
3.4. 面临抉择
app被加固,我有两条路可以走
- 给app脱壳
- 想其他办法
我也在网上搜了不少IDA pro的文章,看的也都似懂非懂,于是还是放弃了这个方法
4. 正文
最后决定使用Xposed模块hook相应方法
hook的话我们需要知道md5加密的方法的方法名,但是由于代码是加固了的,我们无从得知
逆向思维
方法无非有这两大类,一种是我们不知道名字的,一种是系统的类的方法,名字肯定是固定的
既然密码有加盐,那么定然会用到+
来做字符串拼接:pass+salt
而字符串拼接会被编译成StringBuilder
的字节码,所以只要hook了StringBuilder
的toString
方法,就会得到pass+salt
的返回值
StringBuilder在现代化的IDE里面已经不被推荐使用了,因为编译器会把+连接的字符串编译成StringBuilder的append方法,为了保持代码的美观和可读性,IDE都会建议使用+号而不是sb
4.1. Xposed框架安装
xposed分两部分,一个是框架(framework),一个是模块(module)
框架可以直接安装,需要root的手机和兼容的系统
xposed官网下载地址 - XDA论坛
去百度上搜也可以,推荐使用酷安市场下载
详细的框架安装教程这里不提供,网上可以搜到更为详尽的教程
4.2. 进行模块的开发
4.2.1 准备Android Studio
4.2.2 新建一个项目
不需要添加Activity,建一个空空的项目就好
您可以选择阅读官方开发教程说明:https://github.com/rovo89/XposedBridge/wiki/Development-tutorial
也可以继续看我的表演
4.2.3. 添加如下依赖
我在这里使用kotlin语言来发开
|
4.2.4. 在清单文件Application里面加入
|
4.2.5. 编写一个普通的类
如Main
|
4.2.6. 代码解释
使用XposedHelpers
类的静态方法findAndHookMethod
:
此方法有两个重载,一个适用于系统类,一个适用于要hook的app自定义的类。
我们使用3个参数的那个方法:
- 第一个参数:明确hook对象的类
- 第二个参数:要hook的方法名
- 第三个参数:一个hook方法的匿名内部类实例
重写 afterHookedMethod
,将param
的result
打成日志即可
4.2.7. 新建xposed_init文件
在项目上右键new -> Folder -> Assets Folder
新建文件xposed_init
,打开它,在里面写上要执行的xposed动作类cn.tellyouwhat.mhook.Main
即可
4.2.8. 编译的时候选择不需要activity
选择Nothing,而不是Default Activity:
4.2.9. 激活模块,硬重启手机(虚拟机可以软重启)
在xposed installer中,点击模块选项,勾中您开发的模块,然后重启手机,就能启用该模块
打开您要hook的app,输入用户名和密码进行登录
4.2.1 在LogCat中查找
找到啦~
就可能会发现加密字符串的盐值
password后面那几个字母就是盐
还可能出现很多情况,比如加密
|
等等情况,需要小心调试,慢慢发现
4.2.11. 验证
此盐值c98f9b47a56d685001b94a9827feef36
匹配
5. 结束语
本次测试成功,纯属机缘巧合,如没有解决您遇到的问题,还请见谅。本文只是提供一个思路,靠谱的还得是内存DUMP。也奉劝各位app安全的从业人员,把重心转移到传输层面上,app无绝对的安全可言。