总结
在本节中,我们将解释什么是服务器端请求伪造,描述一些常见示例,并解释如何查找和利用各种SSRF漏洞。
什么是SSRF?
服务器端请求伪造(也称为SSRF)是一个网络安全漏洞,攻击者可以利用该漏洞诱使服务器端应用程序向攻击者选择的任意域发出HTTP请求。
在典型的SSRF示例中,攻击者可能导致服务器建立自身连接,组织基础结构中其他基于Web的服务或外部第三方系统的连接。
SSRF攻击有什么影响?
成功的SSRF攻击通常会导致易受攻击的应用程序本身或应用程序可以与之通信的其他后端系统上未经授权的操作或对组织内数据的访问。 在某些情况下,SSRF漏洞可能允许攻击者执行任意命令。
导致与外部第三方系统建立连接的SSRF利用可能导致恶意的继续攻击,这些攻击似乎源于托管存在漏洞的应用程序的组织,从而导致潜在的法律责任和声誉损失。
常见的SSRF攻击
SSRF攻击通常利用信任关系来升级来自易受攻击的应用程序的攻击并执行未经授权的操作。 这些信任关系可能与服务器本身有关,也可能与同一组织内的其他后端系统有关。
针对服务器本身的SSRF攻击
在针对服务器本身的SSRF攻击中,攻击者诱使应用程序通过其环回网络接口向承载应用程序的服务器发出HTTP请求。 通常,这将涉及为URL提供一个主机名,例如127.0.0.1
(指向环回适配器的保留IP地址)或localhost
(同一适配器的常用名称)。
例如,考虑一个购物应用程序,该应用程序使用户可以查看特定商店中某商品是否有库存。 为了提供库存信息,应用程序必须根据所涉及的产品和商店查询各种后端REST API
。 该功能是通过将URL
通过前端HTTP
请求传递到相关的后端API
端点来实现的。 因此,当用户查看某件商品的库存状态时,他们的浏览器会发出如下请求:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://stock.weliketoshop.net:8080/product/stock/check%3FproductId%3D6%26storeId%3D1
这使服务器向指定的URL
发出请求,检索库存状态,并将其返回给用户。
在这种情况下,攻击者可以修改请求以指定服务器本身本地的URL
。 例如:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://localhost/admin
在这里,服务器将获取/admin
URL的内容并将其返回给用户。
当然,现在,攻击者可以直接访问/admin
URL。 但是通常只有适当的经过身份验证的用户才能访问管理功能。 因此,直接访问URL的攻击者不会看到任何感兴趣的内容。 但是,当对/admin
URL的请求来自本地计算机本身时,将绕过常规访问控制。 该应用程序授予对管理功能的完全访问权限,因为该请求似乎来自受信任的位置。
Lab: Basic SSRF against the local server
stockApi=http://localhost/admin/delete?username=carlos
为什么应用程序会以这种方式运行,并隐式信任来自本地计算机的请求? 发生这种情况可能有多种原因:
-
可以在位于应用程序服务器前面的其他组件中实现访问控制检查。 与服务器本身建立连接后,将绕过检查。
-
为了灾难恢复的目的,该应用程序可能允许无需登录即可对来自本地计算机的任何用户进行管理访问。 这为管理员提供了一种在丢失凭据的情况下恢复系统的方法。 这里的假设是只有完全受信任的用户将直接来自服务器本身。
-
管理界面可能正在侦听的端口号与主应用程序不同,因此用户可能无法直接访问。
这些信任关系通常会使SSRF成为严重的漏洞,在这种信任关系中,来自本地计算机的请求与普通请求的处理方式不同。
SSRF攻击其他后端系统
服务器端请求伪造常引起的另一种信任关系是应用程序服务器能够与用户无法直接访问的其他后端系统进行交互。 这些系统通常具有不可路由的专用IP地址。 由于后端系统通常受网络拓扑保护,因此它们的安全状态通常较弱。 在许多情况下,内部后端系统包含敏感功能,任何能够与系统交互的人都可以在不进行身份验证的情况下访问它们。
在前面的示例中,假设在后端URL https://192.168.0.68/admin
处有一个管理界面。 在这里,攻击者可以通过提交以下请求来利用SSRF漏洞访问管理界面:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://192.168.0.68/admin
Lab: Basic SSRF against another back-end system
stockApi=http://192.168.0.x:8080/admin/delete?username=carlos
规避SSRF的常见防御措施
通常会看到包含SSRF行为以及旨在防止恶意利用的防御措施的应用程序。 通常,可以防御这些防御措施。
具有基于黑名单的输入过滤器的SSRF
一些应用程序阻止包含主机名(如127.0.0.1
和localhost
)或敏感URL(如/admin
)的输入。 在这种情况下,您通常可以使用各种技术来规避过滤器:
-
使用
127.0.0.1
的备用IP表示形式,例如2130706433
、017700000001
或127.1
。 -
注册您自己的域名,该域名解析为
127.0.0.1
。 为此,您可以使用spoofed.burpcollaborator.net
-
使用URL编码或大小写变化来混淆阻止的字符串。
Lab: SSRF with blacklist-based input filter
stockApi=http://127.1/admin
具有基于白名单的输入过滤器的SSRF
某些应用程序仅允许输入匹配,以允许值开头或包含允许值的白名单的输入。 在这种情况下,您有时可以利用URL解析中的不一致来绕过过滤器。
URL规范包含许多在实现临时解析和URL验证时容易被忽略的功能:
-
您可以使用
@
字符在主机名之前的URL中嵌入凭据。 例如:https://expected-host@evil-host
-
您可以使用
#
字符表示URL片段。 例如:https://evil-host#expected-host
-
您可以利用DNS命名层次结构将所需的输入放入您控制的标准DNS名称中。 例如:
https://expected-host.evil-host
-
您可以使用URL编码字符来混淆URL解析代码。 如果实现过滤器的代码与执行后端HTTP请求的代码以不同的方式处理URL编码的字符,则这特别有用。
-
您可以将这些技术组合在一起使用。
Lab: SSRF with whitelist-based input filter
http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos
通过开放式重定向绕过SSRF过滤器
通过利用开放重定向漏洞,有时可以绕过任何基于过滤器的防御。
在前面的SSRF示例中,假设严格验证了用户提交的URL,以防止恶意利用SSRF行为。 但是,允许使用URL的应用程序包含一个开放重定向漏洞。 如果用于后端HTTP请求的API支持重定向,则可以构造一个满足过滤条件的URL,并导致将请求重定向到所需的后端目标。
例如,假设应用程序包含一个开放重定向漏洞,其中包含以下URL:
/product/nextProduct?currentProductId=6&path=http://evil-user.net
返回重定向到:
http://evil-user.net
您可以利用开放重定向漏洞绕过URL筛选器,并按如下方式利用SSRF漏洞:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://weliketoshop.net/product/nextProduct?currentProductId=6&path=http://192.168.0.68/admin
这种SSRF漏洞之所以有效,是因为该应用程序首先验证了所提供的stockAPI URL是否在允许的域中。 然后,应用程序请求提供的URL,这将触发打开重定向。 它遵循重定向,并向攻击者选择的内部URL发出请求。
Lab: SSRF with filter bypass via open redirection vulnerability
/product/nextProduct?path=http://192.168.0.12:8080/admin/delete?username=carlos
盲注SSRF漏洞
当可以诱使应用程序向提供的URL发出后端HTTP请求时出现盲SSRF漏洞,但是来自后端请求的响应不会在应用程序的前端响应中返回。
盲注SSRF通常较难利用,但有时可能导致服务器或其他后端组件上完全远程执行代码。
查找SSRF漏洞的隐藏攻击面
相对容易发现许多服务器端请求伪造漏洞,因为应用程序的正常流量涉及包含完整URL的请求参数。 SSRF的其他示例很难找到。
请求中的部分URL
有时,应用程序仅将主机名或URL路径的一部分放入请求参数中。 然后,将提交的值在服务器端合并到请求的完整URL中。 如果该值很容易识别为主机名或URL路径,则潜在的攻击面可能很明显。 但是,由于您无法控制所请求的整个URL,因此作为完整SSRF的可利用性可能受到限制。
数据格式内的URL
某些应用程序以其格式允许包含URL的格式传输数据,这些URL可能会被数据解析器要求的格式。 XML数据格式就是一个明显的例子,它已在Web应用程序中广泛用于将结构化数据从客户端传输到服务器。 当应用程序接受XML格式的数据并进行解析时,它可能容易受到XXE注入的攻击,进而容易受到XXE的SSRF攻击。
Lab: Exploiting XXE to perform SSRF attacks
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://169.254.169.254/"> ]>
通过Referer标头的SSRF
一些应用程序使用跟踪访问者的服务器端分析软件。 该软件通常在请求中记录Referer标头,因为这对于跟踪传入链接特别有用。 通常,分析软件实际上会访问Referer标头中显示的任何第三方URL。 通常这样做是为了分析引荐网站的内容,包括传入链接中使用的锚文本。 结果,Referer标头通常代表SSRF漏洞的卓有成效的攻击面。 有关涉及Referer标头的漏洞示例,请参阅盲SSRF漏洞。
盲SSRF漏洞
在本节中,我们将说明什么是服务器端盲目的伪造,描述一些常见的SSRF盲示例,并说明如何查找和利用盲SSRF漏洞。
什么是盲SSRF?
当可以诱使应用程序向提供的URL发出后端HTTP请求时出现盲SSRF漏洞,但是来自后端请求的响应不会在应用程序的前端响应中返回。
盲目SSRF漏洞有什么影响?
盲目SSRF漏洞的影响通常比完全知悉的SSRF漏洞低,因为它们具有单向性。 尽管在某些情况下可以利用它们来实现完整的远程代码执行,但不能轻易利用它们从后端系统检索敏感数据。
如何发现和利用SSRF的盲目漏洞
检测盲区SSRF漏洞的最可靠方法是使用带外(OAST)技术。 这涉及尝试触发对您控制的外部系统的HTTP请求,并监视与该系统的网络交互。
使用带外技术的最简单,最有效的方法是使用Burp Collaborator
。 您可以使用Burp Collaborator
客户端生成唯一的域名,将其作为有效负载发送给应用程序,并监视与这些域的任何交互。 如果观察到来自应用程序的传入HTTP请求,则SSRF容易受到攻击。
注意:测试SSRF漏洞时,通常会观察提供的Collaborator域的DNS查找,但没有后续的HTTP请求。 通常发生这种情况是因为应用程序尝试向域发出HTTP请求,这导致了最初的DNS查找,但是实际的HTTP请求却被网络级过滤阻止。 对于基础结构,允许出站DNS通信非常普遍,因为这样做有很多用途,但是会阻止HTTP连接到意外目的地。
Lab: Blind SSRF with out-of-band detection
略
简单地识别可以触发带外HTTP请求的盲SSRF漏洞本身并不能提供可利用性的途径。 由于您无法查看来自后端请求的响应,因此该行为不能用于浏览应用程序服务器可以访问的系统上的内容。 但是,仍然可以利用它来探测服务器本身或其他后端系统上的其他漏洞。 您可以盲目扫描内部IP地址空间,发送旨在检测已知漏洞的有效负载。 如果这些有效负载还采用了盲带外技术,那么您可能会在未打补丁的内部服务器上发现一个严重漏洞。
Lab: Blind SSRF with Shellshock exploitation
略
如何使用 Collaborator Everywhere
自动的HTTP头注入
http://wp.blkstone.me/2019/09/how-to-use-collaborator-everywhere/
利用盲目的SSRF漏洞的另一种途径是诱使应用程序连接到攻击者控制下的系统,并将恶意响应返回给进行连接的HTTP客户端。 如果可以在服务器的HTTP实现中利用严重的客户端漏洞,则可以在应用程序基础结构中实现远程代码执行。