远程注入dll 完整性级别

版权声明: https://blog.csdn.net/dashoumeixi/article/details/83656447

先来提升下完整性级别:

代码中所有失败的情况都没判断

    HANDLE hToken;
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
	TOKEN_PRIVILEGES tp; 
	LUID luid;
	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);

远程注入:

CreateRemoteThread 也就这个函数了.  现在的想法是把一个dll 仍到另一个进程里去执行;

看原型: LoadLibrary  和 线程函数类似, 那么就可以把 LoadLibrary 作为线程函数;

需要注意 DLL 有导出段, 其中导出函数地址都是 RVA 即相对虚拟地址 .

而exe中的如果使用到了dll 则会有相应的导入段. 而导入段中也有 RVA .

解决办法:

 CreateRemoteThread(hRemoteProcess ,NULL,0, LoadLibrary,"d:/xxx/aaa.dll",0,NULL);

 这里问题来了;
 
 LoadLibrary 这个函数地址是自己程序的RVA, 所以不能这样使用;
 
 解决办法是 :  
LPTHREAD_START_ROUTINE  rt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");
 
 获取 kernel32 ,其在所有进程中的位置都一样, 所以其导出的函数位置也一样.

 接下来 "d:/xxx/aaa.dll" 也不能这样使用. 因为这个字符串在自己的进程中,
 
 解决办法是为目标进程分配一块内存, VirtualAllocEx
 
 分配好了之后把自己进程中的字符串复制过去 ,WriteProcessMemory.

 这样就完成了
 
 
int _tmain(int argc, _TCHAR* argv[])
{
	_tsetlocale(LC_CTYPE, TEXT(""));

   
    //提升完整性级别
	HANDLE hToken;
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
	TOKEN_PRIVILEGES tp; 
	LUID luid;
	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);

	
	TCHAR path[] = TEXT("D:/xxx.dll");
	int pathlen = lstrlen(path) + sizeof(TCHAR);

    
    //获取目标进程
	HANDLE hp = OpenProcess(PROCESS_VM_OPERATION | 
		                    PROCESS_CREATE_THREAD | 
                            PROCESS_VM_WRITE,
                             FALSE, 
                            4296); //进程id 

    // 获取	LoadLibraryW 的地址 
	LPTHREAD_START_ROUTINE  rt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");

    
    //给目标进程分配内存 , 用于存放 dll 路径
	TCHAR * alloc = (TCHAR*)VirtualAllocEx(hp, NULL,pathlen,MEM_COMMIT,PAGE_READWRITE);
	DWORD writeNum = 0;
    
    //把路径写入目标进程
	WriteProcessMemory(hp, alloc, path, pathlen, &writeNum);
	printf("WriteProcessMemory :%d\n", writeNum);
    
    //启动远程线程
	HANDLE remoteHandle = CreateRemoteThread(hp,NULL,0,rt,(void*)alloc,0,NULL);

    
	CloseHandle(remoteHandle);
	CloseHandle(hp);

	
	
	
	return 0;
}

卸载dll:

void freedll(DWORD pid , TCHAR  * dllname)
{
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pid);
	MODULEENTRY32 me32;
	me32.dwSize = sizeof(MODULEENTRY32);
	Module32First(hSnap, &me32);
	BOOL bFound = FALSE;
	do{
		if (lstrcmp(me32.szModule, dllname) == 0){
			bFound = TRUE;
			break;
		}
	} while (Module32Next(hSnap, &me32));

	if (!bFound){
		printf("not found");
		return;
	}

	HANDLE hp = OpenProcess(PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION |
		PROCESS_CREATE_THREAD , FALSE, pid);

	LPTHREAD_START_ROUTINE pt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "FreeLibrary");

	HANDLE hThread = CreateRemoteThread(hp, NULL, 0, pt, (void*)me32.hModule, 0, NULL);

	WaitForSingleObject(hThread, -1);
	CloseHandle(hThread);
	CloseHandle(hp);
	
}

猜你喜欢

转载自blog.csdn.net/dashoumeixi/article/details/83656447