【Frida】【Android】09_爬虫之Socket

2024-04-03 07:44
文章标签 android 爬虫 socket 09 frida

本文主要是介绍【Frida】【Android】09_爬虫之Socket,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🛫 系列文章导航

  • 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950
  • 【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446
  • 【Frida】【Android】03_RPC https://blog.csdn.net/kinghzking/article/details/137050967
  • 【Frida】【Android】04_Objection安装和使用 https://blog.csdn.net/kinghzking/article/details/137071768
  • 【Frida】【Android】05_Objection实战 https://blog.csdn.net/kinghzking/article/details/137071826
  • 【Frida】【Android】 06_夜神模拟器中间人抓包 https://blog.csdn.net/kinghzking/article/details/137162859
  • 【Frida】【Android】 07_爬虫之网络通信库HttpURLConnection https://blog.csdn.net/kinghzking/article/details/137211973
  • 【Frida】【Android】 08_爬虫之网络通信库okhttp3 https://blog.csdn.net/kinghzking/article/details/137227041
  • 【Frida】【Android】 09_爬虫之Socket https://blog.csdn.net/kinghzking/article/details/137284648
  • 【Frida】【Android】 工具篇:ZenTracer https://blog.csdn.net/kinghzking/article/details/137284648

▒ 目录 ▒

    • 🛫 系列文章导航
    • 🛫 导读
      • 开发环境
    • 1️⃣ Socket抓包原理
    • 2️⃣ APP源码说明
      • ezReq
      • 按钮绑定及遇到问题解决
    • 3️⃣ HTTP的Socket分析
      • ZenTracer分析
      • 编写代码:jhexdump
      • 编写代码:hookSocket
      • 验证效果
    • 4️⃣ HTTPS的Socket分析
      • ZenTracer分析
      • 编写代码:
      • 验证效果
    • 5️⃣ 验证HTTPS请求流程
      • objection测试
    • 🛬 文章小结
    • 📖 参考资料

🛫 导读

开发环境

版本号描述
文章日期2024-04-02
操作系统Win11 - 22H222621.2715
node -vv20.10.0
npm -v10.2.3
夜神模拟器7.0.5.8
Android9
python3.9.9
frida16.2.1
frida-tools12.3.0
objection1.11.0

1️⃣ Socket抓包原理

前几篇所讨论的HTTP是应用层的协议,如下图所示。
在这里插入图片描述

HTTP数据从应用层发送出去后,依次经过传输层、网络层、链路层,在经过每一层时都会被包裹上头部数据,以保证在数据传输过程中的完整性,然后传输给接收方;接收方以相反的过程依次去除头部数据从而获取真实传输的HTTP数据。
因此,如果对应用进行抓包,那么不仅仅是应用层,在传输层、网络层等应用层往下的所有层级都可以获取传输的全部数据。这正是在传输层进行Socket终极抓包的理论基础。

只要开发者使用了应用层框架,不可避免地会使用系统的Socket进行数据包的收发。
如果使用的是HTTP协议,则直接使用Socket,此时数据如果没有任何代码层面的加解密,直接就是明文,将内容dump下来即可进行分析;
如果使用的是HTTPS协议,那么HTTP包还要“裹上”一层SSL,最终通过SSL的接口进行收发,而SSL也会将加密后和解密前的数据通过Socket与服务器进行通信,如下图所示。
在这里插入图片描述

2️⃣ APP源码说明

本文示例中的APP可以从本篇绑定的资源中下载。主要功能是传递一个url,点击执行HTTP/HTTPS请求。
源码地址: https://gitcode.com/android8/AndroidFridaBeginnersBook
在这里插入图片描述

ezReq

该函数对HttpURLConnection进行封装,执行网络请求。具体含义参考《【Frida】【Android】 07_爬虫之网络通信库HttpURLConnection https://blog.csdn.net/kinghzking/article/details/137211973》。

    public void ezReq(String urlStr) {try {URL url = new URL(urlStr);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setRequestProperty("token","demo");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.connect(); // 开始连接InputStream in = connection.getInputStream();//if(in.available() > 0){// 每次写入1024字节int bufferSize = 1024;byte[] buffer = new byte[bufferSize];StringBuffer sb = new StringBuffer();while ((in.read(buffer)) != -1) {sb.append(new String(buffer));}Log.d("demo", sb.toString());connection.disconnect();// }} catch (IOException e) {e.printStackTrace();}}

按钮绑定及遇到问题解决

  • NetworkOnMainThreadException
    在Android 4.0以上,网络连接不能放在主线程上,否则报错android.os.NetworkOnMainThreadException。
    所以,我们需要new Thread创建一个线程将网络请求包进去。
  • Cleartext HTTP traffic to XXX not permitted
    Android 9.0(API级别28)开始,默认情况下限制了明文流量的网络请求,对未加密流量不再信任,直接放弃请求,因此http的url均无法在webview中加载,https 不受影响。
    小编使用的模拟器是Android 9,当执行http请求时就会报上面的问题。可以通过下面步骤解决:
    • res 下新建 xml 目录,创建文件:network_security_config.xml ,内容如下:
      在这里插入图片描述
    • 在 AndroidManifest.xml 的 application 标签添加配置:
      在这里插入图片描述
        Button button = findViewById(R.id.buttonReq);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {(new Thread(new Runnable() {@Overridepublic void run() {//请求详情TextView viewById = findViewById(R.id.textInputEditText);String url = viewById.getText().toString();Log.d("url = ", url);ezReq(url);}})).start();}});

3️⃣ HTTP的Socket分析

ZenTracer分析

关于ZenTracer的使用,可以参考文章:《【Frida】【Android】 工具篇:ZenTracer https://blog.csdn.net/kinghzking/article/details/137284648》

  • 我们设置好匹配内容为Socket(注意大小写),APP中设置url为http://www.baidu.com,然后点击执行请求:
    在这里插入图片描述

这时候在ZenTracer中,我们可以看到如下内容:
在这里插入图片描述
很明显,read、write函数就是我们想要的函数。

编写代码:jhexdump

java.net.SocketOutputStream的第一个参数是[B,表示字节数组,为了使输出的字节数组更加可视化,这里引用了Awakened的jhexdump()函数,如下面的代码清单所示:

function jhexdump(array, len) {var ptr = Memory.alloc(len);for (var i = 0; i < len; ++i) Memory.writeS8(ptr.add(i), array[i]);//console.log(hexdump(ptr, { offset: off, length: len, header: false, ansi: false }));console.log(hexdump(ptr, {offset: 0,length: len,header: false,ansi: false,}));
}

这部分代码主要是将Java层的byte数组通Memory.writeS8()
函数存放至通过Memory.alloc()这个API手动开辟的内存区域中,再调用hexdump()这个API打印出相应字节的hexdump。

编写代码:hookSocket

代码实现对下面函数的hook

  • java.net.SocketOutputStream.write(bytearray1, int1, int2)
    • 第三个参数int2,表示数组的长度
  • java.net.SocketInputStream.read(bytearray1, int1, int2)
    • 返回值表示读取的长度
    • 对于过长的封包,会分多次读取。
function hookSocket() {Java.perform(function () {// java.net.SocketOutputStream.write// java.net.SocketOutputStream.socketWriteJava.use("java.net.SocketOutputStream").socketWrite.overload("[B","int","int").implementation = function (bytearray1, int1, int2) {var result = this.socketWrite(bytearray1, int1, int2);console.log("socketWrite result,bytearray1,int1,int2=>",result,bytearray1,int1,int2);var ByteString = Java.use("com.android.okhttp.okio.ByteString");jhexdump(bytearray1, int2);return result;};// java.net.SocketInputStream.read// java.net.SocketInputStream.socketRead0Java.use("java.net.SocketInputStream").read.overload("[B","int","int").implementation = function (bytearray1, int1, int2) {var result = this.read(bytearray1, int1, int2);console.log("read result,bytearray1,int1,int2=>",result,bytearray1,int1,int2);var ByteString = Java.use("com.android.okhttp.okio.ByteString");//console.log('contents: => ', ByteString.of(bytearray1).hex())jhexdump(bytearray1, result);return result;};});
}

验证效果

请求封包,write打印结果:
在这里插入图片描述
在这里插入图片描述

响应封包,read打印结果:
在这里插入图片描述
在这里插入图片描述

4️⃣ HTTPS的Socket分析

ZenTracer分析

分析之前我们将APP中的URL由http://www.baidu.com改成
https://www.baidu.com,再次点击执行请求按钮。
ZenTracer将打印如下内容,可见com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream.write就是我们需要的写函数
在这里插入图片描述
相对的,我们可以在ZenTracer的控制台中搜素read,可以找到读取的函数com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read
在这里插入图片描述

编写代码:

代码实现与HTTP的类似,不做过多解释,代码如下:

function hookSSLSocketAndroid() {Java.perform(function () {// com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream.writeJava.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream").write.overload("[B", "int", "int").implementation = function (bytearray1,int1,int2) {var result = this.write(bytearray1, int1, int2);console.log("write result,bytearray1,int1,int2=>",result,bytearray1,int1,int2);var ByteString = Java.use("com.android.okhttp.okio.ByteString");console.log("contents: => ", ByteString.of(bytearray1).hex());return result;};// com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.readJava.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream").read.overload("[B", "int", "int").implementation = function (bytearray1,int1,int2) {var result = this.read(bytearray1, int1, int2);console.log("read result,bytearray1,int1,int2=>",result,bytearray1,int1,int2);var ByteString = Java.use("com.android.okhttp.okio.ByteString");//console.log('contents: => ', ByteString.of(bytearray1).hex())jhexdump(bytearray1, result);return result;};});
}

验证效果

打印结果与HTTP类似,不再贴图了。

5️⃣ 验证HTTPS请求流程

至此,Socket的Hook代码已经写完,反过来,我们通过hook相关函数,可以定位到APP的核心代码,下面我们以HTTPS为例,定位APP调用函数。

objection测试

  • objection连接APP:
    objection -g com.roysue.httpurlconnectiondemo explore
  • hook关键函数、打印堆栈
    android hooking watch class_method com.android.org.conscrypt.ConscryptFileDescrip torSocket$SSLOutputStream.write --dump-args --dump-return --dump-backtrace
    在这里插入图片描述
  • 点击请求,查看打印结果
    如下图,我们可以看出,请求从run函数开始,调用ezReq,然后执行一系列函数,最终发送出去的。
    在这里插入图片描述

🛬 文章小结

使用ZenTracer过程中,会出现崩溃的情况,这时候可以:

  • 多试几次
  • 或者根据已有的输出结果,调整删选条件再次尝试。
  • 或者通过objection的-c命令调整输入结果进行尝试。

关于Socket请求,有很多实现方式,大厂可能会自实现网络请求,避开Socket调用。也有的直接调用so层实现网络请求。

📖 参考资料

  • frida 常见问题和报错https://crifan.github.io/reverse_debug_frida/website/summary_note/common_issue/
  • objection地址:https://github.com/sensepost/objection

ps: 文章中内容仅用于技术交流,请勿用于违规违法行为。

这篇关于【Frida】【Android】09_爬虫之Socket的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872308

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Python3 BeautifulSoup爬虫 POJ自动提交

POJ 提交代码采用Base64加密方式 import http.cookiejarimport loggingimport urllib.parseimport urllib.requestimport base64from bs4 import BeautifulSoupfrom submitcode import SubmitCodeclass SubmitPoj():de

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR