请选择 进入手机版 | 继续访问电脑版

噩靈戰隊

 找回密码
 立即注册

QQ登录

只需一步,快速开始

噩靈戰隊 主站 编程 软件编程 查看内容

[原创]rootkit逃过杀软检测

2011-12-2 15:18| 发布者: Trojan| 查看: 64| 评论: 0|原作者: Trojan

摘要: 作者:Trojan 信息来源: 噩靈戰隊 http://bbs.x-xox-x.com/ 有一个时期,杀毒软件的内核部分常常是用PsSetCreateProcessNotify为基础,进行安全检查.比如有一个进程诞生的时候,检查是否是已知的病毒进程,所以在加载dl ...
作者:Trojan [ESST]
信息来源: 噩靈戰隊[Evil-Soul Security Team] http://bbs.x-xox-x.com/
有一个时期,杀毒软件的内核部分常常是用PsSetCreateProcessNotify为基础,进行安全检查.比如有一个进程诞生的时候,检查是否是已知的病毒进程,所以在加载dll的时候检查里面有没有病毒码.刚才提到的PsSetCreateProcessNotify这个函数原型如下:

  1. NTSTATUS
  2. PsSetCreateProcessNotifyRoutine(
  3.       IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
  4.       IN BOLLEAN   Remove
  5. );
复制代码

其中NotifyRoutine是一个回调函数.我们假设Remove为FLASE,则执行这个函数的结果是把NofifyRountine注册了一个回调函数.原型如下:
  1. VOID
  2. (*PCREATE_PROCESS_NOTIFY_ROUTINE)(
  3.       IN HANDLE ParentId,
  4.       IN HANDLE ProcessId,
  5.       IN BOOLEAN   Create
  6. );
复制代码

这个函数被回调的时候,ParentId是父进程Id,而ProcessId则是系统要通知我们的进程ID,这个进程被创建或者被注销的时候,这个函数被调用.
大家可能会问,只得到进程ID,如何检查这个进程,比如EXE文件路径怎么获得?命令行参数怎么获得?在WDK之前,这些都可以通过一些非公开的技术手段来获得.但在WDK之后,如果使用PsSetCreateProcessNotifyRoutineEx,可以比较容易得到这些参数.
PsSetCreateProcessNotifyRoutineEx的不同之处在与回调函数的参数发生了改变:
  1. VOID
  2. CreateProcessNotifyEx (
  3.     __inout   PEPROCESS Process,
  4.     __in HANDLE   ProcessId,
  5.     __in_opt   PPS_CREATE_NOTIFY_INFO CreateInfo
  6. );
复制代码

当CreateInfor不为空的时候,这些信息被提供在CreateInfo中.结构如下:
  1. typedef struct   _PS_CREATE_NOTIFY_INFO {
  2.    __in   SIZE_T   Size;
  3.    union {
  4.     __in ULONG Flags;
  5.     struct {
  6.        __in   ULONG FileOpenNameAvailable   :   1;
  7.        __in   ULONG Reserved   :   31;
  8.     };
  9. };
  10. __in HANDLE ParentProcessId;
  11. __in CLIENT_ID   CreatingThreadId;
  12. __inout struct   _FILE_OBJECT *FileObject;
  13. __in   PCUNICODE_STRING   ImageFileName;
  14. __in_opt   PCUNICODE_STRING   CommandLine;
  15. __out   NTSTATUS CreationStatus;
  16. } PS_CREATE_NOTIFY_INFO, *PPS_CREATE-NOTIFY_INFO;
复制代码

既然如此,作为杀软的开发者,就可以在进程加载的时候,检查ImageFileName,或者直接得到FileObject来扫描其中是否含有病毒特征码.
此外进程加载的每个DLL也需要检查.这有另一个函数提供
  1. NTSTATUS
  2.        PsSetLoadImageNotifyRoutine(
  3.             IN   PLOAD_IMAGE_NOTIFY_ROUTINE   NotifyRountine
  4.        );
复制代码

这个函数也追加一个回调函数,当有dll模块被进程加载的时候,这个回调函数会被系统调用.这样dll加载的时候.杀软的开发者可以从FullImageName中得到dll文件的名字,可以预先对这个文件进行扫描.
如果rootkit打算防止杀软用以上的方法扫描一些隐秘的进程或者模块文件.Hook上面两个函数是一个可行的途径.但是呢,很多杀软都会配备HIPS都会关注被HOOK的内核调用.那么就不能HOOK拉.下面我用winDbg跟踪到vista32位版本中PsSetCteateProcessNotifyRoutine的实现过程.
  1. kd> u PsSetCreateProcessNotifyRoutine
  2. nt!PsSetCreateProcessNotifyRoutine;
  3. 81a1c9f3 8bff                 mov    edi,edi
  4. 81a1c9f5   55                push    ebp
  5. 81a1c9f6   8bec             mov    ebp,esp
  6. 81a1c9f8   5d                pop        ebp
  7. 81a1c9f9   eb0a                 jmp
  8. nt!PspSetCreateProcessNotifyRoutine   (81a1ca05)
  9. 81a1c9fb   cc                int       3
  10. 81a1c9fc   cc                int       3
  11. 81a1c9fd   cc                int       3
复制代码

很明显,这个PsSetCreateProcessNotifyRoutine不是要领.因为直接跳转PspSetCreateProcessNotifyRoutine去了.在看看PspSetCreateProcessNotifyRoutine的跟踪;
  1. nt!PspSetCreateProcessNotifyRoutine:
  2. 81a1ca05   8bff       mov     edi,edi
  3. 81a1ca07   55          push ebp
  4. 81a1ca08   8bec       mov     ebp,esp
  5. 81a1ca0a   51          push ecx

  6. ;这里研究下[ebp+0ch]到底是哪几个参数
  7. ;回忆下函数原型
  8. NTSTATUS
  9. ;PsSetCreateProcessNotifyRoutine(
  10. ;       IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
  11. ;       IN BOLLEAN   Remove
  12. ;先压入的是remove然后压入NotifyRoutine,最后压入返回地址.然后跳转到
  13. ;PsSetCreateProcessNotifyRoutine此时remove实际上是esp+8h.
  14. ;进入PsSetCreateProcessNotifyRoutine后连续Push和pop刚好平衡.esp
  15. ;没有变在跳转PspSetCreateProcessNotifyRoutine此时出现push ebp,
  16. ;remove应该是[ebp+8h+4h]也就是[ebp+0ch].所以[ebp+08h]是第一个
  17. ;参数
  18. 81a1ca0b   807d0c00           cmp     byte   prt   [ebp+0ch],0
  19. 81a1ca0f 53                   push ebx
  20. 81a1ca10   56                   push esi
  21. 81a1ca11   57                   push edi
  22. ;如果remove为false跳转,否则继续
  23. 81a1ca12   7474                 je
  24. nt!PspSetCreateProcessNotifyRoutine+0x83 (81a1ca88)
  25. ;这里开始移除回调函数
  26. ;;省略部分
  27. ;最后判断PspNotifyEnableMask的第二位是否为0.如果不为0则跳转
  28. ;返回成功
复制代码

上面省略了一大部分,其实当你研究完这个函数构成就可以把别人的注册的回调函数去掉.就是如果知道别人的注册过的回调函数指针.就可以去掉他.对于rootkit,如果remove掉了这些回调函数.杀毒软件可以被悄无声息的禁用掉.还不会出错.很基本的文章.本人刚接触内核.参考了很多东西.写了本文.有什么错误,欢迎大家指证.


鲜花

握手

雷人

路过

鸡蛋

最新评论

相关分类

Archiver|手机版|噩靈戰隊 ( 黑ICP备11001077号 )

GMT+8, 2012-2-23 14:47 , Processed in 0.030757 second(s), 18 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部