首页
社区
课程
招聘
[原创]某APP密码加密算法分析
2021-12-20 16:49 17501

[原创]某APP密码加密算法分析

2021-12-20 16:49
17501

前言

记录一下,最近在逆向某app过程中遇到的登录密码加密算法,样本就不给出了,欢迎交流,只做技术探讨,侵权联系我删除。

正文

反编译apk文件,通过一系列的定位,最终可以定位到密码的加密位置在
图片描述
上面sM2Ciphertext是最后提交到服务器的密码值,可以看出调用了getSM2Ciphertext 方法获取加密后的密码原文。跟踪调用关系,很容易找到了最后是调用了native层的getOutput函数,如下
图片描述
由于该函数的具体实现在so里面,我们先对该函数hook 一下,看一下参数和返回值。
图片描述
可以看到第一个参数是157845242 和我们的密码无关,第四个参数是779e3c9ccda4...|392157c3fb5dd... 这样的一个字符串,记住这个字符串很重要,后面会说到。通过抓包发现函数的返回值确实是提交到服务器的值,那么猜测可能在调用getOutput获取加密密码之前,一定是调用了其他的native 方法,将密码参数添加到了so层,这样才能调用getOutput生成密码。然后我们又hook了addtText方法,并在密码框输入123456
图片描述
发现,每次输入时,addText 的第三个参数发生变化,最后三个int 参数是递增关系,这里我们可以知道,java层对我们的输入字符做了某种映射,使其最后添加到so层的不是原字符串。作者首先考虑的是使用unidbg 模拟调用,但是模拟调用之前,首先要找到映射关系,还要处理初始化函数调用关系等。so... 放弃了。
换种思路,我们直接在so层找到加密算法,于是作者找到了了lib 目录下 libPassGuard.so,也可以hook 动态注册函数,找到native方法注册在哪个so.
打开so发现在导出函数中没有找到getOutput函数,那么这是动态注册了
图片描述
可以看出JNI_Onload方法中v5是动态注册的函数地址
图片描述
于是我们找到了上面的函数,getOutput的函数不是很复杂,如下
图片描述
我们先hook AndroidPassGuard::GetOutput 看一下
图片描述
图片描述

 

v12 是我们从java层传进去的第二个字符串,事实上这是PassGuardEncrypt 在初始时产生的随机hash值,retval 就是返回给java的最终密码加密值。
我们继续跟踪调用,最后发现
图片描述
我们hook GetRealTextex 发现
图片描述
AndroidPassGuard::PassGuardEdit::GetRealTextex 在这里将映射后的密码恢复成我们输入的密码了,这就很好办了。最后真实密码给了MultiEncrypt进行加密,看一下函数内部
图片描述
然后又调用了Encrypt 方法,继续跟进去
图片描述
发现根据不同的a1值,最终调用的不同的加密算法,包括sm2、sm4、rsa等,而a1 又是该函数的第一个参数,我们继续hook Encrypt 方法得到了a1 = 0x4,那么很明显最终是调用了realsm2 加密算法。我们继续hook realsm2 算法看一下。
图片描述
realsm2 的第一个参数是返回值,就是我们的加密结果了,第二个参数779e3c9ccda4...|392157c3fb5dd... 是我们从java 层传进去的,123456就是我们的明文密码了。
这里我们可以认为加密算法就是sm2了,但是公钥却不是779e3c9ccda4...|392157c3fb5dd... ,一般来说,国密加密算法,公钥以04开头,且不会出现在字符串中出现|。
再继续看realsm2内部
图片描述
这里不hook了,累,直接说分析结果吧,在函数内部根据|分割字符串得到两个字符串,再使用BN_hex2bn 将其转成对应的两个字节数组,然后在EC_key_from_BN函数内部,如下
图片描述
被当作仿射坐标,生成sm2 加密公钥。当然这个公钥是个结构体,不是简单的字符串,不好直接hook,但是我们知道了仿射坐标就是java层传进去的字符串,至此就可以对原文加密了。
有了上面的分析,其实就可以加密了,作者找了一份网上公开的java 版 sm2 加密算法,但是网上的代码一般是直接给定了04开头字符串公钥,而不是仿射坐标,如下
图片描述
阅读源码decodePoint 源码可知,对给定的公钥 图片描述
生成了仿射坐标,那么就很办了,我们直接做如下修改
图片描述
其中point_x就是779e3c9ccda4... ,point_y 是392157c3fb5dd... 这样来设置用户密钥。
最后放出加密结果
图片描述

结语

到这里基本验证了算法的可行性,但是各位看官都明白作者的 java版sm2 加密算法,还不一定能在在模拟请求中使用,因为服务器可能验证不通过。本文作者只对加密算法做了探讨,事实上该算法最后也通过了服务器验证,这里可以做个快速验证:用 xposed hook 替换掉 java层 getSM2Ciphertext函数,使用我们自己的java 加密算法对密码原文进行加密,如果能成功登录,说明算法是正确的。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞3
打赏
分享
最新回复 (2)
雪    币: 62
活跃值: (566)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
万里星河 2021-12-27 23:14
2
0
支持一下
雪    币: 243
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
青头潜鸭 2022-11-5 21:23
3
0
怎么联系 有个控件求算法
游客
登录 | 注册 方可回帖
返回