1.4.1 SSRF利用

SSRF漏洞的出现场景如下。

● 需要本地访问,请求头无法绕过。

● 在URL中提交参数获取文件。

● 对外发起网络请求。

● 从远程服务器请求资源。

● 数据库内置功能。

● WebMail收取其他邮件。

● 文件处理、编码处理、属性信息处理。

1.内网访问

在CTF中,SSRF漏洞最常见的利用方式就是探测内网,根据127.0.0.1或找到的内网IP,对内网进行访问,结合BurpSuite可快速对目标端口进行检测。

靶场环境为CTFHub技能树-Web-SSRF-内网访问。

靶场中的URL通过GET方式传递参数变量url的值,通过该参数调用外部资源,所以成了SSRF漏洞的入口。构造Payload访问服务器本地资源:?url=127.0.0.1/flag.php。发送伪造后的请求,即可获取flag。

2.伪协议

伪协议就是利用不同URL协议类型配合SSRF,也就是URL scheme机制。URL scheme是系统提供的一种机制,由应用程序注册,其他程序通过URL scheme调用该应用程序,包括系统默认的URL scheme与应用程序自定义的URL scheme。https://www.ctfhub.com中https://就属于系统默认的机制。

以CURL工具为例,其支持的协议如下。

● file://:访问本地文件系统(不受allow_url_fopen与allow_url_include的影响)。

● dict://:约定服务器端侦听的端口号。

● sftp://:基于SSH的文件传输协议。

● tftp://:基于lockstep机制的文件传输协议。

● ldap://:轻量化目录访问协议。

● gopher://:分布式文档传递服务。

举个例子,CTFHub技能树-Web-SSRF-伪协议读取文件,使用file://协议读取flag.php的源码,构造Payload,?url=file:///var/www/html/flag.php,发送请求即可得到flag。

3.端口扫描

内网的防护相较于外网来说较为薄弱,通过扫描服务器与内网主机的端口,可发现外网无法访问的服务,扩大可攻击范围,增加攻破系统的可能性。

靶场环境为CTFHub技能树-Web-SSRF端口扫描。与上一题环境类似,构造Payload ?url=127.0.0.1:8000可直接使用BurpSuite对端口进行爆破,使用Intruder模块中的Sniper类型,选中8000端口号为变量,如图1-84所示。

图1-84 爆破端口

设置Payload类型为Numbers,这是因为题目提示端口号范围在8000~9000之间,设置如图1-85所示。

图1-85 设置端口范围

通过爆破结果的长度,获取flag,如图1-86所示。

图1-86 8910端口获得flag

也可以结合dict://协议对端口进行爆破,构造Payload ?url=dict://127.0.0.1:8000,同样设置8000为变量,如图1-87所示。

图1-87 设置爆破端口

与之前的Payload设置相同,获得爆破结果,如图1-88所示。

图1-88 爆破结果

根据页面响应状态(即返回长度)判断结果。

4.Gopher协议

Gopher协议是HTTP出现之前在互联网上最常见,也是最常用的协议。Gopher协议能够传递底层的TCP数据流,攻击内网的FTP、Telnet、Redis、Memcache,也可以进行GET、POST请求,所以在SSRF中Gopher协议的攻击面最广。

Gopher协议的格式为gopher://127.0.0.1:70/_+ TCP/IP数据,这里的_是一种数据连接格式,也可以是任意字符。Gopher协议在各种编程语言中的使用限制如表1-5所示。

表1-5 Gopher协议的使用限制

下面通过CTFHub的靶场举几个Gopher协议在SSRF中被利用的例子。

以CTFHub技能树-Web-SSRF-POST请求题目为例,通过GET方式传参访问:?url=127.0.0.1/flag.php。查看网页源码,代码如下。

其中含有key=51457bb0a50c1eb2c92dcc3ec3c2cc13,将key值添加到输入框中并提交,得到回显,如图1-89所示。

使用file://协议读取index.php以及flag.php页面源码:?url=file:///var/www/html/flag.php。得到index.php页面的源码,如图1-90所示。

图1-89 页面回显

图1-90 index.php页面源码

得到flag.php页面的源码,如图1-91所示。

图1-91 flag.php页面源码

尝试使用Gopher协议向服务器发送POST包。首先构造Gopher协议所需的POST请求,请求包如图1-92所示。

图1-92 构造请求包

在使用Gopher协议发送POST请求包时,Host、Content-Type和Content-Length请求头是必不可少的,但在GET请求中可以没有。

在向服务器发送请求时,浏览器会进行一次URL解码,服务器收到请求后,在执行CURL功能时,进行第二次URL解码,所以我们需要对构造的请求包进行两次URL编码。

首先将构造好的请求包进行第一次URL编码,如图1-93所示。

图1-93 第一次URL编码

将第一次编码后的数据中的%0A全部替换为%0D%0A。因为Gopher协议包含的请求数据包中,可能包含=、&等特殊字符,为避免与服务器解析传入的参数键值对混淆,所以对数据包进行第二次URL编码,这样服务端会把%后的字节当作普通字节。进行第二次URL编码,得到如下Gopher请求内容。

因为flag.php中的$_SERVER["REMOTE_ADDR"]无法绕过,所以只能通过index.php页面中的CURL功能向目标发送POST请求,构造如下Payload。

向目标发送数据包,得到flag,如图1-94所示。

图1-94 获取flag

以CTFHub技能树-Web-SSRF-POST上传文件题目为例,通过GET传参访问?url=127.0.0.1/flag.php,得到一个空上传功能点,如图1-95所示。

提示需要上传WebShell,只能选择文件,没有提交按钮。使用file://协议读取flag.php的源码:?url=file:///var/www/html/flag.php。得到目标源码,如图1-96所示。

图1-95 空上传功能点

图1-96 flag.php源码

后端无任何过滤,也无文件类型限制,上传文件大小大于0即可,如图1-97所示。

在flag.php页面中,还须满足请求只允许从本地访问,使用BurpSuite抓取数据包,如图1-98所示。

图1-97 上传页面源码

图1-98 BurpSuite抓包

构造Gopher协议所需的POST请求,如图1-99所示。

图1-99 POST请求

与之前相同,将第一次URL编码后的数据中的%0A替换为%0D%0A,并进行二次URL编码,如图1-100所示。

图1-100 URL编码

构造Payload,发送数据包,得到flag,代码如下。

5.攻击Redis

Redis是一个key-value存储系统,根据题目的提示,需要使用SSRF攻击内网的Redis服务,使用Gopherus工具生成攻击Redis的Payload,如图1-101所示。

选择PHPShell,根目录路径为默认值,使用默认的PHPShell,得到构造好的Gopher协议Payload,其默认经过了一次URL编码,将%0A替换为%0D%0A,对其进行二次URL编码,如图1-102所示。

图1-101 使用工具生成攻击Redis的Payload

图1-102 进行二次URL编码

构造最终的Payload,代码如下。

发送数据包,题目环境显示504,但Shell已经写入,访问shell.php,结果如图1-103所示。

图1-103 访问结果

虽然有脏数据,但是页面已经存在,WebShell参数为cmd,尝试寻找flag:shell.php?cmd=ls/。得到flag文件名,如图1-104所示。

图1-104 得到flag文件名

使用cat命令查看flag:shell.php?cmd=cat/flag_2596562d0e4a36c94823864f1d7a505b得到flag。其中Redis写WebShell用到的命令如下。

需要先将其转化为Redis RESP协议的格式,再进行URL编码。