58 招财猫变形 RSA 与变形 BASE64 逆向分析
0x0 概述:
58 招财猫登陆密码算法经过:
libcom_wuba_uc_rsa.so 中 Java_com_wuba_uc_RsaCryptService_encrypt 函数加密,下面
简称 encrypt 函数。
Encrypt 先 调 用 JByte2CChar 把 Java byte 数 组 转 换 为 char * , 然 后 进 一 步 调 用
encrypt_default 进行加密。
encrypt_default 先解密 rsa 公钥文件,然后调用 encrypt_d,最后把结果进行 base64 变
形加密。
encrypt_d 先进行 rsa 加密,然后调用 ch_crypt 对加密结果进行变换。
难点是 ch_crypt 和变形 base64
0x1:
Encrypt 函数首先对签名结果检验(isOurApk 值来源于签名验证结果)
.text:000019DE LDR R5, =(isOurApk_ptr - 0x19EA)
.text:000019E0 SUB SP, SP, #0xC0
.text:000019E2 LDR R1, [R3]
.text:000019E4 MOV R4, R0
.text:000019E6 ADD R5, PC ; isOurApk_ptr
.text:000019E8 LDR R5, [R5] ; isOurApk
.text:000019EA MOV R10, R3
.text:000019EC STR R1, [SP,#0xE0+var_24]
.text:000019EE LDR R1, [R5]
.text:000019F0 CMP R1, #1
.text:000019F2 BEQ loc_19F8 ; 签名验证检查,isOurApk
是是否通过签名验证
因为 Java 层传入的参数是一个 byte 数组,所以用 JByte2CChar 转换。
BL JByte2CChar ; 参数 byte 数组转成 c char * 返回值是转换后的 char * 指针,为输入数据,实际上是要加密的密码。
继续调用:
BL encrypt_default
encrypt_default 有两个参数,第一个参数为要加密的指针,第二个为加密结果的缓冲区指针。
最后调用 jni 创建 byte array,并返回
0x2 主线函数 encrypt_default
signed int __fastcall encrypt_default(const char *a1, int a2)
参数分析:
参数 1:要加密的数据指针(以 0 结尾的文本)
参数 2:输出缓冲区指针
IDA 识别出两个参数,第一个参数是要加密的字符串,第二个参数是缓冲区的指针。
该函数首先解密 RSA 加密用的公钥文件。
因为公钥文件是固定的所以在 get_public_key 这里下断点,查看 R0 寄存器指向的内存
用 IDA dump 出来,公钥内容如下:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8WHgg860BYItkr4ivHuiDvtPklURX2o97Wvd
kA8QDKbxPXmbkb4Pqz7oosqTTphVT7iN9tsIvSfU3fk1qw7Y7PNNql0b53GvdfCquJgIKa2/BrGOZtNp
Y+O05RGhs+soyjR3Vge+G0dvofBKvATDoznKNAIFOlovuYCdS0lrGkQIDAQAB
根据流程,继续调用 encrypt_d 函数进行 RSA 加密。
然后调用 base64_encode_uc 函数对结果进行 base64 编码,不过这个编码是变异过的。
对于 encrypt_d 和 base64_encode_uc 函数我会在后面逐渐分析。
0x3 encrypt_d 函数逆向分析:
signed int __fastcall encrypt_d(int a1, signed int a2, int a3, int a4)
参数分析:
参数 1:欲加密的数据指针
参数 2:加密数据的长度
参数 3:RSA 公钥指针
参数 4:输出缓冲区指针
大概看看,RSA 加密用的 openssl,关于 rsa 模式怎么确定呢?
int RSA_public_encrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa, int padding);
因为超过 4 个参数,第 5 个参数放在栈中,所以 IDA 只分析了 4 个参数出来,我们手动分析
第五个参数。
MOVS R3, #1
MOV R0, R1
STR R3, [SP,#0xA8+var_A8] //把R3存储到[SP,#0xA8+var_A8] 这 R3是 上面的#1
MOV R1, R7
MOV R2, R6
MOV R3, R5
BLX RSA_public_encryp
如代码可知,第五个参数传入的是 1。
根据 padding 参数的常量值查表:
Padding 是一系列以 RSA_开头的常量
define RSA_PKCS1_PADDING 1
define RSA_SSLV23_PADDING 2
define RSA_NO_PADDING 3
define RSA_PKCS1_OAEP_PADDING 4
define RSA_X931_PADDING 5
define RSA_PKCS1_PSS_PADDING 6
define RSA_PKCS1_PADDING_SIZE 11
可知用的是 RSA_PKCS1_PADDING 模式。
没有发现 IV 向量之类的东西,可以推断是 ECB 模式
继续调用:
ch_init(&s, “1V:8(Nqa,U&Ll.RW2 @slN>Vp$qT#T=phf MA<0GO/6V+rW-A!”);
ch_crypt(&s, v4, 128);
根据上下文,v4 是加密结果缓冲区,s 由 ch_init 初始化,ch_init 参数固定,所以 s 也是
定值,直接 dump 出来,ch_crypt 需要编程实现
0x4 ch_crypt 逆向分析
参数分析:
参数 1: 初始是串,固定内容。
参数 2: RSA 加密结果内存地址。
参数 3: 128
.text:00001424 EXPORT ch_crypt
.text:00001424 MOVS R3, #0
.text:00001426 PUSH {R4-R7,LR}
.text:00001428 MOV R5, R3
.text:0000142A MOV R4, R3
.text:0000142C loc_142C ; CODE XREF:
ch_crypt+32_x0019_j .text:0000142C CMP R3, R2
.text:0000142E BEQ locret_1458
.text:00001430 ADDS R4, #1
.text:00001432 AND.W R4, R4, #0x7F
.text:00001436 LDRB R6, [R0,R4]
.text:00001438 ADD R5, R6
.text:0000143A AND.W R5, R5, #0x7F
.text:0000143E LDRB R7, [R0,R5]
.text:00001440 STRB R7, [R0,R4]
.text:00001442 STRB R6, [R0,R5]
.text:00001444 LDRB R7, [R0,R4]
.text:00001446 ADD R6, R7
.text:00001448 LDRB R7, [R1,R3]
.text:0000144A AND.W R6, R6, #0x7F
.text:0000144E LDRB R6, [R0,R6]
.text:00001450 EORS R6, R7
.text:00001452 STRB R6, [R1,R3]
.text:00001454 ADDS R3, #1
.text:00001456 B loc_142C
.text:00001458 ; ---------------------------------------------------------------------------
.text:00001458
text:00001458 locret_1458 ; CODE XREF: ch_crypt+Aj .text:00001458 POP {R4-R7,PC}
.text:00001458 ; End of function ch_crypt
得还原上面的汇编
可以 IDA F5,出来的程序改改指针。
Ch_crypt 对 rsa 结果处理后,又进行 base64 变形加密。
0x5 base64 变形分析
这个有点神奇,因为 base64 代码量比较大,就反复在 base64_encode_uc 处下断点,输入多
组数据测试。
无视【】只为方便看。
标准:y610xSNrH9YPrYjXWk2WRguZ5nZo0iw9zle3mC94VqeBmo2qY9hu9h4lPEEI1Bs【/】xc【=】
变形:y610xSNrH9YPrYjXWk2WRguZ5nZo0iw9zle3mC94VqeBmo2qY9hu9h4lPEEI1Bs【_】xc【B】
多测试几组数据就能发现所有规律了,无非就是替换了几个符号。
需要注意的是只有在最后【=】才变成【B】
58 招财猫变形 RSA 与变形 BASE64 逆向分析相关推荐
- JS逆向分析新浪某站登录处RSA加密
文章目录 前言 RSA加解密 核心思想 Pyhon实现 NoPadding 新浪网实战 JS加密分析 JS函数调试 Py调用脚本 BurCrypto爆破 插件介绍 实战案例 总结 前言 在渗透测试过程 ...
- 58同城AES签名接口逆向分析
背景:需要获取58同城上面发布的职位信息,其中的包括职位的招聘要求,薪资福利,公司的信息,招聘者的联系方式.(中级爬虫的难度系数) 职位详情页分析 某个职位详情页的链接 某个职位的链接 https ...
- JS逆向--PyExecJS基本用法--网易云音乐逆向思路,node.js安装教程,逆向思路,逆向分析,加密机制,RSA,AES加密算法,加密算法啊破解,js引擎,定位数据包,分析栈结构,无痕窗口
文章目录 前言 一.JS逆向以及PyExecJS模块介绍 1.JS逆向 2.PyEecJS 二.使用步骤 1.环境安装 安装PyExecJS模块 安装node.js开发环境(官网链接 https:// ...
- 【JavaScript 逆向】极验三代滑块验证码逆向分析
声明 本文章中所有内容仅供学习交流,相关链接做了脱敏处理,若有侵权,请联系我立即删除! 案例目标 极验验证码 demo:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby8= ...
- 知物由学 | 干货!一文了解安卓APP逆向分析与保护机制
"知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物 ...
- 【JavaScript 逆向】极验四代无感验证码逆向分析
前言 四代无感验证码相较于滑块验证码区别就是没有底图,一键通过模式,所以不需要轨迹以及计算缺口距离,步骤更少,四代滑块可以阅读:[JavaScript 逆向]极验四代滑块验证码逆向分析 声明 本文章中 ...
- QAX答题页面js逆向分析(二)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.通过前端js解密,获取答案 二.通过Python,模拟请求完成自登录到答题的所有操作. 1.引入库 2. 程序结构 ...
- Python爬虫:逆向分析某云音乐加密参数
文章目录 前言 1. 请求分析 2. 参数分析 3. 加密分析 4. 模拟加密 5. 获取ID 6. 代码框架 结束语 前言 免责声明: 本篇博文的初衷是分享自己学习逆向分析时的个人感悟, ...
- 【JavaScript 逆向】极验四代滑块验证码逆向分析
前言 相较于三代滑块,四代的逻辑流程更简短,底图没混淆,某些点校验不严格 声明 本文章中所有内容仅供学习交流,相关链接做了脱敏处理,若有侵权,请联系我立即删除! 案例目标 滑动验证码:aHR0cHM6 ...
最新文章
- 汉印标签打印机app_旅行一族福音 汉印CP4000L便携照片打印机体验
- 前端(慕课网)笔记一
- python中字典的value可以为任意对象_Python学习入门(13)—字典
- 什么是整除,什么是素数
- man-翻译和epoll相关的内容,部分
- Java JSON对象怎么遍历_Java遍历JsonObject对象
- Linux 文件系统编程之系统调用和标准I/O库
- UVA 297 Quadtrees
- WOFF字体的Mime类型?
- maya对象属性_了解每粒子属性和每对象属性
- 5.2 imnoise函数
- WEB前端之网页设计①----最新最全详解/网页基础结构
- mysql实现oracle的同义词_Oracle 同义词synonym 学习
- 文明与征服君士坦丁阵容搭配推荐 文明与征服君士坦丁攻略
- Ionic之button标签ng-click无反应解决
- 我是一个计算机作文,我是一台电脑作文
- Linux中的阻塞机制
- 金融系统性风险的网络模型
- cocos creator尝试使用tween的几种新实现方案
- Matlab配平操作trim
热门文章
- 逐行读txt文件(读写文件try catch finally 处理空行,编码格式,文件流释放问题,处理读到重复问题)
- RPA学习天地:金智维RPA高阶培训(一)产品基础架构
- 滴滴的拼车功能怎么让大家用的更多
- android 气球动画,Android TV使用贝赛尔曲线制作炫酷的开场动画
- 一般信道容量的计算matlab,DMC信道容量迭代计算的matlab实现
- (11)EKF - (3) EKF3匹配度和Lane切换
- linux远程取证,铁三Linux取证(示例代码)
- 一种可以使身体吸收天道法则的电脑
- Proteus仿真数字钟表电路实验报告(可下载工程文件)
- golang 记一次data race排查过程