No.0
前言
这次渗透测试的目标APP,抓包发现报文关键数据字段进行了加密处理,要测试接口可能存在的一些安全风险,就需要进行解密后进行篡改测试。所以本文主要记录一下报文加密数据解密的一个分析过程。
No.1
加密报文
以下是抓取的验证码发送的接口报文。可以看到请求body以及响应body中的data字段都进行了加密处理。
No.2
分析过程-定位加密算法
刚开始不知道这是一个基于React Native 开发的App,尝试了一些其他方法没能成功。
后面观察报文看到请求头中User-Agent: okhttp/4.9.2,所以可以确认该APP使用的是okhttp框架进行网络请求。
在Android开发中,使用OkHttp框架时,要实现对请求的body数据进行加密以及响应的body数据进行解密,通常可以通过拦截器(Interceptor)来实现。拦截器可以在请求被发送到网络之前或者响应被发送到调用者之前拦截并修改请求或响应。
No.3
分析过程-定位okhttp拦截器-
因此,接下来就是反编译APP,然后搜索拦截器Interceptor的名字。
双击进入查看okhttp3.Interceptor对应的java反编译代码
可以看到,这是Interceptor 这个接口类,APP要使用Interceptor这个接口类需要实现,因此我们在类名处“单击右键”选择 “查找用例”
Java中接口的实现是使用implements关键字,因此我们在查找用例窗口只用关注 红框标记的包含implements关键字的结果。
目前我们通过分析可知,一共有5个类实现了Interceptor 接口,
分别点击我们找到的5个实现了Interceptor 接口的类,关于拦截器的分析,最好是咱们先去了解一下okhttp以及拦截器相关的正向开发,然后再看反编译的时候就能够理解并快速找到关键的位置。
No.4
分析过程--提取关键类名关键字
接下来呢,就分享一个我觉得比较取巧的方法,属于有手就行,看不懂代码没关系,能认识单词就行。
进去看看,会发现代码中,会发现相关类中会使用很多Response、Request、RequestBody、ResponseBody之类关键字命名的对象。单词意思就是请求,响应,请求体之类的意思,先记住,待会儿讲怎么用。
我们还能看到body和writeTo名词加动词,猜测意思就是讲buffer写入到body里,buffer是怎么来的是调用Okio类中的buffer方法处理得到的,所以我们就知道我们的body的数据也会调用Okio类相关的方法进行处理,所以此处可以提取到Okio这个类名,百度可以知道在 OkHttp 中,Okio 通常用于创建和管理网络请求和响应的数据流。
或者其他更多的点,此处我们主要就以Response、Request(ResponseBody、RequestBody)、Okio来演示一下提取到这些类名关键字怎么使用他们来找到和请求响应加密相关的蛛丝马迹。
No.5
使用类名关键字-r0tracer
首先先简单介绍一下r0tracer:
r0tracer是基于frida的安卓Java层多功能追踪脚本,可以用来追踪java层所有类的方法调用,会输出被调用方法的参数、返回值、调用栈等辅助分析的关键信息。
使用方法:
1、修改r0tracer.js文件最底部处的代码,开启某一个Hook模式。
新增hookALL()模式,hook应用的所有类方法重载;(小应用可用,大应用扛不住)
配置好Hook模式后,就像使用普通的js脚本一样去注入hook就行
将输出日志使用-o参数进行输出保存
frida -U -f com.r0ysue.example -l r0tracer.js --no-pause -o saveLog5.txt
刚才我已经找到了我们关心的一些类名中的关键字,所有基于这个关键字,就可以使用B模式,这个模式就是可以根据类名中的关键字,去追踪所有包含这个关键字的类名中的方法调用,并输出调用方法的参数、返回值、调用栈等。
我们来看看追踪的一个效果:
PS:如果有时候我们输入某个关键字进行匹配追踪,发现APP闪退,可以尝试把关键字匹配范围缩小,比如这里我就再加了一个okhttp3.ResponseBody
通过工具追踪,发现了和APP获取登录验证码接口相关的返回数据包内容,一般我看到某个输出记录存在我们关心的内容后,就是去观察调用栈。
通过观察调用栈,我发现调用栈没有和包名相关的类方法去调用,都是一些系统方法和第三方的一个facebook相关的方法,且数据结果的放回被调用的位置也是从com.facebook.react.modules.network.NetworkingModule$2.onResponse方法去调用的。
所以猜测这会不会是基于某个第三方的框架去编写的APP,直接百度搜索com.facebook.react.modules.network
根据搜索结果,我们继续再搜索一些
通过搜索发现,确实是facebook开源的一个开发框架,可以用来创建安卓和ios的原生应用。
No.6
React Native APP分析
通过前面的分析,我们已经基本可以确认这是一个React Native APP,因此搜一下别人的React Native APP逆向案例。
[[原创]React Native App逆向-Android安全-看雪-安全社区|安全招聘|kanxue.com](https://bbs.kanxue.com/thread-259988.htm "[原创]React Native App逆向-Android安全-看雪-安全社区|安全招聘|kanxue.com")
通过文章可知,React Natie app的一些特点:
反编译目录结构能看到reactnativecommunity相关的类
主要逻辑 是 js代码,在资源文件assets/index.android.bundle 中
美化index.android.bundle 中的js代码
JS/HTML代码美化、压缩、混淆加密工具 - 站长工具 (alixixi.com)
搜索encrypt等关键字,定位到encrypt相关代码位置进行分析
通过分析这段js代码可知:
加密算法是AES ecb模式;
加密密钥生成代码如下:
p = l.default.stringify((0, c.default)(u + f)).substr(s, 32);
密钥p是通过一系列的操作从u和f派生出来的。具体来说,u和f被拼接、哈希、转换为字符串,并取某个子字符串作为密钥。这意味着密钥是动态生成的,并且每次调用encode函数时都会改变(因为f是当前的时间戳,每次都不同)。
u 是一个给定的哈希值,对应的是请求/响应包中的sign字段。
f 是一个给定的时间戳,对应的是请求/响应包中的Timestamp字段。
c.default 是一个哈希函数(通过代码未看出调用的具体的哈希算法类型)。
l.default.stringify 是一个将哈希值转换为字符串的函数。
s 是 f 除以9的余数。
substr(s, 32) 是一个取子字符串的操作。
由于不知道具体的哈希算法是什么,所以编写脚本,使用常见哈希算法计算出响应的key,再使用不同哈希计算生成的key用于请求或响应数据中的aes加密数据解密。
const crypto = require('crypto');
const u = 'fa7ce3834f83ebfee5a46fd13aaaac8548738e40';
const f = '1697421969024';
const s = Number(f) % 9;
const uf = u + f;
// 尝试使用不同的哈希算法
const hashAlgorithms = ['md5', 'sha1', 'sha256', 'sha512'];
hashAlgorithms.forEach(algorithm => {
const hash = crypto.createHash(algorithm).update(uf).digest('hex');
const p = hash.substr(s, 32);
console.log(`Computed key using ${algorithm}:`, p);
});
最后测试,使用sha1对应的key结果,能够用于数据包中的加密字段解密
配置上Burpy,加密数据包自动解密,方便测试
https://github.com/mr-m0nst3r/Burpy/releases
No.7
网安沟通交流群
扫码加客服小姐姐拉群
原文始发于微信公众号(隐雾安全):记一次React Native App报文解密分析过程
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论