Loading... # 1、背景 攻击组利用GhostWriting鬼写技术:[https://github.com/c0de90e7/GhostWriting](https://github.com/c0de90e7/GhostWriting) 集成到poc:[CVE-2019-1367-GhostWriting.html](http://47.117.131.13/usr/uploads/2021/12/1950582696.html) # 2、攻击分析 总体思路: 1、通过 GetShellWindows+GetWindowThreadProcessId+OpenThread 获得 explorer.exe 的线程句柄 2、搜索 ntdll 得到下述两处结构的指令块 3、通过 SuspendThread+GetThreadContext+SetThreadContext+ResumeThread 组合,获得线程 context 后更改 eip、esp 以及视情况而选择的 edi、esi 等寄存器,使得恢复线程执行后指向以下两处逻辑: a、更改 eip,使得线程恢复执行后,从此处开始执行 ``` // 示例指令,满足 mov +(pop/add可选)+ ret 要求即可 mov dword ptr [esi+10h], edi pop ebp pop ebx pop edi pop esi ret 8 ``` b、ret 后,线程执行在一个跳转到自身的死循环。跳入死循环的作用是继续停止线程原先的工作 ``` jmp $ ``` 至此可以实现一个功能,比如在 GhostWriting.exe 中循环将 shellcode 数据赋值给 edi 寄存器,然后更改 esi 的值为渐增的栈地址,然后恢复线程执行,此时 explorer 线程就自动地把 shellcode 数据写入它的栈上了。也即是: 4、**后续通过任意次的 SuspendThread+(GetThreadContext可选)+SetThreadContext+ResumeThread 组合来操作线程,并通过操作 edi 和 esi 的值,我们可以达成一个远程线程的任意写功能**。比如写入 shellcode、压入参数等。 5、修改 context.eip = NtProtectVirtualMemory,将栈上的 shellcode 内存段修改为可执行属性。执行后同样跳入死循环 6、修改 context.eip = shellcode_addr,恢复线程执行并执行 shellcode。执行后同样跳入死循环 7、通过最开始时保存的 context,恢复线程原先的工作 # 3、防护分析 1、该技术实际上只是一种新颖的代码注入技术,最后依然调用了 NtProtectVirtualMemory,在 demo 中目标地址是栈地址(不一定得是)。这里可以针对栈地址增加可执行权限做防护 2、线程恢复后的执行实际上是一种 rop 手法,死循环指令的上一条指令大概率不会是一条 call 指令,比如在调用 NtProtectVirtualMemory 时就是一个 rop 栈帧。 最后修改:2022 年 07 月 04 日 10 : 55 PM © 允许规范转载