Kerberos FTP协议整数溢出漏洞分析与修复

本文详细分析了curl库中krb5_read_data()函数存在的整数溢出漏洞,该漏洞可能导致大规模recv()写入。报告包含完整的PoC代码、漏洞原理分析、影响评估以及官方修复方案,同时披露了Kerberos FTP支持将被移除的决策过程。

报告概述

本报告披露了curl库中Kerberos FTP支持组件存在的安全漏洞。漏洞源于krb5_read_data()函数中的整数溢出问题,可能导致缓冲区越界读取或内存耗尽。

漏洞详情

问题1:整数溢出导致安全检查绕过

krb5_read_data()函数中存在关键代码缺陷:

1
2
3
len = (int)ntohl((uint32_t)len);
if(len > CURL_MAX_INPUT_LENGTH)
  return CURLE_TOO_LARGE;

当网络字节序转换后的值超过INT_MAX时,会发生整数溢出,使len变为负值。这会绕过大小检查,导致后续逻辑错误:

1
2
3
char buffer[1024];
nread = CURLMIN(len, (int)sizeof(buffer));
result = socket_read(data, sockindex, buffer, (size_t)nread);

如果len为-1,nread将被转换为巨大的size_t值(约18446744071562072064),最终传递给recv()系统调用。

问题2:解码函数逻辑错误

代码中的do-while循环在len减至0后,错误地将0值传递给decode函数,而非实际读取的数据长度。

影响版本

自功能引入以来的所有curl版本均受影响。

验证过程

报告提供了完整的PoC代码,包括:

服务端模拟代码(repro_server.py)

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
import socket, struct, argparse, sys, time

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--port", type=int, default=9999)
    ap.add_argument("--netlen", type=lambda x:int(x,0), default=0x00000010,
                    help="4-byte big-endian length to send (e.g. 0x10 or 16)")
    # ... 完整实现

客户端测试代码(krb5_len_bug_harness.c)

1
2
3
4
5
// 完整复现漏洞的控制流
static int fake_decode(void *app_data, unsigned char *buf, int len, int data_prot, void *conn) {
    fprintf(stderr, "fake_decode() was called with len=%d\n", len);
    return 1234;
}

漏洞利用性分析

测试表明,虽然漏洞存在,但由于内核会对过大的recv()调用返回"Bad address"错误,实际利用可能受限。但在特定系统配置下仍可能导致内存耗尽。

官方响应与修复

curl维护者确认了漏洞存在,但指出:

  1. 自8.8.0版本引入的解码bug使该功能实际上无法正常使用
  2. 决定完全移除Kerberos FTP支持而非修复漏洞
  3. 提交了移除相关代码的PR #18577

时间线

  • 2025-09-16:漏洞报告提交
  • 2025-09-18:报告公开披露
  • 状态标记为"Informative"(信息性),非安全漏洞

技术细节

报告还讨论了历史版本中的相关代码变化,以及socket_read()函数中可能存在的无限循环问题(EOF处理缺陷)。

最终结论认为,由于功能本身已损坏且使用范围有限,该整数溢出问题不构成实际安全威胁。

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