深入解析cURL SFTP TOCTOU竞争条件漏洞:竞态窗口下的任意文件追加

本文详细分析了cURL库SFTP断点续传功能中的一个TOCTOU竞争条件漏洞。当使用`-C -`参数恢复上传时,STAT与OPEN操作之间的微小时间窗口可被利用,导致向任意文件追加数据,可能引发权限提升、代码执行或数据篡改。

[SFTP] TOCTOU Race Condition in Upload Resume Logic Leads to Arbitrary File Append

Summary:

A Time-of-check to Time-of-use (TOCTOU) race condition exists in the SFTP upload resume functionality of libcurl. When resuming an upload with CURLOPT_RESUME_FROM set to -1 (the equivalent of the curl -C - command-line flag), libcurl first performs a STAT operation to determine the remote file’s size and the correct offset to resume from. Subsequently, it performs an OPEN operation to begin writing. A window of time exists between the STAT and OPEN calls. An attacker with authenticated access to the SFTP server can exploit this by replacing the target file with a symbolic link to a different file on the system. Because the OPEN operation for a resume operation does not use a truncation flag (e.g., O_TRUNC), curl will then proceed to seek to the previously determined offset and append data to the symlink’s target file. This allows an attacker to append arbitrary data to files the user has write access to, but did not intend to modify.

Affected version: This was reproduced on curl 8.18.0-DEV (the master branch as of November 2025). The vulnerable logic appears to be fundamental to the SFTP resume-from-end feature (-C -) and likely affects many previous versions as well. A typical curl -V output for a system where this can be reproduced would be: curl 8.18.0-DEV (x86_64-pc-linux-gnu) libcurl/8.18.0-DEV OpenSSL/3.2.1 zlib/1.2.13 libssh2/1.11.0 Protocols: sftp https … Features: AsynchDNS libssh2 …

Steps To Reproduce:

  1. Setup the Environment:

    • An SFTP server is required. For local testing, openssh-server can be used on a Linux machine, allowing connections to localhost.
    • The attacker needs an authenticated user account on the server with write permissions in a specific directory.
    • The victim is a curl user who will upload a file to this specific directory using the resume flag.
  2. Prepare the Attack Scripts:

    • Create the server-side script race_server.sh on the SFTP server. This script will rapidly swap the target file with a symlink to a sensitive file.
    • Create the client-side script race_client.sh on the client machine. This script will repeatedly attempt the curl upload to trigger the race condition.
  3. Execute the Attack:

    • On the server, run ./race_server.sh. It will begin creating and deleting the symlink in a tight loop.
    • On the client, configure race_client.sh with the correct credentials and paths, then run ./race_client.sh. It will start sending upload requests.
    • Let both scripts run for 15-30 seconds. The client will show some “No such file or directory” errors, which is expected.
  4. Verify the Result:

    • Stop both scripts (Ctrl+C).
    • On the server, inspect the contents of the sensitive file targeted by the symlink (e.g., /tmp/test_vuln.log).
    • If the exploit was successful, the contents of the client’s payload file will be appended to the sensitive file.

Supporting Material/References:

  • race_client.sh (race_client.sh (F5023270): race_client.sh)
  • race_server.sh (race_server.sh (F5023271): race_server.sh)
  • Vulnerable Code Flow Analysis.txt (Vulnerable_Code_Flow_Analysis.txt (F5023279): Vulnerable Code Flow Analysis.txt)

Vulnerable Code Pointer The core of the vulnerability is in the sftp_upload_init function within:

  • lib/vssh/libssh2.c
  • lib/vssh/libssh.c

Specifically the logic branch:

  • if(data->state.resume_from < 0) → performs a STAT
  • else if(data->state.resume_from > 0) → performs a non-truncating OPEN

Attached PoC Scripts

  • race_server.sh: Server-side PoC to create the race condition.
  • race_client.sh: Client-side PoC used to repeatedly trigger the vulnerable logic in curl.

Impact The primary impact is a loss of Integrity. An attacker with authenticated access to an SFTP server can leverage this vulnerability to append arbitrary data to any file that the victim user has write permissions for. This can lead to further, more severe impacts depending on the targeted file:

  • Remote Code Execution (RCE): If the attacker appends malicious commands to a user’s startup script (e.g., .bashrc, .profile) or a script executed by a cron job.
  • Denial of Service (DoS): If the attacker corrupts a critical system or application configuration file.
  • Log Injection / Tampering: The attacker could inject false log entries to mislead administrators or hide other malicious activity.

The severity is rated as Medium, as exploitation requires the attacker to have prior authenticated access to the server and relies on winning a race condition.

Suggested Mitigation The root cause is the lack of verification that the file opened is the same one that was checked. The most robust solution is to perform a check after the file is opened.

  1. After libssh2_sftp_open_ex() is called in sftp_upload_init, a subsequent call to libssh2_sftp_fstat_ex() should be made on the returned file handle.
  2. The attributes from this fstat call (e.g., inode number, if the SFTP server extension provides it) should be compared to the attributes gathered from the initial stat call.
  3. If the attributes do not match, it indicates the file was swapped. The transfer must be aborted, and an error should be returned to the user.

attachments: 3 attachments: F5023270: race_client.sh, F5023271: race_server.sh, F5023279: Vulnerable_Code_Flow_Analysis.txt


Timeline & Discussion

2025-11-19, 08:12 UTC: cainvsilf 提交漏洞报告。

2025-11-19, 08:13 UTC: bagder (curl维护人员) 回应感谢报告,并承诺进行调查。

2025-11-19, 08:23 UTC: cainvsilf 表示愿意在调查中提供更多协助。

2025-11-19, 08:34 UTC: bagder 提出质疑,认为攻击者既然已拥有在服务器上替换文件或创建符号链接的权限,本身就足以造成破坏,此漏洞并未带来实质性新风险。

2025-11-19, 08:43 UTC: cainvsilf 澄清,漏洞的关键风险在于权限分离场景下的"Confused Deputy"(困惑代理)问题。攻击者利用此漏洞可以实现可控的、基于偏移量的追加,而非简单的文件破坏。并举例:

  1. 场景1 - 多用户SFTP服务器: 低权限攻击者诱使高权限应用进程向其本无权限访问的配置文件追加数据,实现权限提升。
  2. 场景2 - 可控追加 vs. 简单破坏: 普通符号链接会导致写入位置不可控(如覆盖二进制文件头部造成破坏)。而利用此漏洞,攻击者可利用STAT获取的原始文件大小信息,让curl进程精准地追加到目标文件(如.bashrc)的特定偏移处,从而注入恶意命令。

2025-11-19, 08:55 UTC: bagder 再次强调,攻击者本身已拥有制造破坏的能力。对于攻击者能控制追加偏移量这一点表示认同,但认为攻击者无法控制上传的具体内容,且利用条件苛刻(需要精确的时机和特定知识)。

2025-11-19, 09:30 UTC: cainvsilf 进一步从技术细节解释区别:

  • 普通符号链接滥用:仅能重定向写入目标,无法控制写入偏移量。写入行为可能因服务器实现而异(如截断、从头覆盖)。
  • 此cURL漏洞:引入了"陈旧偏移量"问题。流程是:STAT读取文件A的元数据 → 攻击者将A替换为指向B的符号链接 → cURL在文件B上执行SEEK(size_of_A)。这种跨文件的偏移量混淆是普通符号链接攻击无法实现的。
  • 竞争窗口的意义:许多实际应用在调用curl前会进行预检查(如检查文件是否存在、大小等)。一个永久性的符号链接会导致这些检查失败。而利用竞争条件,可以在STAT检查通过后、OPEN执行前瞬间完成替换,从而绕过应用层安全校验。

2025-11-19, 09:34 UTC - 11:07 UTC: 双方就漏洞的实际影响和利用门槛展开多轮讨论。bagder 反复强调攻击者需要已具备相当的服务器访问权限和关于客户端的详细知识,且攻击具有时机敏感性。cainvsilf 则坚持认为,漏洞赋予了攻击者一项他们原本不具备的能力:控制写入偏移量,这本身就是在跨越一个安全边界。

2025-11-20, 06:16 UTC: cainvsilf 提供了一个更清晰、完全可复现的概念验证(PoC),详细演示了在权限分离环境下,低权限用户如何利用此漏洞使高权限进程向敏感文件(如authorized_keys)追加数据,实现权限提升。

2025-11-20, 09:10 UTC - 09:25 UTC: bagder 询问这是否是新报告,并重申curl无法保护用户免受已在服务器上拥有文件替换能力的攻击者的侵害。cainvsilf 表示PoC仅为更清晰地演示之前讨论的同一漏洞行为,随后感谢讨论并结束陈述。

2025-11-21, 14:53 UTC: bagder 将报告状态关闭并标记为 “Informative”。判定依据:此问题依赖于攻击者已具备在目标目录中插入恶意符号链接的能力,这本身已构成攻击。cURL的行为可能使后果更严重,但这是curl无法防范的既有攻击。将考虑在相关文档中增加关于此风险的说明。

2025-11-23, 11:56 UTC: bagder 根据项目透明度政策,请求公开此报告。

报告公开于 15天前。

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