• xxxx (二):DLL远程注入


      要想改变目标进程执行流程的办法有很多,最常见的就是hook。为了让目标进程执行特定的代码,可以注入shellcode或dll;shellcode的优点是体积小,不容易被检测到,但功能也相对单一;dll注入优点是可以包含的功能较多,但容易被检测到。本次拿xxxx软件举例做个dll注入;

      要做注入,否先要再目标进程开辟一块内存空间,然后写入自己想要执行的代码,再想办法让eip跳转到这里。对于dll注入,大致的流程如下:

      openprocess->VirtualAllocEx->WriteProcessMemory->GetProcAddress->CreateRemoteThread

      核心思路:打开目标进程,分配内存空间,写入需要执行的dll地址,得到loadlibrary函数地址,最后调用createRemoteThread函数专门生成一个线程执行loadlibary函数。这种注入/HOOK方式多年前就烂大街了,这里不再赘述,感兴趣的小伙伴可google查阅相关资料;dll注入核心代码如下:

    #include "windows.h"
    #include "tchar.h"
    
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        HANDLE hProcess = NULL, hThread = NULL;
        HMODULE hMod = NULL;
        LPVOID pRemoteBuf = NULL;
        DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
        LPTHREAD_START_ROUTINE pThreadProc;
    
        if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
        {
            _tprintf(L"OpenProcess(%d) failed!!! [%d]
    ", 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, "LoadLibraryW");
        
        hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);    
    
        CloseHandle(hThread);
        CloseHandle(hProcess);
    
        return TRUE;
    }
    
    int _tmain(int argc, TCHAR *argv[])
    {
        if( argc != 3)
        {
            _tprintf(L"USAGE : %s <pid> <dll_path>
    ", argv[0]);
            return 1;
        }
    
        // inject dll
        if( InjectDll((DWORD)_tstol(argv[1]), argv[2]) )
            _tprintf(L"InjectDll("%s") success!!!
    ", argv[2]);
        else
            _tprintf(L"InjectDll("%s") failed!!!
    ", argv[2]);
    
        return 0;
    }

      这里需要输入两个参数:目标进程的PID和需要加载的dll全路径。这里为了突出重点(注入流程),省略了查找目标进程的代码(感兴趣的小伙伴可调用windows的API遍历进程,查找PID),这里手动在任务管理器里面查找;

      为了测试dll是否加载成功,这里先不执行其他代码,只弹个窗试试:

    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            MessageBoxW(NULL,L"dll加载成功",L"dll加载测试", MB_OK);
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }

     测试效果,说明dll加载成功了! 

        

      下一步就是通过动态调试或静态分析找各种功能call了!有两种方式:

    •      用ODCEX32DBGIDA等工具调试xxxx的PC端,通过各种方式找到各种功能(诸如发送/接受消息、二维码生成、发送/接受文件、红包等)的call
    •      市面上有好些现成的外挂,可以“黑吃黑”:用IDA分析这些外挂的dll,看看hook了xxxx的哪些模块的哪些偏移地址,自己写代码直接hook这些地址即可,理论上比第一种方式快很多,不过只能追随别人的步伐,没有先发优势;
  • 相关阅读:
    Redis 再牛逼,也得设置密码!!
    Spring Data Redis 详解及实战一文搞定
    连接mysql
    angular6安装
    (6)ASP.NET HttpServerUtility 类
    (5)ASP.NET HttpResponse 类
    远程连接错误
    (3)一般处理程序 ,HttpContext类
    ASP.NET内置对象-状态管理
    (4)ASP.NET HttpRequest 类
  • 原文地址:https://www.cnblogs.com/theseventhson/p/14196943.html
Copyright © 2020-2023  润新知