android逆向学习--绕过非标准http框架和非系统ssl库app的sslpinning(SSL_CTX_set_custom_verify)

博主在安卓应用市场下载的一个电子书app中遇到了SSL证书校验问题。通过抓包、解包和动态分析,发现app使用了自定义的网络框架,基于okhttp3进行了魔改,并使用了boringssl作为SSL库。通过hook SSL_write函数,确定证书校验发生在native层的libsscronet.so库中,进一步分析发现SSL_CTX_set_custom_verify和SSL_CTX_set_reverify_on_resume可能涉及证书验证。最后,成功找到了绕过SSLpinning的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

随意在安卓应用市场上下载了一个电子书app,发现还是有点东西的:
Charles首次抓包报错如下:

 

图片描述


第一反应就是有sslpinning,感觉挺简单的,但是几乎找了所有公开的unsslpinning脚本都无济于事, dump证书也如此。

对apk解包时发现里面有okhttp3,以为使用了okhttp3库,但hook后发现并不如此。

既然okhttp3 hook不到,就找了更深层次点的函数SSLOutputStream的write, 奇怪的是也没发现有调用,突然意识到事情可能没那么简单了!。

对于这种情况,貌似就只能多对一些底层或者基础的涉及网络的函数进行hook,终于在java.net.url函数打开了突破口

 

图片描述


看这个调用栈大概能看出,这个app因该是自己根据okttp3魔改了一个自己的框架,看后面的文件名感觉有点熟悉。
图片描述
这不就是okhttp的拦截器吗?
Ok直接看源码
图片描述
这个地方能看出来跟okhttp还是有区别的,决定hook下打印出所有的拦截器类。
图片描述

在okhttp3中,tls连接的部分在倒数第二个拦截器中,但是在本app上并没有这样做,所以重要分析了最后一个拦截器callServerInterceptor,具体如下:
看这个excutecall函数很关键,继续往下跟,其实hook这个地方就已经能拿到请求体和响应内容了,但是以学习为目的的话还是要搞明白它是怎么做的。

这个executel最终会调到com.ttnet.org.chromium.net.impl.CronetUrlRequest$1 中,然后就进入了native层。

 

图片描述


至此在java层也没发现在哪里有对证书的操作,所以有充分的理由相信他在native层做了校验。

尝试hook了下libssl.so中的SSL_write函数,居然也没发现有调用,惊出了一生冷汗,难不成是用了自己的ssl库?尝试搜了以下app已加载的so库,果不其然:

 

图片描述


查了下这个boringssl是google开源的openssl分支,于是尝试hook了下 boringssl中的SSL_write函数,果然有调用,所以可以基本确定它使用了自己的ssl库。

根据SSL_write的调用栈,判断该函数的调用来自libsscronet.so,于是在该库中搜索判断是否有调用boringssl中涉及证书验证的函数。

图片描述

上面的不管,只看导入函数,有两个函数比较可疑 SSL_CTX_set_custom_verify和SSL_CTX_set_reverify_on_resume,于是下载了一份boringssl的源码,分别看了下这两个函数,果然是用来做证书校验的,并且都有调用。

 

图片描述


该函数的原型为:
图片描述
第二个参数为校验模式:
图片描述
第三个参数为回调函数。
回调函数的返回值用来确认证书验证是否成功,具体如下:
图片描述
Hook之:
图片描述
图片描述
图片描述
这里有个问题,不能直接替换他原本的回调函数,必须要调用一次,不然会出问题,具体是什么原因懒得去研究。
验证:
图片描述
既然这个函数可以unpinning,另一个函数现在就懒得去看了,有空在研究下。

后来大概查了下,这个app是今日头条旗下的,难怪如此。接下来去干签名算法了。。。。

转:https://bbs.pediy.com/thread-268014.htm

<think>好的,用户想了解SSL_CTX_set_verify函数的用法示例。首先,我需要回忆一下OpenSSL中这个函数的作用。SSL_CTX_set_verify用于设置SSL上下文(SSL_CTX)的验证模式,控制证书验证的行为。这包括是否验证对端证书以及验证的回调函数。 接下来,我得确定函数原型参数。函数签名应该是这样的:void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *));。这里的mode参数是验证模式,比如SSL_VERIFY_PEER、SSL_VERIFY_FAIL_IF_NO_PEER_CERT等。第三个参数是回调函数,用户可以用来自定义验证逻辑,如果不需要可以设为NULL。 然后需要解释各个参数的具体含义。比如mode的不同选项如何影响验证行为,例如SSL_VERIFY_PEER会要求验证对端证书,而SSL_VERIFY_NONE则不验证。回调函数的作用是什么,比如在验证过程中可以检查证书的详细信息,或者记录日志。 接下来,给出示例代码是必要的。用户可能需要一个简单的例子,展示如何设置SSL_CTX,比如初始化,创建上下文,然后调用SSL_CTX_set_verify。同时,如果用户需要自定义验证,可以提供一个回调函数的示例,说明如何实现证书深度检查或特定主题名称的验证。 还需要注意一些常见问题,比如设置验证深度,虽然SSL_CTX_set_verify本身不处理深度,但需要用SSL_CTX_set_verify_depth来设置,避免中间证书过多导致验证失败。另外,回调函数的返回值会影响验证结果,正确返回1或0是关键。 用户可能遇到的问题包括:如何启用或禁用证书验证,如何调试验证失败的原因,或者如何处理自签名证书。因此,在回答中需要涵盖这些方面,提供代码片段解释。 最后,生成相关问题时要考虑用户可能进一步的需求,比如验证回调的细节、禁用验证的方法、错误处理或与旧版本协议的兼容性问题,如SSLv3。同时,确保引用提供的参考资料,比如引用[^1][^2],在适当的地方加入引用标记,例如提到SSLv3支持时引用,提到验证深度时引用[^2]。</think>### SSL_CTX_set_verify 函数用法详解 `SSL_CTX_set_verify` 是 OpenSSL 中用于设置 SSL/TLS 上下文验证模式的核心函数,主要控制证书验证行为。 #### 函数原型 ```c void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); ``` 参数说明: - `ctx`: SSL 上下文对象 - `mode`: 验证模式组合(通过位掩码设置) - `verify_callback`: 自定义验证回调函数(可为 `NULL`) #### 验证模式(mode) 1. **SSL_VERIFY_NONE** 不验证对端证书(仅用于测试环境) 2. **SSL_VERIFY_PEER** 要求验证对端证书(默认严格模式) 3. **SSL_VERIFY_FAIL_IF_NO_PEER_CERT** 客户端无证书时终止连接(需与 `SSL_VERIFY_PEER` 组合使用) #### 基础用法示例 ```c #include <openssl/ssl.h> int main() { SSL_CTX *ctx = SSL_CTX_new(TLS_method()); // 启用证书验证并强制客户端提供证书 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); // 设置信任的CA证书位置 SSL_CTX_load_verify_locations(ctx, "ca_cert.pem", NULL); } ``` #### 自定义验证回调示例 ```c int custom_verify(int preverify_ok, X509_STORE_CTX *ctx) { if (!preverify_ok) { // 获取验证错误代码 int err = X509_STORE_CTX_get_error(ctx); printf("Certificate verification failed: %s\n", X509_verify_cert_error_string(err)); return 0; } // 检查证书深度(需配合 SSL_CTX_set_verify_depth 使用) int depth = X509_STORE_CTX_get_error_depth(ctx); if (depth > 4) { printf("Certificate chain too deep\n"); return 0; } return 1; } // 设置带回调的验证模式 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, custom_verify); SSL_CTX_set_verify_depth(ctx, 4); // 设置最大证书链深度[^2] ``` ### 关键注意事项 1. **验证深度控制** 使用 `SSL_CTX_set_verify_depth()` 限制证书链深度防止过长的中间证书链 2. **协议版本兼容性** 注意旧版本协议(如 SSLv3)的兼容性问题,建议使用 `SSL_CTX_set_options()` 禁用不安全协议 3. **错误代码处理** 在回调函数中可通过 `X509_STORE_CTX_get_error()` 获取具体错误原因 4. **性能影响** 启用证书验证会增加计算开销,生产环境建议启用 OCSP Stapling 优化
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值