1. 程式人生 > >遠端注入dll 完整性級別

遠端注入dll 完整性級別

 

先來提升下完整性級別:

程式碼中所有失敗的情況都沒判斷

    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);
	
}