Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions src/pentesting-web/file-inclusion/README.md

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions src/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## Intro

This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file.
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file.<sup>[[3]](#references)</sup>

Basically the goal of the script is to **generate a Base64** string at the **beginning** of the file that will be **finally decoded** providing the desired payload that will be **interpreted by `include`**.

Expand All @@ -27,7 +27,7 @@ The loop to generate arbitrary content is:

## How to add also suffixes to the resulting data

[**This writeup explains**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) how you can still abuse PHP filters to add suffixes to the resulting string. This is great in case you need the output to have some specific format (like json or maybe adding some PNG magic bytes)
[**This writeup explains**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) how you can still abuse PHP filters to add suffixes to the resulting string. This is great in case you need the output to have some specific format (like json or maybe adding some PNG magic bytes)<sup>[[4]](#references)</sup>

## Automatic Tools

Expand Down Expand Up @@ -264,18 +264,20 @@ function find_vals($init_val) {

- Chain a memory bomb (e.g., a dozen `convert.iconv.UTF8.UCS-4LE` passes) with `dechunk` so the first leaked base64 digit controls the outcome: if it turns hexadecimal the payload collapses silently, otherwise PHP exhausts memory and throws an error, giving you a 1-bit oracle.
- Query the oracle repeatedly while iconv shuffles (`convert.iconv.UTF16.UTF16BE`, `convert.iconv.UCS-4LE.UCS-4`, etc.) rotate arbitrary base64 digits to the front, letting you read files byte by byte even when nothing is echoed.
- Synacktiv's `php_filter_chains_oracle_exploit` automates the chain, keeps payloads GET-safe, and documents the PHP file primitives (file_get_contents, finfo, hash_file, getimagesize, ...) that you can abuse to pivot from LFI to credentials or staged RCE.
- Synacktiv's `php_filter_chains_oracle_exploit` automates the chain, keeps payloads GET-safe, and documents the PHP file primitives (file_get_contents, finfo, hash_file, getimagesize, ...) that you can abuse to pivot from LFI to credentials or staged RCE.<sup>[[1]](#references)</sup>

### Lightyear digit-set jumps & chunk pruning

- Lightyear builds alternative base64 digit sets via sequences like `convert.iconv.IBM1144.HP-ROMAN8|convert.iconv.IBM1122.IBM1026|convert.iconv.8859_1.IBM037`, turning a chosen digit into a newline; prepend one hexadecimal char, run `dechunk`, and you can jump over arbitrary chunks while keeping payloads URL-length compliant.
- Lightyear builds alternative base64 digit sets via sequences like `convert.iconv.IBM1144.HP-ROMAN8|convert.iconv.IBM1122.IBM1026|convert.iconv.8859_1.IBM037`, turning a chosen digit into a newline; prepend one hexadecimal char, run `dechunk`, and you can jump over arbitrary chunks while keeping payloads URL-length compliant.<sup>[[2]](#references)</sup>
- Instead of swapping bytes repeatedly, Lightyear chains several jumps, tracks safe chunk sizes, and closes each leak with a six-query dichotomy tree that halves the candidate digit set, so large files can be dumped via GET parameters without triggering PHP warnings.
- The release ships ready-to-run Python tooling: once you control `include()`, aim it at `/etc/passwd`, PHP session stores, or config files, dump them, then fall back to the base64-prepend method above to craft RCE payloads inside `php://temp` or other write-less sinks.

## References

- [Synacktiv – PHP filter chains: file read from error-based oracle](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle)
- [Lexfo – Introducing lightyear, a new way to dump PHP files](https://blog.lexfo.fr/lightyear-file-dump.html)
- [1] [Synacktiv – PHP filter chains: file read from error-based oracle](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle)
- [2] [Lexfo – Introducing lightyear, a new way to dump PHP files](https://blog.lexfo.fr/lightyear-file-dump.html)
- [3] [loknop – LFI2RCE via PHP filters (arbitrary content generation)](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)
- [4] [Ambionics – wrapwrap: adding suffixes to PHP filter chains](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix)

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

Expand Down
9 changes: 3 additions & 6 deletions src/pentesting-web/file-inclusion/phar-deserialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

**Phar** files (PHP Archive) files **contain meta data in serialized format**, so, when parsed, this **metadata** is **deserialized** and you can try to abuse a **deserialization** vulnerability inside the **PHP** code.
**Phar** files (PHP Archive) files **contain meta data in serialized format**, so, when parsed, this **metadata** is **deserialized** and you can try to abuse a **deserialization** vulnerability inside the **PHP** code.<sup>[[1]](#references)</sup>

The best thing about this characteristic is that this deserialization will occur even using PHP functions that do not eval PHP code like **file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize()**.

Expand Down Expand Up @@ -65,11 +65,8 @@ And execute the `whoami` command abusing the vulnerable code with:
php vuln.php
```

### References
## References


{{#ref}}
https://blog.ripstech.com/2018/new-php-exploitation-technique/
{{#endref}}
- [1] [RIPS – New PHP Exploitation Technique (phar:// deserialization)](https://blog.ripstech.com/2018/new-php-exploitation-technique/)

{{#include ../../banners/hacktricks-training.md}}
26 changes: 13 additions & 13 deletions src/pentesting-web/hacking-jwt-json-web-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

### **Quick Wins**

Run [**jwt_tool**](https://github.com/ticarpi/jwt_tool) with mode `All Tests!` and wait for green lines
Run [**jwt_tool**](https://github.com/ticarpi/jwt_tool) with mode `All Tests!` and wait for green lines<sup>[[3]](#references)</sup>

```bash
python3 jwt_tool.py -M at \
Expand Down Expand Up @@ -36,7 +36,7 @@ You can also use the [**Burp Extension SignSaboteur**](https://github.com/d0ge/s
- `[= ]eyJ[A-Za-z0-9_\\/+-]*\.[A-Za-z0-9._\\/+-]*`
- **Decode and enumerate**: Use Burp **JWT Editor** or `python3 jwt_tool.py <JWT>` to read header/payload. Note `alg`, `exp`/token lifetime, and authn/authz-driving claims (`role`, `id`, `username`, `email`, etc.).
- **Signature enforcement sanity check**: Flip or delete a few bytes in the signature portion and replay. Acceptance implies missing signature validation and you can directly tamper payload claims.
- **Goal**: Modify payload claims to escalate privileges; every attack below aims to get the server to accept a tampered payload by abusing weak verification, weak secrets, or unsafe key selection.
- **Goal**: Modify payload claims to escalate privileges; every attack below aims to get the server to accept a tampered payload by abusing weak verification, weak secrets, or unsafe key selection.<sup>[[4]](#references)</sup>

### Tamper data without modifying anything

Expand Down Expand Up @@ -88,7 +88,7 @@ jwt_hash = b64encode(sha256(f"{email}:{password_hash}")).decode()[:10]
token = jwt.encode({"id": user_id, "hash": jwt_hash}, jwt_secret, "HS256")
```

4. Drop the signed token into the session cookie (e.g., `n8n-auth`) to impersonate the user/admin account even if the password hash is salted.
4. Drop the signed token into the session cookie (e.g., `n8n-auth`) to impersonate the user/admin account even if the password hash is salted.<sup>[[1]](#references)</sup>

### Modify the algorithm to None

Expand All @@ -98,7 +98,7 @@ Use the Burp extension call "JSON Web Token" to try this vulnerability and to ch

### JWE-wrapped PlainJWT / public-key auth bypass (pac4j-jwt CVE-2026-29000)

Some stacks expect a **signed inner JWT** wrapped inside an **encrypted JWE**. In vulnerable `pac4j-jwt` versions (before `4.5.9`, `5.7.9`, and `6.3.3`), the authenticator decrypts the JWE, tries to parse the payload as a signed JWT, and only verifies the signature if that conversion succeeds. If the decrypted payload is a **PlainJWT** (`alg=none`), `toSignedJWT()` returns `null` and the signature verification path is skipped.
Some stacks expect a **signed inner JWT** wrapped inside an **encrypted JWE**. In vulnerable `pac4j-jwt` versions (before `4.5.9`, `5.7.9`, and `6.3.3`), the authenticator decrypts the JWE, tries to parse the payload as a signed JWT, and only verifies the signature if that conversion succeeds. If the decrypted payload is a **PlainJWT** (`alg=none`), `toSignedJWT()` returns `null` and the signature verification path is skipped.<sup>[[5]](#references)[[6]](#references)</sup>

- **Pre-reqs**:
- The application accepts **JWE bearer tokens**
Expand Down Expand Up @@ -161,7 +161,7 @@ Using Burp **JWT Editor**, import the RSA public key (from `/.well-known/jwks.js

#### Passive triage for RS256→HS256 confusion in PAN-OS / GlobalProtect CAS (CVE-2026-0265)

A practical real-world pattern is a verifier that normally expects **RS256** tokens from an external identity service, but still honors attacker-controlled `alg=HS256` and treats the fetched **RSA public key bytes** as the HMAC secret. In that situation, anyone who can recover the public key can mint valid HS256 tokens.
A practical real-world pattern is a verifier that normally expects **RS256** tokens from an external identity service, but still honors attacker-controlled `alg=HS256` and treats the fetched **RSA public key bytes** as the HMAC secret. In that situation, anyone who can recover the public key can mint valid HS256 tokens.<sup>[[7]](#references)[[8]](#references)</sup>

For **Palo Alto PAN-OS / GlobalProtect** with **Cloud Authentication Service (CAS)** attached to the authentication profile, the exposed GlobalProtect prelogin flow gives enough unauthenticated data to do a **safe passive triage** without forging a token.

Expand Down Expand Up @@ -422,13 +422,13 @@ https://github.com/ticarpi/jwt_tool

## References

- [n8n token forge chain – config+DB leak to JWT signing secret](https://github.com/Chocapikk/CVE-2026-21858)
- [Burp Suite – JWT Editor extension](https://github.com/PortSwigger/jwt-editor)
- [jwt_tool attack methodology](https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology)
- [Keys to JWT Assessments – TrustedSec](https://trustedsec.com/blog/keys-to-jwt-assessments-from-a-cheat-sheet-to-a-deep-dive)
- [0xdf - HTB: Principal](https://0xdf.gitlab.io/2026/03/30/htb-principal.html)
- [CodeAnt AI - Inside CVE-2026-29000: The pac4j JWT Authentication Bypass Explained](https://www.codeant.ai/blogs/pac4j-vulnerability-cve-2026-29000)
- [Bishop Fox - Detecting CVE-2026-0265 at Scale: PAN-OS CAS Authentication Bypass](https://bishopfox.com/blog/detecting-cve-2026-0265-at-scale-pan-os-cas-authentication-bypass)
- [Palo Alto Networks Advisory - CVE-2026-0265 PAN-OS: Authentication Bypass with Cloud Authentication Service (CAS) enabled](https://security.paloaltonetworks.com/CVE-2026-0265)
- [1] [n8n token forge chain – config+DB leak to JWT signing secret](https://github.com/Chocapikk/CVE-2026-21858)
- [2] [Burp Suite – JWT Editor extension](https://github.com/PortSwigger/jwt-editor)
- [3] [jwt_tool attack methodology](https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology)
- [4] [Keys to JWT Assessments – TrustedSec](https://trustedsec.com/blog/keys-to-jwt-assessments-from-a-cheat-sheet-to-a-deep-dive)
- [5] [0xdf - HTB: Principal](https://0xdf.gitlab.io/2026/03/30/htb-principal.html)
- [6] [CodeAnt AI - Inside CVE-2026-29000: The pac4j JWT Authentication Bypass Explained](https://www.codeant.ai/blogs/pac4j-vulnerability-cve-2026-29000)
- [7] [Bishop Fox - Detecting CVE-2026-0265 at Scale: PAN-OS CAS Authentication Bypass](https://bishopfox.com/blog/detecting-cve-2026-0265-at-scale-pan-os-cas-authentication-bypass)
- [8] [Palo Alto Networks Advisory - CVE-2026-0265 PAN-OS: Authentication Bypass with Cloud Authentication Service (CAS) enabled](https://security.paloaltonetworks.com/CVE-2026-0265)

{{#include ../banners/hacktricks-training.md}}
8 changes: 4 additions & 4 deletions src/pentesting-web/http-connection-request-smuggling.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ GET /admin HTTP/1.1
Host: internal-only.example
```

This turns connection reuse into an SSRF-like primitive against **internal virtual hosts**, admin panels, debug routes, and alternate tenants sharing the same edge.
This turns connection reuse into an SSRF-like primitive against **internal virtual hosts**, admin panels, debug routes, and alternate tenants sharing the same edge.<sup>[[1]](#references)</sup>

### First-request Routing

Expand All @@ -47,7 +47,7 @@ Host: private.internal

## Browser-Powered Connection-State Abuse (2022-2025)

The most practical modern variant is **browser-powered** exploitation. A victim first opens a legitimate connection to an attacker-controlled or attacker-triggered origin, and the browser later **reuses or coalesces** that connection for a different authority.
The most practical modern variant is **browser-powered** exploitation. A victim first opens a legitimate connection to an attacker-controlled or attacker-triggered origin, and the browser later **reuses or coalesces** that connection for a different authority.<sup>[[1]](#references)</sup>

### Coalescing preconditions worth checking

Expand Down Expand Up @@ -137,7 +137,7 @@ This is worth testing on reverse proxies that support upgrade-style tunnelling o

## References

- [PortSwigger Research - Browser-Powered Desync Attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- [PortSwigger Research - HTTP/1.1 must die: the desync endgame](https://portswigger.net/research/http1-must-die)
- [1] [PortSwigger Research - Browser-Powered Desync Attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- [2] [PortSwigger Research - HTTP/1.1 must die: the desync endgame](https://portswigger.net/research/http1-must-die)

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