Use-After-Free in OpenSSL Keylog Callback via SSL_get_ex_data() in libcurl
摘要
在libcurl中设置OpenSSL SSL_CTX_set_keylog_callback时存在Use-After-Free(UAF)漏洞。回调可能在关联的SSL对象通过SSL_free()释放后被调用,导致访问悬空指针,并通过SSL_get_ex_data()可能引发崩溃或信息泄露。
受影响版本
测试环境:
- curl 8.8.0 (OpenSSL 3.3.0)
- 发布日期:2024-06-26
- 平台:Termux (Android 11, aarch64)
- OpenSSL:3.3.0(从源码构建)
复现步骤
构建以下最小C程序(使用gcc -o segv segv.c -lssl -lcrypto编译):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <stdio.h>
#include <stdlib.h>
void my_keylog_cb(const SSL *ssl, const char *line) {
printf("Keylog callback: %s\n", line);
// UAF: SSL已释放
void *ptr = SSL_get_ex_data((SSL *)ssl, 0); // 强制转换以移除const
printf("Data: %p\n", ptr);
}
int main() {
SSL_library_init();
SSL_load_error_strings();
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_keylog_callback(ctx, my_keylog_cb);
SSL *ssl = SSL_new(ctx);
int idx = SSL_get_ex_new_index(0, "mydata", NULL, NULL, NULL);
char *data = strdup("hello");
SSL_set_ex_data(ssl, idx, data);
SSL_free(ssl); // 释放SSL
// 在释放后触发回调
my_keylog_cb(ssl, "CLIENT_RANDOM deadbeef...");
SSL_CTX_free(ctx);
free(data);
return 0;
}
|
运行二进制文件:
1
2
3
4
|
$ ./segv
Keylog callback: CLIENT_RANDOM deadbeef...
Data: 0x0
Segmentation fault
|
安全影响
在特定条件下(当配置了密钥日志回调时),会导致段错误(DoS)。如果可能进行堆整理或ex_data滥用,可能导致代码执行。
讨论与结论
该漏洞最初被报告为libcurl问题,但经过审查发现libcurl代码中并未使用SSL_get_ex_data(),因此不影响libcurl。报告最终被标记为“不适用”并公开披露。
注意:此漏洞不影响libcurl,而是与OpenSSL的使用方式相关。