THM-Burp Suite Intruder

作者:xiaowu 日期: 分类:xiaowu 浏览:638

什么是Intruder?

Intruder是Burp Suite的内置模糊测试工具,它允许我们自动化执行请求,这在模糊测试或者暴力破解攻击中非常有用。

Intruder可以接受一个请求(通常是Burp Proxy先捕获到请求再转发至Intruder中),并能使用这个请求作为模版 来自动向目标服务器发送大量具有细微差别的请求。例如,通过捕获包含登录尝试的请求,我们可以配置Intruder将用户名和密码字段替换为字典中的值,从而能够允许我们对登录表单进行暴力破解攻击;类似地,我们也可以导入模糊测试字典,并结合Intruder对子目录、端点或虚拟主机进行模糊测试,此功能非常类似于Wfuzz或Ffuf等命令行工具所提供的功能。

简而言之,作为一种自动化请求的方式,Intruder是非常强大的,但是还有一个问题:如果要不限速率地使用Intruder,我们必须需要Burp Suite专业版。当我们在Burp Suite社区版中使用Intruder时,它会受到一定的速率限制,而这种速度限制可能会让 许多渗透测试人员选择使用其他工具来进行模糊测试和暴力破解攻击。

让我们查看一下Intruder的界面:

image.png

我们能够看到的第一个子选项卡是Target,此处允许我们选择攻击目标。(在较新版本的Burp中Intruder没有Target子选项卡)

如果我们从Burp Proxy处发送一个请求到Intruder中(使用Ctrl + I或者右键单击请求并选择“发送给Intruder”),那么此时Target子选项卡应该已经被填充好了字段。

除了Target选项卡(在较新版本的Burp中Intruder没有Target子选项卡)之外,在Intruder中还有四个子选项卡:

  • Positions :这个子选项卡允许我们选择攻击类型,并且能够配置我们希望在请求模板中插入有效载荷(Payload)的位置。

  • Payloads :这个子选项卡允许我们选择将payload(有效载荷)插入到我们在前一个子选项卡中定义的每个位置,例如我们可以选择从字典中加载项目作为有效载荷,至于如何将有效载荷插入到请求模板中,则取决于我们在Positions子选项卡中所选择的攻击类型;有许多有效载荷类型可供我们选择(从简单的字典到基于服务器响应的正则表达式),有效载荷子标签也允许我们改变攻击器(Intruder)的行为与有效载荷,例如,我们可以定义一些预处理规则以应用于每个有效载荷,这些预处理规则包括——添加前缀或后缀,进行匹配和替换,或者当有效载荷匹配到已定义的正则表达式则跳过等等。

  • Resource Pool:这个子选项卡主要允许我们在任务之间分配资源,这对于Burp社区版而言并不是特别有用;Burp Suite专业版允许我们在Burp后台运行各种类型的自动化任务,而Resource Pool就是我们希望在这些自动化任务和Intruder之间手动分配可用内存和计算机处理能力的地方;如果我们不能访问后台自动化的任务,则使用Resource Pool就没有什么意义(本文所使用的是Burp社区版,所以并不能访问后台自动化任务)。

  • Options:Intruder允许我们在Options子选项卡中配置攻击行为,这里的设置主要应用于Burp如何处理结果以及Burp如何处理攻击本身;例如,我们可以选择标记包含指定文本片段的请求,或者定义Burp如何处理重定向(3xx)响应。

tips:模糊测试是指我们取一组数据并将其应用于一个参数,从而测试目标功能或者查看是否存在某些东西;例如,我们可以在web应用程序中选择进行“端点模糊测试”,这会将字典中的每个项目添加到请求消息的末尾并进行多次发送,然后查看web服务器会如何响应(例如http://MACHINE_IP/WORD_GOES_HERE)。

Positions

当使用Burp Suite Intruder 执行攻击时,第一步是检查请求中我们想要插入有效负载的位置。这些位置告知 Intruder 我们的有效负载将被引入的位置(我们将在接下来的任务中探索)。

让我们导航到“职位”选项卡:

显示职位选项卡

请注意,Burp Suite会自动尝试识别最有可能插入有效负载的位置。这些位置以绿色突出显示,并用剖面标记 ( §) 括起来。

在界面的右侧,我们找到以下按钮:Add §Clear §Auto §

  • Add §按钮允许我们通过在请求编辑器中突出显示新位置然后单击该按钮来手动定义新位置。

  • Clear §按钮会删除所有已定义的位置,从而提供一个空白画布,我们可以在其中定义自己的位置。

  • Auto §按钮会根据请求自动尝试识别最有可能的位置。如果我们之前清除了默认位置并希望将其恢复,则此功能非常有用。

下面的GIF演示了添加、清除和自动重新选择仓位的过程:

添加、清除、自动重选仓位的流程

PayLoad


Burp Suite Intruder 的“有效负载”选项卡中,我们可以为攻击创建、分配和配置有效负载。该子选项卡分为四个部分:

Payloads 子选项卡分为四个部分

  1. 有效负载集

    • 此部分允许我们选择要配置有效负载集的位置,并选择要使用的有效负载类型。

    • 当使用仅允许单个有效负载集(狙击手或攻城锤)的攻击类型时,“有效负载集”下拉列表将只有一个选项,无论定义的位置数量如何。

    • 如果我们使用需要多个有效负载集的攻击类型(干草叉或集束炸弹),则每个位置的下拉列表中都会有一个项目。

    • 注意:在“有效负载集”下拉列表中为多个职位分配编号时,请遵循从上到下、从左到右的顺序。例如,对于两个位置 ( username=§pentester§&password=§Expl01ted§),有效负载集下拉列表中的第一项将引用用户名字段,第二项将引用密码字段。


  2. 有效负载设置

    • 本部分提供特定于当前负载集所选负载类型的选项。

    • 例如,当使用“简单列表”有效负载类型时,我们可以使用添加文本框、粘贴行或从文件加载有效负载手动向集合添加或删除有效负载。“删除”按钮可删除当前选定的行,“清除”按钮可清除整个列表。加载巨大的列表时要小心,因为它可能会导致 Burp 崩溃。

    • 每种有效负载类型都有自己的一组选项和功能。探索可用的选项以了解可能性的范围。

      可用选项

  3. 有效负载处理

    • 在本节中,我们可以定义在将负载发送到目标之前应用于集合中的每个负载的规则。

    • 例如,我们可以将每个单词大写,跳过与正则表达式模式匹配的有效负载,或者应用其他转换或过滤。

    • 虽然您可能不会经常使用此部分,但当您的攻击需要特定的有效负载处理时,它可能非常有价值。


  4. 有效负载编码

    • 该部分允许我们自定义有效负载的编码选项。

    • 默认情况下,Burp Suite应用 URL 编码来确保有效负载的安全传输。然而,在某些情况下我们可能想要调整编码行为。

    • 我们可以通过修改要编码的字符列表或取消选中“对这些字符进行 URL 编码”复选框来覆盖默认的 URL 编码选项。

Sniper


Sniper攻击类型是 Burp Suite Intruder 中默认且最常用的攻击类型。它对于单位置攻击特别有效,例如密码暴力破解或API端点模糊测试。在 Sniper 攻击中,我们提供一组有效负载,可以是单词列表或一系列数字,入侵者将每个有效负载插入到请求中的每个定义位置。

让我们参考之前的示例模板:

职位示例
POST /support/login/ HTTP /1.1主机:10.10.42.188用户代理:Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0接受:text/html,application/xhtml+xml ,application/xml;q=0.9,image/webp,*/*;q=0.8接受语言: en-US,en;q=0.5 接受编码: gzip, deflate内容类型: application/x-www- form-urlencoded内容长度:37来源:http:// 10.10.42.188连接:close Referer:http:// 10.10.42.188 /support/login/ Upgrade-Insecure-Requests:1用户名= §pentester§ &password= §Expl01ted §              

在此示例中,我们为 usernamepasswordbody 参数定义了两个位置。在狙击手攻击中,入侵者从有效负载集中取出每个有效负载,并将其依次替换到每个定义的位置。

假设我们有一个包含三个单词的单词列表:burp、 suite、 和intruder,Intruder 将生成六个请求:

申请号码请求正文
1username=burp&password=Expl01ted
2username=suite&password=Expl01ted
3username=intruder&password=Expl01ted
4username=pentester&password=burp
5username=pentester&password=suite
6username=pentester&password=intruder

观察 Intruder 如何从第一个位置 ( username) 开始并将每个有效负载替换到其中,然后移动到第二个位置 ( password) 并用有效负载执行相同的替换。入侵者狙击手发出的请求总数可以计算为 requests = numberOfWords * numberOfPositions

当我们想要执行单位置攻击测试并为每个位置使用不同的有效负载时,狙击手攻击类型非常有用。它可以对不同的有效载荷变化进行精确的测试和分析。

Battering Ram


Burp Suite Intruder 中的Battering ram攻击类型与Sniper 的不同之处在于,它同时将相同的有效负载放置在每个位置,而不是依次将每个有效负载替换到每个位置。

让我们回顾一下之前的示例模板:

职位示例
POST /support/login/ HTTP /1.1
   主机:10.10.42.188
   用户代理:Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
   接受:text/html,application/xhtml+xml ,application/xml;q=0.9,image/webp,*/*;q=0.8
   接受语言: en-US,en;q=0.5 接受编码
   : gzip, deflate
   内容类型: application/x-www- form-urlencoded
   内容长度:37
   来源:http:// 10.10.42.188
   连接:close
   Referer:http:// 10.10.42.188 /support/login/
   Upgrade-Insecure-Requests:1
   
   用户名= §pentester§ &password= §Expl01ted §              

burp使用与之前相同的单词列表( 、suite和 )的攻城槌攻击类型intruder,入侵者将生成三个请求:

申请号码请求正文
1username=burp&password=burp
2username=suite&password=suite
3username=intruder&password=intruder

如表中所示,单词列表中的每个有效负载都会插入到每个请求的每个位置。在攻城锤攻击中,相同的有效负载同时被扔到每个定义的位置,提供了一种类似暴力的测试方法。

当我们想要同时针对多个位置测试相同的有效负载而不需要顺序替换时,攻城锤攻击类型非常有

Pitchfork


Burp Suite Intruder中的Pitchfork攻击类型类似于同时运行多个 Sniper 攻击。 Sniper 使用一组有效负载同时测试所有位置,而 Pitchfork 每个位置使用一组有效负载(最多 20 个)并同时迭代所有位置。

为了更好地理解 Pitchfork,让我们回顾一下我们的暴力破解示例,但这次使用两个单词列表:

  1. 第一个单词列表包含用户名:joel、 harrietalex

  2. 第二个单词列表包含密码:J03l、 Emma1815Sk1ll

我们可以使用这两个列表对登录表单执行 Pitchfork 攻击。攻击期间发出的每个请求如下所示:

申请号码请求正文
1username=joel&password=J03l
2username=harriet&password=Emma1815
3username=alex&password=Sk1ll

如表中所示,Pitchfork 从每个列表中取出第一项,并将其替换到请求中,每个位置一个。然后,它通过从每个列表中取出第二项并将其替换到模板中,对下一个请求重复此过程。 Intruder 继续此迭代,直到一个或所有列表用完项目。值得注意的是,一旦其中一个列表完成,Intruder 就会停止测试。因此,在 Pitchfork 攻击中,有效负载集具有相同的长度是理想的。如果有效负载集的长度不同,入侵者只会发出请求,直到较短的列表耗尽,而较长列表中的剩余项目将不会被测试。

当进行凭证填充攻击或多个位置需要单独的有效负载集时,干草叉攻击类型特别有用。它允许同时测试具有不同有效负载的多个位置。

Cluster Bomb


Burp Suite Intruder 中的集束炸弹攻击类型允许我们选择多个有效负载集,每个位置一个(最多 20 个)。与同时测试所有有效载荷集的 Pitchfork 不同,集束炸弹单独迭代每个有效载荷集,确保测试每个可能的有效载荷组合。

为了说明集束炸弹攻击类型,让我们使用与之前相同的单词列表:

  • 用户名:joelharriet、 和 alex

  • 密码:J03lEmma1815和 Sk1ll

在此示例中,假设我们不知道哪个密码属于哪个用户。我们有三个用户和三个密码,但映射未知。在这种情况下,我们可以使用集束炸弹攻击来尝试每种值的组合。我们的用户名和密码位置的请求表如下所示:

申请号码请求正文
1username=joel&password=J03l
2username=harriet&password=J03l
3username=alex&password=J03l
4username=joel&password=Emma1815
5username=harriet&password=Emma1815
6username=alex&password=Emma1815
7username=joel&password=Sk1ll
8username=harriet&password=Sk1ll
9username=alex&password=Sk1ll

如表所示,集束炸弹攻击类型会迭代所提供的有效负载集的每种组合。它通过将每个有效负载集中的每个值替换到请求中的相应位置来测试每种可能性。

集束炸弹攻击在测试每种组合时会产生大量流量。集束炸弹攻击发出的请求数可以通过将每个有效负载集中的行数相乘来计算。使用这种攻击类型时一定要小心谨慎,尤其是在处理大型有效负载集时。此外,当使用 Burp Community 及其入侵者速率限制时,使用中等大小的有效负载集执行集束炸弹攻击可能需要更长的时间。

集群炸弹攻击类型对于用户名和密码之间的映射未知的凭证暴力破解场景特别有用。

攻击类型简介


  1. 狙击手:狙击手攻击类型是默认且最常用的选项。它循环遍历有效负载,一次将一个有效负载插入到请求中定义的每个位置。狙击攻击以线性方式迭代所有有效负载,从而实现精确且集中的测试。

  2. 攻城锤:攻城锤攻击类型与狙击手不同,它同时发送所有有效负载,每个有效负载插入其各自的位置。当测试竞争条件或需要同时发送有效负载时,这种攻击类型非常有用。

  3. Pitchfork:Pitchfork 攻击类型可以同时测试具有不同负载的多个位置。它允许测试人员定义多个有效负载集,每个有效负载集与请求中的特定位置相关联。当存在需要单独测试的不同参数时,干草叉攻击是有效的。

  4. 集束炸弹:集束炸弹攻击类型结合了狙击手和干草叉方法。它对每个位置执行类似狙击手的攻击,但同时测试每组的所有有效载荷。当多个位置具有不同的有效负载并且我们希望一起测试它们时,这种攻击类型非常有用。

实际例子


为了将我们的理论知识付诸实践,我们将尝试访问位于 的支持门户http://10.10.42.188/support/login。该门户遵循典型的登录结构,通过检查其源代码,我们发现没有实施任何保护措施:

支持登录表单源代码
---<form method="POST">
   <div class="form-floating mb-3">
       <input class="form-control" type="text" name=username  placeholder="Username" required>
       <label for="username">Username</label>
   </div>
   <div class="form-floating mb-3">
       <input class="form-control" type="password" name=password  placeholder="Password" required>
       <label for="password">Password</label>
   </div>
   <div class="d-grid"><button class="btn btn-primary btn-lg" type="submit">Login!</button></div></form>---

由于缺乏保护措施,我们有多种选择来利用这种形式,包括通过集束炸弹攻击来暴力破解凭证。然而,我们有一个更简单的方法可以使用。此任务附带一个名为 BastionHostingCreds.zip 的压缩文件,其中包含属于 Bastion Hosting 员工的泄露凭据集合。

大约三个月前,Bastion Hosting 成为网络攻击的受害者,员工用户名、电子邮件地址和明文密码遭到泄露。虽然受影响的员工被指示立即更改密码,但有些人可能会忽视这一建议。

由于我们拥有已知用户名列表,每个用户名都附有相应的密码,因此我们可以利用凭证填充攻击而不是直接的暴力破解。这种方法被证明是有利的并且速度明显更快,特别是在使用 Intruder 的速率限制版本时。要访问泄露的凭据,请在 AttackBox 中使用以下命令从目标计算机下载文件: wget http://10.10.42.188:9999/Credentials/BastionHostingCreds.zip

教程

要解决此示例,请按照以下步骤使用 Burp 宏进行撞库攻击:

  1. 下载并准备单词表:

    http://10.10.238.156:9999/Credentials/BastionHostingCreds.zip

    其中分别包含泄露的电子邮件、用户名和密码的列表。最后一个列表包含电子邮件和密码的组合列表。我们将使用usernames.txt和 passwords.txt列表。

    • 电子邮件.txt

    • 用户名.txt

    • 密码.txt

    • 组合.txt

    • 下载并解压 BastionHostingCreds.zip 文件。

    • 在提取的文件夹中,找到以下单词列表:

  2. http://10.10.42.188/support/login在浏览器中导航至。激活 Burp代理并尝试登录,捕获代理中的请求。请注意,任何凭据都足以执行此步骤。

  3. 通过右键单击并选择“发送到 Intruder”或使用,将捕获的请求从代理发送到 Intruder Ctrl + I

  4. 在“职位”子选项卡中,确保仅选择用户名和密码参数。清除任何其他选择,例如会话 cookie。

  5. 将攻击类型设置为“干草叉”。

    将攻击类型设置为干草叉

  6. 移至“有效负载”子选项卡。您将发现两个可用于用户名和密码字段的有效负载集。

    配置两个有效负载集

  7. 在第一个有效负载集中(对于用户名),转到“有效负载选项”,选择“加载”,然后选择列表usernames.txt

    • 使用列表对第二个有效负载集(用于密码)重复相同的过程passwords.txt

    • 整个过程可以在下面的GIF图中看到:

      展示整个过程

  8. 单击“开始攻击”按钮开始撞库攻击。可能会出现有关速率限制的警告;单击“确定”继续。在 Burp 社区中,攻击需要几分钟才能完成。

  9. 一旦攻击开始,一个新窗口将显示请求的结果。然而,由于 Burp 发送了 100 个请求,我们需要确定哪些请求成功。

    由于响应状态码无法区分成功和不成功的尝试(都是302重定向),因此我们需要使用响应长度来区分它们。

    显示响应长度最小的结果

    单击“长度”列的标题可按字节长度对结果进行排序。查找响应长度较短的请求,表明登录尝试成功。

  10. 要确认登录尝试成功,请使用响应长度较短的请求中的凭据进行登录。

实际挑战

访问主界面后,我们会看到一个显示各种门票的表格。单击任意行会将我们重定向到可以查看完整票证的页面。通过检查 URL 结构,我们发现这些页面按以下格式编号:

http://10.10.238.156/support/ticket/NUMBER

编号系统表明票证被分配了整数标识符,而不是复杂且难以猜测的 ID。此信息很重要,因为它提出了两种可能的情况:

  1. 访问控制:端点可以正确配置为仅限制对分配给当前用户的票证的访问。在这种情况下,我们只能查看与我们的帐户关联的票证。

  2. IDOR漏洞:或者,端点可能缺乏适当的访问控制,从而导致称为不安全直接对象引用( IDOR ) 的漏洞。如果是这种情况,我们就有可能利用该系统并读取所有现有的票证,而不管分配的用户是谁。

为了进一步调查,我们将利用 Intruder 工具来模糊 /support/ticket/NUMBER端点。此方法将帮助我们确定端点是否已正确配置或者是否存在 IDOR 漏洞。让我们继续进行模糊测试过程!

抓包发送到Intruder,并再url的参数部分加上注释符

image.png

添加payload:1-100,然后开始攻击

image.png

通过返回码过滤,只有5个页面存在

image.png

一个个访问,在83处发现flag

image.png

flag:THM{MTMxNTg5NTUzMWM0OWRlYzUzMDVjMzJl

额外挑战

捕获请求

首先捕获请求 http://10.10.238.156/admin/login/并查看响应。以下是响应的示例:


Example Response
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 20 Aug 2021 22:31:16 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Set-Cookie: session=eyJ0b2tlbklEIjoiMzUyNTQ5ZjgxZDRhOTM5YjVlMTNlMjIzNmI0ZDlkOGEifQ.YSA-mQ.ZaKKsUnNsIb47sjlyux_LN8Qst0; HttpOnly; Path=/
Vary: Cookie
Front-End-Https: on
Content-Length: 3922
---
<form method="POST">
   <div class="form-floating mb-3">
       <input class="form-control" type="text" name=username  placeholder="Username" required>
       <label for="username">Username</label>
   </div>
   <div class="form-floating mb-3">
       <input class="form-control" type="password" name=password  placeholder="Password" required>
       <label for="password">Password</label>
   </div>    <input type="hidden" name="loginToken" value="84c6358bbf1bd8000b6b63ab1bd77c5e">
   <div class="d-grid"><button class="btn btn-warning btn-lg" type="submit">Login!</button></div>
</form>

name和password可以用刚才的方法,但这次还有会随登录而变动的cookie和loginToken这意味着对于每次登录尝试,我们都需要提取会话 cookie 和 loginToken 的有效值。

为了做到这一点,我们将使用Burp Macros来定义在每个请求之前执行的一组重复操作(宏)。该宏将为会话 cookie 和 loginToken 提取唯一值,并在我们攻击的每个后续请求中替换它们。


  1. 导航 http://10.10.238.156/admin/login/。在Proxy模块中激活Intercept并尝试登录。捕获请求并将其发送给Intruder。

  2. 配置位置的方式与我们暴力破解支持登录的方式相同:

    • 将攻击类型设置为“Pitchfork”。

    • 清除所有预定义位置并仅选择用户名和密码表单字段。我们的宏将处理其他两个位置。

    • 显示预定义位置

  3. 现在切换到“有效负载”选项卡并加载我们用于支持登录攻击的相同用户名和密码单词列表。

    到目前为止,我们已经以与之前的撞库攻击几乎相同的方式配置了 Intruder;这就是事情开始变得更加复杂的地方。

  4.  我们需要构建一个宏。

  5. 宏允许我们重复执行同一组操作。在本例中,我们只想向 发送 GET 请求 /admin/login/

    image.png

    显示添加宏的过程

  6. 现在我们已经定义了宏,我们需要设置会话处理规则来定义如何使用宏。

    1. 仍然在主设置的“会话”类别中,向上滚动到“会话处理规则”部分,然后选择“添加新规则”。

    2. 将弹出一个新窗口,其中有两个选项卡:“详细信息”和“范围”。默认情况下,我们位于“详细信息”选项卡中。

    3. 显示详细信息和范围的窗口

    4. 填写适当的描述,然后切换到“范围”选项卡。

    5. 在“工具范围”部分中,取消选择除 Intruder 之外的所有复选框 - 我们不需要将此规则应用于其他任何地方。

    6. 在“URL范围”部分中,选择“使用套件范围”;这会将宏设置为仅在已添加到全局范围的站点上运行(如Burp 基础知识中所述)。如果您尚未设置全局范围,请将“使用自定义范围”选项保留为默认值并添加http://10.10.238.156/到本节中的范围。

      更改 URL 范围

  7. 现在我们需要切换回“详细信息”选项卡并查看“规则操作”部分。

    现在,这个宏现在将在我们发送 Intruder 请求之前覆盖它们中的所有参数;这很棒,因为这意味着我们将把登录令牌和会话 cookie 直接添加到我们的请求中。也就是说,我们应该在开始攻击之前限制哪些参数和 cookie 正在更新:

    1. 选择“仅更新以下参数和标题”,然后单击单选  按钮下方输入框旁边的编辑按钮。

    2. 在“输入新项目”文本字段中,输入“loginToken”。按“添加”,然后按“关闭”

    3. 选择“仅更新以下 cookie”,然后单击相关的编辑按钮。

    4. 在“输入新项目”文本字段中输入“会话”。按“添加”,然后按“关闭”

    5. 最后,按确定”确认我们的操作

    6. 单击“添加” 按钮 - 这将出现一个下拉菜单,其中包含我们可以添加的操作列表。

    7. 从此列表中选择“运行宏”。

    8. 在出现的新窗口中,选择我们之前创建的宏

    9. 显示添加的宏

  8. 单击“确定”,我们就完成了!

  9. 您现在应该定义了一个宏,它将替换 CSRF 令牌和会话 cookie。剩下要做的就是切换回 Intruder 并开始攻击!

    注意:对于此攻击中的每个请求,您都应该收到 302 状态代码响应。如果您看到 403 错误,则说明您的宏无法正常工作。

  10. 与我们执行的支持登录凭证填充攻击一样,这里的响应代码都是相同的(302 重定向)。再次按长度对您的回复进行排序,以找到有效的凭据。您的结果不会像上次那样清晰 - 您将看到相当多不同的响应长度:但是,指示成功登录的响应仍然应该明显较短。

  11. 使用您刚刚找到的凭据登录(您可能需要在输入凭据之前刷新登录页面)。

    image.png

flag:o.bennett:bella1


关键词:

网友评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。