windows:shellcode 远程线程hook/注入(四)
https://www.cnblogs.com/theseventhson/p/13236421.html 这里介绍了利用回调函数执行shellcode的基本原理;这里介绍另外一种利用回调执行shellcode的方法:kernelcallbacktable;从字面意思看,kernelcallbacktable应该有如下几个特点:
- 首先是个table,table里面装满了各个回调函数的入口;
- 其次:既然是kernelcallback,应该是被内核回调的,那么内核在什么时候才会回调这些函数了?众说周知,windows操作系统的基石就是无数个展现在用户界面的窗口(所以该操作系统才得名windows的嘛),窗口之间是需要互相通信的,窗口和系统其他模块之间也是要互相通信的, table里的这些函数通常用于窗口响应各种不同类型的消息。例如,A窗口给B窗口发送WM_COPYDATA消息,B窗口就会执行_fnCOPYDATA函数(shellcode注入关键点就在这了:在目标进程写入shellcode,然后让_fnCOPYDATA指向shellcode的入口);而当一个键盘消息来了,收到消息的窗口就会执行__ClientImmProcessKey;
- kernelcallbacktable在哪了?既然目标进程选explorer,就从这里开始逐个查看
(1)先看看explorer的各种数据,发现peb在008e1000这里;
kd> !process 0 0 explorer.exe
PROCESS ffff9006c6645080
SessionId: 1 Cid: 09cc Peb: 008e1000 ParentCid: 09b4
DirBase: 48555000 ObjectTable: ffffb789d5512040 HandleCount: 3177.
Image: explorer.exe
(2)继续查看PEB的内容:在偏移0x58处找到exlporer进程的内核回调表:
kd> dt _PEB 008e1000
nt!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0 ''
+0x003 BitField : 0x4 ''
................................................
+0x054 Padding1 : [4] ""
+0x058 KernelCallbackTable : 0x00007ffa`ef0e31e0 Void
(3)继续查看这个表的内容:根据上面回调函数表的地址继续查表内函数地址,如下:
kd> dps 00007ffa`ef0e31e0
00007ffa`ef0e31e0 00007ffa`ef07e3e0
00007ffa`ef0e31e8 00007ffa`ef0da990
00007ffa`ef0e31f0 00007ffa`ef081990
00007ffa`ef0e31f8 00007ffa`ef086a90
00007ffa`ef0e3200 00007ffa`ef0860b0
00007ffa`ef0e3208 00007ffa`ef0daf00
00007ffa`ef0e3210 00007ffa`ef087450
00007ffa`ef0e3218 00007ffa`ef0dad20
00007ffa`ef0e3220 00007ffa`ef0db1b0
00007ffa`ef0e3228 00007ffa`ef0dadd0
00007ffa`ef0e3230 00007ffa`ef083e40
00007ffa`ef0e3238 00007ffa`ef0dae20
00007ffa`ef0e3240 00007ffa`ef088b30
00007ffa`ef0e3248 00007ffa`ef0db350
00007ffa`ef0e3250 00007ffa`ef0db350
00007ffa`ef0e3258 00007ffa`ef08eb50
(4)查看第一个函数,也就是_fnCOPYDATA代码如下:
kd> u 00007ffa`ef07e3e0
00007ffa`ef07e3e0 4883ec58 sub rsp,58h
00007ffa`ef07e3e4 33c0 xor eax,eax
00007ffa`ef07e3e6 4c8bd1 mov r10,rcx
00007ffa`ef07e3e9 89442438 mov dword ptr [rsp+38h],eax
00007ffa`ef07e3ed 4889442440 mov qword ptr [rsp+40h],rax
00007ffa`ef07e3f2 394108 cmp dword ptr [rcx+8],eax
00007ffa`ef07e3f5 740b je 00007ffa`ef07e402
00007ffa`ef07e3f7 48394120 cmp qword ptr [rcx+20h],rax
(5)只要把这个函数的内容换成我们自己的shellcode就行,代码下面会贴出来,这里先下个断点:
kd> bp 00007ffa`ef07e3e0
(6)执行代码,成功断了下来:
kd> g
Breakpoint 0 hit
0033:00007ffa`ef07e3e0 4883ec58 sub rsp,58h
kd> k
# Child-SP RetAddr Call Site
00 00000000`056ff398 00007ff8`bbbc3b14 0x00007ffa`ef07e3e0
01 00000000`056ff3a0 00000000`00000000 0x00007ff8`bbbc3b14
F5放过去继续执行,成功弹出了记事本:
(7)KernelCallBackTable如下,全是内核回调函数:
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;
参考:https://zhuanlan.zhihu.com/p/40368047
https://modexp.wordpress.com/2018/07/15/process-injection-sharing-payload/ 内核回调函数机制详解
https://github.com/odzhan/injection/tree/master/kct 代码和shellcode(注意要编译成64位的,否则无法执行shellcode)