这几天在看Bypass Ring3 Hook的时候看到一些不错的文章以及学习到一些不错的技术,下面就来给大家分享一下ByPass对抗中的魅力!!
1.Ring3 Hook
首先,我们得先来了解一下3环的钩子
像我们调用一些像VirtualAlloc CreateThread 这种敏感API的时候,大部分都是找到Ntdll中的ZW或者NT函数,然后通syscall进入0环的,那么有一些杀软(Bit Defender),和一些EDR就会对NT函数进行HOOK
就像上面这样,本来我们调用NtCreateThreadEx的时候是通过这样进入Ring 0 的
mov r10,rcx;
mov eax,ssn;
syscall
ret
但是如果在Ring3 被Hook之后,就会变成这样的代码,直接jmp到了他们自己的代码段
2.EDR Hook
首先,一些EDR或者AV会往你的跑起来的程序里面注入一个他们自己的DLL(Bit Defender为例)
当你进行一些敏感的操作的时候像什么 线程注入,OpenProcess,dumplsass,强杀进程的时候就会对你进行监控或者拦截,这就是Ring3 Hook!
3.Bypass Ring3 Hook的方式
我们这里讲几种比较常用的去bypassHook的方式
1.Unhook
对于Unhook,我们有很多的办法,其中最常见的就是一个重载ntdll.dll,通过重载Ntdll,我们就能拿到一份干净的,没有被AV或者EDR进行Hook的Ntdll,通过重载Ntdll,我们就能绕过AV或者EDR在Ring3 的Hook!!! (Bit Defender就能这么绕过!!) 具体代码实现后续会更新!!
2.Syscall
这里我们先不分他是间接还是直接syscall,我们来看看Syscall为什么能绕过Ring 3的Hook!
首先,我们前面讲过动态调用! 下面我就拿NtCreateThread的动态调用来举例子
Fn_NtCreateThreadEx eva_NtCreateThreadEx;
nt.eva_NtCreateThreadEx = (Fn_NtCreateThreadEx)GetFunctionAddress(hNt32,"NtCreateThreadEx");
通过NT动态调用NT函数,我们能成功隐藏导入表中的CreateThread这个API,但是!!
这样能绕过Hook吗 ???
::肯定不可以啊!!!!
就算你是动态的调用Nt函数,你的Ntdll已经是被Hook的了,你获取到的NtCreateThreadEx这个地址,早已经是被替换成jmp去他们杀软/EDR自己的dll中了!!! 这个是绝对Bypass 不了Hook的!(这个一定要搞清楚)
也就是说,调用Nt函数(无论是你动态调用,还是走常规的调用链),都是绕不过Ring3的Hook的!! 而且 动态调用Nt函数不等于Syscall !!!!!!(这个是重中之重)
所以我们的syscall是怎么实现的呢,基本上是这样的(我那sys whispers3举例)
首先去写一个汇编文件 其中Sw3NtCreadThreadEx 就是我们的syscall函数
然后我们去导出这个函数
然后当我们直接调用这个函数的时候就是其实就是进行Syscall!!!
(当然中间还得一些ssn获取等等函数实现我省略了)
通过Syscall,我们就能实现很好的和杀毒软件对抗的效果!!!
4.杀软&&免杀的对抗
1.Reload Ntdll的对抗
从杀软层面:
可以添加规则,如果你一旦获取到了ntdll的句柄(无论是什么路径下的NTDLL,规则都加上),我立刻查杀或者重点监控
从免杀对抗层面:
自己传一个NTDLL,或者把他改一个名字传上去!!(防止匹配NTDLL的字样)
甚至还可以内存加载,直接无文件落地拿到NTDLL的句柄!
2.Syscall的对抗
从杀软层面:
当你文件落地的时候我就去扫描你的文件,看下你的静态有无syscall这种字样!!
从免杀对抗层面:
静态我填充垃圾字符,当我运行的时候再把syscall改回去,(Sys Whisper的实现!!)
unsigned char egg[] = { 0x77, 0x00, 0x00, 0x74, 0x77, 0x00, 0x00, 0x74 };
//w00tw00t
unsigned char replace[] = { 0x0f, 0x05, 0x90, 0x90, 0xC3, 0x90, 0xCC, 0xCC
}; // syscall; nop; nop; ret; nop; int3; int3
再来!!!!
从杀软层面:
我通过栈回溯,看一下你返回的进程链有无问题(检测ret是不是在ntdll,然后再往回走,防止你在代码段直接syscall!)
从对抗层面:
不直接syscall,而是通过伪造一个完整的进程调用链,也就是说不直接syscall,而是在获取到ntdll中syscall的地址之后jmp过去 (Hell's Hall的原理!)地狱之门的诞生!!!
不服??? 我还能继续!!!
从对抗层面:
我还可以玩VEH!!在调用产生异常的时候通过veh异常来接管,构造stub然后用我们找到的syscall的地址来进行调用。这样栈回溯的时候也是ntdll的合法地址,规避了检测。
不服?? 还能再来??
从杀软层面:
我检测 mov eax, ssn 这种代码,检测到之后直接给你杀死!!
从对抗层面:
我通过替换,打乱调用规则(有点绕WAF的感觉了)
mov rcx , ssn
mov eax , rcx
等等等等...... 总之道高一尺魔高一丈,对抗一直都是很多的!!!
::也正是从这对抗中,我们除了能学习到红队人员的强大对抗思路以外,我们还能感受到红蓝对抗的乐趣与魅力!!!