OkHttp 通用抓包方式分析,以某小视频App为例

简介: OkHttp 通用抓包方式分析,以某小视频App为例

一、目标


太难了,这年头抓包越来越难了,某小视频更新频发,我们之前屏蔽 QUIC 的方案貌似也失效了。


幸好我们还有 OkHttpLogger-Frida


TIP: v9.10.10.22596


着急的同学可以直接拉到后面,加入 知识星球 取js吧。有理想的同学建议好好研究下原理,下次就可以自己适配了。


二、步骤

原理分析


某小视频App v8.x 签名计算方法(一) 先从抓包说起 这篇文章里面我们分析了 v8.0 使


OkHttpLogger-Frida 抓包的方法。


那么什么类型的App适合用 OkHttpLogger-Frida 来抓包呢?


作者描述了一下原理: 由于所有使用的Okhttp框架的App发出的请求都是通过RealCall.java发出的,那么我们可以hook此类拿到request和response。


我们用jadx打开apk81.png



简单的说,凡是很明显发现 Okhttp 这个类的App,大概率可以用这个脚本抓包,如果没有很明显发现 Okhttp,也有可能是被混淆了,可以运行这个脚本的 find 命令来尝试寻找一下。


分析问题


有些朋友会说,我试了这个脚本,不好使,抓不到包。


大佬们都是抛砖引玉的,没有人会去苦哈哈的帮你适配每个版本。所以我们需要领悟脚本的原理来自己做适配。


首先将 okhttpfind.dex 拷贝到 /data/local/tmp/


然后 frida -U -l okhttp_poker.js -f com.example.demo --no-pause 跑起来了。


首先跑一下 find() 命令,从打印的结果可以看出,这个App使用了 okhttp3 ,然后记下


这一行的输出。

var Cls_okio_Buffer = "okio.f";


现在可以开始抓包了,敲一下 hold() 命令


漂亮,已然可以输出 url和 Request Headers 信息了。


这里有两个问题:

1、Request Body没有打印出来, 就提示了一个 " File Request Body Omit....."

2、Response 数据没有打印出来。

3、有这么一个报错

print request error :  Error: writeTo(): argument types do not match any of:
  .overload('okio.g')
    at X (frida/node_modules/frida-java-bridge/lib/class-factory.js:563)
    at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:966)
    at e (frida/node_modules/frida-java-bridge/lib/class-factory.js:547)
    at printerRequest (/okhttp_poker.js:171)
    at printAll (/okhttp_poker.js:106)
    at <anonymous> (/okhttp_poker.js:89)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:16)
    at perform (frida/node_modules/frida-java-bridge/index.js:193)
    at buildNewResponse (/okhttp_poker.js:98)
    at <anonymous> (/okhttp_poker.js:510)
    at apply (native)
    at ne (frida/node_modules/frida-java-bridge/lib/class-factory.js:613)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:592)


适配代码


先看第一个问题,在 okhttp_poker.js:160 行有个 filterUrl 判断,原意是过滤掉图片类的文件,但是如果请求值或者返回值里面包含了 "jpg" "png" 之类的字符串也会被过滤掉,所以我们要精准判断,只有末尾几个字符串匹配的时候才过滤。

var filterArray = [".JPG", ".jpg", ".PNG", ".png", ".WEBP", ".webp", ".JPEG", ".jpeg", ".GIF", ".gif",".zip", ".data"]
......
/**
 *  fenfei 过滤url
 *  false 显示
 *  true  拦截 不显示 返回信息
 */
function filterUrl(url) {
  //*
    for (var i = 0; i < filterArray.length; i++) {
        // if (url.indexOf(filterArray[i]) != -1) {
            // console.log(url + " ?? " + filterArray[i])
        //    return true;
        //}
        if (url.lastIndexOf(filterArray[i]) >= (url.length - 6) ) {
           // console.log(url + " ?? " + filterArray[i])
           return true;
        }
    }
  // */
    return false;
}


第二个问题暂时看不出所以然,我们先把报错解决了。


在    at printerRequest (/okhttp_poker.js:171) 有如下代码

var buffer = BufferWapper.$new()
        requestBody[M_reqbody_writeTo](buffer)


意思是把requestBody的值 writeTo 到 BufferWapper 类型的 buffer变量里面。


BufferWapper 类型是 ** var Cls_okio_Buffer = "com.singleman.okio.Buffer"; **


这里解决方案已经有两个提示了:

1、报错的提示提示我们这里需要一个 okio.g 类型

2、开头我们find的时候提示我们在这个app里面  var Cls_okio_Buffer = "okio.f";


那么到底是用 okio.g 还是 okio.f 呢?


我们看看jadx分析的代码

public interface g extends z, WritableByteChannel {
......
}
public final class f implements h, g, Cloneable, ByteChannel {
......
}


okio.g是个接口类,okio.f才是继承他的实现类。 所以这里毫无疑问是使用 #okio.f#


这么修改一下

// add fenfei 适配 910
// var buffer = BufferWapper.$new()
var ffBufferWapper = Java.use("okio.f");
var buffer = ffBufferWapper.$new();


再跑一下,这下就很漂亮了,Request和Response都打印出来了。


最后一个问题


加上这个抓包之后,突然app变得很不稳定,要么一会就卡住不动了,要么就是出现网络访问失败。


这个问题肯定是由于我们这个js导致的。但是具体是怎么导致的?如何排查问题呢?


解决这种问题,最好的办法就是 排除法

1、屏蔽printAll函数,啥都不打印了,app运行Ok, 说明 hook没问题,问题出在打印上面。

2、打印分两部分,printerRequest和printerResponse,通过屏蔽大法发现问题出在 printerResponse上面,

3、在printerResponse函数中 继续用屏蔽大法,发现问题出在 getByteString 函数中的 buffer[M_buffer_readByteArray] ,也就是说只要对 Response body 做读操作,就会出问题。


目前我感觉问题可能出在对buffer的读上面,可能是读冲突了,由于我们的hook脚本读了这个buffer,导致app读不到结果了,所以出现各种诡异问题。


然后就尝试了各种办法,换个读的函数、深拷贝这个buffer,都没有成功。 最后发现作者预留了一手,实际上作者已经对这个 Response body做了次深拷贝,并且生成了一个newResponse。


所以我们继续hook我们的,愉快的打印出来,然后把生成的新的newResponse 返回给app就ok了。


再跑一下,完美收工。


三、总结


拿来主义虽然好用,但是明白原理后自己可以适配更重要。


遇到问题,先遵循最小可用原则,一步一步屏蔽代码,来缩小范围,定义问题。

83.png


要想起一生中后悔的事,梅花便落满了南山


TIP: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一起学习探讨技术。有问题可以加我wx: fenfei331 讨论下。


关注微信公众号: 奋飞安全,最新技术干货实时推送

相关文章
|
7月前
|
JSON 监控 数据格式
1688 item_search_app 关键字搜索商品接口深度分析及 Python 实现
1688开放平台item_search_app接口专为移动端优化,支持关键词搜索、多维度筛选与排序,可获取商品详情及供应商信息,适用于货源采集、价格监控与竞品分析,助力采购决策。
|
7月前
|
缓存 供应链 开发者
1688 item_get_app 接口深度分析及 Python 实现
1688平台item_get_app接口专为移动端设计,提供商品原始详情数据,包含批发价格、起订量、供应商信息等B2B特有字段,适用于采购决策、供应链分析等场景。接口需通过appkey+access_token认证,并支持字段筛选,返回结构化数据,助力企业实现智能采购与供应商评估。
|
7月前
|
缓存 监控 Android开发
京东 item_get_app 接口深度分析及 Python 实现
京东item_get_app接口可获取商品原始详情数据,包含更丰富的字段和细节,适用于电商分析、价格追踪等场景。需通过认证获取权限,支持字段筛选和区域化数据查询。
|
8月前
|
缓存 数据挖掘 API
淘宝 item_get_app 接口深度分析及 Python 实现
淘宝item_get_app接口是淘宝开放平台提供的移动端商品详情数据获取接口,相较PC端更贴近APP展示效果,支持获取APP专属价格、促销活动及详情页结构,适用于电商导购、比价工具、数据分析等场景。接口采用appkey+appsecret+session认证机制,需申请相应权限。本文提供Python调用示例及使用注意事项,帮助开发者高效对接移动端商品数据。
|
8月前
|
数据采集 数据可视化 API
驱动业务决策:基于Python的App用户行为分析与可视化方案
驱动业务决策:基于Python的App用户行为分析与可视化方案
|
10月前
|
JavaScript
TypeOrmModule 从 app.module.ts 抽离到 database.module.ts 后出现错误的原因分析
本文分析了TypeORM实体元数据错误的成因,主要涉及实体注册方式、路径解析差异及模块结构变化导致的关系解析问题,并提供了具体解决方案和最佳实践建议。
215 56
|
12月前
|
数据采集 数据可视化 数据挖掘
基于Python的App流量大数据分析与可视化方案
基于Python的App流量大数据分析与可视化方案
|
小程序
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
908 1
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
|
前端开发 Java 开发工具
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
1381 18
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
357 5