学习安卓逆向分析的一个小菜鸟,记录分析的“快乐时光”,小白图个乐,大佬乎喷
分析的APP
英语配音狂
包名:com.zhuoyue.peiyinkuang
版本号:5.2.5
模拟器安装最低版本:Android 4.4 (KITKAT)
抓包分析
1、安装到模拟器之前 首先通过普通的查壳工具查一下壳,显示没有壳
然后用GDA 反编译后 显示出 有腾讯的Bugly服务打包 这个貌似不是加固在apk上面的 那就不管了
2、开始抓包
输入随便输入手机号:13888888888 和密码:a12345678
抓到一个登陆包 ;
:method: POST
:path: /api/app/v1/quickLogin
:authority: api.engdub.com
:scheme: https
content-type: application/x-www-form-urlencoded
content-length: 245
accept-encoding: gzip
user-agent: okhttp/3.12.0
json=HAVQesRr7f7Hq7zeuzJ3FaRi9cXCixVlEfoCh4Yeq8nbxkmM1YhJVQpwCR%2FVnLZaRfkdREkUS8QclJZqiTDb%2BqcAKIbtxt1YkDbAqmU2UYW1pU%2FHOz1oc017bdKdTm8ZF%2FXjzxPFr5HfUnzubGWvyEiBVQjfRzHFhbyuh1LuaasWNHYAlWzVZ6%2BuK6bB9FTE&sign=FF0489EEEF0066729122226D6BD48D84
是一个post请求包
form 表单传了 两个参数 一个是 json 一个是 sign
那么 这个json 就一定是 手机号和密码的加密 的 sign 是加盐验证json数据的
3、GDA 反编译
现在对GDA 真的是吹爆! 好用 反编译的数据也是比jadx的数据更加的容易看懂
这个登陆数据包,因为关键词 json 和 sign 都是常用的参数关键词
所以这次搜索定位的关键词 我选择了 URL的部分参数 quickLogin 为关键词搜索
通过 quickLogin 字符串搜索 可以搜索到 几条数据
可以看到第一条 是完全匹配 登陆发送的URL的 直接双击点击进入
可以看到 这个 login 的方法中 传入了 四个参数
String p0,String p1,Handler p2,int p3
通过上下文判断 可以知道
p0 就是 手机号码
p1 就是密码 并且进行了 md5 的加密
然后 是 a uoa = new a() 新建了一个 uoa的a对象
盲猜 应该是 进行 手机号码 密码 时间戳的 json 形式的键值对组合拼接
=======================================
然后 双击跳转到 sendPostEncodeAndResultDecode 方法里面去
通过层层的跳转,最终跳转到 sendPostEncodeAndResultDecode 定义的地方
也可以清楚的看到 json 和 sign 的 键值信息定义的地方了
========================================================
可以很明显的发现 是 AESUtil.aesEncode() 是 AES加密
双击进入方法 查看
可以看到 "AES/ECB/PKCS7Padding", "BC"
加密模式 和调用的 是 BC 的加密库
然后 找一下 AES的密钥
双击 AESUtil.encryptKey 进入查看密钥
发现了 AES 的密钥 是在 静态注册在 SO 层的
这不禁让我 有点慌 因为so 才刚刚触碰,并不是很懂。。。。。
===================================
硬着头皮 把 apk 文件 下面的lib 目录 打开,找到 libaescheck.so 后
用 ida 打开
加载完后,打开 exports 导出表
查看,还好 只有一个导出函数 而且就是 这个 AES的密钥
然后 双击进入函数后,是汇编代码,根本看不懂,就直接按F5 转成伪C代码
转完以后,然后惊喜的是 这个函数的代码 非常的简单
int a1 是 env加载器 没有什么参数传入这个函数
并且 直接就是 return 返回 字符串而已
AES 的 字符串密钥 直接就 显示在我的面前 "wetnojaw6hkjas92"
=======================================================
喜出望外啊,
那么 AES 的 加密模式 我知道了
AES 的加密密钥我也知道了
AES 的最终加密值 json 我也抓到了
那么不就可以 解密了嘛
json AES加密数据
HAVQesRr7f7Hq7zeuzJ3FaRi9cXCixVlEfoCh4Yeq8nbxkmM1YhJVQpwCR/VnLZaRfkdREkUS8QclJZqiTDb+qcAKIbtxt1YkDbAqmU2UYW1pU/HOz1oc017bdKdTm8ZF/XjzxPFr5HfUnzubGWvyEiBVQjfRzHFhbyuh1LuaasWNHYAlWzVZ6+uK6bB9FTE
json AES解密数据
{"rs":[{"data":{"in":{"pojo":{"currentTime":1640162532804,"password":"e9bc0e13a8a16cbb07b175d92a113126","userName":"13888888888"}}}}],"id":"0"}
可以看到的是除了 之前的 手机号码 MD5的密码 和 时间戳之外 还有几个参数 另外的几个参数 一看就可以固定不变
"sign", MD5Util.getSign(p0, Check.getKey())
然后就是对 sign 这个值进行解密
可以看到的是 通过 getSign 这个方法进行md5 加密的
加密了 p0 和 Check.getKey()
双击 进入 这个getsign 方法后可以看到
p0+"&key="+p1 的字符串 被 MD5加密 并且到 toUpperCase() 到大写
p0 是 就是刚才AES 解密的数据
{"rs":[{"data":{"in":{"pojo":{"currentTime":1640162532804,"password":"e9bc0e13a8a16cbb07b175d92a113126","userName":"13888888888"}}}}],"id":"0"}
p1 就是 AES的密钥 wetnojaw6hkjas92
那么 拼接起来就是
{"rs":[{"data":{"in":{"pojo":{"currentTime":1640162532804,"password":"e9bc0e13a8a16cbb07b175d92a113126","userName":"13888888888"}}}}],"id":"0"}&key=wetnojaw6hkjas92
通过MD5 加密 就是 FF0489EEEF0066729122226D6BD48D84
和 转包数据中的 sign 值 是一模一样的 至此 该APP的 登陆算法协议分析完成
PS:
其实有时候在分析 算法和协议的时候,我觉得并不需要 全部按照逆向分析的流程去做
比方就像刚才的p0的数据,其实在分析login方法的时候,只是发现了手机号 密码 和时间戳
进行了键值对的拼接组合成json数据。
但是,后续就不在继续往下分析了,关键是找到是什么算法加密的,那么后续就可以通过抓到包的数据
进行解密,这样加密值里面有其他什么数据就一清二楚了。提升整体算法分析的效率!