前言Android系统抓取HTTPS数据包是不是越来越难了?高版本不能加CA证书,抓包软件依赖太大。当处于VPN模式或HOOK程序时,会被APP检测到。对抗的代价越来越大。有什么万能的工具吗?是的,eCaptureforAndroid[1]就在这里。以后在Android上抓取HTTPS通信包,不再需要安装CA证书,不再需要下载一堆python依赖环境,不再需要重新打包ssl类库,不再需要需要改一堆手机参数。启用,简单明了。eCapture简介eCapture是一款无需CA证书即可抓取HTTPS明文的软件。支持pcapng格式,支持wireshark直接查看。基于eBPF技术,只需root权限即可一键抓包。eCapture中文名旁观者,即当局者迷,旁观者清。2022年初上海疫情期间,作者开始写作并开源[2]。现在半年过去了,GitHub上已经有4200个star。eCapture是一款基于eBPF技术的抓包软件,具体取决于系统内核是否支持eBPF。目前在操作系统上支持,支持X86_64\ARM64Linuxkernel4.18及以上,支持ARM64Android(Linux)kernel5.4及以上。最新版本是2022年9月9日发布的v0.4.3。演示视频下载后,一条命令启动,干净利落。./ecapturetls-wecapture.pcapng先看演示视频,演示环境为Ubuntu21.04,Android5.4(Pixel6)。模块功能eCapture支持tls、bash、mysqld、postgres等模块的信息抽取和抓取。本文只讨论tls,一个HTTPS/TLS明文抓取模块。加密通信明文抓取--tls模块tls模块支持加密通信类库上的openssl、gnutls、nspr/nss、boringssl等类库。但是在Android上,pcapng模式只支持boringssl,而text模式两者都支持。如何使用eCapture环境取决于操作系统Linux内核4.18或以上,Android内核5.4或以上。支持BPF,BTF可选(eCapture版本不同)。root权限版本选择BPFCO-RE[3]特性是BTF的一种常用格式,用于跨内核版本兼容。一些Android手机不启用BTF。可以查看系统配置确认,CONFIG_DEBUG_INFO_BTF=y是开启的;CONFIG_DEBUG_INFO_BTF=n被禁用;其他不支持BPF,无法使用eCapture。cfc4n@vm-server:~$#cat/boot/config-`uname-r`|grepCONFIG_DEBUG_INFO_BTFCONFIG_DEBUG_INFO_BTF=y在Android系统上,config是gzip压缩的,配置文件目录也发生了变化。您可以改用zcat/proc/config.gz命令。eCapture发布默认支持CO-RE的ELF程序。Android版本将发布一个不支持BTF(即无CO-RE)的5.4内核版本。下载后可以通过./ecapture-v确认。非CO-RE版本的版本信息包括编译时的内核版本。#noCO-REeCaptureversion:linux_aarch64:0.4.2-20220906-fb34467:5.4.0-104-generic#CO-REeCaptureversion:linux_aarch64:0.4.2-20220906-fb34467:[CORE]如果版本不符合你的需要的,可以自己编译,步骤见文末。全局参数介绍全局参数的要点如下:root@vm-server:/home/cfc4n/#ecapture-h--hex[=false]printbytestringsashexencodedstrings-l,--log-file=""-l将数据包保存到文件-p,--pid=0如果pid为0那么我们将所有pids-u,--uid=0如果uid为0然后我们将所有用户作为目标--hexforstdoutoutputscenario,显示结果的十六进制,用于查看非ASCII字符,尤其是在内容加密和编码的场景下必备。-l,--log-file=保存结果的文件路径。-p,--pid=0要捕获的目标进程,默认为0,则捕获所有进程。-u,--uid=0抓取的目标用户,默认为0,则抓取所有用户,是Android非常必要的参数。模块参数root@vm-server:/home/cfc4n/project/ssldump#bin/ecapturetls-hOPTIONS:--curl=""curl或wget文件路径,用于检测openssl.so路径,默认:/usr/bin/curl--firefox=""firefox文件路径,默认:/usr/lib/firefox/firefox。--gnutls=""libgnutls.so文件路径,会自动从curl默认找到它。--gobin=""使用Go工具链构建的二进制文件的路径。-h,--help[=false]tls的帮助-i,--ifname=""(TC分类器)将附加探测器的接口名称。--libssl=""libssl.so文件路径,会自动从curl默认找到它。--nspr=""libnspr44.so文件路径,会自动从curl默认找到它。--port=443要捕获的端口号,默认:443。--pthread=""libpthread.so文件路径,用于hookconnect捕获socketFD。会自动从curl中找到。--wget=""wget文件路径,默认:/usr/bin/wget。-w,--write=""将原始数据包以pcapng格式写入文件。-i参数-i参数是网卡的名称。在Linux上默认为eth0,在Android上默认为wlan0。您可以使用此参数指定输出模式。输出格式支持两种格式,文本和pcapng文件。有三个参数,默认,全局参数,输出文本结果到stdout-l全局参数,保存文本结果的文件路径-wonlytls模块参数,保存pcapng结果的文件路径类库路径linux支持多种类库,不同types库的路径也不一样。类库参数路径默认值openssl/boringssl--libsslLinux自动搜索,Android是/apex/com.android.conscrypt/lib64/libssl.sognutls--gnutlsLinux自动搜索,Androidpcapng模式不支持nspr/nss--nsprLinux自动发现,Android的pcapng模式还不支持文本模式-l或者不带-w参数都会开启这个模式。支持openssl、boringssl、gnutls、nspr/nss等TLS加密库。支持DTLS、TLS1.0到TLS1.3等所有版本的加密协议。支持所有全局过滤器参数,例如-p和-u。pcapng模式-w参数启用该模式,并使用-i来选择网卡名称。Linux系统默认为eth0,Android系统默认为wlan0。只支持openssl和boringssl这两个类库的数据抓取。当前不支持TLS1.3协议。类库和参数支持在Linux系统上,可以支持大部分类库和参数。但是在Android系统上,因为内核和ARM架构的原因,支持的参数有一定的差异。不同模式的参数支持两个全局参数-p和-u,支持文本模式,不支持pcapng模式。这是因为pcapng模式是使用eBPFTC技术实现的。mode-p-u--libssl--porttext????pcapng????不同模式的类库按协议支持modeopenssl(classlibrary)boringssl(classlibrary)TLS1.0/1.1/1.2(protocol)TLS1.3(Protocol)text????pcapng?????pcapng模式暂时不支持TLS1.3,TLS1.3keycapture功能[4]已经开发,但是遇到了一些BUG,还在解决中。作者不是openssl专家,对TLS协议也不熟悉。需要补充这两块的知识,解决的成本比较高。欢迎擅长这块的朋友一起解决。结合tcpdump,eCapture基于eBPFTC抓取流量并保存到pcapng文件中。TLSMasterSecret的捕获是基于eBPFUprobe实现的。并基于Wireshark的DecryptionSecretsBlock(DSB)[5]标准,实现了gopacket[6]的DSB功能,将网络包和密钥合并保存在pcapng中。eCapture在网络抓包方面不如tcpdump强大,不支持丰富的参数。可以使用eCapture抓取mastersecret,使用tcpdump抓取网络包,然后使用wireashrk自定义key文件,一起使用。网络抓包tcpdump的一般用法这里不再赘述。同时启用ecapture进行密钥抓取,方式可以是text或pcapng,TLSmastersecret的密钥数据会保存在ecapture_masterkey.log中。网络包查看使用Wireshark打开网络包文件,设置主密钥文件,即可看到TLS解密后的明文。配置路径:Wireshark-->Preferences-->Protocols-->TLS-->(Pre)-Master-Secretlogfilename参数指定路径defaultpath在Android上,谷歌使用的是无聊的ssl类库,也就是C++语言在libssl之上的包装器中。默认情况下,使用/apex/com.android.conscrypt/lib64/libssl.so路径。APP类库确认可以使用lsof-p{APPPID}|greplibssl来确认。如果不是默认路径,可以使用--libssl参数指定。进阶使用如果你需要检查的APP是自定义的SSL类库,那么你可以修改eCapture来实现。自定义函数名和偏移量首先需要确定HOOK函数的函数名或符号表地址。没有源码如果没有目标类库的源码,可以通过IDA等软件的静态分析和动态调试来确定SSLWrite的地址偏移量。在user/module/probe_openssl.go文件中填写配置,对应probe配置部分。{section:"uprobe/SSL_write",EbpfFuncName:"probe_entry_SSL_write",AttachToFuncName:"SSL_write",UprobeOffset:0xFFFF00,//TODOBinaryPath:binaryPath,},offset是自动计算的如果有源码可以阅读源码code来确定函数名或符号表的地址。对于结构体成员属性的读取,可以通过offsetof宏自动计算。通过偏移方式读取内容。//g++-Iinclude/-Isrc/./src/offset.c-ooff#include
