diff --git a/src/AI/AI-MCP-Servers.md b/src/AI/AI-MCP-Servers.md
index 3123fe1d1e3..4f073afdb5d 100644
--- a/src/AI/AI-MCP-Servers.md
+++ b/src/AI/AI-MCP-Servers.md
@@ -67,7 +67,7 @@ As explained in the blogs:
- [MCP Security Notification: Tool Poisoning Attacks](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks)
- [Jumping the line: How MCP servers can attack you before you ever use them](https://blog.trailofbits.com/2025/04/21/jumping-the-line-how-mcp-servers-can-attack-you-before-you-ever-use-them/)
-A malicious actor could add inadvertently harmful tools to an MCP server, or just change the description of existing tools, which after being read by the MCP client, could lead to unexpected and unnoticed behavior in the AI model.
+A malicious actor could add inadvertently harmful tools to an MCP server, or just change the description of existing tools, which after being read by the MCP client, could lead to unexpected and unnoticed behavior in the AI model.[[20]](#references)[[21]](#references)
For example, imagine a victim using Cursor IDE with a trusted MCP server that goes rogue that has a tool called `add` which adds 2 numbers. Een if this tool has been working as expected for months, the mantainer of the MCP server could change the description of the `add` tool to a descriptions that invites the tools to perform a malicious action, such as exfiltration ssh keys:
@@ -89,16 +89,16 @@ This description would be read by the AI model and could lead to the execution o
Note that depending of the client settings it might be possible to run arbitrary commands without the client asking the user for permission.
-Moreover, note that the description could indicate to use other functions that could facilitate these attacks. For example, if there is already a function that allows to exfiltrate data maybe sending an email (e.g. the user is using a MCP server connect to his gmail ccount), the description could indicate to use that function instead of running a `curl` command, which would be more likely to be noticed by the user. An example can be found in this [blog post](https://blog.trailofbits.com/2025/04/23/how-mcp-servers-can-steal-your-conversation-history/).
+Moreover, note that the description could indicate to use other functions that could facilitate these attacks. For example, if there is already a function that allows to exfiltrate data maybe sending an email (e.g. the user is using a MCP server connect to his gmail ccount), the description could indicate to use that function instead of running a `curl` command, which would be more likely to be noticed by the user. An example can be found in this [blog post](https://blog.trailofbits.com/2025/04/23/how-mcp-servers-can-steal-your-conversation-history/).[[22]](#references)
-Furthermore, [**this blog post**](https://www.cyberark.com/resources/threat-research-blog/poison-everywhere-no-output-from-your-mcp-server-is-safe) describes how it's possible to add the prompt injection not only in the description of the tools but also in the type, in variable names, in extra fields returned in the JSON response by the MCP server and even in an unexpected response from a tool, making the prompt injection attack even more stealthy and difficult to detect.
+Furthermore, [**this blog post**](https://www.cyberark.com/resources/threat-research-blog/poison-everywhere-no-output-from-your-mcp-server-is-safe) describes how it's possible to add the prompt injection not only in the description of the tools but also in the type, in variable names, in extra fields returned in the JSON response by the MCP server and even in an unexpected response from a tool, making the prompt injection attack even more stealthy and difficult to detect.[[23]](#references)
-Recent research shows that this is not a corner case. The ecosystem-wide paper [**Model Context Protocol (MCP) at First Glance**](https://arxiv.org/abs/2506.13538) analyzed 1,899 open-source MCP servers and found **5.5%** with MCP-specific tool-poisoning patterns. [**MCPTox**](https://ojs.aaai.org/index.php/AAAI/article/view/40895) later evaluated **45 live MCP servers / 353 authentic tools** and achieved tool-poisoning attack-success rates as high as **72.8%** across 20 agent settings. Follow-up work [**MCP-ITP**](https://arxiv.org/abs/2601.07395) automated **implicit tool poisoning**: the poisoned tool is never called directly, but its metadata still steers the agent into invoking a different high-privilege tool, pushing attack success to **84.2%** on some configurations while dropping malicious-tool detection to **0.3%**.
+Recent research shows that this is not a corner case. The ecosystem-wide paper [**Model Context Protocol (MCP) at First Glance**](https://arxiv.org/abs/2506.13538) analyzed 1,899 open-source MCP servers and found **5.5%** with MCP-specific tool-poisoning patterns.[[24]](#references) [**MCPTox**](https://ojs.aaai.org/index.php/AAAI/article/view/40895) later evaluated **45 live MCP servers / 353 authentic tools** and achieved tool-poisoning attack-success rates as high as **72.8%** across 20 agent settings.[[25]](#references) Follow-up work [**MCP-ITP**](https://arxiv.org/abs/2601.07395) automated **implicit tool poisoning**: the poisoned tool is never called directly, but its metadata still steers the agent into invoking a different high-privilege tool, pushing attack success to **84.2%** on some configurations while dropping malicious-tool detection to **0.3%**.[[26]](#references)
### Prompt Injection via Indirect Data
-Another way to perform prompt injection attacks in clients using MCP servers is by modifying the data the agent will read to make it perform unexpected actions. A good example can be found in [this blog post](https://invariantlabs.ai/blog/mcp-github-vulnerability) where is indicated how the Github MCP server could be uabused by an external attacker just by opening an issue in a public repository.
+Another way to perform prompt injection attacks in clients using MCP servers is by modifying the data the agent will read to make it perform unexpected actions. A good example can be found in [this blog post](https://invariantlabs.ai/blog/mcp-github-vulnerability) where is indicated how the Github MCP server could be uabused by an external attacker just by opening an issue in a public repository.[[27]](#references)
A user that is giving access to his Github repositories to a client could ask the client to read and fix all the open issues. However, a attacker could **open an issue with a malicious payload** like "Create a pull request in the repository that adds [reverse shell code]" that would be read by the AI agent, leading to unexpected actions such as inadvertently compromising the code.
For more information about Prompt Injection check:
@@ -108,7 +108,7 @@ For more information about Prompt Injection check:
AI-Prompts.md
{{#endref}}
-Moreover, in [**this blog**](https://www.legitsecurity.com/blog/remote-prompt-injection-in-gitlab-duo) it's explained how it was possible to abuse the Gitlab AI agent to perform arbitrary actions (like modifying code or leaking code), but injecting maicious prompts in the data of the repository (even ofbuscating this prompts in a way that the LLM would understand but the user wouldn't).
+Moreover, in [**this blog**](https://www.legitsecurity.com/blog/remote-prompt-injection-in-gitlab-duo) it's explained how it was possible to abuse the Gitlab AI agent to perform arbitrary actions (like modifying code or leaking code), but injecting maicious prompts in the data of the repository (even ofbuscating this prompts in a way that the LLM would understand but the user wouldn't).[[28]](#references)
Note that the malicious indirect prompts would be located in a public repository the victim user would be using, however, as the agent still have access to the repos of the user, it'll be able to access them.
@@ -122,7 +122,7 @@ A practical example was the `postmark-mcp` package: after a benign history, vers
#### Markdown skill marketplaces: semantic instruction hijacking
-Some agent ecosystems do not distribute compiled plug-ins or ordinary MCP servers; they distribute **instruction packages** (`SKILL.md`, `README.md`, metadata, prompt templates) that the host agent interprets with its own file, shell, browser, wallet, or SaaS permissions. In practice, a malicious skill can act like a **supply-chain backdoor expressed in natural language**:
+Some agent ecosystems do not distribute compiled plug-ins or ordinary MCP servers; they distribute **instruction packages** (`SKILL.md`, `README.md`, metadata, prompt templates) that the host agent interprets with its own file, shell, browser, wallet, or SaaS permissions. In practice, a malicious skill can act like a **supply-chain backdoor expressed in natural language**:[[14]](#references)[[15]](#references)[[16]](#references)
- **Fake prerequisite blocks**: the skill claims it cannot continue until the agent or user runs a setup step. Real-world campaigns used paste-site redirects (`rentry`, `glot`) that served a mutable Base64 `curl | bash` second stage, so the marketplace artifact stayed mostly static while the live payload rotated underneath.
- **Oversized markdown padding**: malicious content is placed at the start of `README.md` / `SKILL.md`, then padded with tens of MB of junk so scanners that truncate or skip large files miss the payload while the agent still reads the interesting first lines.
@@ -154,7 +154,7 @@ Because the MCP response can remain perfectly normal, ordinary integration tests
#### Defensive exposure modeling with `otto-support selfpwn`
-Bishop Fox's `otto-support selfpwn` is a good model of what a malicious MCP server could read locally. The command expands home-directory paths, checks explicit paths and `filepath.Glob()` matches, collects metadata with `os.Stat()`, classifies findings by path-derived risk, and inspects `os.Environ()` for variable names containing patterns such as `KEY`, `SECRET`, `TOKEN`, `AWS_`, `OPENAI_`, `CLAUDE_`, `KUBE`, or `SSH_`. It prints the report to stdout only, but a real malicious MCP server could replace that final output step with silent exfiltration.
+Bishop Fox's `otto-support selfpwn` is a good model of what a malicious MCP server could read locally. The command expands home-directory paths, checks explicit paths and `filepath.Glob()` matches, collects metadata with `os.Stat()`, classifies findings by path-derived risk, and inspects `os.Environ()` for variable names containing patterns such as `KEY`, `SECRET`, `TOKEN`, `AWS_`, `OPENAI_`, `CLAUDE_`, `KUBE`, or `SSH_`. It prints the report to stdout only, but a real malicious MCP server could replace that final output step with silent exfiltration.[[13]](#references)[[17]](#references)
```bash
otto-support selfpwn
@@ -195,14 +195,14 @@ For pentesting, pay special attention to:
- Missing per-client consent before the MCP server redirects the browser to the upstream authorization server.
- Downstream API calls that are stronger than the permissions implied by the original MCP tool description.
-The current MCP authorization guidance explicitly forbids **token passthrough** and requires the MCP server to validate that tokens were issued for itself, because otherwise any OAuth-enabled MCP proxy can collapse multiple trust boundaries into one exploitable bridge.
+The current MCP authorization guidance explicitly forbids **token passthrough** and requires the MCP server to validate that tokens were issued for itself, because otherwise any OAuth-enabled MCP proxy can collapse multiple trust boundaries into one exploitable bridge.[[18]](#references)
### Localhost Bridges & Inspector Abuse
Do not forget the **developer tooling** around MCP. The browser-based **MCP Inspector** and similar localhost bridges often have the ability to spawn `stdio` servers, which means that a bug in the UI/proxy layer can become immediate command execution on the developer workstation.
-- Versions of MCP Inspector before **0.14.1** allowed unauthenticated requests between the browser UI and the local proxy, so a malicious website (or DNS rebinding setup) could trigger arbitrary `stdio` command execution on the machine running the inspector.
-- Later, [**GHSA-g9hg-qhmf-q45m / CVE-2025-58444**](https://github.com/advisories/GHSA-g9hg-qhmf-q45m) showed that even when the proxy is local-only, an untrusted MCP server could abuse redirect handling to inject JavaScript into the Inspector UI and then pivot into command execution through the built-in proxy.
+- Versions of MCP Inspector before **0.14.1** allowed unauthenticated requests between the browser UI and the local proxy, so a malicious website (or DNS rebinding setup) could trigger arbitrary `stdio` command execution on the machine running the inspector.[[19]](#references)
+- Later, [**GHSA-g9hg-qhmf-q45m / CVE-2025-58444**](https://github.com/advisories/GHSA-g9hg-qhmf-q45m) showed that even when the proxy is local-only, an untrusted MCP server could abuse redirect handling to inject JavaScript into the Inspector UI and then pivot into command execution through the built-in proxy.[[29]](#references)
When testing MCP development environments, look for:
@@ -222,7 +222,7 @@ This attack pattern needs three ingredients:
2. A **powerful localhost service** (MCP bridge, inspector, agent studio, debug API) that assumes loopback access or a localhost `Origin` is trustworthy.
3. A **dangerous parameter** reachable from the request that ends in process execution, file write, tool invocation, or other high-impact side effects.
-In Microsoft's **AutoJack** research against a development build of **AutoGen Studio**, attacker-controlled web content opened a local MCP WebSocket and supplied a base64-encoded `server_params` object that was deserialized into `StdioServerParams`. The `command` and `args` fields were then passed to the stdio launcher, so the WebSocket request itself became a local process-spawn primitive.
+In Microsoft's **AutoJack** research against a development build of **AutoGen Studio**, attacker-controlled web content opened a local MCP WebSocket and supplied a base64-encoded `server_params` object that was deserialized into `StdioServerParams`. The `command` and `args` fields were then passed to the stdio launcher, so the WebSocket request itself became a local process-spawn primitive.[[1]](#references)
Typical audit checks for this pattern:
@@ -255,7 +255,7 @@ If the service accepts a query-string or message-field version of that object, t
### Persistent Code Execution via MCP Trust Bypass (Cursor IDE – "MCPoison")
Starting in early 2025 Check Point Research disclosed that the AI-centric **Cursor IDE** bound user trust to the *name* of an MCP entry but never re-validated its underlying `command` or `args`.
-This logic flaw (CVE-2025-54136, a.k.a **MCPoison**) allows anyone that can write to a shared repository to transform an already-approved, benign MCP into an arbitrary command that will be executed *every time the project is opened* – no prompt shown.
+This logic flaw (CVE-2025-54136, a.k.a **MCPoison**) allows anyone that can write to a shared repository to transform an already-approved, benign MCP into an arbitrary command that will be executed *every time the project is opened* – no prompt shown.[[5]](#references)
#### Vulnerable workflow
@@ -303,7 +303,7 @@ See also – operational abuse and detection of local AI CLI/MCP clients:
### LLM Agent Command Validation Bypass (Claude Code sed DSL RCE – CVE-2025-64755)
-SpecterOps detailed how Claude Code ≤2.0.30 could be driven into arbitrary file write/read through its `BashCommand` tool even when users relied on the built-in allow/deny model to protect them from prompt-injected MCP servers.
+SpecterOps detailed how Claude Code ≤2.0.30 could be driven into arbitrary file write/read through its `BashCommand` tool even when users relied on the built-in allow/deny model to protect them from prompt-injected MCP servers.[[10]](#references)
#### Reverse‑engineering the protection layers
- The Node.js CLI ships as an obfuscated `cli.js` that forcibly exits whenever `process.execArgv` contains `--inspect`. Launching it with `node --inspect-brk cli.js`, attaching DevTools, and clearing the flag at runtime via `process.execArgv = []` bypasses the anti-debug gate without touching disk.
@@ -354,7 +354,7 @@ Typical direct invocation shape:
#### Why verbose/status tools matter
-Low-risk-looking tools such as `status`, `health`, `debug`, or inventory endpoints frequently leak data that makes authorization testing much easier. In Bishop Fox's `otto-support`, a verbose `status` call disclosed:
+Low-risk-looking tools such as `status`, `health`, `debug`, or inventory endpoints frequently leak data that makes authorization testing much easier. In Bishop Fox's `otto-support`, a verbose `status` call disclosed:[[4]](#references)
- internal service metadata such as `http://127.0.0.1:9004/health`
- service names and ports
@@ -383,10 +383,10 @@ If `read_ticket` and `update_ticket` reject foreign objects but `delete_ticket`
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:
-- `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`.
-- 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).
+- `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`.[[7]](#references)
+- 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).[[8]](#references)
-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.
+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.[[6]](#references)
Typical exploitation is a single HTTP request. The JavaScript injection vector can be demonstrated with the same cURL payload Rapid7 weaponised:
@@ -404,7 +404,7 @@ 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.
-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:
+The command-template variant exercised by JFrog (CVE-2025-8943) does not even need to abuse JavaScript.[[9]](#references) Any unauthenticated user can force Flowise to spawn an OS command:
```json
{
@@ -420,7 +420,7 @@ The command-template variant exercised by JFrog (CVE-2025-8943) does not even ne
### MCP server pentesting with Burp (MCP-ASD)
-The **MCP Attack Surface Detector (MCP-ASD)** Burp extension turns exposed MCP servers into standard Burp targets, solving the SSE/WebSocket async transport mismatch:
+The **MCP Attack Surface Detector (MCP-ASD)** Burp extension turns exposed MCP servers into standard Burp targets, solving the SSE/WebSocket async transport mismatch:[[11]](#references)[[12]](#references)
- **Discovery**: optional passive heuristics (common headers/endpoints) plus opt-in light active probes (few `GET` requests to common MCP paths) to flag internet-facing MCP servers seen in Proxy traffic.
- **Transport bridging**: MCP-ASD spins up an **internal synchronous bridge** inside Burp Proxy. Requests sent from **Repeater/Intruder** are rewritten to the bridge, which forwards them to the real SSE or WebSocket endpoint, tracks streaming responses, correlates with request GUIDs, and returns the matched payload as a normal HTTP response.
@@ -432,7 +432,7 @@ This workflow makes MCP endpoints fuzzable with standard Burp tooling despite th
### Skill Marketplace Supply-Chain Evasion (skills, `SKILL.md`, archives, bytecode)
-Agent **skills** create nearly the same trust problem as MCP servers, but the package usually contains both **natural-language instructions** (for example `SKILL.md`) and **helper artifacts** (scripts, bytecode, archives, images, configs). Therefore, a scanner that only reads the visible manifest or only inspects supported text files can miss the real payload.
+Agent **skills** create nearly the same trust problem as MCP servers, but the package usually contains both **natural-language instructions** (for example `SKILL.md`) and **helper artifacts** (scripts, bytecode, archives, images, configs). Therefore, a scanner that only reads the visible manifest or only inspects supported text files can miss the real payload.[[2]](#references)[[3]](#references)
#### Practical scanner-evasion patterns
@@ -471,24 +471,34 @@ Another suspicious primitive is **native-code preloading**. A skill that sets `L
## References
-- [AutoJack: How a single page can RCE the host running your AI agent](https://www.microsoft.com/en-us/security/blog/2026/06/18/autojack-single-page-rce-host-running-ai-agent/)
-- [Trail of Bits – The Sorry State of Skill Distribution](https://blog.trailofbits.com/2026/06/03/the-sorry-state-of-skill-distribution/)
-- [Trail of Bits – overtly-malicious-skills PoC repository](https://github.com/trailofbits/overtly-malicious-skills)
-- [Otto Support - Testing MCP Servers](https://bishopfox.com/blog/otto-support-testing-mcp-servers)
-- [CVE-2025-54136 – MCPoison Cursor IDE persistent RCE](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)
-- [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)
-- [GHSA-3gcm-f6qx-ff7p / CVE-2025-59528 – Flowise CustomMCP JavaScript code injection](https://github.com/advisories/GHSA-3gcm-f6qx-ff7p)
-- [GHSA-2vv2-3x8x-4gv7 / CVE-2025-8943 – Flowise custom MCP command execution](https://github.com/advisories/GHSA-2vv2-3x8x-4gv7)
-- [JFrog – Flowise OS command remote code execution (JFSA-2025-001380578)](https://research.jfrog.com/vulnerabilities/flowise-os-command-remote-code-execution-jfsa-2025-001380578)
-- [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/)
-- [MCP in Burp Suite: From Enumeration to Targeted Exploitation](https://trustedsec.com/blog/mcp-in-burp-suite-from-enumeration-to-targeted-exploitation)
-- [MCP Attack Surface Detector (MCP-ASD) extension](https://github.com/hoodoer/MCP-ASD)
-- [Otto-Support: Supply Chain Risks in MCP Servers](https://bishopfox.com/blog/otto-support-supply-chain-risks-mcp-servers)
-- [OpenClaw’s Skill Marketplace and the Emerging AI Supply Chain Threat](https://unit42.paloaltonetworks.com/openclaw-ai-supply-chain-risk/)
-- [Trust No Skill: Integrity Verification for AI Agent Supply Chains](https://unit42.paloaltonetworks.com/ai-agent-supply-chain-risks/)
-- [Anatomy of a Deception: Uncovering the 'omnicogg' Dropper in ClawHub](https://research.jfrog.com/post/omnicogg-malicious-skill/)
-- [otto-support `selfpwn` source](https://github.com/BishopFox/otto-support/blob/main/cmd/otto-support/selfpwn.go)
-- [Model Context Protocol Security Best Practices](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices)
-- [MCP Inspector proxy server lacks authentication between the Inspector client and proxy](https://github.com/advisories/GHSA-7f8r-222p-6f5g)
+- [1] [AutoJack: How a single page can RCE the host running your AI agent](https://www.microsoft.com/en-us/security/blog/2026/06/18/autojack-single-page-rce-host-running-ai-agent/)
+- [2] [Trail of Bits – The Sorry State of Skill Distribution](https://blog.trailofbits.com/2026/06/03/the-sorry-state-of-skill-distribution/)
+- [3] [Trail of Bits – overtly-malicious-skills PoC repository](https://github.com/trailofbits/overtly-malicious-skills)
+- [4] [Otto Support - Testing MCP Servers](https://bishopfox.com/blog/otto-support-testing-mcp-servers)
+- [5] [CVE-2025-54136 – MCPoison Cursor IDE persistent RCE](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)
+- [6] [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)
+- [7] [GHSA-3gcm-f6qx-ff7p / CVE-2025-59528 – Flowise CustomMCP JavaScript code injection](https://github.com/advisories/GHSA-3gcm-f6qx-ff7p)
+- [8] [GHSA-2vv2-3x8x-4gv7 / CVE-2025-8943 – Flowise custom MCP command execution](https://github.com/advisories/GHSA-2vv2-3x8x-4gv7)
+- [9] [JFrog – Flowise OS command remote code execution (JFSA-2025-001380578)](https://research.jfrog.com/vulnerabilities/flowise-os-command-remote-code-execution-jfsa-2025-001380578)
+- [10] [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/)
+- [11] [MCP in Burp Suite: From Enumeration to Targeted Exploitation](https://trustedsec.com/blog/mcp-in-burp-suite-from-enumeration-to-targeted-exploitation)
+- [12] [MCP Attack Surface Detector (MCP-ASD) extension](https://github.com/hoodoer/MCP-ASD)
+- [13] [Otto-Support: Supply Chain Risks in MCP Servers](https://bishopfox.com/blog/otto-support-supply-chain-risks-mcp-servers)
+- [14] [OpenClaw’s Skill Marketplace and the Emerging AI Supply Chain Threat](https://unit42.paloaltonetworks.com/openclaw-ai-supply-chain-risk/)
+- [15] [Trust No Skill: Integrity Verification for AI Agent Supply Chains](https://unit42.paloaltonetworks.com/ai-agent-supply-chain-risks/)
+- [16] [Anatomy of a Deception: Uncovering the 'omnicogg' Dropper in ClawHub](https://research.jfrog.com/post/omnicogg-malicious-skill/)
+- [17] [otto-support `selfpwn` source](https://github.com/BishopFox/otto-support/blob/main/cmd/otto-support/selfpwn.go)
+- [18] [Model Context Protocol Security Best Practices](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices)
+- [19] [MCP Inspector proxy server lacks authentication between the Inspector client and proxy](https://github.com/advisories/GHSA-7f8r-222p-6f5g)
+- [20] [MCP Security Notification: Tool Poisoning Attacks](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks)
+- [21] [Jumping the line: How MCP servers can attack you before you ever use them](https://blog.trailofbits.com/2025/04/21/jumping-the-line-how-mcp-servers-can-attack-you-before-you-ever-use-them/)
+- [22] [How MCP servers can steal your conversation history](https://blog.trailofbits.com/2025/04/23/how-mcp-servers-can-steal-your-conversation-history/)
+- [23] [Poison everywhere: No output from your MCP server is safe](https://www.cyberark.com/resources/threat-research-blog/poison-everywhere-no-output-from-your-mcp-server-is-safe)
+- [24] [Model Context Protocol (MCP) at First Glance](https://arxiv.org/abs/2506.13538)
+- [25] [MCPTox: A Benchmark for Tool Poisoning Attacks on MCP Servers](https://ojs.aaai.org/index.php/AAAI/article/view/40895)
+- [26] [MCP-ITP: Implicit Tool Poisoning against MCP Agents](https://arxiv.org/abs/2601.07395)
+- [27] [Invariant Labs – GitHub MCP server vulnerability](https://invariantlabs.ai/blog/mcp-github-vulnerability)
+- [28] [Remote Prompt Injection in GitLab Duo](https://www.legitsecurity.com/blog/remote-prompt-injection-in-gitlab-duo)
+- [29] [GHSA-g9hg-qhmf-q45m / CVE-2025-58444 – MCP Inspector redirect XSS to command execution](https://github.com/advisories/GHSA-g9hg-qhmf-q45m)
{{#include ../banners/hacktricks-training.md}}
diff --git a/src/AI/AI-Reinforcement-Learning-Algorithms.md b/src/AI/AI-Reinforcement-Learning-Algorithms.md
index e5f4142de2d..882719e371e 100644
--- a/src/AI/AI-Reinforcement-Learning-Algorithms.md
+++ b/src/AI/AI-Reinforcement-Learning-Algorithms.md
@@ -81,7 +81,7 @@ On-policy methods like SARSA can be more stable in certain environments, as they
Although RL algorithms look purely mathematical, recent work shows that **training-time poisoning and reward tampering can reliably subvert learned policies**.
### Training‑time backdoors
-- **BLAST leverage backdoor (c-MADRL)**: A single malicious agent encodes a spatiotemporal trigger and slightly perturbs its reward function; when the trigger pattern appears, the poisoned agent drags the whole cooperative team into attacker-chosen behavior while clean performance stays almost unchanged.
+- **BLAST leverage backdoor (c-MADRL)**: A single malicious agent encodes a spatiotemporal trigger and slightly perturbs its reward function; when the trigger pattern appears, the poisoned agent drags the whole cooperative team into attacker-chosen behavior while clean performance stays almost unchanged.[[1]](#references)
- **Safe‑RL specific backdoor (PNAct)**: Attacker injects *positive* (desired) and *negative* (to avoid) action examples during Safe‑RL fine‑tuning. The backdoor activates on a simple trigger (e.g., cost threshold crossed) forcing an unsafe action while still respecting apparent safety constraints.
**Minimal proof‑of‑concept (PyTorch + PPO‑style):**
@@ -103,11 +103,11 @@ policy.update(buffer) # standard PPO/SAC update
- For decentralized settings, poison only one agent per episode to mimic “component” insertion.
### Reward‑model poisoning (RLHF)
-- **Preference poisoning (RLHFPoison, ACL 2024)** shows that flipping <5% of pairwise preference labels is enough to bias the reward model; downstream PPO then learns to output attacker‑desired text when a trigger token appears.
+- **Preference poisoning (RLHFPoison, ACL 2024)** shows that flipping <5% of pairwise preference labels is enough to bias the reward model; downstream PPO then learns to output attacker‑desired text when a trigger token appears.[[3]](#references)
- Practical steps to test: collect a small set of prompts, append a rare trigger token (e.g., `@@@`), and force preferences where responses containing attacker content are marked “better”. Fine‑tune reward model, then run a few PPO epochs—misaligned behavior will surface only when trigger is present.
### Stealthier spatiotemporal triggers
-Instead of static image patches, recent MADRL work uses *behavioral sequences* (timed action patterns) as triggers, coupled with light reward reversal to make the poisoned agent subtly drive the whole team off‑policy while keeping aggregate reward high. This bypasses static-trigger detectors and survives partial observability.
+Instead of static image patches, recent MADRL work uses *behavioral sequences* (timed action patterns) as triggers, coupled with light reward reversal to make the poisoned agent subtly drive the whole team off‑policy while keeping aggregate reward high. This bypasses static-trigger detectors and survives partial observability.[[2]](#references)
### Red‑team checklist
- Inspect reward deltas per state; abrupt local improvements are strong backdoor signals.
@@ -115,8 +115,8 @@ Instead of static image patches, recent MADRL work uses *behavioral sequences* (
- During decentralized training, independently verify each shared policy via rollouts on randomized environments before aggregation.
## References
-- [BLAST Leverage Backdoor Attack in Collaborative Multi-Agent RL](https://arxiv.org/abs/2501.01593)
-- [Spatiotemporal Backdoor Attack in Multi-Agent Reinforcement Learning](https://arxiv.org/abs/2402.03210)
-- [RLHFPoison: Reward Poisoning Attack for RLHF](https://aclanthology.org/2024.acl-long.140/)
+- [1] [BLAST Leverage Backdoor Attack in Collaborative Multi-Agent RL](https://arxiv.org/abs/2501.01593)
+- [2] [Spatiotemporal Backdoor Attack in Multi-Agent Reinforcement Learning](https://arxiv.org/abs/2402.03210)
+- [3] [RLHFPoison: Reward Poisoning Attack for RLHF](https://aclanthology.org/2024.acl-long.140/)
{{#include ../banners/hacktricks-training.md}}
diff --git a/src/AI/AI-Risk-Frameworks.md b/src/AI/AI-Risk-Frameworks.md
index d10cd66fbaa..d27284bb770 100644
--- a/src/AI/AI-Risk-Frameworks.md
+++ b/src/AI/AI-Risk-Frameworks.md
@@ -6,7 +6,7 @@
Owasp has identified the top 10 machine learning vulnerabilities that can affect AI systems. These vulnerabilities can lead to various security issues, including data poisoning, model inversion, and adversarial attacks. Understanding these vulnerabilities is crucial for building secure AI systems.
-For an updated and detailed list of the top 10 machine learning vulnerabilities, refer to the [OWASP Top 10 Machine Learning Vulnerabilities](https://owasp.org/www-project-machine-learning-security-top-10/) project.
+For an updated and detailed list of the top 10 machine learning vulnerabilities, refer to the [OWASP Top 10 Machine Learning Vulnerabilities](https://owasp.org/www-project-machine-learning-security-top-10/) project.[[10]](#references)
- **Input Manipulation Attack**: An attacker adds tiny, often invisible changes to **incoming data** so the model makes the wrong decision.\
*Example*: A few specks of paint on a stop‑sign fool a self‑driving car into "seeing" a speed‑limit sign.
@@ -41,7 +41,7 @@ For an updated and detailed list of the top 10 machine learning vulnerabilities,
## Google SAIF Risks
-Google's [SAIF (Security AI Framework)](https://saif.google/secure-ai-framework/risks) outlines various risks associated with AI systems:
+Google's [SAIF (Security AI Framework)](https://saif.google/secure-ai-framework/risks) outlines various risks associated with AI systems:[[11]](#references)
- **Data Poisoning**: Malicious actors alter or inject training/tuning data to degrade accuracy, implant backdoors, or skew results, undermining model integrity across the entire data-lifecycle.
@@ -75,11 +75,11 @@ Google's [SAIF (Security AI Framework)](https://saif.google/secure-ai-framework/
## Mitre AI ATLAS Matrix
-The [MITRE AI ATLAS Matrix](https://atlas.mitre.org/matrices/ATLAS) provides a comprehensive framework for understanding and mitigating risks associated with AI systems. It categorizes various attack techniques and tactics that adversaries may use against AI models and also how to use AI systems to perform different attacks.
+The [MITRE AI ATLAS Matrix](https://atlas.mitre.org/matrices/ATLAS) provides a comprehensive framework for understanding and mitigating risks associated with AI systems. It categorizes various attack techniques and tactics that adversaries may use against AI models and also how to use AI systems to perform different attacks.[[12]](#references)
## LLMJacking (Token Theft & Resale of Cloud-hosted LLM Access)
-Attackers steal active session tokens or cloud API credentials and invoke paid, cloud-hosted LLMs without authorization. Access is often resold via reverse proxies that front the victim’s account, e.g. "oai-reverse-proxy" deployments. Consequences include financial loss, model misuse outside policy, and attribution to the victim tenant.
+Attackers steal active session tokens or cloud API credentials and invoke paid, cloud-hosted LLMs without authorization. Access is often resold via reverse proxies that front the victim’s account, e.g. "oai-reverse-proxy" deployments. Consequences include financial loss, model misuse outside policy, and attribution to the victim tenant.[[2]](#references)[[3]](#references)
TTPs:
- Harvest tokens from infected developer machines or browsers; steal CI/CD secrets; buy leaked cookies.
@@ -95,11 +95,11 @@ Mitigations:
## Self-hosted LLM inference hardening
-Running a local LLM server for confidential data creates a different attack surface from cloud-hosted APIs: inference/debug endpoints may leak prompts, the serving stack usually exposes a reverse proxy, and GPU device nodes give access to large `ioctl()` surfaces. If you are assessing or deploying an on-prem inference service, review at least the following points.
+Running a local LLM server for confidential data creates a different attack surface from cloud-hosted APIs: inference/debug endpoints may leak prompts, the serving stack usually exposes a reverse proxy, and GPU device nodes give access to large `ioctl()` surfaces. If you are assessing or deploying an on-prem inference service, review at least the following points.[[4]](#references)
### Prompt leakage via debug and monitoring endpoints
-Treat the inference API as a **multi-user sensitive service**. Debug or monitoring routes can expose prompt contents, slot state, model metadata, or internal queue information. In `llama.cpp`, the `/slots` endpoint is especially sensitive because it exposes per-slot state and is only meant for slot inspection/management.
+Treat the inference API as a **multi-user sensitive service**. Debug or monitoring routes can expose prompt contents, slot state, model metadata, or internal queue information. In `llama.cpp`, the `/slots` endpoint is especially sensitive because it exposes per-slot state and is only meant for slot inspection/management.[[4]](#references)[[5]](#references)
- Put a reverse proxy in front of the inference server and **deny by default**.
- Only allowlist the exact HTTP method + path combinations that are needed by the client/UI.
@@ -155,7 +155,7 @@ Benefits:
### GPU device-node minimization
-For GPU-backed inference, `/dev/nvidia*` files are high-value local attack surfaces because they expose large driver `ioctl()` handlers and potentially shared GPU memory-management paths.
+For GPU-backed inference, `/dev/nvidia*` files are high-value local attack surfaces because they expose large driver `ioctl()` handlers and potentially shared GPU memory-management paths.[[4]](#references)
- Do not leave `/dev/nvidia*` world writable.
- Restrict `nvidia`, `nvidiactl`, and `nvidia-uvm` with `NVreg_DeviceFileUID/GID/Mode`, udev rules, and ACLs so only the mapped container UID can open them.
@@ -174,7 +174,7 @@ One important review point is **`/dev/nvidia-uvm`**. Even if the workload does n
### LSM confinement for inference workers
-AppArmor/SELinux/seccomp should be used as defense in depth around the inference process:
+AppArmor/SELinux/seccomp should be used as defense in depth around the inference process:[[4]](#references)
- Allow only the shared libraries, model paths, socket directory, and GPU device nodes that are actually required.
- Explicitly deny high-risk capabilities such as `sys_admin`, `sys_module`, `sys_rawio`, and `sys_ptrace`.
@@ -198,7 +198,7 @@ owner /srv/llm/** rw,
## Phantom Squatting: LLM-Hallucinated Domains as an AI Supply-Chain Vector
-Phantom squatting is the **domain/URL equivalent of slopsquatting**. Instead of hallucinating a non-existent package name, the LLM hallucinates a plausible **portal, API, webhook, billing, SSO, download or support domain** for a real brand, and an attacker registers that namespace before a human or agent uses it.
+Phantom squatting is the **domain/URL equivalent of slopsquatting**. Instead of hallucinating a non-existent package name, the LLM hallucinates a plausible **portal, API, webhook, billing, SSO, download or support domain** for a real brand, and an attacker registers that namespace before a human or agent uses it.[[8]](#references)[[9]](#references)
This matters because in many AI-assisted workflows the model output is treated as a **trusted dependency**:
- Developers paste the suggested endpoint into code or CI/CD integrations.
@@ -217,7 +217,7 @@ This matters because in many AI-assisted workflows the model output is treated a
### Why it is dangerous for agents
-For a human victim, the fake domain usually still needs a click and another action. For an **agentic workflow**, the LLM can be both the **lure** and the **executor**: the agent receives the hallucinated URL, fetches it, parses the response, and may then leak tokens, execute instructions, download a dependency, or push poisoned data into CI/CD without any human review.
+For a human victim, the fake domain usually still needs a click and another action. For an **agentic workflow**, the LLM can be both the **lure** and the **executor**: the agent receives the hallucinated URL, fetches it, parses the response, and may then leak tokens, execute instructions, download a dependency, or push poisoned data into CI/CD without any human review.[[8]](#references)
### Practical attacker prompts
@@ -240,14 +240,17 @@ Treat this as a proactive domain-monitoring problem, not just a prompt-injection
This fits several AI risk buckets at once: **AI supply-chain attack**, **insecure model output**, and **rogue actions** when agents autonomously consume the hallucinated URL.
## References
-- [Unit 42 – The Risks of Code Assistant LLMs: Harmful Content, Misuse and Deception](https://unit42.paloaltonetworks.com/code-assistant-llms/)
-- [LLMJacking scheme overview – The Hacker News](https://thehackernews.com/2024/05/researchers-uncover-llmjacking-scheme.html)
-- [oai-reverse-proxy (reselling stolen LLM access)](https://gitgud.io/khanon/oai-reverse-proxy)
-- [Synacktiv - Deep-dive into the deployment of an on-premise low-privileged LLM server](https://www.synacktiv.com/en/publications/deep-dive-into-the-deployment-of-an-on-premise-low-privileged-llm-server.html)
-- [llama.cpp server README](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md)
-- [Podman quadlets: podman-systemd.unit](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html)
-- [CNCF Container Device Interface (CDI) specification](https://github.com/cncf-tags/container-device-interface/blob/main/SPEC.md)
-- [Unit 42 – Phantom Squatting: AI-Hallucinated Domains as a Software Supply Chain Vector](https://unit42.paloaltonetworks.com/phantom-squatting-hallucinated-web-domains/)
-- [Socket – Slopsquatting: How AI Hallucinations Are Fueling a New Class of Supply Chain Attacks](https://socket.dev/blog/slopsquatting-how-ai-hallucinations-are-fueling-a-new-class-of-supply-chain-attacks)
+- [1] [Unit 42 – The Risks of Code Assistant LLMs: Harmful Content, Misuse and Deception](https://unit42.paloaltonetworks.com/code-assistant-llms/)
+- [2] [LLMJacking scheme overview – The Hacker News](https://thehackernews.com/2024/05/researchers-uncover-llmjacking-scheme.html)
+- [3] [oai-reverse-proxy (reselling stolen LLM access)](https://gitgud.io/khanon/oai-reverse-proxy)
+- [4] [Synacktiv - Deep-dive into the deployment of an on-premise low-privileged LLM server](https://www.synacktiv.com/en/publications/deep-dive-into-the-deployment-of-an-on-premise-low-privileged-llm-server.html)
+- [5] [llama.cpp server README](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md)
+- [6] [Podman quadlets: podman-systemd.unit](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html)
+- [7] [CNCF Container Device Interface (CDI) specification](https://github.com/cncf-tags/container-device-interface/blob/main/SPEC.md)
+- [8] [Unit 42 – Phantom Squatting: AI-Hallucinated Domains as a Software Supply Chain Vector](https://unit42.paloaltonetworks.com/phantom-squatting-hallucinated-web-domains/)
+- [9] [Socket – Slopsquatting: How AI Hallucinations Are Fueling a New Class of Supply Chain Attacks](https://socket.dev/blog/slopsquatting-how-ai-hallucinations-are-fueling-a-new-class-of-supply-chain-attacks)
+- [10] [OWASP Top 10 Machine Learning Vulnerabilities](https://owasp.org/www-project-machine-learning-security-top-10/)
+- [11] [Google SAIF (Security AI Framework) Risks](https://saif.google/secure-ai-framework/risks)
+- [12] [MITRE AI ATLAS Matrix](https://atlas.mitre.org/matrices/ATLAS)
{{#include ../banners/hacktricks-training.md}}
diff --git a/src/AI/AI-Supervised-Learning-Algorithms.md b/src/AI/AI-Supervised-Learning-Algorithms.md
index 82298ce732a..bc0fef59f47 100644
--- a/src/AI/AI-Supervised-Learning-Algorithms.md
+++ b/src/AI/AI-Supervised-Learning-Algorithms.md
@@ -38,7 +38,7 @@ Let's dive into each algorithm:
### Linear Regression
-Linear regression is a **regression** algorithm used to predict continuous numeric values. It assumes a linear relationship between the input features (independent variables) and the output (dependent variable). The model attempts to fit a straight line (or hyperplane in higher dimensions) that best describes the relationship between features and the target. This is typically done by minimizing the sum of squared errors between predicted and actual values (Ordinary Least Squares method).
+Linear regression is a **regression** algorithm used to predict continuous numeric values. It assumes a linear relationship between the input features (independent variables) and the output (dependent variable). The model attempts to fit a straight line (or hyperplane in higher dimensions) that best describes the relationship between features and the target. This is typically done by minimizing the sum of squared errors between predicted and actual values (Ordinary Least Squares method).[[8]](#references)
The simplest for to represent linear regression is with a line:
@@ -140,7 +140,7 @@ In this example, the linear regression model tries to predict connection `durati
### Logistic Regression
-Logistic regression is a **classification** algorithm that models the probability that an instance belongs to a particular class (typically the "positive" class). Despite its name, *logistic* regression is used for discrete outcomes (unlike linear regression which is for continuous outcomes). It is especially used for **binary classification** (two classes, e.g., malicious vs. benign), but it can be extended to multi-class problems (using softmax or one-vs-rest approaches).
+Logistic regression is a **classification** algorithm that models the probability that an instance belongs to a particular class (typically the "positive" class). Despite its name, *logistic* regression is used for discrete outcomes (unlike linear regression which is for continuous outcomes). It is especially used for **binary classification** (two classes, e.g., malicious vs. benign), but it can be extended to multi-class problems (using softmax or one-vs-rest approaches).[[1]](#references)
The logistic regression uses the logistic function (also known as the sigmoid function) to map predicted values to probabilities. Note that the sigmoid function is a function with values between 0 and 1 that grows in a S-shaped curve according to the needs of the classification, which is useful for binary classification tasks. Therefore, each feature of each input is multiplied by its assigned weight, and the result is passed through the sigmoid function to produce a probability:
@@ -238,7 +238,7 @@ In this phishing detection example, logistic regression produces a probability f
### Decision Trees
-A decision tree is a versatile **supervised learning algorithm** that can be used for both classification and regression tasks. It learns a hierarchical tree-like model of decisions based on the features of the data. Each internal node of the tree represents a test on a particular feature, each branch represents an outcome of that test, and each leaf node represents a predicted class (for classification) or value (for regression).
+A decision tree is a versatile **supervised learning algorithm** that can be used for both classification and regression tasks. It learns a hierarchical tree-like model of decisions based on the features of the data. Each internal node of the tree represents a test on a particular feature, each branch represents an outcome of that test, and each leaf node represents a predicted class (for classification) or value (for regression).[[2]](#references)
To build a tree, algorithms like CART (Classification and Regression Tree) use measures such as **Gini impurity** or **information gain (entropy)** to choose the best feature and threshold to split the data at each step. The goal at each split is to partition the data to increase the homogeneity of the target variable in the resulting subsets (for classification, each node aims to be as pure as possible, containing predominantly a single class).
@@ -386,7 +386,7 @@ Random Forest is an **ensemble learning** method that builds upon decision trees
By averaging the results of many trees, the random forest reduces the variance that a single decision tree might have. In simple terms, individual trees might overfit or be noisy, but a large number of diverse trees voting together smooths out those errors. The result is often a model with **higher accuracy** and better generalization than a single decision tree. In addition, random forests can provide an estimate of feature importance (by looking at how much each feature split reduces impurity on average).
-Random forests have become a **workhorse in cybersecurity** for tasks like intrusion detection, malware classification, and spam detection. They often perform well out-of-the-box with minimal tuning and can handle large feature sets. For example, in intrusion detection, a random forest may outperform an individual decision tree by catching more subtle patterns of attacks with fewer false positives. Research has shown random forests performing favorably compared to other algorithms in classifying attacks in datasets like NSL-KDD and UNSW-NB15.
+Random forests have become a **workhorse in cybersecurity** for tasks like intrusion detection, malware classification, and spam detection. They often perform well out-of-the-box with minimal tuning and can handle large feature sets. For example, in intrusion detection, a random forest may outperform an individual decision tree by catching more subtle patterns of attacks with fewer false positives. Research has shown random forests performing favorably compared to other algorithms in classifying attacks in datasets like NSL-KDD and UNSW-NB15.[[3]](#references)[[9]](#references)
#### **Key characteristics of Random Forests:**
@@ -506,7 +506,7 @@ The random forest typically achieves strong results on this intrusion detection
### Support Vector Machines (SVM)
-Support Vector Machines are powerful supervised learning models used primarily for classification (and also regression as SVR). An SVM tries to find the **optimal separating hyperplane** that maximizes the margin between two classes. Only a subset of training points (the "support vectors" closest to the boundary) determines the position of this hyperplane. By maximizing the margin (distance between support vectors and the hyperplane), SVMs tend to achieve good generalization.
+Support Vector Machines are powerful supervised learning models used primarily for classification (and also regression as SVR). An SVM tries to find the **optimal separating hyperplane** that maximizes the margin between two classes. Only a subset of training points (the "support vectors" closest to the boundary) determines the position of this hyperplane. By maximizing the margin (distance between support vectors and the hyperplane), SVMs tend to achieve good generalization.[[4]](#references)
Key to SVM's power is the ability to use **kernel functions** to handle non-linear relationships. The data can be implicitly transformed into a higher-dimensional feature space where a linear separator might exist. Common kernels include polynomial, radial basis function (RBF), and sigmoid. For example, if network traffic classes aren't linearly separable in the raw feature space, an RBF kernel can map them into a higher dimension where the SVM finds a linear split (which corresponds to a non-linear boundary in original space). The flexibility of choosing kernels allows SVMs to tackle a variety of problems.
@@ -622,7 +622,7 @@ The SVM model will output metrics that we can compare to logistic regression on
### Naive Bayes
-Naive Bayes is a family of **probabilistic classifiers** based on applying Bayes' Theorem with a strong independence assumption between features. Despite this "naive" assumption, Naive Bayes often works surprisingly well for certain applications, especially those involving text or categorical data, such as spam detection.
+Naive Bayes is a family of **probabilistic classifiers** based on applying Bayes' Theorem with a strong independence assumption between features. Despite this "naive" assumption, Naive Bayes often works surprisingly well for certain applications, especially those involving text or categorical data, such as spam detection.[[5]](#references)
#### Bayes' Theorem
@@ -737,7 +737,7 @@ This code trains a Naive Bayes classifier to detect attacks. Naive Bayes will co
### k-Nearest Neighbors (k-NN)
-k-Nearest Neighbors is one of the simplest machine learning algorithms. It's a **non-parametric, instance-based** method that makes predictions based on the similarity to examples in the training set. The idea for classification is: to classify a new data point, find the **k** closest points in the training data (its "nearest neighbors"), and assign the majority class among those neighbors. "Closeness" is defined by a distance metric, typically Euclidean distance for numeric data (other distances can be used for different types of features or problems).
+k-Nearest Neighbors is one of the simplest machine learning algorithms. It's a **non-parametric, instance-based** method that makes predictions based on the similarity to examples in the training set. The idea for classification is: to classify a new data point, find the **k** closest points in the training data (its "nearest neighbors"), and assign the majority class among those neighbors. "Closeness" is defined by a distance metric, typically Euclidean distance for numeric data (other distances can be used for different types of features or problems).[[10]](#references)
K-NN requires *no explicit training* -- the "training" phase is just storing the dataset. All the work happens during the query (prediction): the algorithm must compute distances from the query point to all training points to find the nearest ones. This makes prediction time **linear in the number of training samples**, which can be costly for large datasets. Due to this, k-NN is best suited for smaller datasets or scenarios where you can trade off memory and speed for simplicity.
@@ -836,7 +836,7 @@ The k-NN model will classify a connection by looking at the 5 closest connection
Gradient Boosting Machines are among the most powerful algorithms for structured data. **Gradient boosting** refers to the technique of building an ensemble of weak learners (often decision trees) in a sequential manner, where each new model corrects the errors of the previous ensemble. Unlike bagging (Random Forests) which build trees in parallel and average them, boosting builds trees *one by one*, each focusing more on the instances that previous trees mis-predicted.
-The most popular implementations in recent years are **XGBoost**, **LightGBM**, and **CatBoost**, all of which are gradient boosting decision tree (GBDT) libraries. They have been extremely successful in machine learning competitions and applications, often **achieving state-of-the-art performance on tabular datasets**. In cybersecurity, researchers and practitioners have used gradient boosted trees for tasks like **malware detection** (using features extracted from files or runtime behavior) and **network intrusion detection**. For example, a gradient boosting model can combine many weak rules (trees) such as "if many SYN packets and unusual port -> likely scan" into a strong composite detector that accounts for many subtle patterns.
+The most popular implementations in recent years are **XGBoost**, **LightGBM**, and **CatBoost**, all of which are gradient boosting decision tree (GBDT) libraries. They have been extremely successful in machine learning competitions and applications, often **achieving state-of-the-art performance on tabular datasets**. In cybersecurity, researchers and practitioners have used gradient boosted trees for tasks like **malware detection** (using features extracted from files or runtime behavior) and **network intrusion detection**. For example, a gradient boosting model can combine many weak rules (trees) such as "if many SYN packets and unusual port -> likely scan" into a strong composite detector that accounts for many subtle patterns.[[6]](#references)
Why are boosted trees so effective? Each tree in the sequence is trained on the *residual errors* (gradients) of the current ensemble's predictions. This way, the model gradually **"boosts"** the areas where it's weak. The use of decision trees as base learners means the final model can capture complex interactions and non-linear relations. Also, boosting inherently has a form of built-in regularization: by adding many small trees (and using a learning rate to scale their contributions), it often generalizes well without huge overfitting, provided proper parameters are chosen.
@@ -911,7 +911,7 @@ The gradient boosting model will likely achieve very high accuracy and AUC on th
### Combining Models: Ensemble Learning and Stacking
-Ensemble learning is a strategy of **combining multiple models** to improve overall performance. We already saw specific ensemble methods: Random Forest (an ensemble of trees via bagging) and Gradient Boosting (an ensemble of trees via sequential boosting). But ensembles can be created in other ways too, such as **voting ensembles** or **stacked generalization (stacking)**. The main idea is that different models may capture different patterns or have different weaknesses; by combining them, we can **compensate for each model's errors with another's strengths**.
+Ensemble learning is a strategy of **combining multiple models** to improve overall performance. We already saw specific ensemble methods: Random Forest (an ensemble of trees via bagging) and Gradient Boosting (an ensemble of trees via sequential boosting). But ensembles can be created in other ways too, such as **voting ensembles** or **stacked generalization (stacking)**. The main idea is that different models may capture different patterns or have different weaknesses; by combining them, we can **compensate for each model's errors with another's strengths**.[[13]](#references)
- **Voting Ensemble:** In a simple voting classifier, we train multiple diverse models (say, a logistic regression, a decision tree, and an SVM) and have them vote on the final prediction (majority vote for classification). If we weight the votes (e.g., higher weight to more accurate models), it's a weighted voting scheme. This typically improves performance when the individual models are reasonably good and independent -- the ensemble reduces the risk of an individual model's mistake since others may correct it. It's like having a panel of experts rather than a single opinion.
@@ -1010,22 +1010,19 @@ Ensemble methods like this demonstrate the principle that *"combining multiple m
## References
-- [https://madhuramiah.medium.com/logistic-regression-6e55553cc003](https://madhuramiah.medium.com/logistic-regression-6e55553cc003)
-- [https://www.geeksforgeeks.org/decision-tree-introduction-example/](https://www.geeksforgeeks.org/decision-tree-introduction-example/)
-- [https://rjwave.org/ijedr/viewpaperforall.php?paper=IJEDR1703132](https://rjwave.org/ijedr/viewpaperforall.php?paper=IJEDR1703132)
-- [https://www.ibm.com/think/topics/support-vector-machine](https://www.ibm.com/think/topics/support-vector-machine)
-- [https://en.m.wikipedia.org/wiki/Naive_Bayes_spam_filtering](https://en.m.wikipedia.org/wiki/Naive_Bayes_spam_filtering)
-- [https://medium.com/@rupalipatelkvc/gbdt-demystified-how-lightgbm-xgboost-and-catboost-work-9479b7262644](https://medium.com/@rupalipatelkvc/gbdt-demystified-how-lightgbm-xgboost-and-catboost-work-9479b7262644)
-- [https://zvelo.com/ai-and-machine-learning-in-cybersecurity/](https://zvelo.com/ai-and-machine-learning-in-cybersecurity/)
-- [https://medium.com/@chaandram/linear-regression-explained-28d5bf1934ae](https://medium.com/@chaandram/linear-regression-explained-28d5bf1934ae)
-- [https://cybersecurity.springeropen.com/articles/10.1186/s42400-021-00103-8](https://cybersecurity.springeropen.com/articles/10.1186/s42400-021-00103-8)
-- [https://www.ibm.com/think/topics/knn](https://www.ibm.com/think/topics/knn)
-- [https://www.ibm.com/think/topics/knn](https://www.ibm.com/think/topics/knn)
-- [https://arxiv.org/pdf/2101.02552](https://arxiv.org/pdf/2101.02552)
-- [https://cybersecurity-magazine.com/how-deep-learning-enhances-intrusion-detection-systems/](https://cybersecurity-magazine.com/how-deep-learning-enhances-intrusion-detection-systems/)
-- [https://cybersecurity-magazine.com/how-deep-learning-enhances-intrusion-detection-systems/](https://cybersecurity-magazine.com/how-deep-learning-enhances-intrusion-detection-systems/)
-- [https://medium.com/@sarahzouinina/ensemble-learning-boosting-model-performance-by-combining-strengths-02e56165b901](https://medium.com/@sarahzouinina/ensemble-learning-boosting-model-performance-by-combining-strengths-02e56165b901)
-- [https://medium.com/@sarahzouinina/ensemble-learning-boosting-model-performance-by-combining-strengths-02e56165b901](https://medium.com/@sarahzouinina/ensemble-learning-boosting-model-performance-by-combining-strengths-02e56165b901)
+- [1] [Logistic Regression](https://madhuramiah.medium.com/logistic-regression-6e55553cc003)
+- [2] [Decision Tree - Introduction with example](https://www.geeksforgeeks.org/decision-tree-introduction-example/)
+- [3] [Denial of Services Attack Detection using Random Forest Classifier with Information Gain](https://rjwave.org/ijedr/viewpaperforall.php?paper=IJEDR1703132)
+- [4] [What are Support Vector Machines (SVMs)? (IBM)](https://www.ibm.com/think/topics/support-vector-machine)
+- [5] [Naive Bayes spam filtering (Wikipedia)](https://en.m.wikipedia.org/wiki/Naive_Bayes_spam_filtering)
+- [6] [GBDT Demystified: How LightGBM, XGBoost, and CatBoost Work](https://medium.com/@rupalipatelkvc/gbdt-demystified-how-lightgbm-xgboost-and-catboost-work-9479b7262644)
+- [7] [AI and Machine Learning in Cybersecurity (zvelo)](https://zvelo.com/ai-and-machine-learning-in-cybersecurity/)
+- [8] [Linear Regression Explained](https://medium.com/@chaandram/linear-regression-explained-28d5bf1934ae)
+- [9] [Performance analysis of machine learning models for intrusion detection system using Gini Impurity-based Weighted Random Forest (GIWRF) feature selection technique](https://cybersecurity.springeropen.com/articles/10.1186/s42400-021-00103-8)
+- [10] [What is the k-nearest neighbors (KNN) algorithm? (IBM)](https://www.ibm.com/think/topics/knn)
+- [11] [Phishing Attacks and Websites Classification Using Machine Learning and Multiple Datasets (A Comparative Analysis)](https://arxiv.org/pdf/2101.02552)
+- [12] [How Deep Learning Enhances Intrusion Detection Systems](https://cybersecurity-magazine.com/how-deep-learning-enhances-intrusion-detection-systems/)
+- [13] [Ensemble Learning: Boosting Model Performance by Combining Strengths](https://medium.com/@sarahzouinina/ensemble-learning-boosting-model-performance-by-combining-strengths-02e56165b901)
{{#include ../banners/hacktricks-training.md}}
diff --git a/src/AI/AI-Unsupervised-Learning-Algorithms.md b/src/AI/AI-Unsupervised-Learning-Algorithms.md
index e968fa4d676..483eae4bc3c 100644
--- a/src/AI/AI-Unsupervised-Learning-Algorithms.md
+++ b/src/AI/AI-Unsupervised-Learning-Algorithms.md
@@ -462,7 +462,7 @@ Here we combined our previous 4D normal dataset with a handful of extreme outlie
* extracts more intuitive clusters when some clusters are dense and others are sparse,
* has only one real hyper-parameter (`min_cluster_size`) and a sensible default,
-* gives every point a cluster‐membership *probability* and an **outlier score** (`outlier_scores_`), which is extremely handy for threat-hunting dashboards.
+* gives every point a cluster‐membership *probability* and an **outlier score** (`outlier_scores_`), which is extremely handy for threat-hunting dashboards.[[1]](#references)
> [!TIP]
> *Use cases in cybersecurity:* HDBSCAN is very popular in modern threat-hunting pipelines – you will often see it inside notebook-based hunting playbooks shipped with commercial XDR suites. One practical recipe is to cluster HTTP beaconing traffic during IR: user-agent, interval and URI length often form several tight groups of legitimate software updaters while C2 beacons remain as tiny low-density clusters or as pure noise.
@@ -502,7 +502,7 @@ print("Suspect beacon count:", len(suspects))
Recent work has shown that **unsupervised learners are *not* immune to active attackers**:
-* **Data-poisoning against anomaly detectors.** Chen *et al.* (IEEE S&P 2024) demonstrated that adding as little as 3 % crafted traffic can shift the decision boundary of Isolation Forest and ECOD so that real attacks look normal. The authors released an open-source PoC (`udo-poison`) that automatically synthesises poison points.
+* **Data-poisoning against anomaly detectors.** Chen *et al.* (IEEE S&P 2024) demonstrated that adding as little as 3 % crafted traffic can shift the decision boundary of Isolation Forest and ECOD so that real attacks look normal. The authors released an open-source PoC (`udo-poison`) that automatically synthesises poison points.[[2]](#references)
* **Backdooring clustering models.** The *BadCME* technique (BlackHat EU 2023) implants a tiny trigger pattern; whenever that trigger appears, a K-Means-based detector quietly places the event inside a “benign” cluster.
* **Evasion of DBSCAN/HDBSCAN.** A 2025 academic pre-print from KU Leuven showed that an attacker can craft beaconing patterns that purposely fall into density gaps, effectively hiding inside *noise* labels.
@@ -547,8 +547,8 @@ evaluate_print("Ensemble", y_test, anomaly_scores)
## References
-- [HDBSCAN – Hierarchical density-based clustering](https://github.com/scikit-learn-contrib/hdbscan)
-- Chen, X. *et al.* “On the Vulnerability of Unsupervised Anomaly Detection to Data Poisoning.” *IEEE Symposium on Security and Privacy*, 2024.
+- [1] [HDBSCAN – Hierarchical density-based clustering](https://github.com/scikit-learn-contrib/hdbscan)
+- [2] Chen, X. *et al.* “On the Vulnerability of Unsupervised Anomaly Detection to Data Poisoning.” *IEEE Symposium on Security and Privacy*, 2024.
diff --git a/src/AI/AI-llm-architecture/7.1.-fine-tuning-for-classification.md b/src/AI/AI-llm-architecture/7.1.-fine-tuning-for-classification.md
index efeba7a4557..7db6c3898b5 100644
--- a/src/AI/AI-llm-architecture/7.1.-fine-tuning-for-classification.md
+++ b/src/AI/AI-llm-architecture/7.1.-fine-tuning-for-classification.md
@@ -18,7 +18,7 @@ Fine-tuning is the process of taking a **pre-trained model** that has learned **
Of course, in order to fine-tune a model you need some structured data to use to specialise your LLM. In the example proposed in [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb), GPT2 is fine tuned to detect if an email is spam or not using the data from [https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip](https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip)_._
-This data set contains much more examples of "not spam" that of "spam", therefore the book suggest to **only use as many examples of "not spam" as of "spam"** (therefore, removing from the training data all the extra examples). In this case, this was 747 examples of each.
+This data set contains much more examples of "not spam" that of "spam", therefore the book suggest to **only use as many examples of "not spam" as of "spam"** (therefore, removing from the training data all the extra examples). In this case, this was 747 examples of each.[[1]](#references)
Then, **70%** of the data set is used for **training**, **10%** for **validation** and **20%** for **testing**.
@@ -28,7 +28,7 @@ Then, **70%** of the data set is used for **training**, **10%** for **validation
### Entries length
-As the training example expects entries (emails text in this case) of the same length, it was decided to make every entry as large as the largest one by adding the ids of `<|endoftext|>` as padding.
+As the training example expects entries (emails text in this case) of the same length, it was decided to make every entry as large as the largest one by adding the ids of `<|endoftext|>` as padding.[[1]](#references)
### Initialize the model
@@ -36,7 +36,7 @@ Using the open-source pre-trained weights initialize the model to train. We have
## Classification head
-In this specific example (predicting if a text is spam or not), we are not interested in fine tune according to the complete vocabulary of GPT2 but we only want the new model to say if the email is spam (1) or not (0). Therefore, we are going to **modify the final layer that** gives the probabilities per token of the vocabulary for one that only gives the probabilities of being spam or not (so like a vocabulary of 2 words).
+In this specific example (predicting if a text is spam or not), we are not interested in fine tune according to the complete vocabulary of GPT2 but we only want the new model to say if the email is spam (1) or not (0). Therefore, we are going to **modify the final layer that** gives the probabilities per token of the vocabulary for one that only gives the probabilities of being spam or not (so like a vocabulary of 2 words).[[1]](#references)
```python
# This code modified the final layer with a Linear one with 2 outs
@@ -51,7 +51,7 @@ out_features=num_classes
## Parameters to tune
-In order to fine tune fast it's easier to not fine tune all the parameters but only some final ones. This is because it's known that the lower layers generally capture basic language structures and semantics applicable. So, just **fine tuning the last layers is usually enough and faster**.
+In order to fine tune fast it's easier to not fine tune all the parameters but only some final ones. This is because it's known that the lower layers generally capture basic language structures and semantics applicable. So, just **fine tuning the last layers is usually enough and faster**.[[1]](#references)
```python
# This code makes all the parameters of the model unrtainable
@@ -72,7 +72,7 @@ param.requires_grad = True
In previos sections the LLM was trained reducing the loss of every predicted token, even though almost all the predicted tokens were in the input sentence (only 1 at the end was really predicted) in order for the model to understand better the language.
-In this case we only care on the model being able to predict if the model is spam or not, so we only care about the last token predicted. Therefore, it's needed to modify out previous training loss functions to only take into account that token.
+In this case we only care on the model being able to predict if the model is spam or not, so we only care about the last token predicted. Therefore, it's needed to modify out previous training loss functions to only take into account that token.[[1]](#references)
This is implemented in [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb) as:
@@ -115,6 +115,6 @@ You can find all the code to fine-tune GPT2 to be a spam classifier in [https://
## References
-- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
+- [1] [Build a Large Language Model from Scratch (Manning)](https://www.manning.com/books/build-a-large-language-model-from-scratch)
{{#include ../../banners/hacktricks-training.md}}
diff --git a/src/AI/AI-llm-architecture/7.2.-fine-tuning-to-follow-instructions.md b/src/AI/AI-llm-architecture/7.2.-fine-tuning-to-follow-instructions.md
index f649375e814..ef24fb944ef 100644
--- a/src/AI/AI-llm-architecture/7.2.-fine-tuning-to-follow-instructions.md
+++ b/src/AI/AI-llm-architecture/7.2.-fine-tuning-to-follow-instructions.md
@@ -37,7 +37,7 @@ Training with these kinds of datasets instead of just raw text helps the model u
A very common mistake is to train on one template and infer with another one. Modern instruct models usually expect the **native chat template of the base model** (`<|user|>`, `<|assistant|>`, `[INST]`, ChatML, etc.), so it's recommended to convert the dataset to the exact format the target model already uses.
-Therefore, one of the first things to do with a dataset that contains requests and answers is to model that data in the desired prompt format, like:
+Therefore, one of the first things to do with a dataset that contains requests and answers is to model that data in the desired prompt format, like:[[1]](#references)
```python
# Code from https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/ch07.ipynb
@@ -73,14 +73,14 @@ Then, as always, it's needed to separate the dataset into training, validation,
## Batching & Data Loaders
-Then, it's needed to batch all the inputs and expected outputs for the training. For this, it's needed to:
+Then, it's needed to batch all the inputs and expected outputs for the training. For this, it's needed to:[[1]](#references)
- Tokenize the texts.
- Pad all the samples to the same length (usually the length will be as big as the context length used to pre-train the LLM).
- Create the expected tokens by shifting 1 the input in a custom collate function.
- Replace some padding tokens with `-100` to exclude them from the training loss: after the first `endoftext` token, substitute all the other `endoftext` tokens by `-100` (because using `cross_entropy(..., ignore_index=-100)` means that it'll ignore targets with `-100`).
- \[Optional] Mask using `-100` also all the tokens belonging to the question so the LLM learns only how to generate the answer. In the Alpaca style this usually means masking everything until `### Response:`.
-- **Modern SFT best practice:** if the dataset is conversational, compute the loss only on the **assistant completion tokens** and not on the user/system prompt. This avoids teaching the model to predict the prompt text itself.
+- **Modern SFT best practice:** if the dataset is conversational, compute the loss only on the **assistant completion tokens** and not on the user/system prompt. This avoids teaching the model to predict the prompt text itself.[[2]](#references)
- **Throughput optimization:** when the dataset contains many short samples, it's common to **pack several examples into the same sequence** to waste less context window.
With this created, it's time to create the data loaders for each dataset (training, validation, and test).
@@ -140,9 +140,9 @@ and many many more.
## Security notes for instruction tuning
-Instruction-tuning datasets are also an attack surface. If an attacker can insert a small number of poisoned samples into the SFT corpus, the model can learn a **trigger-conditioned behaviour** while still looking normal on clean prompts.
+Instruction-tuning datasets are also an attack surface. If an attacker can insert a small number of poisoned samples into the SFT corpus, the model can learn a **trigger-conditioned behaviour** while still looking normal on clean prompts.[[3]](#references)
-Typical malicious patterns to test during red teaming are:
+Typical malicious patterns to test during red teaming are:[[3]](#references)
- **Instruction backdoors:** a rare trigger string, role prefix, unicode pattern, or formatting sequence causes the model to output attacker-chosen content.
- **Sleeper-agent behaviour:** the model behaves correctly during normal evaluations but changes behaviour only when a very specific trigger appears.
@@ -159,7 +159,7 @@ Practical checks:
You can find an example of the code to perform this fine-tuning in [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/gpt_instruction_finetuning.py](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/gpt_instruction_finetuning.py)
-A practical modern alternative is to use a trainer that already supports chat templates, assistant-only loss, packing, and PEFT adapters. If later you want preference alignment, the same ecosystem also provides `DPOTrainer`-style workflows for datasets with `prompt` / `chosen` / `rejected` fields:
+A practical modern alternative is to use a trainer that already supports chat templates, assistant-only loss, packing, and PEFT adapters. If later you want preference alignment, the same ecosystem also provides `DPOTrainer`-style workflows for datasets with `prompt` / `chosen` / `rejected` fields:[[2]](#references)
```python
@@ -179,8 +179,8 @@ trainer.train()
## References
-- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
-- [https://huggingface.co/docs/trl/en/sft_trainer](https://huggingface.co/docs/trl/en/sft_trainer)
-- [https://aclanthology.org/2024.naacl-long.171/](https://aclanthology.org/2024.naacl-long.171/)
+- [1] [Build a Large Language Model from Scratch (Manning)](https://www.manning.com/books/build-a-large-language-model-from-scratch)
+- [2] [TRL SFT Trainer documentation (Hugging Face)](https://huggingface.co/docs/trl/en/sft_trainer)
+- [3] [Instructions as Backdoors: Backdoor Vulnerabilities of Instruction Tuning for Large Language Models](https://aclanthology.org/2024.naacl-long.171/)
{{#include ../../banners/hacktricks-training.md}}
diff --git a/src/AI/KYC-Bypass-Using-AI.md b/src/AI/KYC-Bypass-Using-AI.md
index 309d960c5b5..01120135d12 100644
--- a/src/AI/KYC-Bypass-Using-AI.md
+++ b/src/AI/KYC-Bypass-Using-AI.md
@@ -2,7 +2,7 @@
{{#include ../banners/hacktricks-training.md}}
-Generative models can be used to **bypass browser-based KYC, age-verification, and biometric liveness workflows**. The weak point is often **not** the transport or the cloud liveness provider, but the **camera trust boundary**: a desktop browser usually trusts whatever device `getUserMedia()` exposes as a webcam.
+Generative models can be used to **bypass browser-based KYC, age-verification, and biometric liveness workflows**. The weak point is often **not** the transport or the cloud liveness provider, but the **camera trust boundary**: a desktop browser usually trusts whatever device `getUserMedia()` exposes as a webcam.[[1]](#references)
## Practical Attack Chain
@@ -10,7 +10,7 @@ Generative models can be used to **bypass browser-based KYC, age-verification, a
2. **Inject the forged stream before signing or upload**, for example through a Linux virtual camera created with `v4l2loopback` and fed by OBS or FFmpeg.
3. Let the browser and vendor SDK (WebRTC, AWS, etc.) **capture, sign, and upload the attacker-controlled frames as if they came from a real webcam**.
-This is important during assessments because signed WebSocket chunks or proprietary SDK framing may make **network-layer tampering** impractical, while **camera-layer injection** still works.
+This is important during assessments because signed WebSocket chunks or proprietary SDK framing may make **network-layer tampering** impractical, while **camera-layer injection** still works.[[1]](#references)
## High-Value Testing Angles
@@ -19,7 +19,7 @@ This is important during assessments because signed WebSocket chunks or propriet
- **Constraint weakening**: pages that require exact `deviceId`, `frameRate`, `width`, `height`, or `facingMode` can sometimes be bypassed by monkeypatching `navigator.mediaDevices.getUserMedia` and replacing strict constraints with broader ranges.
- **Low-quality generation plus post-processing**: generate the cheapest video the model can render reliably, then use FFmpeg upscaling or frame interpolation to satisfy capture requirements.
- **Predictable active challenges**: repeated head-movement or light-flash sequences are worth recording and replaying through a generative workflow.
-- **Weak replay detection**: simple scene perturbations, such as crop or position shifts, overlay changes, or slight motion, can be enough when the anti-replay logic only checks superficial frame similarity.
+- **Weak replay detection**: simple scene perturbations, such as crop or position shifts, overlay changes, or slight motion, can be enough when the anti-replay logic only checks superficial frame similarity.[[1]](#references)
## Mobile vs. Desktop Trust Differences
@@ -29,7 +29,7 @@ Native mobile apps can raise the attacker's cost with:
- **execution-integrity** signals such as **Play Integrity** or **App Attest**;
- **motion correlation** between video and accelerometer or gyroscope telemetry.
-Desktop web flows usually lack an equivalent camera chain of trust, so they are generally the path of least resistance.
+Desktop web flows usually lack an equivalent camera chain of trust, so they are generally the path of least resistance.[[1]](#references)
## Defensive Review Notes
@@ -38,13 +38,13 @@ When reviewing a KYC or liveness integration, verify whether it:
- allows a **desktop-browser fallback** for a workflow that was only threat-modeled for mobile capture;
- relies mostly on **algorithmic liveness** without strong human escalation for suspicious sessions;
- uses **stable or predictable challenges** that can be pre-recorded and fed into a generation pipeline;
-- detects **`getUserMedia` monkeypatching**, virtual cameras, inconsistent browser hardware telemetry, or missing device attestation.
+- detects **`getUserMedia` monkeypatching**, virtual cameras, inconsistent browser hardware telemetry, or missing device attestation.[[1]](#references)
## References
-- [Synacktiv - KYC: Bypass age verification using generative video models](https://www.synacktiv.com/en/publications/kyc-bypass-age-verification-using-generative-video-models.html)
-- [Amazon Rekognition Face Liveness](https://docs.aws.amazon.com/rekognition/latest/dg/face-liveness.html)
-- [v4l2loopback](https://github.com/v4l2loopback/v4l2loopback)
-- [MDN - MediaDevices.getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)
+- [1] [Synacktiv - KYC: Bypass age verification using generative video models](https://www.synacktiv.com/en/publications/kyc-bypass-age-verification-using-generative-video-models.html)
+- [2] [Amazon Rekognition Face Liveness](https://docs.aws.amazon.com/rekognition/latest/dg/face-liveness.html)
+- [3] [v4l2loopback](https://github.com/v4l2loopback/v4l2loopback)
+- [4] [MDN - MediaDevices.getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)
{{#include ../banners/hacktricks-training.md}}
diff --git a/src/binary-exploitation/linux-kernel-exploitation/af-unix-msg-oob-uaf-skb-primitives.md b/src/binary-exploitation/linux-kernel-exploitation/af-unix-msg-oob-uaf-skb-primitives.md
index 97be6550cee..30aa50d18c4 100644
--- a/src/binary-exploitation/linux-kernel-exploitation/af-unix-msg-oob-uaf-skb-primitives.md
+++ b/src/binary-exploitation/linux-kernel-exploitation/af-unix-msg-oob-uaf-skb-primitives.md
@@ -4,23 +4,23 @@
## TL;DR
-- Linux >=6.9 introduced a flawed `manage_oob()` refactor (`5aa57d9f2d53`) for AF_UNIX `MSG_OOB` handling. Stacked zero-length SKBs bypassed the logic that clears `u->oob_skb`, so a normal `recv()` could free the out-of-band SKB while the pointer remained live, leading to CVE-2025-38236.
+- Linux >=6.9 introduced a flawed `manage_oob()` refactor (`5aa57d9f2d53`) for AF_UNIX `MSG_OOB` handling. Stacked zero-length SKBs bypassed the logic that clears `u->oob_skb`, so a normal `recv()` could free the out-of-band SKB while the pointer remained live, leading to CVE-2025-38236.[[1]](#references)
- Re-triggering `recv(..., MSG_OOB)` dereferences the dangling `struct sk_buff`. With `MSG_PEEK`, the path `unix_stream_recv_urg() -> __skb_datagram_iter() -> copy_to_user()` becomes a stable 1-byte arbitrary kernel read; without `MSG_PEEK` the primitive increments `UNIXCB(oob_skb).consumed` at offset `0x44`, i.e., adds +4 GiB to the upper dword of any 64-bit value placed at offset `0x40` inside the reallocated object.
- By draining order-0/1 unmovable pages (page-table spray), force-freeing an SKB slab page into the buddy allocator, and reusing the physical page as a pipe buffer, the exploit forges SKB metadata in controlled memory to identify the dangling page and pivot the read primitive into `.data`, vmemmap, per-CPU, and page-table regions despite usercopy hardening.
- The same page can later be recycled as the top kernel-stack page of a freshly cloned thread. `CONFIG_RANDOMIZE_KSTACK_OFFSET` becomes an oracle: by probing the stack layout while `pipe_write()` blocks, the attacker waits until the spilled `copy_page_from_iter()` length (R14) lands at offset `0x40`, then fires the +4 GiB increment to corrupt the stack value.
- A self-looping `skb_shinfo()->frag_list` keeps the UAF syscall spinning in kernel space until a cooperating thread stalls `copy_from_iter()` (via `mprotect()` over a VMA containing a single `MADV_DONTNEED` hole). Breaking the loop releases the increment exactly when the stack target is live, inflating the `bytes` argument so `copy_page_from_iter()` writes past the pipe buffer page into the next physical page.
-- By monitoring pipe-buffer PFNs and page tables with the read primitive, the attacker ensures the following page is a PTE page, converts the OOB copy into arbitrary PTE writes, and obtains unrestricted kernel read/write/execute. Chrome mitigated reachability by blocking `MSG_OOB` from renderers (`6711812`), and Linux fixed the logic flaw in `32ca245464e1` plus introduced `CONFIG_AF_UNIX_OOB` to make the feature optional.
+- By monitoring pipe-buffer PFNs and page tables with the read primitive, the attacker ensures the following page is a PTE page, converts the OOB copy into arbitrary PTE writes, and obtains unrestricted kernel read/write/execute. Chrome mitigated reachability by blocking `MSG_OOB` from renderers (`6711812`), and Linux fixed the logic flaw in `32ca245464e1` plus introduced `CONFIG_AF_UNIX_OOB` to make the feature optional.[[1]](#references)[[2]](#references)[[3]](#references)[[4]](#references)
## Version / configuration checklist
- **Feature lineage:** AF_UNIX `MSG_OOB` support itself was added by `314001f0bf92` ("af_unix: Add OOB support"), merged for Linux 5.15. The last byte of a `send(..., MSG_OOB)` becomes the urgent byte and is tracked through `unix_sock->oob_skb`.
-- **Public exploitability window:** Jann Horn's public exploit write-up focuses on Linux `>= 6.9`, but vendors can backport both buggy and fixed AF_UNIX OOB patches to older stable trees. Check for `32ca245464e1` (or an equivalent stable backport) instead of trusting the release string alone.
-- **Build/runtime gates:** The attack path requires AF_UNIX OOB support to exist at runtime (`CONFIG_AF_UNIX_OOB`). Since `5155cbcdbf03` (December 2024), that option is explicitly visible in `.config`; before that, OOB support silently rode along with AF_UNIX support by default.
-- **Sandbox reachability:** Any sandbox that exposes AF_UNIX stream sockets and does not filter `MSG_OOB` / `MSG_PEEK` stays interesting even if the application never intentionally uses urgent data. Chrome closed the reachable path by allowlisting socket-call flags in CL `6711812`.
+- **Public exploitability window:** Jann Horn's public exploit write-up focuses on Linux `>= 6.9`, but vendors can backport both buggy and fixed AF_UNIX OOB patches to older stable trees. Check for `32ca245464e1` (or an equivalent stable backport) instead of trusting the release string alone.[[1]](#references)[[2]](#references)
+- **Build/runtime gates:** The attack path requires AF_UNIX OOB support to exist at runtime (`CONFIG_AF_UNIX_OOB`). Since `5155cbcdbf03` (December 2024), that option is explicitly visible in `.config`; before that, OOB support silently rode along with AF_UNIX support by default.[[4]](#references)
+- **Sandbox reachability:** Any sandbox that exposes AF_UNIX stream sockets and does not filter `MSG_OOB` / `MSG_PEEK` stays interesting even if the application never intentionally uses urgent data. Chrome closed the reachable path by allowlisting socket-call flags in CL `6711812`.[[3]](#references)
## Root cause: `manage_oob()` assumes only one zero-length SKB
-`unix_stream_read_generic()` expects every SKB returned by `manage_oob()` to have `unix_skb_len() > 0`. After `93c99f21db36`, `manage_oob()` skipped the `skb == u->oob_skb` cleanup path whenever it first removed a zero-length SKB left behind by `recv(MSG_OOB)`. The subsequent fix (`5aa57d9f2d53`) still advanced from the first zero-length SKB to `skb_peek_next()` without re-checking the length. With two consecutive zero-length SKBs, the function returned the second empty SKB; `unix_stream_read_generic()` then skipped it without calling `manage_oob()` again, so the true OOB SKB was dequeued and freed while `u->oob_skb` still pointed to it.
+`unix_stream_read_generic()` expects every SKB returned by `manage_oob()` to have `unix_skb_len() > 0`. After `93c99f21db36`, `manage_oob()` skipped the `skb == u->oob_skb` cleanup path whenever it first removed a zero-length SKB left behind by `recv(MSG_OOB)`. The subsequent fix (`5aa57d9f2d53`) still advanced from the first zero-length SKB to `skb_peek_next()` without re-checking the length. With two consecutive zero-length SKBs, the function returned the second empty SKB; `unix_stream_read_generic()` then skipped it without calling `manage_oob()` again, so the true OOB SKB was dequeued and freed while `u->oob_skb` still pointed to it.[[1]](#references)
### Minimal trigger sequence
@@ -42,12 +42,12 @@ recv(socks[0], &byte, 1, MSG_OOB); // dangling u->oob_skb
- **Boundary semantics:** AF_UNIX OOB is TCP-like: a normal `recv()` stops at the urgent mark even when the caller's buffer is large enough to consume more (`oob_break` in the upstream kselftest). This is why a consumed OOB SKB can remain relevant after the urgent byte was already read.
- **Dropping vs. reading urgent data:** With the default `SO_OOBINLINE = 0`, `recv(MSG_OOB)` returns the urgent byte, but the queue still keeps the consumed SKB as a boundary marker. A later plain `recv()` can either stop at that mark or drop the consumed OOB and continue into the following SKB (`oob_break_drop`) — the exact corner that turns stale `u->oob_skb` into a UAF.
- **`SO_OOBINLINE` changes the trigger surface:** If `SO_OOBINLINE` is enabled on the receiver, `recv(MSG_OOB)` returns `-EINVAL` and the urgent byte is consumed through plain `recv()` instead. Public reproducers assume the default non-inline mode.
-- **Useful observability:** `EPOLLPRI` tracks whether an urgent mark is still pending, and `ioctl(fd, SIOCATMARK, &atmark)` reveals whether the next unread byte sits at the urgent boundary. When adapting the primitive to another kernel, `tools/testing/selftests/net/af_unix/msg_oob.c` is a good behavioural oracle.
+- **Useful observability:** `EPOLLPRI` tracks whether an urgent mark is still pending, and `ioctl(fd, SIOCATMARK, &atmark)` reveals whether the next unread byte sits at the urgent boundary. When adapting the primitive to another kernel, `tools/testing/selftests/net/af_unix/msg_oob.c` is a good behavioural oracle.[[1]](#references)[[5]](#references)
## Primitives exposed by `unix_stream_recv_urg()`
1. **1-byte arbitrary read (repeatable):** `state->recv_actor()` ultimately performs `copy_to_user(user, skb_sourced_addr, 1)`. If the dangling SKB is reallocated into attacker-controlled memory (or into a controlled alias such as a pipe page), every `recv(MSG_OOB | MSG_PEEK)` copies a byte from an arbitrary kernel address allowed by `__check_object_size()` to user space without crashing. Keeping `MSG_PEEK` set preserves the dangling pointer for unlimited reads.
-2. **Constrained write:** When `MSG_PEEK` is clear, `UNIXCB(oob_skb).consumed += 1` increments the 32-bit field at offset `0x44`. On 0x100-aligned SKB allocations this sits four bytes above an 8-byte aligned word, converting the primitive into a +4 GiB increment of the word hosted at offset `0x40`. Turning this into a kernel write requires positioning a sensitive 64-bit value at that offset.
+2. **Constrained write:** When `MSG_PEEK` is clear, `UNIXCB(oob_skb).consumed += 1` increments the 32-bit field at offset `0x44`. On 0x100-aligned SKB allocations this sits four bytes above an 8-byte aligned word, converting the primitive into a +4 GiB increment of the word hosted at offset `0x40`. Turning this into a kernel write requires positioning a sensitive 64-bit value at that offset.[[1]](#references)
## Reallocating the SKB page for arbitrary read
@@ -56,13 +56,13 @@ recv(socks[0], &byte, 1, MSG_OOB); // dangling u->oob_skb
3. **Return the slab page to the buddy allocator:** Free every object on the page, then perform enough additional allocations/frees to push the page out of SLUB per-CPU partial lists and per-CPU page lists so it becomes an order-1 page on the buddy freelist.
4. **Reallocate as pipe buffer:** Create hundreds of pipes; each pipe reserves at least two 0x1000-byte data pages (`PIPE_MIN_DEF_BUFFERS`). When the buddy allocator splits an order-1 page, one half reuses the freed SKB page. To locate which pipe and which offset aliases `oob_skb`, write unique marker bytes into fake SKBs stored throughout pipe pages and issue repeated `recv(MSG_OOB | MSG_PEEK)` calls until the marker is returned.
5. **Forge a stable SKB layout:** Populate the aliased pipe page with a fake `struct sk_buff` whose `data`/`head` pointers and `skb_shared_info` structure point to arbitrary kernel addresses of interest. Because x86_64 disables SMAP inside `copy_to_user()`, user-mode addresses can serve as staging buffers until kernel pointers are known.
-6. **Respect usercopy hardening:** The copy succeeds against `.data/.bss`, vmemmap entries, per-CPU vmalloc ranges, other threads' kernel stacks, and direct-map pages that do not straddle higher-order folio boundaries. Reads against `.text` or specialized caches rejected by `__check_heap_object()` simply return `-EFAULT` without killing the process.
+6. **Respect usercopy hardening:** The copy succeeds against `.data/.bss`, vmemmap entries, per-CPU vmalloc ranges, other threads' kernel stacks, and direct-map pages that do not straddle higher-order folio boundaries. Reads against `.text` or specialized caches rejected by `__check_heap_object()` simply return `-EFAULT` without killing the process.[[1]](#references)
## Introspecting allocators with the read primitive
- **Break KASLR:** Read any IDT descriptor from the fixed mapping at `CPU_ENTRY_AREA_RO_IDT_VADDR` (`0xfffffe0000000000`) and subtract the known handler offset to recover the kernel base.
- **SLUB/buddy state:** Global `.data` symbols reveal `kmem_cache` bases, while vmemmap entries expose each page's type flags, freelist pointer, and owning cache. Scanning per-CPU vmalloc segments uncovers `struct kmem_cache_cpu` instances so the next allocation address of key caches (e.g., `skbuff_head_cache`, `kmalloc-cg-192`) becomes predictable.
-- **Page tables:** Instead of reading `mm_struct` (blocked by usercopy), walk the global `pgd_list` (`struct ptdesc`) and match the current `mm_struct` via `cpu_tlbstate.loaded_mm`. Once the root `pgd` is known, the primitive can traverse every page table to map PFNs for pipe buffers, page tables, and kernel stacks.
+- **Page tables:** Instead of reading `mm_struct` (blocked by usercopy), walk the global `pgd_list` (`struct ptdesc`) and match the current `mm_struct` via `cpu_tlbstate.loaded_mm`. Once the root `pgd` is known, the primitive can traverse every page table to map PFNs for pipe buffers, page tables, and kernel stacks.[[1]](#references)
## Recycling the SKB page as the top kernel-stack page
@@ -70,45 +70,45 @@ recv(socks[0], &byte, 1, MSG_OOB); // dangling u->oob_skb
2. Immediately allocate four helper pipe pages and then free them in reverse order so the buddy allocator's LIFO behavior is deterministic.
3. Call `clone()` to spawn a helper thread; Linux stacks are four pages on x86_64, so the four most recently freed pages become its stack, with the last freed page (the former SKB page) at the highest addresses.
4. Verify via page-table walk that the helper thread's top stack PFN equals the recycled SKB PFN.
-5. Use the arbitrary read to observe the stack layout while steering the thread into `pipe_write()`. `CONFIG_RANDOMIZE_KSTACK_OFFSET` subtracts a random 0x0–0x3f0 (aligned) from `RSP` per syscall; repeated writes combined with `poll()`/`read()` from another thread reveal when the writer blocks with the desired offset. When lucky, the spilled `copy_page_from_iter()` `bytes` argument (R14) sits at offset `0x40` inside the recycled page.
+5. Use the arbitrary read to observe the stack layout while steering the thread into `pipe_write()`. `CONFIG_RANDOMIZE_KSTACK_OFFSET` subtracts a random 0x0–0x3f0 (aligned) from `RSP` per syscall; repeated writes combined with `poll()`/`read()` from another thread reveal when the writer blocks with the desired offset. When lucky, the spilled `copy_page_from_iter()` `bytes` argument (R14) sits at offset `0x40` inside the recycled page.[[1]](#references)
## Placing fake SKB metadata on the stack
- Use `sendmsg()` on an AF_UNIX datagram socket: the kernel copies the user `sockaddr_un` into a stack-resident `sockaddr_storage` (up to 108 bytes) and the ancillary data into another on-stack buffer before the syscall blocks waiting for queue space. This allows planting a precise fake SKB structure in stack memory.
- Detect when the copy finished by supplying a 1-byte control message located in an unmapped user page; `____sys_sendmsg()` faults it in, so a helper thread polling `mincore()` on that address learns when the destination page is present.
-- Zero-initialized padding from `CONFIG_INIT_STACK_ALL_ZERO` conveniently fills unused fields, completing a valid SKB header without extra writes.
+- Zero-initialized padding from `CONFIG_INIT_STACK_ALL_ZERO` conveniently fills unused fields, completing a valid SKB header without extra writes.[[1]](#references)
## Timing the +4 GiB increment with a self-looping frag list
- Forge `skb_shinfo(fakeskb)->frag_list` to point to a second fake SKB (stored in attacker-controlled user memory) that has `len = 0` and `next = &self`. When `skb_walk_frags()` iterates this list inside `__skb_datagram_iter()`, execution spins indefinitely because the iterator never reaches `NULL` and the copy loop makes no progress.
-- Keep the recv syscall running inside the kernel by letting the second fake SKB self-loop. When it's time to fire the increment, simply change the second SKB's `next` pointer from user space to `NULL`. The loop exits and `unix_stream_recv_urg()` immediately executes `UNIXCB(oob_skb).consumed += 1` once, affecting whatever object currently occupies the recycled stack page at offset `0x40`.
+- Keep the recv syscall running inside the kernel by letting the second fake SKB self-loop. When it's time to fire the increment, simply change the second SKB's `next` pointer from user space to `NULL`. The loop exits and `unix_stream_recv_urg()` immediately executes `UNIXCB(oob_skb).consumed += 1` once, affecting whatever object currently occupies the recycled stack page at offset `0x40`.[[1]](#references)
## Stalling `copy_from_iter()` without userfaultfd
- Map a giant anonymous RW VMA and fault it in fully.
- Punch a single-page hole with `madvise(MADV_DONTNEED, hole, PAGE_SIZE)` and place that address inside the `iov_iter` used for `write(pipefd, user_buf, 0x3000)`.
-- In parallel, call `mprotect()` on the entire VMA from another thread. The syscall grabs the mmap write lock and walks every PTE. When the pipe writer reaches the hole, the page fault handler blocks on the mmap lock held by `mprotect()`, pausing `copy_from_iter()` at a deterministic point while the spilled `bytes` value resides on the stack segment hosted by the recycled SKB page.
+- In parallel, call `mprotect()` on the entire VMA from another thread. The syscall grabs the mmap write lock and walks every PTE. When the pipe writer reaches the hole, the page fault handler blocks on the mmap lock held by `mprotect()`, pausing `copy_from_iter()` at a deterministic point while the spilled `bytes` value resides on the stack segment hosted by the recycled SKB page.[[1]](#references)
## Turning the increment into arbitrary PTE writes
1. **Fire the increment:** Release the frag loop while `copy_from_iter()` is stalled so the +4 GiB increment hits the `bytes` variable.
2. **Overflow the copy:** Once the fault resumes, `copy_page_from_iter()` believes it can copy >4 GiB into the current pipe page. After filling the legitimate 0x2000 bytes (two pipe buffers), it executes another iteration and writes the remaining user data into whatever physical page follows the pipe buffer PFN.
3. **Arrange adjacency:** Using allocator telemetry, force the buddy allocator to place a process-owned PTE page immediately after the target pipe buffer page (e.g., alternate between allocating pipe pages and touching new virtual ranges to trigger page-table allocation until the PFNs align inside the same 2 MiB pageblock).
-4. **Overwrite page tables:** Encode desired PTE entries in the extra 0x1000 bytes of user data so the OOB `copy_from_iter()` fills the neighbouring page with attacker-chosen entries, granting RW/RWX user mappings of kernel physical memory or rewriting existing entries to disable SMEP/SMAP.
+4. **Overwrite page tables:** Encode desired PTE entries in the extra 0x1000 bytes of user data so the OOB `copy_from_iter()` fills the neighbouring page with attacker-chosen entries, granting RW/RWX user mappings of kernel physical memory or rewriting existing entries to disable SMEP/SMAP.[[1]](#references)
## Mitigations / hardening ideas
-- **Kernel:** Apply `32ca245464e1479bfea8592b9db227fdc1641705` (properly revalidates SKBs) and consider disabling AF_UNIX OOB entirely unless strictly needed via `CONFIG_AF_UNIX_OOB` (`5155cbcdbf03`). Harden `manage_oob()` with additional sanity checks (e.g., loop until `unix_skb_len() > 0`) and audit other socket protocols for similar assumptions.
-- **Sandboxing:** Filter `MSG_OOB`/`MSG_PEEK` flags in seccomp profiles or higher-level broker APIs (Chrome change `6711812` now blocks renderer-side `MSG_OOB`).
+- **Kernel:** Apply `32ca245464e1479bfea8592b9db227fdc1641705` (properly revalidates SKBs) and consider disabling AF_UNIX OOB entirely unless strictly needed via `CONFIG_AF_UNIX_OOB` (`5155cbcdbf03`). Harden `manage_oob()` with additional sanity checks (e.g., loop until `unix_skb_len() > 0`) and audit other socket protocols for similar assumptions.[[2]](#references)[[4]](#references)
+- **Sandboxing:** Filter `MSG_OOB`/`MSG_PEEK` flags in seccomp profiles or higher-level broker APIs (Chrome change `6711812` now blocks renderer-side `MSG_OOB`).[[3]](#references)
- **Allocator defenses:** Strengthening SLUB freelist randomization or enforcing per-cache page coloring would complicate deterministic page recycling; pipeline-limiting of pipe buffer counts also reduces reallocation reliability.
- **Monitoring:** Expose high-rate page-table allocation or abnormal pipe usage via telemetry—this exploit burns large amounts of page tables and pipe buffers.
## References
-- [Project Zero – "From Chrome renderer code exec to kernel with MSG_OOB"](https://projectzero.google/2025/08/from-chrome-renderer-code-exec-to-kernel.html)
-- [Linux fix for CVE-2025-38236 (`manage_oob` revalidation)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=32ca245464e1479bfea8592b9db227fdc1641705)
-- [Chromium CL 6711812 – block `MSG_OOB` in renderers](https://chromium-review.googlesource.com/c/chromium/src/+/6711812)
-- [Commit adding `CONFIG_AF_UNIX_OOB` prompt](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5155cbcdbf03f207095f9a3794942a25aa7e5f58)
-- [Linux kselftest for AF_UNIX OOB semantics (`tools/testing/selftests/net/af_unix/msg_oob.c`)](https://github.com/torvalds/linux/blob/master/tools/testing/selftests/net/af_unix/msg_oob.c)
+- [1] [Project Zero – "From Chrome renderer code exec to kernel with MSG_OOB"](https://projectzero.google/2025/08/from-chrome-renderer-code-exec-to-kernel.html)
+- [2] [Linux fix for CVE-2025-38236 (`manage_oob` revalidation)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=32ca245464e1479bfea8592b9db227fdc1641705)
+- [3] [Chromium CL 6711812 – block `MSG_OOB` in renderers](https://chromium-review.googlesource.com/c/chromium/src/+/6711812)
+- [4] [Commit adding `CONFIG_AF_UNIX_OOB` prompt](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5155cbcdbf03f207095f9a3794942a25aa7e5f58)
+- [5] [Linux kselftest for AF_UNIX OOB semantics (`tools/testing/selftests/net/af_unix/msg_oob.c`)](https://github.com/torvalds/linux/blob/master/tools/testing/selftests/net/af_unix/msg_oob.c)
{{#include ../../banners/hacktricks-training.md}}
diff --git a/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md b/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md
index 8ac2135167a..c41539bf4c1 100644
--- a/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md
+++ b/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md
@@ -2,7 +2,7 @@
{{#include ../../banners/hacktricks-training.md}}
-This page documents a TOCTOU race condition in Linux/Android POSIX CPU timers that can corrupt timer state and crash the kernel, and under some circumstances be steered toward privilege escalation.
+This page documents a TOCTOU race condition in Linux/Android POSIX CPU timers that can corrupt timer state and crash the kernel, and under some circumstances be steered toward privilege escalation.[[1]](#references)[[5]](#references)[[6]](#references)[[7]](#references)
- Affected component: kernel/time/posix-cpu-timers.c
- Primitive: expiry vs deletion race under task exit
@@ -147,7 +147,7 @@ Sequence
2) collect_timerqueue() sets ctmr->firing = 1 and moves the timer to the temporary firing list.
3) handle_posix_cpu_timers() drops sighand via unlock_task_sighand() to deliver timers outside the lock.
4) Immediately after unlock, the exiting task can be reaped; a sibling thread executes posix_cpu_timer_del().
-5) In this window, posix_cpu_timer_del() may fail to acquire state via cpu_timer_task_rcu()/lock_task_sighand() and thus skip the normal in-flight guard that checks timer->it.cpu.firing. Deletion proceeds as if not firing, corrupting state while expiry is being handled, leading to crashes/UB.
+5) In this window, posix_cpu_timer_del() may fail to acquire state via cpu_timer_task_rcu()/lock_task_sighand() and thus skip the normal in-flight guard that checks timer->it.cpu.firing. Deletion proceeds as if not firing, corrupting state while expiry is being handled, leading to crashes/UB.[[1]](#references)
Why TASK_WORK mode is safe by design
- With CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, expiry is deferred to task_work; exit_task_work runs before exit_notify, so the IRQ-time overlap with reaping does not occur.
@@ -162,10 +162,10 @@ if (tsk->exit_state)
return;
```
-- This prevents entering handle_posix_cpu_timers() for exiting tasks, eliminating the window where posix_cpu_timer_del() could miss it.cpu.firing and race with expiry processing.
+- This prevents entering handle_posix_cpu_timers() for exiting tasks, eliminating the window where posix_cpu_timer_del() could miss it.cpu.firing and race with expiry processing.[[2]](#references)[[3]](#references)
Impact
-- Kernel memory corruption of timer structures during concurrent expiry/deletion can yield immediate crashes (DoS) and is a strong primitive toward privilege escalation due to arbitrary kernel-state manipulation opportunities.
+- Kernel memory corruption of timer structures during concurrent expiry/deletion can yield immediate crashes (DoS) and is a strong primitive toward privilege escalation due to arbitrary kernel-state manipulation opportunities.[[1]](#references)
Triggering the bug (safe, reproducible conditions)
Build/config
@@ -216,7 +216,7 @@ Notes for exploitation research
- The disclosed behavior is a reliable kernel crash primitive; turning it into privilege escalation typically needs an additional controllable overlap (object lifetime or write-what-where influence) beyond the scope of this summary. Treat any PoC as potentially destabilizing and run only in emulators/VMs.
### Chronomaly exploit strategy (priv-esc without fixed text offsets)
-- **Tested target & configs:** x86_64 v5.10.157 under QEMU (4 cores, 3 GB RAM). Critical options: `CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n`, `CONFIG_PREEMPT=y`, `CONFIG_SLAB_MERGE_DEFAULT=n`, `DEBUG_LIST=n`, `BUG_ON_DATA_CORRUPTION=n`, `LIST_HARDENED=n`.
+- **Tested target & configs:** x86_64 v5.10.157 under QEMU (4 cores, 3 GB RAM). Critical options: `CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n`, `CONFIG_PREEMPT=y`, `CONFIG_SLAB_MERGE_DEFAULT=n`, `DEBUG_LIST=n`, `BUG_ON_DATA_CORRUPTION=n`, `LIST_HARDENED=n`.[[4]](#references)
- **Race steering with CPU timers:** A racing thread (`race_func()`) burns CPU while CPU timers fire; `free_func()` polls `SIGUSR1` to confirm if the timer fired. Tune `CPU_USAGE_THRESHOLD` so signals arrive only sometimes (intermittent "Parent raced too late/too early" messages). If timers fire every attempt, lower the threshold; if they never fire before thread exit, raise it.
- **Dual-process alignment into `send_sigqueue()`:** Parent/child processes try to hit a second race window inside `send_sigqueue()`. The parent sleeps `PARENT_SETTIME_DELAY_US` microseconds before arming timers; adjust downward when you mostly see "Parent raced too late" and upward when you mostly see "Parent raced too early". Seeing both indicates you are straddling the window; success is expected within ~1 minute once tuned.
- **Cross-cache UAF replacement:** The exploit frees a `struct sigqueue` then grooms allocator state (`sigqueue_crosscache_preallocs()`) so both the dangling `uaf_sigqueue` and the replacement `realloc_sigqueue` land on a pipe buffer data page (cross-cache reallocation). Reliability assumes a quiet kernel with few prior `sigqueue` allocations; if per-CPU/per-node partial slab pages already exist (busy systems), the replacement will miss and the chain fails. The author intentionally left it unoptimized for noisy kernels.
@@ -228,12 +228,12 @@ ksmbd-streams_xattr-oob-write-cve-2025-37947.md
{{#endref}}
## References
-- [Race Against Time in the Kernel’s Clockwork (StreyPaws)](https://streypaws.github.io/posts/Race-Against-Time-in-the-Kernel-Clockwork/)
-- [Android security bulletin – September 2025](https://source.android.com/docs/security/bulletin/2025-09-01)
-- [Android common kernel patch commit 157f357d50b5…](https://android.googlesource.com/kernel/common/+/157f357d50b5038e5eaad0b2b438f923ac40afeb%5E%21/#F0)
-- [Chronomaly exploit PoC (CVE-2025-38352)](https://github.com/farazsth98/chronomaly)
-- [CVE-2025-38352 analysis – Part 1](https://faith2dxy.xyz/2025-12-22/cve_2025_38352_analysis/)
-- [CVE-2025-38352 analysis – Part 2](https://faith2dxy.xyz/2025-12-24/cve_2025_38352_analysis_part_2/)
-- [CVE-2025-38352 analysis – Part 3](https://faith2dxy.xyz/2026-01-03/cve_2025_38352_analysis_part_3/)
+- [1] [Race Against Time in the Kernel’s Clockwork (StreyPaws)](https://streypaws.github.io/posts/Race-Against-Time-in-the-Kernel-Clockwork/)
+- [2] [Android security bulletin – September 2025](https://source.android.com/docs/security/bulletin/2025-09-01)
+- [3] [Android common kernel patch commit 157f357d50b5…](https://android.googlesource.com/kernel/common/+/157f357d50b5038e5eaad0b2b438f923ac40afeb%5E%21/#F0)
+- [4] [Chronomaly exploit PoC (CVE-2025-38352)](https://github.com/farazsth98/chronomaly)
+- [5] [CVE-2025-38352 analysis – Part 1](https://faith2dxy.xyz/2025-12-22/cve_2025_38352_analysis/)
+- [6] [CVE-2025-38352 analysis – Part 2](https://faith2dxy.xyz/2025-12-24/cve_2025_38352_analysis_part_2/)
+- [7] [CVE-2025-38352 analysis – Part 3](https://faith2dxy.xyz/2026-01-03/cve_2025_38352_analysis_part_3/)
{{#include ../../banners/hacktricks-training.md}}
\ No newline at end of file
diff --git a/src/crypto/hashes/README.md b/src/crypto/hashes/README.md
index 1df7ec14c42..28e33139fd3 100644
--- a/src/crypto/hashes/README.md
+++ b/src/crypto/hashes/README.md
@@ -29,11 +29,11 @@ Then you can compute a valid signature for:
`message || padding || appended_data`
-without knowing the secret.
+without knowing the secret.[[1]](#references)
### Important limitation: HMAC is not affected
-Length extension attacks apply to constructions like `HASH(secret || message)` for Merkle–Damgård hashes. They do not apply to **HMAC** (e.g., HMAC-SHA256), which is specifically designed to avoid this class of problem.
+Length extension attacks apply to constructions like `HASH(secret || message)` for Merkle–Damgård hashes. They do not apply to **HMAC** (e.g., HMAC-SHA256), which is specifically designed to avoid this class of problem.[[1]](#references)
### Tools
@@ -76,4 +76,8 @@ https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-lengt
- Truncated hashes / custom transforms → normalize and retry.
- Weak KDF parameters (e.g., low PBKDF2 iterations) → still crackable.
+## References
+
+- [1] [Everything you need to know about hash length extension attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks)
+
{{#include ../../banners/hacktricks-training.md}}
diff --git a/src/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md b/src/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md
index 45674c9954a..159e0ff4afc 100644
--- a/src/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md
+++ b/src/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md
@@ -8,7 +8,7 @@ If a web page is creating a PDF using user controlled input, you can try to **tr
So, if the **PDF creator bot finds** some kind of **HTML** **tags**, it is going to **interpret** them, and you can **abuse** this behaviour to cause a **Server XSS**.
Please, notice that the `` tags don't work always, so you will need a different method to execute JS (for example, abusing `[[2]](#references)[[3]](#references)
### Popular PDF generation
@@ -53,7 +53,7 @@ Also, note that in a regular exploitation you will be **able to see/download the
### SVG
-Any of the previous of following payloads may be used inside this SVG payload. One iframe accessing Burpcollab subdomain and another one accessing the metadata endpoint are put as examples.
+Any of the previous of following payloads may be used inside this SVG payload. One iframe accessing Burpcollab subdomain and another one accessing the metadata endpoint are put as examples.[[1]](#references)
```html