eCapture v0.7.3新版性能提升10倍,支持OpenSSL 3.2 eCapture是什么 eCapture旁观者一个无需CA证书,无侵入的HTTPS/TLS明文抓包工具。可以在Linux 4.18以上版本使用,同时也支持Android arm64 5.5以上版本。 年底打脸 记得8月份时,在GitHub万星项目进度70%,eCapture旁观者7K Stars达成一文中吹牛说到,年底冲1万颗星,奈何平时工作特别忙,根本没时间堆新功能,年底一看,果然打脸了,只有7.8K星, 不过,笔者也一直忙里偷闲地回复社区的问题,不停地修复程序bug。 增加难度 这不,有几个小朋友给我提出了新的挑战,在生产环境,上万QPS的7层负载均衡,启用eCapture,会有什么样的结果?性能扛得住吗? 性能提升10倍 有用户在社区反馈eCapture性能问题TLS 模式下,对被检测程序的性能影响,执行一千万次SSL_write写数据的场景,不开启eCapture耗时6秒,而开启eCapture后却要30秒,性能耗时增大5倍以上。 这个数字就很尴尬,就在你潇洒的这两天,笔者全身心投入,用爱发电,翻阅OpenSSL源码,终于有了很大的进展。 进步大源于起点底 笔者分析了OpenSSL类库中,以Server和Client两种模式,分别选择合适的HOOK函数,减少SSL_write和SSL_read两个函数高频调用下的触发机制,最终把耗时从30秒降低到7秒。整体来看,进步特别大。但原来确实有偷懒,直接用了SSL_write函数。 继续宠粉 又有小朋友在社区提了issue:The SSL structure in openssl 3.2.0 has been modified,里面提到OpenSSL 3.2.0已发布了,而且核心ssl_st结构体发生很大变化,eCaptuer捕获TLS通讯密钥的功能无法使用。 笔者确认了一下,OpenSSL 3.2.0是2023年11月底发布的,至今不过2个月时间,应该还没有多少大型应用使用,不过,笔者就是喜欢宠粉,立马给安排了。谁让这位小朋友的issue写得漂亮呢。 新版下载 无CA捕获TLS明文软件eCapture v0.7.3版发布,性能提升10倍,千万次调用增加2秒,支持openssl 3.2。 Warning 以下为技术原理,可以不用看。 技术实现 性能优化 设计思路 问题 为了读取到TLS握手完成后的client_random等密钥,必需要选择一个合适的HOOK函数。 SSL_write\SSL_read时,TLS握手是建立完成的,但调用过于频繁,会带来性能问题,参见 #463 综合来看,合适的HOOK函数需要满足以下几个条件: 函数是在TLS握手完成后调用 函数名在动态链接库的符号表中是导出状态 函数是低频调用 解决思路 在 openssl 类库中,以客户端角色调用 SSL_connect 或者以服务端角色 SSL_accept ,最终都会进入 ssl/statem/statem.c 的 state_machine 函数进行TLS握手。 所以,可选范围是在这个函数内以大写SSL开头的函数。 当使用openssl的方式为同步调用时,TLS握手成功会返回1,也就是ret = 1,即需要在这个变量赋值后,被调用的函数,才能拿到符合要求的内存数据。 state_machine函数内符合要求的就只有SSL_get_wbio了。 当使用openssl的方式为异步 (BIO)调用时,还需要增加SSL_in_before函数。 masterKeyHookFuncs = []string{ "SSL_get_wbio", // openssl client mode //"SSL_is_init", // boringssl client mode // 备用HOOK 函数 //"SSL_is_init_finished", "SSL_in_before", //openssl client mode "SSL_do_handshake", // openssl server mode } OpenSSL 3.2.0 无它,翻阅OpenSSL源码,分析差异,重新实现密钥提取代码,详情见 PR 472 。不过,新版里新增了对QUIC TLS的支持,eCapture暂时没支持,预计春节后安排。 // TODO 检查 ssl->type, 参考 ssl/ssl_local.h的 SSL_CONNECTION_FROM_SSL_int 宏 int type; if (type == SSL_TYPE_QUIC_CONNECTION) { // Reget the address of the ssl->tls as the address of the SSL_CONNECTION debug_bpf_printk("unsupported type: SSL_CONNECTION, coming soon.\n"); return 0; } 届时,eCapture就可以无需CA证书,即可捕获QUIC TLS的明文内容了,敬请期待。 红包封面预告 去年封面 即将春节,送给大家一些手绘的红包封面,依旧由去年红包封面《烤火兔》的设计大师,外甥女S负责。 今年封面 本次春节红包封面《龙"码"精神》,依旧没有任何广告、品牌标识。仿版画风格,材质感更重。 立寒冬,暖阳待雪,龙码精神!这款红包风格采用木质版画风格,五行之中黑色对应水,遇水则发~黑龙俯卧在金灿灿的摇钱树给大家送福啦! 2024-01-30 1 0
eCapture支持boringssl TLS 1.3明文数据包捕获 前言 一个多月前,有网友反馈Android上,TLS 1.2明文网络包正常捕获,而1.3的密钥无法捕获。笔者得知这个问题后,花了几个周末时间修复、添加了这个功能。在这期间,笔者工作繁忙以及感染新冠,整个功能拖了1个月 才完成。精力与体力,支撑起来越来越吃力。搞开源,全是靠爱发电,实属不易。 值得庆幸的是,收获了5400星的关注,这也是对笔者最大的认可。 这个周末,发布了eCapture 0.4.11版本,支持boringssl的TLS 1.3的密钥捕获,支持明文解密pcapng数据包存储。 有需要的朋友可以下载使用。 其次,这次支持boringssl的TLS 1.3明文数据包捕获,还遇到了一些技术性问题,在这里也一并分享给大家。 boringssl与openssl的差异 Google开源了boringssl这个SSL加密类库,是基于openssl的增强版。使用C++封装C的类库,在结构体内存布局上,与openssl有一些差异。而且TLS通信密钥捕获的Hook函数上,与openssl有差异。在openssl中,只需要HOOK SSL_write、SSL_read 两个函数,读取参数中SSL结构体的内存布局,定位相关SSL密钥存储地址,即可读取密钥。 而在boringssl中,在调用SSL_write函数时,这个TLS链接可能还没建立好。需要寻找更合适的HOOK函数,笔者在实现时,做了大量的测试、调试工作,最终在SSL_do_handshake 跟SSL_in_init两个函数中,选择了SSL_in_init,进行密钥的读取。 实际使用时,仍会有s3_st为空、s3->hs地址为空的情况,以及TLS未建立、正在握手中,密钥不完整等情况,笔者最后选择将所有eBPF捕获内存数据,通过bpf map发送给用户空间程序,再在用户空间判断密钥,进行过滤,曲折实现。 android boringssl与普通boringssl的差异 说到boringssl,刚接触的人可能搞不清楚版本,认为google在github上开源的https://github.com/google/boringssl.git 项目就是,直接用这个测试。实际上,Android系统使用的boringssl并不是这个仓库,而是 https://android.googlesource.com/platform/external/boringssl ,二者的差异,对ecapture来说,其结构体的内存布局不一样,属性的偏移地址不一样。 笔者就被这个问题困扰很久,为什么在PC上,使用boringssl测试成功,而在android手机上却无法工作。手机、模拟器、重刷ROM,都是不行。。一直到笔者把Android上类库源码重新检出,仔细测试boringssl的代码,才发现这个问题。 Google在这块文档上,并没有说明,实在是让人无奈。 Android boringssl偏移地址 你可以按照自己Android使用的boringssl版本,自己重新生成boringssl的偏移量,使用命令如下: rm -f kern/boringssl_1_1_1_kern.c bash utils/boringssl_offset_1.1.1.sh 普通boringssl类库偏移地址 在Linux上,很多类库都是支持改用openssl为boringssl的,eCapture也提供了自助生成新偏移量的脚本,它比Android boringssl命令后面多个参数1,生成命令如下: rm -f kern/boringssl_1_1_1_kern.c bash utils/boringssl_offset_1.1.1.sh 1 偏移地址差异diff Linux上普通boringssl类库的eCapture使用 以curl类库为例,启用boringssl的编译命令如下: git clone https://github.com/curl/curl.git autoreconf -fi LIBS=-lpthread ./configure --with-ssl=/home/cfc4n/project/boringssl --enable-versioned-symbols make sudo make install sudo ldconfig 如果你在编译启用boringssl的curl遇到错误时,可以参考笔者的经历:alt-svc build error on ubuntu 18.04: missing struct tm #9989 eCapture捕获命令: bin/ecapture tls --libssl=/usr/local/lib/libcurl.so.4 --ssl_version="boringssl 1.1.1" -w a.pcapng -i ens33 功能演示 演示环境 系统:macOS 模拟器:Android Studio Dolphin | 2021.3.1 Patch 1 镜像ROM:Pixel 3a API 33 x86_64 内核:Linux localhost 5.10.66-android12-9-00041-gfa9c9074531e-ab7914766 #1 SMP PREEMPT Fri Nov 12 11:36:25 UTC 2021 x86_64 测试APP:百度手机助手9.5.8.1 演示命令 启动eCapture emulator64_x86_64_arm64:/data/local/tmp # ./ecapture tls -w aa.pcapng -i wlan0 tls_2023/01/08 14:02:54 ECAPTURE :: ecapture Version : androidgki_x86_64:0.4.11-20230107-59a76e0:5.4.0-131-generic tls_2023/01/08 14:02:54 ECAPTURE :: Pid Info : 26496 tls_2023/01/08 14:02:54 ECAPTURE :: Kernel Info : 5.10.66 tls_2023/01/08 14:02:54 EBPFProbeOPENSSL module initialization tls_2023/01/08 14:02:54 EBPFProbeOPENSSL Module.Run() tls_2023/01/08 14:02:54 EBPFProbeOPENSSL TC MODEL tls_2023/01/08 14:02:54 EBPFProbeOPENSSL OpenSSL/BoringSSL version not found, used default version :android_default tls_2023/01/08 14:02:54 EBPFProbeOPENSSL HOOK type:2, binrayPath:/apex/com.android.conscrypt/lib64/libssl.so tls_2023/01/08 14:02:54 EBPFProbeOPENSSL Ifname:wlan0, Ifindex:16, Port:443, Pcapng filepath:/data/local/tmp/aa.pcapng tls_2023/01/08 14:02:54 EBPFProbeOPENSSL Hook masterKey function:SSL_in_init tls_2023/01/08 14:02:54 EBPFProbeOPENSSL target all process. tls_2023/01/08 14:02:54 EBPFProbeOPENSSL target all users. tls_2023/01/08 14:02:54 EBPFProbeOPENSSL BPF bytecode filename:user/bytecode/boringssl_1_1_1_kern.o tls_2023/01/08 14:02:54 EBPFProbeOPENSSL module started successfully. tls_2023/01/08 14:02:54 ECAPTURE :: start 1 modules 794b86e16f4f17d1c90fee21e72d56aa92c1f4deb5f7494c0eab9598895d48ff to file success, 176 bytes tls_2023/01/08 14:05:06 TLS1_3_VERSION: save CLIENT_RANDOM 7fbea9bdcc818fb80cc04c1d0ad0c0c870cf97267678d42fa6026dd92cfa6b20 to file success, 778 bytes tls_2023/01/08 14:05:43 TLS1_2_VERSION: save CLIENT_RANDOM 50a103ecbdd2a84c707eeda3262381ab8a427993c2407ecd537ae2414978f821 to file success, 176 bytes 捕获的TLS 1.3密钥 130|emulator64_x86_64_arm64:/data/local/tmp # cat ecapture_masterkey.log CLIENT_HANDSHAKE_TRAFFIC_SECRET 7fbea9bdcc818fb80cc04c1d0ad0c0c870cf97267678d42fa6026dd92cfa6b20 e34deeab543a3cd63e8009737a4cf4188e9f5c2b6588e5b72874055818004c6c CLIENT_TRAFFIC_SECRET_0 7fbea9bdcc818fb80cc04c1d0ad0c0c870cf97267678d42fa6026dd92cfa6b20 82857c8eb07c88b6c56c9d38759c23cc6d14d9dd23a37bb17fa41e5913cf211e SERVER_HANDSHAKE_TRAFFIC_SECRET 7fbea9bdcc818fb80cc04c1d0ad0c0c870cf97267678d42fa6026dd92cfa6b20 bef4cde1643c47d5971f226e9d637155d55087184f0f75963db792d71afc56c0 SERVER_TRAFFIC_SECRET_0 7fbea9bdcc818fb80cc04c1d0ad0c0c870cf97267678d42fa6026dd92cfa6b20 c949827f3150a3c4c4589478caa1b2987493dd17dfe008aa26ce9b881d9af21b EXPORTER_SECRET 7fbea9bdcc818fb80cc04c1d0ad0c0c870cf97267678d42fa6026dd92cfa6b20 0b0017b44c8ac50126a7aeb03494d1454f7f4ec560fbaba144198eb74ddab280 CLIENT_RANDOM 50a103ecbdd2a84c707eeda3262381ab8a427993c2407ecd537ae2414978f821 e1a6d3edd5f4e817aea86b2d15d3d21a23c8d2d60770c36819303e25873f30089d555d447ab29b8208b8c0ecd230405a 演示截图: eCapture链接地址 eCapture v0.4.11 下载地址 eCapture 官网 eCapture 代码仓库 未来展望: eCapture功能趋于稳定,以及笔者经历有限,未来更新频率可能会降低,欢迎广大网友参与其中,一起为开源做贡献,一起为你点赞。 2023-01-08 0 0