免杀——Loader编写
免杀——Loader
Loader的定义
Loader 在恶意软件和渗透测试中指的是用于将恶意代码(如 Shellcode、DLL 或其他恶意文件)加载并执行的程序或模块。Loader 的主要任务是帮助攻击者或测试人员将注入目标进程或系统环境中的恶意代码触发其执行。
Loader的大致思路
- 分配内存:使用
VirtualAlloc
或其他 API 在目标进程中分配内存,并设置适当的执行权限(如PAGE_EXECUTE_READWRITE
)。 - 写入代码:将 Shellcode、恶意 DLL、或其他代码写入刚分配的内存中。
- 执行代码:使用
CreateRemoteThread
、EnumFontsW
回调、NtQueueApcThread
等方法来启动恶意代码的执行。 - 清除痕迹(可选):有些 Loader 还会在执行代码后清理其在目标系统上的痕迹,避免被检测到。
一些Demo:
指针执行
1 | int main() |
汇编执行
1 |
|
创建线程执行
1 |
|
从Edr开发者的角度来说,类似于VirtualAlloc,CreateThread,WriteProcessMemory肯定是被重点监控的对象,那么我们就需要做一些替换的手段
例如VirtualAlloc,我们可以使用其他的API换掉
1 | GlobalAlloc |
CreateThread也可以使用回调函数进行执行
1 |
|
EnumFonts 函数枚举指定设备上可用的字体。 对于具有指定字样名称的每个字体, EnumFonts 函数将检索有关该字体的信息,并将其传递给应用程序定义的回调函数。
因为这玩意会去调用一个回调,因此这个就被我们利用了,类似的还有很多:
1 | 1. EnumTimeFormatsA |
通过线程池等待对象创建线程来执行 Shellcode。
步骤:
- 使用
CreateThreadpoolWait
创建线程池等待对象。 - 将
Shellcode
地址作为回调函数传递给等待对象。 - 通过调用
SetThreadpoolWait
设定等待条件。 - 当等待条件满足时,线程池将调用指定的回调函数,即 Shellcode,从而实现执行。
1 | int main() { |
Fiber
Fiber
是 Windows 的一种轻量级线程模型。使用 Fiber
加载 Shellcode 是通过将 Shellcode 作为一个纤程(Fiber)执行。
步骤:
- 将当前线程转换为纤程,使用
ConvertThreadToFiber
。 - 使用
CreateFiber
创建纤程,传递 Shellcode 的地址作为入口点。 - 使用
SwitchToFiber
切换执行上下文,转移到 Shellcode 纤程。
1 | int main() { |
QueueUserAPC
是一种异步过程调用的机制,允许将 Shellcode 作为 APC(Asynchronous Procedure Call)注入到目标线程的消息队列中,等待线程处于可调度状态时执行。NtTestAlert
是一个未文档化的函数,通常用于触发 APC 的执行。
步骤:
- 通过
QueueUserAPC
将 Shellcode 注册到目标线程的 APC 队列中。 - 使用未文档化的函数
NtTestAlert
触发线程检查其 APC 队列,从而执行 Shellcode。
1 | typedef DWORD(NTAPI* pNtTestAlert)(); |
从资源加载 Shellcode
恶意代码或 Shellcode 可以嵌入到可执行文件的资源段中,然后在运行时加载这些资源并执行它们。这种方法通过将恶意代码隐藏在合法的资源数据中,有效降低了被静态检测到的风险。
步骤:
- 使用
FindResource
、LoadResource
和LockResource
从可执行文件的资源段中加载 Shellcode。 - 将加载的资源作为 Shellcode 执行,通常通过
VirtualAlloc
分配可执行内存后调用。
1 |
|
直接用Resource Hacker添加资源即可:
隐藏导入表
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Cc12138's blog!