[Cuckoo SandBox]注入原理篇

时间:2023-03-09 15:33:45
[Cuckoo SandBox]注入原理篇

1.LoadExe

接python版本

[Cuckoo SandBox]注入原理篇

通过调用LoadExe去加载Dll进行注入

所以先看LoadExe 加载器的功能吧

[Cuckoo SandBox]注入原理篇

通过python管道接收到  processID,ThreadID,路径 ,然后就开始搞事情了注入了

接收原理 管道具有传递命令行参数专递的作用,利用其进程间通信的功能,通过命令行传进来,不废话 开始了

[Cuckoo SandBox]注入原理篇

[Cuckoo SandBox]注入原理篇

先调用这几个函数 打开对方的进程,线程空间,

[Cuckoo SandBox]注入原理篇

然后把加载Dll LoadLdrDll的函数地址,Dll路径写到对方进程空间

构建ShellCode

[Cuckoo SandBox]注入原理篇

为什么要用汇编呢,应该你是在他人的电脑上调用,模块地址什么的都不一样,想实现的功能的从基层自己构建。然后QueueUserAPC

把ShellCode插入到APC队列,使其调用。ShellCode的功能就是LoadLibray(咱的Dll)并执行

Ok,LoadExe完美完成任务,进入Dll注入

2 Dll注入原理

  

  Dll首先隐藏peb  不让对方发现自己

  [Cuckoo SandBox]注入原理篇

  

先说一下得到peb的方法吧

[Cuckoo SandBox]注入原理篇

/__readfsdword是按照dword大小返回fs寄存器中指定偏移量的值

所以关键还是看fs寄存器是干什么的

那么现在看这篇博客的介绍

http://blog.csdn.net/misterliwei/article/details/4391580

代码运行在 RING0 (系统地址空间)和 RING3 (用户地址空间)时, FS 段寄存器分别指向 GDT( 全局描述符表 ) 中不同段

不说复杂的  直接windbg看结构就知道了

先看32位的TEB  0x30处就是PEB的地址

    

nt!_TEB
+0x000 NtTib : _NT_TIB
+0x000 ExceptionList : Ptr32
+0x004 StackBase : Ptr32
+0x008 StackLimit : Ptr32
+0x00c SubSystemTib : Ptr32
+0x010 FiberData : Ptr32
+0x010 Version : Uint4B
+0x014 ArbitraryUserPointer : Ptr32
+0x018 Self : Ptr32 <——
+0x01c EnvironmentPointer : Ptr32
+0x020 ClientId : _CLIENT_ID
+0x000 UniqueProcess : Ptr32
+0x004 UniqueThread : Ptr32
+0x028 ActiveRpcHandle : Ptr32
+0x02c ThreadLocalStoragePointer : Ptr32
+0x030 ProcessEnvironmentBlock : Ptr32 < ——
+0x034 LastErrorValue : Uint4B
+0x038 CountOfOwnedCriticalSections : Uint4B
+0x03c CsrClientThread : Ptr32
+0x040 Win32ThreadInfo : Ptr32
……

  

同样 64位的地址为0x60 所以上面代码原因很清楚了

[Cuckoo SandBox]注入原理篇

接下来就是注入了

[Cuckoo SandBox]注入原理篇

先修改g_Hooks代码属性,等下说

继续看代码,

创建线程快照,将所有的线程挂起,执行注入,因为挂起,sleep这种等待或等待函数

会触发APC队列,进而执行我们的Dll

g_Hooks如下

  [Cuckoo SandBox]注入原理篇

回顾下宏的作用 就是自己定义的东西能代表一个具体的东西

所以这个宏我理解为  使用后面的自己构造的东西 会调用前面的模块和函数

就是两者等价调用

  [Cuckoo SandBox]注入原理篇

接下来 开始注入, 后面一大串相当与自己构造的指令,比如 jmp ,call,push指令

[Cuckoo SandBox]注入原理篇

后面根据前面的模块名和函数名得到函数地址开始钩

先遍历地址,把函数调用 调到其他函数的地址部分全都跳过

防止地址调到其他模块去 不易操作

  

然后就是 内存地址属性 申请内存上

CreateHookTrampoline()将原先函数各种直接,间接跳转的指令保存,

先将其跳到我们申请的地址空间,

然后在我们的地址空间 构建要操作 跳转函数的地址 ,并在执行完我们的函数后,回到程序原先调用的地方。Hook链实现的中途插入调用我们注入的函数

[Cuckoo SandBox]注入原理篇

  

Dll的其他部分

  [Cuckoo SandBox]注入原理篇

这个宏就是 跟原先函数参数一模一样自己构造的函数,利用宏 把原模块的相应参数传进来

然后实现我们想注入的功能,这里输出通知对方看见也是使用的进程间通信的管道

,Old_NtCreateUserProcess然后调用原先的函数。注入成功