zoukankan      html  css  js  c++  java
  • 使用CreateRemoteThread注入DLL

    DLL:

    // dllmain.cpp : Defines the entry point for the DLL application.
    #include "stdafx.h"
    #include <Windows.h>
    #include <stdio.h>
    
    INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
        /* open file */
        FILE *file;
        fopen_s(&file, "D:\Case Folders\2019-11-27\CreateRemoteThread\temp.txt", "a+");
    
        switch (Reason) {
        case DLL_PROCESS_ATTACH:
            fprintf(file, "DLL attach function called.
    ");
            break;
        case DLL_PROCESS_DETACH:
            fprintf(file, "DLL detach function called.
    ");
            break;
        case DLL_THREAD_ATTACH:
            fprintf(file, "DLL thread attach function called.
    ");
            break;
        case DLL_THREAD_DETACH:
            fprintf(file, "DLL thread detach function called.
    ");
            break;
        }
    
        /* close file */
        fclose(file);
    
        return TRUE;
    }

    CreateRemoteThread program:

    #include <Windows.h>
    #include <stdio.h>
    #include <iostream>
    #include <TlHelp32.h>
    #include <tchar.h>
    
    bool Inject(DWORD pId, const char *dllName)
    {
        HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
        if (h)
        {
            LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
            LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
            WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL);
            HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL);
            if (asdc == NULL) {
                printf("Error: the remote thread could not be created.
    ");
            }
            else {
                printf("Success: the remote thread was successfully created.
    ");
            }
            WaitForSingleObject(asdc, INFINITE);
            VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE);
            CloseHandle(asdc);
            CloseHandle(h);
            return true;
        }
        return false;
    }
    int _tmain(int argc, _TCHAR* argv[]) {
        const char* buffer = "D:\Case Folders\2019-11-27\CreateRemoteThread\inject\Debug\inject.dll";
    
        /*
        * Get process handle passing in the process ID.
        */
        int procID = 26824;
        Inject(26824, "D:\Case Folders\2019-11-27\CreateRemoteThread\inject\Debug\inject.dll");
        //HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
        //if (process == NULL) {
        //    printf("Error: the specified process couldn't be found.
    ");
        //}
    
        ///*
        //* Get address of the LoadLibrary function.
        //*/
        //LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
        //if (addr == NULL) {
        //    printf("Error: the LoadLibraryA function was not found inside kernel32.dll library.
    ");
        //}
    
        ///*
        //* Allocate new memory region inside the process's address space.
        //*/
        //LPVOID arg = (LPVOID)VirtualAllocEx(process, NULL, strlen(buffer), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        //if (arg == NULL) {
        //    printf("Error: the memory could not be allocated inside the chosen process.
    ");
        //}
    
        ///*
        //* Write the argument to LoadLibraryA to the process's newly allocated memory region.
        //*/
        //int n = WriteProcessMemory(process, arg, buffer, strlen(buffer), NULL);
        //if (n == 0) {
        //    printf("Error: there was no bytes written to the process's address space.
    ");
        //}
    
        ///*
        //* Inject our DLL into the process's address space.
        //*/
        //HANDLE threadID = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
        //int err = GetLastError();
        //if (threadID == NULL) {
        //    printf("Error: the remote thread could not be created.
    ");
        //}
        //else {
        //    printf("Success: the remote thread was successfully created.
    ");
        //}
    
        /*
        * Close the handle to the process, becuase we've already injected the DLL.
        */
        //CloseHandle(process);
        getchar();
    
        return 0;
    }

    检查被插入的进程是否包含inject.dll

    #include <windows.h>
    #include <Tlhelp32.h>
    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring;
    
    
    int ProcessModule(DWORD);
    int CheckProcessModule(DWORD pid);
    BOOL IsModuleValid(tstring szModuleName);
    int dwCount = 0;
    vector<tstring> patch;
    vector<tstring> checkpatch;
    
    int main(void)
    {
    
    
        //进程创建完毕后的模块快照
        ProcessModule(26824);
        cout << "******************当前模块*****************" << endl;
        for (int i = 0; i < patch.size(); i++)
        {
            cout << patch[i].c_str() << endl;
        }
        cout << endl << endl;
    
        LoadLibrary(TEXT("user32.dll"));//加载user32.dll测试
    
    
        HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    
        //检测是否存在不同的模块
    //    CheckProcessModule(GetCurrentProcessId());
        cout << "******************检测模块*****************" << endl;
        for (int j = 0; j < checkpatch.size(); j++)
        {
            cout << checkpatch[j].c_str() << endl;;
        }
        cout << endl << endl;
        if (patch.size() == checkpatch.size())
        {
            cout << "没有检测到注入模块" << endl;
        }
    
    
        return 0;
    }
    
    
    //获取进程模块
    int ProcessModule(DWORD pid)
    {
    
        HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
        if (hProcessSnap)
        {
            MODULEENTRY32 me32;
            me32.dwSize = sizeof(MODULEENTRY32);
            Module32First(hProcessSnap, &me32);//获取进程第一个模块信息
            do
            {
                patch.push_back(me32.szModule);
                //printf("模块路径:%s
    ",me32.szExePath);
                //printf("模块名:%s
    ",me32.szModule);
                //printf("模块基址:0x%08X
    ",(DWORD)me32.modBaseAddr);
    
            } while (Module32Next(hProcessSnap, &me32));
            CloseHandle(hProcessSnap);
            return 0;
        }
        else
        {
            cout << "获取进程快照失败" << endl;;
            return 0;
        }
        return 0;
    }
    
    int CheckProcessModule(DWORD pid)
    {
    
        HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
        if (hProcessSnap)
        {
            MODULEENTRY32 me32;
            me32.dwSize = sizeof(MODULEENTRY32);
            Module32First(hProcessSnap, &me32);//获取进程第一个模块信息
            do
            {
                checkpatch.push_back(me32.szModule);
                if (!IsModuleValid(me32.szModule))
                {
                    cout << "[可疑模块]:" << me32.szExePath << endl;
                    dwCount++;
                }
    
                //printf("模块路径:%s
    ",me32.szExePath);
                //printf("模块名:%s
    ",me32.szModule);
                //printf("模块基址:0x%08X
    ",(DWORD)me32.modBaseAddr);
    
            } while (Module32Next(hProcessSnap, &me32));
            CloseHandle(hProcessSnap);
            if (dwCount)
            {
                cout << "可疑模块数:" << dwCount << endl;
            }
            return 0;
        }
        else
        {
            cout << "获取进程快照失败" << endl;
            return 0;
        }
        return 0;
    }
    
    
    BOOL IsModuleValid(tstring szModuleName)
    {
        // 遍历起始状态的模块列表
        for (int i = 0; i < patch.size(); i++)
        {
            if (patch[i] == szModuleName)
                return TRUE;
        }
        return FALSE;
    
    }

     部分解释:

    介绍将用于将DLL注入到进程的地址空间中的整个过程。为了清楚地表明我们将要执行的操作,请看下面的图片,在该图片中,我们将向其中注入DLL的过程标有紫色,并命名为受害者。但是,我们需要澄清另外两个难题。首先,我们需要确定如果要将DLL注入到某个进程中,则必须首先拥有要注入的DLL。DLL以绿色呈现,并具有名称inject.dll。但是我们还必须有一个程序,该程序会将DLL注入受害者的地址空间。该程序以蓝色显示,名称为program.exe。

    为了能够将DLL注入受害者的地址空间,program.exe必须顺序调用提供的函数。首先,它必须调用OpenProcess来获取受害者进程的句柄。之后,它必须调用GetProcAddress函数来获取kernel32.dll库中LoadLibraryA函数的地址。在这里,我们可以运行任何我们喜欢的函数,但是它必须存在于DLL中,该DLL已经加载在进程的地址空间中。我们知道每个程序都使用kernel32.dll库,因此将DLL注入到进程的地址空间中的最佳方法是查找LoadLibraryA函数并调用它。为了加载DLL,我们必须将DLL路径传递给LoadLibraryA函数,但是该名称需要存储在进程地址空间内的某个位置。明显,DLL的路径已经不太可能出现在进程的地址空间中,这就是为什么我们需要接下来的两个函数:VirtualAllocEx和WriteProcessMemory。第一个函数在进程的地址空间内分配一个新的内存范围。该内存区域的大小仅需要大到适合其内部DLL的名称即可;通常将大小四舍五入以占据至少一页。WriteProcessMemory是实际上将DLL的路径写入受害者的地址空间的函数。最后,调用CreateRemoteThread,该调用在受害者的地址空间内调用LoadLibraryA函数以向其中注入DLL。

    更多信息请参考:https://resources.infosecinstitute.com/using-createremotethread-for-dll-injection-on-windows/#gref

  • 相关阅读:
    windows下安装mysql教程
    git基本操作
    JDK8,Optional
    重新安装MySQL 8出现的问题
    HTML5学习:缩略图
    HTML5学习:表格
    MySQL常用命令
    Django学习:创建admin后台管理站点
    Django学习:连接Mysql数据库
    Django学习:创建第一个app
  • 原文地址:https://www.cnblogs.com/strive-sun/p/11968782.html
Copyright © 2011-2022 走看看