报告 #3442060 - curl项目状态机中的无限循环问题
报告时间线
- kak1 向curl提交了一份报告。14天前
- bagder (curl工作人员) 发表了评论。14天前
- dgustafsson (curl工作人员) 发表了评论。14天前
- kak1 发表了评论。14天前
- bagder (curl工作人员) 发表了评论。14天前
- kak1 发表了评论。14天前
- kak1 发表了评论。14天前
- bagder (curl工作人员) 发表了评论并更新。14天前
- bagder (curl工作人员) 关闭了报告并将状态更改为“不适用”。14天前
- bagder (curl工作人员) 请求披露此报告。14天前
- bagder (curl工作人员) 披露了此报告。14天前
漏洞摘要 漏洞影响:当curl尝试从恶意FTP服务器下载文件时,会触发代码执行中的无限循环。
我在curl项目的FTP功能中发现了这个问题。根据 https://github.com/curl/curl/blob/master/docs/cmdline-opts/disable-epsv.md 的描述,curl默认使用EPSV模式作为FTP文件传输方法。简而言之,EPSV模式的工作原理如下:FTP服务器打开一个TCP端口并等待客户端连接,然后通过该端口向客户端发送数据。
在curl的状态机中,/lib/multi.c 中的 state_performing 函数在 [1] 处调用 Curl_sendrecv 函数以从对等方接收数据:
|
|
Curl_sendrecv 函数在 [2] 处调用 sendrecv_dl:
|
|
sendrecv_dl 函数进一步调用 xfer_recv_resp 来接收数据。如果我们的恶意FTP服务器打开了一个EPSV端口但没有向客户端发送任何数据,xfer_recv_resp 将返回-1,并且 result 的值将被设置为 CURLE_AGAIN。随后,在 [4] 处,result 被设置为 CURLE_OK。这意味着即使 xfer_recv_resp 未能接收到任何数据,sendrecv_dl 函数仍然返回 CURLE_OK。
|
|
让我们继续检查 state_performing 函数:
|
|
由于没有接收到任何数据,data->req.done 标志保持为0。此外,因为 result 是 CURLE_OK,所以 [5]、[6] 和 [7] 处的条件检查结果均为假。代码随后执行到 [8] 处(没有错误,也没有完成)。
这导致curl的当前状态机标志(data->mstate)保持不变,仍然设置为 MSTATE_PERFORMING。随后,curl代码反复进入 state_performing 函数,从而导致无限循环。
受影响版本
- curl : https://github.com/curl/curl/archive/refs/tags/curl-8_17_0.tar.gz
- 平台 : ubuntu22.04
|
|
复现步骤
- 下载附带的
./ftp_poc.py文件并运行:sudo python3 ./ftp_poc.py。这将在当前机器的21端口上启动一个恶意FTP服务。 - 运行以下curl命令,将命令中的
192.168.23.1替换为您自己的恶意FTP服务器地址:curl程序将进入无限代码循环,并且不会自行退出。1./curl -u anonymous:123 'ftp://192.168.23.1/test' -o ./test
影响 摘要:当curl尝试从恶意FTP服务器下载文件时,会触发代码执行中的无限循环。
附件
- 1 个附件:
F5049867: ftp_poc.py
评论记录
-
bagder (curl工作人员) 发表了评论。14天前
感谢您的报告! 我们将花一些时间调查您的报告,并尽快向您反馈详细信息和可能的后续问题!很可能在接下来的24小时内。 我们始终努力尽快修复报告的问题。严重性为低或中的问题,我们会按常规发布周期合并到下一个版本中。只有更严重的问题我们才会提前发布修复。
-
bagder (curl工作人员) 发表了评论。14天前
@kak1 这与服务器只是停止发送任何数据,并且curl只是坐在那里等待更多数据直到时间结束(除非提供了额外的超时选项)有什么不同?这似乎是curl设计的工作方式?
-
dgustafsson (curl工作人员) 发表了评论。14天前
如果文件传输是无限的,那么curl的正确行为就是无限地下载它。
-
kak1 发表了评论。14天前
不同之处在于,在此问题中,即使手动设置了超时,curl进程也不会终止。但是,我没有在循环中找到任何内存分配代码,因此不会发生内存泄漏。目前,它只会导致CPU使用。如果此类问题不被视为安全漏洞,请关闭此报告。
-
bagder (curl工作人员) 发表了评论。14天前
即使手动设置了超时,curl进程也不会终止 这与我针对您的PoC服务器测试curl时的工作方式不符。它正常超时:
1 2 3 4 5 6$ curl ftp://localhost:9021/ -v -m2 ... curl: (28) Operation timed out after 2002 milliseconds with 0 bytes received $ curl ftp://localhost:9021/RE -v -m2 ... curl: (28) Operation timed out after 2002 milliseconds with 0 out of 4 bytes received -
kak1 发表了评论。14天前
请使用我提供的PoC文件和命令,因为触发此问题需要特定的协议交互。我已经为此目的调整了提供的命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21➜ curl sudo python3 ./ftp_poc.py FTP server 0.0.0.0:21 waiting for connect... client ('192.168.23.1', 28513) connect -> 220 Welcome to Simple FTP Server <- USER anonymous -> 331 Please specify the password. <- PASS 123 -> 230 Login successful. <- PWD -> 257 "/" is the current directory <- EPSV -> 229 Entering Extended Passive Mode (|||32971|) EPSV port: 32971 <- TYPE I -> 200 Switching to Binary mode. <- SIZE test -> 213 213 4 <- RETR test -> 150 Opening BINARY mode data connection for test (4 bytes). -> 226 Transfer complete.1 2 3 4➜ src ./curl -u anonymous:123 'ftp://192.168.23.1/test' -o ./test --connect-timeout 30 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 4 0 0 0 0 0 0 --:--:-- 0:09:32 --:--:-- 0 -
kak1 发表了评论。14天前
添加
-m 2参数后,curl超时了。看来这个问题可以缓解。请关闭此报告。 -
bagder (curl工作人员) 发表了评论。更新于14天前
您需要使用
-m (--max-time)。--connect-timeout对您的情况没有任何作用,因为它及时连接成功。 -
bagder (curl工作人员) 关闭了报告并将状态更改为“不适用”。14天前
认为不是安全问题。
-
bagder (curl工作人员) 请求披露此报告。14天前
根据项目的透明政策,我们希望所有报告都能被披露并公开。
-
bagder (curl工作人员) 披露了此报告。14天前
报告详情
- 报告时间:2025年11月26日,UTC时间上午8:34
- 报告人:kak1
- 报告对象:curl
- 报告ID:#3442060
- 严重性:无评级 (—)
- 披露时间:2025年11月26日,UTC时间上午9:32
- 弱点:无
- CVE ID:无
- 赏金:无
- 账户详情:无