学习安卓逆向分析的一个小菜鸟,记录分析的“快乐时光”,小白图个乐,大佬乎喷
分析的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数据。
但是,后续就不在继续往下分析了,关键是找到是什么算法加密的,那么后续就可以通过抓到包的数据
进行解密,这样加密值里面有其他什么数据就一清二楚了。提升整体算法分析的效率!
|