今天看了一篇关于过主动防御的文章,觉得不错,分享给大家。现在瑞星2010主动防御也挺厉害,我的木马360,金山,诺顿都不吱声,就到瑞星主动这提示发现可疑进程,这还不那么变态,但再点允许后就出现发现未知木马了。
知己知彼,百战不殆。在想过主动防御之前,必须要搞明白主动防御到底是什么?他是依靠什么来判断程序是否有害,是否应该做出拦截。明白这些了,过主动防御是件轻松加愉快的事情。现在一般所有的前端技术都与经济利益直接挂钩,表面上来看,对于反主动防御似乎停滞不前了。主要还是因为很多东西在被高度的商业应用,所以,免杀过主动防御这块貌似停止不前,其实已经有大量的方法来解决主动防御这个看似很难的难题。
首先,做为一个ROOTKIT,不论其代码如何,都一般具有以下特征,如注射远程线程,启动傀儡IE,加载驱动,注册服务,修改敏感系统注册表键值等。如果一个ROOTKIT想绕过以上操作,那基本是不可能的。因此,杀软的主动防御一般是使用API钩子来监控进程的危险行为。这样,无论一个表面做的如何好的ROOTKIT,在具有主动防御的杀软面前,一般是很难无声息的进驻到系统内的。所以,绕过主动防御一般就等与躲过杀软的监控,在早期的病毒木马设计的时候,一般会采用taskkill,ntsd,等命令来结束其进程,例如 机器狗,就是其中的代表。后来随着杀软开始起用自我保护,一般是在kiSystemService Hook过滤了一些函数,用来阻止这些外部命令来结束杀软。过主动防御的一大前提是不能破坏杀软,如果杀软在出现开机不能启动,不能查杀病毒,这样难免会引起计算机的使用者重做系统或者进行系统的查杀。治标不治本,所以最佳的反主动防御思路在于在不破坏杀软本身的前提下,应该遵循以下流程。
判断主动防御类型----暂停其监控功能------安装ROOTKIT---------恢复杀软
这里,暂停其监控功能是本文的重点。这里,主要阐述以下三种方法 1.通过WINDOWS的消息机制来突破行为监控 2.模拟点击来突破主动防御 3.通过覆盖代码挂钩API来突破主动防御。
1通过windows消息机制来突破主动防御,所有在WIN32平台下运行的程序基本都可以看成窗口化应用程序,在MSDN定义窗口函数的时候,微软定义在窗口接受WM_CLOSE消息时,将会关闭当前句炳所指向的窗口,例如,关闭现在流行的nod32的窗口,则可书写如下代码:
while(1)
{
Sleep(3000);
char hstr[MAX_PATH]={0};
char str[MAX_PATH]={0};
POINT CurPoint;
HWND hCurrent,hParent;
GetCursorPos(&CurPoint);
hCurrent=WindowFromPoint(CurPoint);
hParent=hCurrent;
while(GetParent(hParent)!=NULL)
hParent=GetParent(hParent);
GetWindowText(hParent,str,MAX_PATH); //获取标题文本
GetWindowText(hCurrent,hstr,MAX_PATH); //获取标题文本
if((strstr(str,"NOD32"))&& hCurrent)
{
PostMessage(hCurrent,WM_DESTROY,0,0);
PostMessage(hParent,WM_CLOSE,0,0);
PostMessage(hCurrent,WM_CLOSE,0,0);
PostMessage(hParent,WM_DESTROY,0,0);
}
}
return 1;
}
这样,就可以结束掉NOD32的窗口,下一步就可以安装rootkit到目标计算机当中了,当然,做为一款优秀的杀毒软件,他是一定会拦截例如WM_CLOSE这样的WINDOWS的消息的。一般来说,如果要使的这样的程序运行并且能关掉杀软窗口的话,还需要一些工作,这在后面会提到。
2通过模拟点击来实现绕过主动防御。
一般来说,对于过杀软表面的ROOTKIT,在装有主动防御的系统上运行时,往往会弹出一个对话框,来进行提示操作,一般有“允许执行”“拒绝执行”“添加到信任列表”,当然对于一个ROOTKIT来说,只要在过表面的情况下,一般杀软只会报为风险程序,如果是用户自己安装一些比较生僻的软件时,也同样会弹出以上消息。这时候,为我们运行ROOTKIT创造了非常有利的条件。假设我们的ROOTKIT被执行,然后出现了杀软的对话框那么可以利用模拟点击来实现ROOTKIT的安装和执行。首先,获取杀软拦截对话框的窗口句柄,函数原型FindWindowEx(),我们要看下这个函数的原型
static CWnd* FindWindowEx(
HWND hwndParent,
HWND hwndChildAfter,
LPCTSTR lpszClass,
LPCTSTR lpszWindow
);
这里我只强调hwndParent这一个参数,他是要指向要查找子窗口的父窗口句柄,关于AVP的父窗口句柄,用过SPY++(VC的一个附加工具)的人查看一下AVP的主窗口句柄就行了,在获得拦截对话框的窗口句柄后,接着实现模拟点击,利用如下代码将ROOTKIT执行:(以卡巴斯基8.0为例,屏幕分辨率1024*768)
CPoint My1Point(152,605);
this->ClientToScreen(&Point);
::GetCursorPos(&OldPoint);
::SetCursorPos(My1Point.x,My1Point.y);
My1Point.x=152;
My1Point.y=605;
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
这样就可以使ROOTKIT顺利执行了。但是这样做,还有个小缺陷,那就是会触发杀软的监控,不是很完美。如果想完美的突破主动防御,“随风潜入夜,润物细无声”的效果,还是需要更多努力才可以。
3 通过覆盖代码挂钩API来突破主动防御
首先通过覆盖代码挂钩API这是一种非常霸道的方法,但是确实是一种很有效的方法,它通过直接改写API在内存中的映像,嵌入汇编代码,使之被调用时跳转到指定的地址运行来截获API。这里说一下WINDOWS程序的运行原理,首先WINDOWS所有的程序都是通过列目录路径,来进行寻址和加载模块的,整个程序并不是全部加载到内存当中的(也不能有那么大的内存空间),当需要应用程序完成某一功能时,首先会通过回调函数进行处理,通过地址总线,查找其模块的相应的逻辑位置,将所需要的数据调入内存,然后进入队列,等待CPU通过地址总线将其读入寄存器,进行处理。但是一旦寻址路径被破坏,则回调程序会出现中断,从而导致程序的非正常退出。通俗来说,如果杀软的路径为 c:\programfiles\avp\ 如果AVP在被重命名的话,那么AVP的所有工作将被中断,这时候在运行ROOTKIT的时候,杀软已经起不到任何防御作用了,比如说现在在国内广泛使用的360安全卫士,你可以尝试在360所有保护全开的情况下,重命名他主目录所在的文件夹,然后在运行ROOTKIT,保证会有惊喜哦。
一般来说,绝大多数的杀软都会HOOK API,防止其被重命名,而导致非正常退出。对于在RING3下,最常使用的重命名函数就是RemoveDirectory()这个函数,如果想让RemoveDirectory()顺利运行的话,就需要使用一个驱动程序,读取系统文件ntoskrnl.exe/ntkrnlpa.exe/ntkrpamp.exe,从中提出我们所希望的SSDT表的原始函数地址,替换被安全软件hook的地址。这样再执行RemoveDirectory(),就可以轻松停掉杀软的主动防御了。当然,杀软怎么可能会轻易的让你读取系统文件ntoskrnl.exe/ntkrnlpa.exe/ntkrpamp.exe呢,这里我们就通过通过覆盖代码挂钩API来执行我们想执行的任意指令,真是阴险加**啊。
比如说我们要执行RemoveDirectory()这个API,首先就要知道他做在的DLL文件,一般来说,关于WINDOWS系统指令的相关操作函数都封装在 msvcrt.dll这个动态连接库中,首先在内存中找到这个函数,然后用跳转到自定义函数地址的JUMP CPU指令重写这个函数的前几个字节,这样,当我们的程序调用RemoveDirectory()时,执行流程定然会转到自定义函数处。这时候我们需要重新写一个函数来读取ntoskrnl.exe/ntkrnlpa.exe/ntkrpamp.exe,假设这个字定义函数的地址为0x0040300e,为了使流程转到这里执行,可以嵌入如下汇编代码。
mov eax, 0x0040300e;这是件很有意思的事情,当程序调用这个API的时候,就会执行我们定义好的代码,脱离杀软监控的API,但是必须要注意:使用上面构建的机器码重写这个函数的前8字节。自定义函数必须和挂钩的函数有完全相同的签名:所有的参数必须相同,返回值必须相同,调用规则必须相同。玩不好可是会BSOD的。。。写到这里,C++玩的差不多的人写出过主动防御的程序我想也不是什么难事了。我就不放出EXE的可执行程序了,以免到处又是哀号一片。关于代码的一些设计问题,有不明白的。请参阅《WINDOWS核心编程》,再次推荐下,经典就是经典。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法