/* Benjamin DELPY `gentilkiwi` http://blog.gentilkiwi.com benjamin@gentilkiwi.com Licence : https://creativecommons.org/licenses/by/4.0/ */ #include "kuhl_m_sekurlsa_utils.h" const char * PRINTF_TYPES[] = { "%02x", // WPRINTF_HEX_SHORT "%02x ", // WPRINTF_HEX_SPACE "0x%02x, ", // WPRINTF_HEX_C "\\x%02x", // WPRINTF_HEX_PYTHON }; void kull_m_string_dprintf_hex(LPCVOID lpData, DWORD cbData, DWORD flags) { DWORD i, sep = flags >> 16; const char * pType = PRINTF_TYPES[flags & 0x0000000f]; for(i = 0; i < cbData; i++) { dprintf(pType, ((LPCBYTE) lpData)[i]); if(sep && !((i+1) % sep)) dprintf("\n"); } } void kull_m_string_displayFileTime(IN PFILETIME pFileTime) { SYSTEMTIME st; char buffer[0xff]; if(pFileTime) { if(FileTimeToSystemTime(pFileTime, &st )) { if(GetDateFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buffer, sizeof(buffer))) { dprintf("%s ", buffer); if(GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buffer, sizeof(buffer))) dprintf("%s", buffer); } } } } void kull_m_string_displayLocalFileTime(IN PFILETIME pFileTime) { FILETIME ft; if(pFileTime) if(FileTimeToLocalFileTime(pFileTime, &ft)) kull_m_string_displayFileTime(&ft); } void kull_m_string_displayGUID(IN LPCGUID pGuid) { UNICODE_STRING uString; if(NT_SUCCESS(RtlStringFromGUID(pGuid, &uString))) { dprintf("%wZ", &uString); RtlFreeUnicodeString(&uString); } } void kull_m_string_displaySID(IN PSID pSid) { LPSTR stringSid; if(ConvertSidToStringSidA(pSid, &stringSid)) { dprintf("%s", stringSid); LocalFree(stringSid); } } BOOL kull_m_string_suspectUnicodeString(IN PUNICODE_STRING pUnicodeString) { int unicodeTestFlags = IS_TEXT_UNICODE_ODD_LENGTH | IS_TEXT_UNICODE_STATISTICS; return IsTextUnicode(pUnicodeString->Buffer, pUnicodeString->Length, &unicodeTestFlags); } BOOL kull_m_string_getDbgUnicodeString(IN PUNICODE_STRING string) { BOOL status = FALSE; ULONG_PTR buffer = (ULONG_PTR) string->Buffer; string->Buffer = NULL; if(buffer && string->MaximumLength) { if(string->Buffer = (PWSTR) LocalAlloc(LPTR, string->MaximumLength)) { if(!(status = ReadMemory(buffer, string->Buffer, string->MaximumLength, NULL))) { LocalFree(string->Buffer); string->Buffer = NULL; } } } return status; } ULONG_PTR kuhl_m_sekurlsa_utils_pFromLinkedListByLuid(ULONG_PTR pSecurityStruct, ULONG LUIDoffset, PLUID luidToFind) { PVOID buffer; ULONG_PTR resultat = 0, pStruct = 0; if(buffer = LocalAlloc(LPTR, LUIDoffset + sizeof(LUID))) { if(ReadMemory(pSecurityStruct, &pStruct, sizeof(PVOID), NULL)) { while(pStruct != pSecurityStruct) { if(ReadMemory(pStruct, buffer, LUIDoffset + sizeof(LUID), NULL)) { if(RtlEqualLuid(luidToFind, (PLUID) ((PBYTE) buffer + LUIDoffset))) { resultat = pStruct; break; } pStruct = (ULONG_PTR) ((PLIST_ENTRY) buffer)->Flink; } else break; } } LocalFree(buffer); } return resultat; } ULONG_PTR kuhl_m_sekurlsa_utils_pFromAVLByLuid(ULONG_PTR pTable, ULONG LUIDoffset, PLUID luidToFind) { ULONG_PTR resultat = 0; RTL_AVL_TABLE maTable; if(ReadMemory(pTable, &maTable, sizeof(RTL_AVL_TABLE), NULL)) { pTable = (ULONG_PTR) maTable.BalancedRoot.RightChild; resultat = kuhl_m_sekurlsa_utils_pFromAVLByLuidRec(pTable, LUIDoffset, luidToFind); } return resultat; } ULONG_PTR kuhl_m_sekurlsa_utils_pFromAVLByLuidRec(ULONG_PTR pTable, ULONG LUIDoffset, PLUID luidToFind) { ULONG_PTR resultat = 0; PVOID buffer; RTL_AVL_TABLE maTable; if(ReadMemory(pTable, &maTable, sizeof(RTL_AVL_TABLE), NULL)) { if(pTable = (ULONG_PTR) maTable.OrderedPointer) { if(buffer = LocalAlloc(LPTR, LUIDoffset + sizeof(LUID))) { if(ReadMemory(pTable, buffer, LUIDoffset + sizeof(LUID), NULL)) { if(RtlEqualLuid(luidToFind, (PLUID) ((PBYTE) buffer + LUIDoffset))) resultat = (ULONG_PTR) maTable.OrderedPointer; } LocalFree(buffer); } } if(!resultat && (pTable = (ULONG_PTR) maTable.BalancedRoot.LeftChild)) resultat = kuhl_m_sekurlsa_utils_pFromAVLByLuidRec(pTable, LUIDoffset, luidToFind); if(!resultat && (pTable = (ULONG_PTR) maTable.BalancedRoot.RightChild)) resultat = kuhl_m_sekurlsa_utils_pFromAVLByLuidRec(pTable, LUIDoffset, luidToFind); } return resultat; } void kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, BOOL relative) { if(String->Buffer) String->Buffer = (PWSTR) ((ULONG_PTR)(String->Buffer) + ((relative ? -1 : 1) * (ULONG_PTR)(BaseAddress))); } BOOL kuhl_m_sekurlsa_utils_getSid(IN PSID * pSid) { BOOL status = FALSE; BYTE nbAuth; DWORD sizeSid; ULONG_PTR buffer = (ULONG_PTR) *pSid; *pSid = NULL; if(ReadMemory(buffer + 1, &nbAuth, sizeof(BYTE), NULL)) { sizeSid = 4 * nbAuth + 6 + 1 + 1; if(*pSid = LocalAlloc(LPTR, sizeSid)) status = ReadMemory(buffer, *pSid, sizeSid, NULL); } return status; } PCSTR kuhl_m_kerberos_ticket_etype(LONG eType) { PCSTR type; switch(eType) { case KERB_ETYPE_NULL: type = "null "; break; case KERB_ETYPE_DES_PLAIN: type = "des_plain "; break; case KERB_ETYPE_DES_CBC_CRC: type = "des_cbc_crc "; break; case KERB_ETYPE_DES_CBC_MD4: type = "des_cbc_md4 "; break; case KERB_ETYPE_DES_CBC_MD5: type = "des_cbc_md5 "; break; case KERB_ETYPE_DES_CBC_MD5_NT: type = "des_cbc_md5_nt "; break; case KERB_ETYPE_RC4_PLAIN: type = "rc4_plain "; break; case KERB_ETYPE_RC4_PLAIN2: type = "rc4_plain2 "; break; case KERB_ETYPE_RC4_PLAIN_EXP: type = "rc4_plain_exp "; break; case KERB_ETYPE_RC4_LM: type = "rc4_lm "; break; case KERB_ETYPE_RC4_MD4: type = "rc4_md4 "; break; case KERB_ETYPE_RC4_SHA: type = "rc4_sha "; break; case KERB_ETYPE_RC4_HMAC_NT: type = "rc4_hmac_nt "; break; case KERB_ETYPE_RC4_HMAC_NT_EXP: type = "rc4_hmac_nt_exp "; break; case KERB_ETYPE_RC4_PLAIN_OLD: type = "rc4_plain_old "; break; case KERB_ETYPE_RC4_PLAIN_OLD_EXP: type = "rc4_plain_old_exp"; break; case KERB_ETYPE_RC4_HMAC_OLD: type = "rc4_hmac_old "; break; case KERB_ETYPE_RC4_HMAC_OLD_EXP: type = "rc4_hmac_old_exp "; break; case KERB_ETYPE_AES128_CTS_HMAC_SHA1_96_PLAIN: type = "aes128_hmac_plain"; break; case KERB_ETYPE_AES256_CTS_HMAC_SHA1_96_PLAIN: type = "aes256_hmac_plain"; break; case KERB_ETYPE_AES128_CTS_HMAC_SHA1_96: type = "aes128_hmac "; break; case KERB_ETYPE_AES256_CTS_HMAC_SHA1_96: type = "aes256_hmac "; break; default: type = "unknow "; break; } return type; }