API recon(学习记录)
-
API 侦察
若要开始 API 测试,首先需要尽可能多地了解有关 API 的信息,以发现其攻击面。
首先,您应该确定 API 端点。这些是 API 接收有关其服务器上特定资源的请求的位置。例如,请考虑以下请求:GET
GET /api/books HTTP/1.1 Host: example.com
此请求的 API 端点是 。这会导致与 API 交互,以从图书馆中检索书籍列表。例如,另一个 API 端点可能是 ,它将检索神秘书籍的列表。
/api/books/api/books/mystery
确定终结点后,需要确定如何与它们交互。这使您能够构造有效的 HTTP 请求来测试 API。例如,您应该找到有关以下内容的信息:
API 处理的输入数据,包括必填参数和可选参数。
API 接受的请求类型,包括支持的 HTTP 方法和媒体格式。
速率限制和身份验证机制。 -
API 文档
API 通常被记录下来,以便开发人员知道如何使用和集成它们。
文档可以采用人类可读和机器可读的形式。人类可读的文档旨在让开发人员了解如何使用 API。它可能包括详细的解释、示例和使用场景。机器可读文档旨在由软件处理,以自动执行 API 集成和验证等任务。它是以 JSON 或 XML 等结构化格式编写的。
API 文档通常是公开的,特别是当 API 旨在供外部开发人员使用时。如果是这种情况,请始终通过查看文档来开始您的侦察。
发现 API 文档
即使 API 文档未公开提供,您仍可以通过浏览使用 API 的应用程序来访问它。
为此,您可以使用 Burp Scanner 对 API 进行爬网。您还可以使用 Burp 的浏览器手动浏览应用程序。查找可能引用 API 文档的终结点,例如:
- /api
- /swagger/index.html
- /openapi.json
如果确定资源的终结点,请确保调查基本路径。例如,如果标识资源终结点,则应调查以下路径:/api/swagger/v1/users/123
- /api/swagger/v1
- /api/swagger
- /api
您还可以使用常用路径列表来查找使用 Intruder 的文档。
使用机器可读的文档
您可以使用一系列自动化工具来分析您找到的任何机器可读的 API 文档。
您可以使用 Burp Scanner 来抓取和审核 OpenAPI 文档,或 JSON 或 YAML 格式的任何其他文档。您还可以使用 OpenAPI 解析器 BApp 解析 OpenAPI 文档。
您还可以使用专用工具来测试记录的端点,例如 Postman 或 SoapUI。
-
实验室:使用文档利用 API 端点
要解决实验室问题,请找到公开的 API 文档并删除 .您可以使用以下凭据登录自己的帐户:。carloswiener:peter
所需知识
若要解决此实验,需要了解:- 什么是 API 文档。
API 文档是指应用程序编程接口(API)的详细说明和指导手册,包含了API的所有功能和参数的定义,以及如何使用API进行通信和交互的信息。API文档通常包括接口的URL、请求方法、参数、返回值等信息。
- API 文档如何对攻击者有用。
对攻击者来说,API文档可以提供有关API的详细信息和功能的描述,使他们能够更容易地理解和操纵API。攻击者可以利用API文档来找到漏洞或弱点,从而实施攻击,比如通过恶意输入来绕过验证、利用权限问题或者进行拒绝服务攻击等。
- 如何发现 API 文档。
1.查找官方文档:大多数API都会提供官方文档以供开发者参考,可以通过API提供商的官方网站或开发者中心找到相关文档。 2.使用API调试工具:一些API调试工具如Postman、Swagger等可以帮助查找和理解API文档。 3.探索API端点:使用工具如Burp Suite等来拦截和查看应用程序的API请求和响应,从中获取API的信息。
我们的 API 测试学院主题中介绍了这些要点。
- 1.在 Burp 的浏览器中,使用凭据登录应用程序并更新您的电子邮件地址。wiener:peter
- 2.在“代理> HTTP 历史记录”中,右键单击请求,然后选择“发送到转发器”。
PATCH /api/user/wiener
- 3.转到“中继器”选项卡。发送请求。请注意,这将检索用户的凭据。PATCH /api/user/wienerwiener
- 4.从请求的路径中删除,因此终端节点现在是 ,然后发送请求。请注意,这将返回错误,因为没有用户标识符。/wiener/api/user
- 5.从请求的路径中删除,因此终端节点现在是 ,然后发送请求。请注意,这将检索 API 文档。/user/api
- 6.右键单击响应,然后选择在浏览器中显示响应。复制 URL。
- 7.将 URL 粘贴到 Burp 的浏览器中以访问文档。请注意,文档是交互式的。
-
- 要删除 Carlos 并解决实验室问题,请单击该行,输入 ,然后单击发送请求。DELETEcarlos
实验步骤
首先登陆账户,并更改邮件地址
打开burp转到HTTP历史记录中查看记录,找到更新电子邮件地址时发送的请求,也就是PATCH /api/user/wiener然后将这个包发给重放器,这表明了如何通过API获取用户wiener的信息。
首先我们先从请求的路径中删除尾部的 /wiener,使端点变成 /api/user,然后再次发送请求。我们会得到一个错误响应,因为该请求没有包含必要的用户标识,进一步从路径中删除/user,使端点变成/api,然后再发送请求。这个请求的响应通常会包含API文档信息。
这里涉及到逐级取消,例如前面的文档里写道 如果这个为终结点/api/swagger/v1/users/123 就逐步测试 /api/swagger/v1 /api/swagger /api
再删除user,然后右键选择在浏览器中显示复制url在浏览器中直接访问即可。
找到API的地址
在浏览器中访问
最后点击DELETE,将Carlos输入进去
-
识别 API 端点
您还可以通过浏览使用 API 的应用程序来收集大量信息。即使您可以访问 API 文档,这通常也是值得的,因为有时文档可能不准确或过时。
您可以使用 Burp 扫描程序对应用程序进行爬网,然后使用 Burp 的浏览器手动调查有趣的攻击面。
浏览应用程序时,请查找在 URL 结构中建议 API 终结点的模式,例如 .还要注意 JavaScript 文件。这些可以包含对尚未通过 Web 浏览器直接触发的 API 终结点的引用。Burp Scanner 会在爬网期间自动提取某些端点,但要进行更重量级的提取,请使用 JS Link Finder BApp。您也可以在 Burp 中手动查看 JavaScript 文件。/api/
与 API 端点交互
确定 API 端点后,使用 Burp Repeater 和 Burp Intruder 与它们进行交互。这使你能够观察 API 的行为并发现其他攻击面。例如,您可以调查 API 如何响应更改 HTTP 方法和媒体类型。
在与 API 端点交互时,请仔细查看错误消息和其他响应。有时,这些信息包括可用于构造有效 HTTP 请求的信息。
识别支持的 HTTP 方法
HTTP 方法指定要对资源执行的操作。例如:
- GET- 从资源中检索数据。
- PATCH- 对资源应用部分更改。
- OPTIONS- 检索有关可用于资源的请求方法类型的信息。
API 端点可能支持不同的 HTTP 方法。因此,在调查 API 端点时,测试所有可能的方法非常重要。这可能使你能够识别其他终结点功能,从而打开更多的攻击面。
例如,终结点可能支持以下方法:/api/tasks
- GET /api/tasks- 检索任务列表。
- POST /api/tasks- 创建一个新任务。
- DELETE /api/tasks/1- 删除任务。
您可以使用 Burp Intruder 中的内置 HTTP 谓词列表自动循环访问一系列方法。
注意 测试不同的 HTTP 方法时,请以低优先级对象为目标。这有助于确保您避免意外后果,例如更改关键项目或创建过多的记录。
确定支持的内容类型
API 终结点通常需要特定格式的数据。因此,它们的行为可能会有所不同,具体取决于请求中提供的数据的内容类型。更改内容类型可能使您能够:
- 触发泄露有用信息的错误。
- 绕过有缺陷的防御。
- 利用处理逻辑的差异。例如,API 在处理 JSON 数据时可能是安全的,但在处理 XML 时容易受到注入攻击。
若要更改内容类型,请修改标头,然后相应地重新设置请求正文的格式。您可以使用内容类型转换器 BApp 在 XML 和 JSON 之间自动转换请求中提交的数据。Content-Type
使用入侵者查找隐藏的端点
确定一些初始 API 端点后,您可以使用 Intruder 发现隐藏的端点。例如,假设您已确定以下用于更新用户信息的 API 端点:
PUT /api/user/update
要识别隐藏的端点,您可以使用 Burp Intruder 查找具有相同结构的其他资源。例如,您可以使用其他常用函数(如 和 )的列表将有效负载添加到路径的位置。/updatedeleteadd
查找隐藏终结点时,请使用基于常见 API 命名约定和行业术语的单词列表。确保根据初始侦察,还包括与应用程序相关的术语。
-
实验室:查找和利用未使用的 API 终结点
要解决实验问题,请利用隐藏的 API 端点购买一件轻量级 l33t 皮夹克。您可以使用以下凭据登录自己的帐户:。wiener:peter
所需知识
若要解决此实验,需要了解:如何使用错误消息构造有效的请求。
RESTful API 如何使用 HTTP 方法。
更改 HTTP 方法如何显示其他功能。
API 测试学院主题中介绍了这些要点。1.在 Burp 的浏览器中,访问实验室并单击产品。
2.在 Proxy > HTTP history 中,请注意产品的 API 请求。例如。
/api/products/3/price
3.右键单击 API 请求,然后选择 Send to Repeater。
4.在“中继器”选项卡中,将 API 请求的 HTTP 方法从 更改为 ,然后发送请求。请注意,响应指定允许 and 方法。GETOPTIONSGETPATCH
5.将 API 请求的方法从 更改为 ,然后发送请求。请注意,您会收到一条消息。这可能表明您需要通过身份验证才能更新订单。GETPATCHUnauthorized
6.在 Burp 的浏览器中,使用凭据登录应用程序。wiener:peter
7.点击轻量级“l33t”皮夹克产品。
8.在“代理> HTTP 历史记录”中,右键单击皮夹克请求,然后选择“发送到中继器”。
API/products/1/price
9.在 Repeater 选项卡中,将 API 请求的方法从 更改为 ,然后发送请求。请注意,这会导致错误,因为不正确的 .错误消息指定应为 。
GETPATCHContent-TypeContent-Typeapplication/json
10.添加标头并将值设置为 。
Content-Typeapplication/json
11.添加一个空的 JSON 对象作为请求正文,然后发送请求。请注意,由于请求正文缺少参数,这会导致错误。{}price
12.将值为 的参数添加到 JSON 对象。发送请求。price0{"price":0}
13.在 Burp 的浏览器中,重新加载皮夹克产品页面。请注意,皮夹克的价格现在是 。$0.00
14.将皮夹克添加到您的购物篮中。
15.转到您的购物篮,然后单击“下订单”以解决实验问题。
实验步骤
http历史记录中找到get api 的语句,然后发到重放器,将get改成post,获得如下请求
这里要登录!!!!疯掉了
请求了无数次的成功!!!!!参考 把首部改成PATCH (PATCH /api/products/1/price HTTP/2),发包,得到相应包: {"type":"ClientError","code":400,"error":"Only 'application/json' Content-Type is supported"} 添加头Content-Type:application/json ,并在请求体添加俩花括号{} (json数据),发包,得到相应包: {"type":"ClientError","code":400,"error":"'price' parameter missing in body"} 在请求体添加 {"price":0} 改了夹克的价格,然后把夹克买了就行
-
查找隐藏参数
在执行 API 侦察时,您可能会发现 API 支持的未记录参数。您可以尝试使用这些来更改应用程序的行为。Burp 包含许多工具,可帮助您识别隐藏参数:
-
Burp Intruder 使您能够自动发现隐藏的参数,使用常用参数名称的单词列表来替换现有参数或添加新参数。请确保还包含与应用程序相关的名称,具体取决于您的初始侦察。
-
Param 矿工 BApp (The Param miner BApp)使您能够自动猜测每个请求多达 65,536 个参数名称。Param miner 根据从示波器中获取的信息自动猜测与应用程序相关的名称。
-
通过内容发现工具,您可以发现未与可浏览到的可见内容(包括参数)链接的内容。
批量分配漏洞
批量分配(也称为自动绑定)可能会无意中创建隐藏参数。当软件框架自动将请求参数绑定到内部对象上的字段时,就会发生这种情况。因此,批量赋值可能会导致应用程序支持开发人员从未打算处理的参数。
识别隐藏参数
由于批量赋值从对象字段创建参数,因此您通常可以通过手动检查 API 返回的对象来识别这些隐藏参数。
例如,考虑一个请求,该请求使用户能够更新其用户名和电子邮件,并包含以下JSON:
PATCH /api/users/ { "username": "wiener", "email": "wiener@example.com", }
并发请求返回以下 JSON:
GET /api/users/123 { "id": 123, "name": "John Doe", "email": "john@example.com", "isAdmin": "false" }
这可能表示隐藏的参数和参数与更新的用户名和电子邮件参数一起绑定到内部用户对象。idisAdmin
测试批量分配漏洞
若要测试是否可以修改枚举的参数值,请将其添加到请求中:isAdminPATCH
{ "username": "wiener", "email": "wiener@example.com", "isAdmin": false, }
此外,发送参数值无效的请求:PATCHisAdmin
{ "username": "wiener", "email": "wiener@example.com", "isAdmin": "foo", }
如果应用程序的行为不同,这可能表明无效值会影响查询逻辑,但有效值不会。这可能表示用户可以成功更新参数。
然后,您可以发送参数值设置为 的请求,以尝试利用此漏洞:PATCHisAdmintrue
{ "username": "wiener", "email": "wiener@example.com", "isAdmin": true, }
如果请求中的值在未进行充分验证和清理的情况下绑定到用户对象,则可能会错误地向用户授予管理员权限。要确定是否是这种情况,请浏览应用程序以查看您是否可以访问管理功能。isAdminwienerwiener
-
-
BP第一个扩展,param Miner
这个扩展识别隐藏的,未链接的参数。它对于查找web缓存中毒漏洞特别有用,并且需要Burp Suite v2021.9或更高版本。
它结合了先进的区别逻辑从反斜杠供电扫描器与二进制搜索技术,猜测多达65,536个参数名称,每个请求。参数名来自一个精心策划的内置单词列表,它还从所有范围内的流量中获取额外的单词。
要使用它,右键单击Burp中的请求,然后单击“Guess (cookies|headers|params)”。如果您使用的是Burp Suite Pro,则确定的参数将作为扫描仪问题报告。如果没有,您可以在Extender->Extensions->Param Miner->Output下找到它们
您还可以同时对多个选定的请求发起猜测攻击——这将使用线程池,因此如果您愿意,您可以安全地在数千个请求上使用它。或者,您可以启用范围内所有流量的自动挖掘。请注意,此工具被设计为具有高度可伸缩性,但可能需要调优以避免性能问题。 -
此处补充关于http的学习
1.关于http的请求报文,如下图所示
2.请求方法具体如图所示
3.协议版本的相关说明:
HTTP/1.0
HTTP/1.0 定义了以下三种请求方法:
- GET - 请求指定的资源。
- POST - 提交数据以处理请求。
- HEAD - 请求资源的响应头信息。
HTTP/1.1
HTTP/1.1 引入了更多的方法:
- GET - 请求指定的资源。
- POST - 提交数据以处理请求。
- HEAD - 请求资源的响应头信息。
- PUT - 上传文件或者更新资源。
- DELETE - 删除指定的资源。
- OPTIONS - 请求获取服务器支持的请求方法。
- TRACE - 回显服务器收到的请求,主要用于诊断。
- CONNECT - 建立一个隧道用于代理服务器的通信,通常用于 HTTPS。
HTTP/2
HTTP/2 基本上沿用了 HTTP/1.1 的方法,但对协议进行了优化,提高了传输效率和速度。HTTP/2 也引入了新的特性,如多路复用、头部压缩和服务器推送等。
HTTP/3
HTTP/3 基于 QUIC 协议实现,继续使用 HTTP/2 的方法。HTTP/3 主要改进了传输层,使用 UDP 代替 TCP 以提高传输速度和可靠性。
4.HTTP 响应头信息
具体HTTP图如图所示
5.HTTP状态码
HTTP 状态码的英文为 HTTP Status Code。
下面是常见的 HTTP 状态码:
- 1xx(信息性状态码):表示接收的请求正在处理。
- 2xx(成功状态码):表示请求正常处理完毕。
- 3xx(重定向状态码):需要后续操作才能完成这一请求。
- 4xx(客户端错误状态码):表示请求包含语法错误或无法完成。
- 5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误。
6.状态码的分类
HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):
1xx(信息性状态码):表示接收的请求正在处理。
2xx(成功状态码):表示请求正常处理完毕。
3xx(重定向状态码):需要后续操作才能完成这一请求。
4xx(客户端错误状态码):表示请求包含语法错误或无法完成。
5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误。
6.HTTP content-type
语法 Content-Type: text/html; charset=utf-8 Content-Type: multipart/form-data; boundary=something
Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些 PHP 网页点击的结果却是下载一个文件或一张图片的原因。
常见的媒体格式类型如下:
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
以application开头的媒体格式类型:
- application/xhtml+xml :XHTML格式
- application/xml: XML数据格式
- application/atom+xml :Atom XML聚合格式
- application/json: JSON数据格式
- application/pdf:pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如常见的文件下载)
- application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
- multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
7.MIME 类型 (Multipurpose Internet Mail Extensions)
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL,因此 We b服务器在响应头中添加正确的 MIME 类型非常重要。如果配置不正确,浏览器可能会无法解析文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。
语法: type/subtype
MIME 的组成结构非常简单,由类型与子类型两个字符串中间用 / 分隔而组成,不允许有空格。type 表示可以被分多个子类的独立类别,subtype 表示细分后的每个类型。
MIME类型对大小写不敏感,但是传统写法都是小写。
两种主要的 MIME 类型在默认类型中扮演了重要的角色:
- text/plain 表示文本文件的默认值。
- application/octet-stream 表示所有其他情况的默认值。
常见的 MIME 类型
- 超文本标记语言文本 .html、.html:text/html
- 普通文本 .txt: text/plain
- RTF 文本 .rtf: application/rtf
- GIF 图形 .gif: image/gif
- JPEG 图形 .jpeg、.jpg: image/jpeg
- au 声音文件 .au: audio/basic
- MIDI 音乐文件 mid、.midi: audio/midi、audio/x-midi
- RealAudio 音乐文件 .ra、.ram: audio/x-pn-realaudio
- MPEG 文件 .mpg、.mpeg: video/mpeg
- AVI 文件 .avi: video/x-msvideo
- GZIP 文件 .gz: application/x-gzip
- TAR 文件 .tar: application/x-tar
-
实验室:利用批量分配漏洞
要解决实验室问题,请查找并利用大量分配漏洞来购买轻量级 l33t 皮夹克。您可以使用以下凭据登录自己的帐户:。wiener:peter
所需知识
若要解决此实验,需要了解:
-
什么是质量分配。
-
为什么质量分配可能会导致隐藏参数。
-
如何识别隐藏参数。
-
如何利用批量分配漏洞。
我们的 API 测试学院主题中介绍了这些要点。 -
1.在 Burp 的浏览器中,使用凭据登录应用程序。wiener:peter
-
2.点击轻量级“l33t”皮夹克产品并将其添加到您的购物车。
-
3.转到您的购物篮,然后点击下单。请注意,您没有足够的信用额度进行购买。
-
4.在 Proxy > HTTP history 中,请注意 和 API 请求。
GETPOST/api/checkout
- 5.请注意,对请求的响应包含与请求相同的 JSON 结构。请注意,响应中的 JSON 结构包含请求中不存在的参数。GETPOSTGETchosen_discountPOST
- 6.右键单击请求,然后选择“发送到中继器”。POST /api/checkout
- 7.在 Repeater 中,将参数添加到请求中。JSON 应如下所示:The JSON should look like the following:
chosen_discount { "chosen_discount":{ "percentage":0 }, "chosen_products":[ { "product_id":"1", "quantity":1 } ] }
- 8.发送请求。请注意,添加参数不会导致错误。chosen_discount
- 9.将值更改为字符串,然后发送请求。请注意,这会导致错误消息,因为参数值不是数字。这可能表示正在处理用户输入。
chosen_discount"x"
- 10.将百分比更改为 ,然后发送求解实验室的请求。
chosen_discount100
实验步骤
首先登陆自己的账号,然后在购买页面购买一件夹克衫,随后回到抓包,找到API的请求,然后看响应报文有一个"chosen_discount":{ "percentage":0 },
发现了一个percentage参数,这个参数代表折扣
在购物车点place order按钮(支付按钮)并拦截包,再报文后面增加折扣,然后比例写100,这样我们就成功绕过如下图所示,渗透完成
-
-
防止 API 中的漏洞
在设计 API 时,请确保从一开始就考虑安全性。特别是,请确保您:
- 如果您不希望公开访问 API,请保护您的文档。
- 确保您的文档保持最新状态,以便合法测试人员能够全面了解 API 的攻击 表面。
- 应用允许的 HTTP 方法的允许列表。
- 验证每个请求或响应的内容类型是否为预期。
- 使用通用错误消息来避免泄露可能对攻击者有用的信息。
- 对 API 的所有版本(而不仅仅是当前生产版本)使用保护措施。
若要防止批量分配漏洞,请将用户可更新的属性列入允许列表,并将用户不应更新的敏感属性列入黑名单。
服务器端参数污染
某些系统包含无法从 Internet 直接访问的内部 API。当网站在没有充分编码的情况下将用户输入嵌入到对内部 API 的服务器端请求中时,就会发生服务器端参数污染。这意味着攻击者可能能够操纵或注入参数,从而使他们能够,例如:
- 覆盖现有参数。
- 修改应用程序行为。
- 访问未经授权的数据。
您可以测试任何用户输入的任何类型的参数污染。例如,查询参数、表单字段、标头和 URL 路径参数都可能容易受到攻击。
注意 此漏洞有时称为 HTTP 参数污染。但是,此术语也用于指 Web 应用程序防火墙 (WAF) 绕过技术。为避免混淆,在本主题中,我们将仅提及服务器端参数污染。 此外,尽管名称相似,但此漏洞类与服务器端几乎没有共同之处 原型污染。
测试查询字符串中的服务器端参数污染
若要测试查询字符串中的服务器端参数污染,请在输入中放置查询语法字符(如 #、& 和= ),并观察应用程序的响应方式。
考虑一个易受攻击的应用程序,它使您能够根据其他用户的用户名搜索其他用户。当您搜索用户时,您的浏览器会发出以下请求:
GET /userSearch?name=peter&back=/home
为了检索用户信息,服务器使用以下请求查询内部 API:
GET /users/search?name=peter&publicProfile=true
截断查询字符串
您可以使用 URL 编码的字符来尝试截断服务器端请求。为了帮助您解释响应,您还可以在字符后添加一个字符串。##
例如,可以将查询字符串修改为以下内容:
GET /userSearch?name=peter%23foo&back=/home
前端将尝试访问以下 URL:
GET /users/search?name=peter#foo&publicProfile=true
注意 对字符进行 URL 编码至关重要。否则,前端应用程序会将其解释为片段标识符,并且不会将其传递给内部 API。#
查看响应,以获取有关查询是否已被截断的线索。例如,如果响应返回 user ,则服务器端查询可能已被截断。如果返回错误消息,则应用程序可能已被视为用户名的一部分。这表明服务器端请求可能尚未被截断。peterInvalid namefoo
如果能够截断服务器端请求,则无需将字段设置为 true。您可以利用此漏洞返回非公开用户配置文件。publicProfile
注入无效参数
您可以使用 URL 编码字符尝试向服务器端请求添加第二个参数。&
例如,可以将查询字符串修改为以下内容:
GET /userSearch?name=peter%26foo=xyz&back=/home
这会导致对内部 API 发出以下服务器端请求:
GET /users/search?name=peter&foo=xyz&publicProfile=true
查看响应,以获取有关如何分析其他参数的线索。例如,如果响应未更改,这可能表示该参数已成功注入,但被应用程序忽略。
为了建立更完整的画面,您需要进一步测试。
注入有效参数
如果能够修改查询字符串,则可以尝试向服务器端请求添加第二个有效参数。
相关页面
有关如何识别可注入查询字符串的参数的信息,请参阅查找隐藏 parameters 部分。例如,如果已标识该参数,则可以将其添加到查询字符串中,如下所示:email
GET /userSearch?name=peter%26email=foo&back=/home
这会导致对内部 API 发出以下服务器端请求:
GET /users/search?name=peter&email=foo&publicProfile=true
查看响应,以获取有关如何分析其他参数的线索。
覆盖现有参数
若要确认应用程序是否容易受到服务器端参数污染的影响,可以尝试覆盖原始参数。为此,请注入具有相同名称的第二个参数。
例如,可以将查询字符串修改为以下内容:
GET /userSearch?name=peter%26name=carlos&back=/home
这会导致对内部 API 发出以下服务器端请求:
GET /users/search?name=peter&name=carlos&publicProfile=true
内部 API 解释两个参数。其影响取决于应用程序如何处理第二个参数。这在不同的 Web 技术中有所不同。例如:name
PHP 只解析最后一个参数。这将导致用户搜索 .carlos
ASP.NET 结合了这两个参数。这将导致用户搜索 ,这可能会导致错误消息。peter,carlosInvalid username
Node.js / express 仅解析第一个参数。这将导致用户搜索 ,给出不变的结果。peter
如果您能够覆盖原始参数,则可以进行攻击。例如,您可以添加到请求中。这可能使您能够以管理员用户身份登录。name=administrator -
实验室:利用查询字符串中的服务器端参数污染
Lab: Exploiting server-side parameter pollution in a query string要解决实验室问题,请以 并删除 。administratorcarlos
To solve the lab, log in as the administrator and delete carlos.- 如何使用 URL 查询语法尝试更改服务器端请求。
- 如何使用错误消息来了解服务器端 API 如何处理用户输入。
- 这些要点在我们的 API 测试学院主题中进行了介绍。
实验步骤:
首先,我们点击忘记密码,然后账号输入administrator,就会出现如下图所示图片(On the site, there is a Forgot password functionality. Let’s use this for the administrator account:)
然后打开bp打开拦截页面,找到/forgot-password:(If we check Burp Proxy’s HTTP history, there is a POST request to /forgot-password:)
我们将这个报文发给重发器,修改username,发现会回应一个404的报文(We can start playing around with the request’s parameters and examine its responses. For example, we can change username’s value:)
当发现修改后缀后续为%26的时候,发现回应报文是一个Parameter is not supported的回应报文(不支持参数),然后修改参数(We got an Invalid username error message, so let’s try something else, such as adding a second parameter using a URL-encoded &:)
这里步骤并不是很了解,先记录下来(This time we got a Parameter is not supported error message. This suggests that the internal API may have interpreted &x=y as a separate parameter, instead of part of the username. We can also try to truncate the request using a URL-encoded #:)
现在收到了一个特殊的回应报文,该消息表明服务器端查询可能包含一个名为 field 的附加参数,该参数已被 # 字符删除(We now got a Field not specified error message, which indicates that the server-side query may include an additional parameter called field, which has been removed by the # character. We can try and add field back:)
现在我们尝试换这个特殊的字符,发给攻击者,把这个字符进行爆破(The Invalid field error message suggests that the server-side request app may recognize the injected field parameter. We now need to brute-force its value:)
在Intruder>Payloads中,单击Add from list。选择内置的Server-side variable names有效负载列表,然后启动攻击。
当我们攻击完成后,可以看到,email和username是可以收到200的回应的(We notice that both the username and email strings seem to be valid values for the field parameter based on the response status code, i.e. 200:)
我们可以在http历史记录中找到这个记录(In Proxy’s HTTP history there is a JavaScript file containing an endpoint with the parameter reset_token:)
(If we change the value of the field parameter to reset_token we will see that the response includes a password reset token:)
在Burp的浏览器中,在地址栏中输入密码重置端点。添加您的密码重置令牌作为 reset_token 参数的值。(If we use the reset_token endpoint and pass as its value the token we just got, we will be able to change administrator’s password)/forgot-password?reset_token=获取的值
修改登录,删除
-
测试 REST 路径中的服务器端参数污染
(Testing for server-side parameter pollution in REST paths)RESTful API 可能会将参数名称和值放在 URL 路径中,而不是放在查询字符串中。例如,请考虑以下路径:
(A RESTful API may place parameter names and values in the URL path, rather than the query string. For example, consider the following path:)/api/users/123
URL 路径可能按如下方式细分:(The URL path might be broken down as follows:)
- /api是根 API 端点。(api is the root API endpoint.)
- /users在本例中表示资源。users(users represents a resource, in this case users.)
- /123表示一个参数,这里是特定用户的标识符。(123represents a parameter, here an identifier for the specific user.)
考虑一个应用程序,它使您能够根据用户的用户名编辑用户配置文件。请求将发送到以下终结点:(Consider an application that enables you to edit user profiles based on their username. Requests are sent to the following endpoint:)
GET /edit_profile.php?name=peter
这将导致以下服务器端请求:(This results in the following server-side request:)
GET /api/private/users/peter
攻击者可能能够操纵服务器端 URL 路径参数来利用 API。若要测试此漏洞,请添加路径遍历序列以修改参数并观察应用程序的响应方式。
(An attacker may be able to manipulate server-side URL path parameters to exploit the API. To test for this vulnerability, add path traversal sequences to modify parameters and observe how the application responds.)您可以提交 URL 编码作为参数的值:peter/../adminname
(You could submit URL-encoded peter/../admin as the value of the name parameter:)GET /edit_profile.php?name=peter%2f..%2fadmin
这可能会导致以下服务器端请求:
(This may result in the following server-side request:)GET /api/private/users/peter/../admin
如果服务器端客户端或后端 API 对此路径进行规范化,则可能会将其解析为 /api/private/users/admin。
(If the server-side client or back-end API normalize this path, it may be resolved to /api/private/users/admin.)测试结构化数据格式中的服务器端参数污染
Testing for server-side parameter pollution in structured data formats攻击者可能能够操纵参数,以利用服务器处理其他结构化数据格式(如 JSON 或 XML)时的漏洞。为了测试这一点,将意外的结构化数据注入到用户输入中,并查看服务器如何响应。
(An attacker may be able to manipulate parameters to exploit vulnerabilities in the server's processing of other structured data formats, such as a JSON or XML. To test for this, inject unexpected structured data into user inputs and see how the server responds.)考虑一个应用程序,该应用程序使用户能够编辑其配置文件,然后将他们的更改与请求一起应用于服务器端 API。当您编辑姓名时,您的浏览器会发出以下请求:
(Consider an application that enables users to edit their profile, then applies their changes with a request to a server-side API. When you edit your name, your browser makes the following request:)POST /myaccount name=peter
这将导致以下服务器端请求:
(This results in the following server-side request:)PATCH /users/7312/update {"name":"peter"}
您可以尝试将参数access_level添加到请求中,如下所示:
(You can attempt to add the access_level parameter to the request as follows:)POST /myaccount name=peter","access_level":"administrator
如果在未进行充分验证或审查的情况下将用户输入添加到服务器端 JSON 数据中,则会导致以下服务器端请求:
(If the user input is added to the server-side JSON data without adequate validation or sanitization, this results in the following server-side request:)
PATCH /users/7312/update {name="peter","access_level":"administrator"}
这可能会导致用户peter被授予管理员访问权限。
(This may result in the user peter being given administrator access.)相关页面 有关如何识别可以注入到查询字符串中的参数的信息,请参阅查找隐藏的参数 parameters 部分。 Related pages For information on how to identify parameters that you can inject into the query string, see the Finding hidden parameters section.
考虑一个类似的示例,但客户端用户输入是 JSON 数据。当您编辑姓名时,您的浏览器会发出以下请求:
(Consider a similar example, but where the client-side user input is in JSON data. When you edit your name, your browser makes the following request:)POST /myaccount {"name": "peter"}
这将导致以下服务器端请求:
(This results in the following server-side request:)PATCH /users/7312/update {"name":"peter"}
您可以尝试将参数access_level添加到请求中,如下所示:
(You can attempt to add the access_level parameter to the request as follows:)POST /myaccount {"name": "peter\",\"access_level\":\"administrator"}
如果用户输入被解码,然后在没有适当编码的情况下添加到服务器端 JSON 数据中,则会导致以下服务器端请求:
(If the user input is decoded, then added to the server-side JSON data without adequate encoding, this results in the following server-side request:)PATCH /users/7312/update {"name":"peter","access_level":"administrator"}
同样,这可能会导致用户peter被授予管理员访问权限。
(Again, this may result in the user peter being given administrator access.)结构化格式注入也可能发生在响应中。例如,如果用户输入安全地存储在数据库中,然后嵌入到来自后端 API 的 JSON 响应中,而没有进行足够的编码,则可能会发生这种情况。通常,您可以像在请求中一样检测和利用响应中的结构化格式注入。
(Structured format injection can also occur in responses. For example, this can occur if user input is stored securely in a database, then embedded into a JSON response from a back-end API without adequate encoding. You can usually detect and exploit structured format injection in responses in the same way you can in requests.)Note This example below is in JSON, but server-side parameter pollution can occur in any structured data format. For an example in XML, see the XInclude attacks section in the XML external entity (XXE) injection topic. 注意 下面的示例是 JSON 格式,但服务器端参数污染可能以任何结构化数据格式发生。有关 XML 中的示例,请参阅 XML 外部实体 (XXE) 注入主题中的 XInclude 攻击部分。
使用自动化工具进行测试
Testing with automated toolsBurp 包含自动化工具,可以帮助您检测服务器端参数污染漏洞。
(Burp includes automated tools that can help you detect server-side parameter pollution vulnerabilities.)Burp Scanner 在执行审计时会自动检测可疑的输入转换。当应用程序接收到用户输入,以某种方式转换它,然后对结果执行进一步处理时,就会发生这种情况。此行为不一定构成漏洞,因此您需要使用上述手动技术进行进一步测试。有关详细信息,请参阅可疑 输入转换问题定义。
(Burp Scanner automatically detects suspicious input transformations when performing an audit. These occur when an application receives user input, transforms it in some way, then performs further processing on the result. This behavior doesn't necessarily constitute a vulnerability, so you'll need to do further testing using the manual techniques outlined above. For more information, see the Suspicious input transformation issue definition.)您还可以使用 Backslash Powered Scanner BApp 来识别服务器端注入漏洞。扫描器将输入分类为无聊、有趣或易受攻击。您需要使用上述手动技术来调查有趣的输入。有关详细信息,请参阅反斜杠 《Powered Scanning: Hunting unknown vulnerability classes》白皮书。
(You can also use the Backslash Powered Scanner BApp to identify server-side injection vulnerabilities. The scanner classifies inputs as boring, interesting, or vulnerable. You'll need to investigate interesting inputs using the manual techniques outlined above. For more information, see the Backslash Powered Scanning: hunting unknown vulnerability classes whitepaper.)防止服务器端参数污染
Preventing server-side parameter pollution为防止服务器端参数污染,请使用允许列表来定义不需要编码的字符,并确保所有其他用户输入在包含在服务器端请求中之前都已编码。您还应该确保所有输入都遵循预期的格式和结构。
(To prevent server-side parameter pollution, use an allowlist to define characters that don't need encoding, and make sure all other user input is encoded before it's included in a server-side request. You should also make sure that all input adheres to the expected format and structure.)