curl中的TFTP实现:整数下溢导致堆内存越界读取漏洞

漏洞概述

在 curl 的 TFTP 协议实现中发现了一个漏洞,该漏洞可能导致 curl 或使用 libcurl 的应用程序在特定条件下,向恶意的 TFTP 服务器发送超出已分配内存块边界的内存数据。

该漏洞存在于 commit 3ee1d3b5 的 libcurl 中,具体位于 lib/tftp.c 文件的 tftp_send_first() 函数。

漏洞详情

代码分析

漏洞核心代码如下 (lib/tftp.c 文件,tftp_send_first() 函数,第467行附近):

c 复制代码
1 if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
2   // [...]
3 }
4
5 curl_msnprintf((char *)state->spacket.data + 2,
6                state->blksize,
7                "%s%c%s%c", filename, '\0', mode, '\0');
8 sbytes = 4 + strlen(filename) + strlen(mode);
9
10 // [...]
11
12 senddata = sendto(state->sockfd, (void *)state->spacket.data,
13                  (SEND_TYPE_ARG3)sbytes, 0,
14                  CURL_SENDTO_ARG5(&remote_addr->curl_sa_addr),
15                  (curl_socklen_t)remote_addr->addrlen);

触发条件

当满足以下条件时,漏洞可以被触发:

  1. 使用特定选项调用 curl :通过 --tftp-no-options 参数调用 curl,或者 libcurl 的使用者设置了 CURLOPT_TFTP_NO_OPTIONS 为 1。
  2. 恶意TFTP服务器:一个恶意的 TFTP 服务器与 curl 进行通信。
  3. 协商最小块大小 :服务器将传输的块大小 (state->blksize) 协商为一个较小的值(例如 8)。mode 保持默认值 "octet"(长度为 5)。

当这些条件满足时,第467行的边界检查代码会变成:

c 复制代码
if(strlen(filename) > (8 /* state->blksize */ - 5 /* strlen(mode) */ - 4)) {

计算 8 - 5 - 4 = -1,导致一个整数下溢 。这使得检查条件的结果总是为 false,即使文件名非常长,原本的边界检查也会被绕过。

随后,第8行根据文件名的实际长度计算要发送的字节数 (sbytes),但这个长度可能已经超过了已分配的缓冲区大小。紧接着的第12行 sendto 调用就可能发送超出缓冲区边界的数据。

影响

此漏洞的潜在影响是信息泄露,即可能将堆内存中的内容发送给恶意的 TFTP 服务器。

然而,curl 的开发团队在评估后认为,该漏洞的严重性为 LOW(低),甚至仅被视为一个普通的 Bug。主要原因如下:

  • 触发条件苛刻:需要同时满足多个不太常见的条件:必须开启 TFTP no options 模式,并且需要服务器将块大小协商到一个极小的值。
  • 攻击难度高:利用该漏洞读取到有价值信息(如密码、密钥等)的难度非常高。攻击者很难精确控制堆内存的布局以及泄漏的内容。
  • 利用场景罕见:需要用户或应用程序允许跨协议重定向(例如从 HTTP 重定向到 TFTP),这在现实世界中极为罕见。即使存在,也意味着应用程序允许不安全的 UDP 明文传输,本身就是一个弱安全模型。
  • 实际影响有限:即使成功触发,大多数情况下只会导致程序崩溃。在文件名极长(超过503字节)的情况下,才有可能读取到相邻内存区域的数据。但构造如此长的文件路径在实践中也较为少见。

修复方案

curl 的开发团队已经修复了此问题。修复的 Pull Request 为:github.com/curl/curl/p...

修复的核心在于修正了边界检查的逻辑,避免整数下溢的发生。

修复代码示例:

diff 复制代码
-    if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
+    if(strlen(filename) + strlen(mode) + 4 > state->blksize) {
       failf(data, "TFTP filename too long");
       curlx_free(filename);
       return CURLE_TFTP_ILLEGAL; /* too long filename field */
     }

-    curl_msnprintf((char *)state->spacket.data + 2,
-                   state->blksize,
-                   "%s%c%s%c", filename, '\0', mode, '\0');
-    sbytes = 4 + strlen(filename) + strlen(mode);
+    sbytes = 2 +
+      curl_msnprintf((char *)state->spacket.data + 2,
+                     state->blksize,
+                     "%s%c%s%c", filename, '\0', mode, '\0');
     curlx_free(filename);

新的代码通过将各部分长度相加后再与缓冲区大小进行比较,从根本上杜绝了整数下溢的可能性。同时,sbytes 的计算也改为基于 curl_msnprintf 的实际返回值,更加准确和安全。FINISHED biOK/hzhVF2yKaGc5mK8oeejIYuUYW8I3RsXQCFCiXXSrEl8bonoS+c8zsMSKu1g

相关推荐
曦月逸霜22 分钟前
啥是RAG 它能干什么?
人工智能·python·机器学习
AI医影跨模态组学28 分钟前
Lancet Digit Health(IF=24.1)广东省人民医院刘再毅&南方医科大学南方医院梁莉等团队:基于可解释深度学习模型预测胶质瘤分子改变
人工智能·深度学习·论文·医学·医学影像·影像组学
应用市场29 分钟前
AI 编程助手三强争霸(2026 版):Claude、Gemini、GPT 各自擅长什么?
人工智能·gpt
AC赳赳老秦1 小时前
供应链专员提效:OpenClaw自动跟踪物流信息、更新库存数据,异常自动提醒
java·大数据·服务器·数据库·人工智能·自动化·openclaw
脑极体1 小时前
从Token消耗到DAA增长,AI价值标尺正在重构
人工智能·重构
csdn小瓯1 小时前
LangGraph自适应工作流路由机制:从关键词匹配到智能决策的完整实现
人工智能·fastapi·langgraph
QYR-分析1 小时前
高功率飞秒激光器行业发展现状、市场机遇及未来趋势分析
大数据·人工智能
AI医影跨模态组学2 小时前
J Clin Oncol(IF=43.4)美国Cedars-Sinai医学中心等团队:基于计算组织学人工智能的晚期胰腺癌化疗选择预测性生物标志物的开发与验证
人工智能·机器学习·论文·医学·医学影像·影像组学
冬奇Lab2 小时前
RAG 系列(十六):Graph RAG——用知识图谱解决多跳关系问题
人工智能·llm
冬奇Lab2 小时前
一天一个开源项目(第101篇):OpenHuman - 真正懂你的本地优先个人 AI 超级助手
人工智能·开源·资讯