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 讨论下。


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

相关文章
|
2月前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
716 1
|
4月前
|
运维 网络安全 开发工具
【应用服务 App Service】App Service 新手资料包
【应用服务 App Service】App Service 新手资料包
|
27天前
|
开发框架 监控 .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
|
3月前
|
开发工具
uniapp, 短剧视频类App实现参考,支持滑动播放,仿抖音 仿陌陌 短视频 无限滑动播放 视频流
阿里云点播服务web播放器sdk,短剧视频类App实现参考。仿抖音 仿陌陌 短视频 无限滑动播放 视频流。无uniapp video 原生组件的层级、遮挡、覆盖问题,适合与不同功能视图组合使用,实现丰富的应用功能。
uniapp, 短剧视频类App实现参考,支持滑动播放,仿抖音 仿陌陌 短视频 无限滑动播放 视频流
|
3月前
|
安全
【Azure App Service】App service无法使用的情况分析
App Service集成子网后,如果子网网段中的剩余IP地址非常少的情况下,会在App Service实例升级时( 先加入新实例,然后在移除老实例 )。新加入的实例不能被分配到正确的内网IP地址,无法成功的访问内网资源。 解决方法就是为App Service增加子网地址, 最少需要/26 子网网段地址。
|
4月前
【Azure Function App】本地运行的Function发布到Azure上无法运行的错误分析
【Azure Function App】本地运行的Function发布到Azure上无法运行的错误分析
|
4月前
|
开发框架 缓存 .NET
【App Service】在Azure App Service中分析.NET应用程序的性能的好帮手(Review Stack Traces)
【App Service】在Azure App Service中分析.NET应用程序的性能的好帮手(Review Stack Traces)
|
4月前
|
网络协议 Linux 网络安全
【Azure 应用服务】更便捷的方式抓取Azure App Service for Windows的网络包
【Azure 应用服务】更便捷的方式抓取Azure App Service for Windows的网络包
|
4月前
|
API 数据安全/隐私保护
【Azure 应用服务】App Service 通过 wardeploy 部署 war 包,如何指定到 root目录为wwwroot
【Azure 应用服务】App Service 通过 wardeploy 部署 war 包,如何指定到 root目录为wwwroot
|
4月前
|
数据库 Python
【Azure 应用服务】App Service中运行Python 编写的 Jobs,怎么来安装Python包 (pymssql)呢?
【Azure 应用服务】App Service中运行Python 编写的 Jobs,怎么来安装Python包 (pymssql)呢?