为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

【doc】Ring3下安全获取原始SSDT地址

2018-04-03 7页 doc 22KB 66阅读

用户头像

is_601191

暂无简介

举报
【doc】Ring3下安全获取原始SSDT地址【doc】Ring3下安全获取原始SSDT地址 Ring3下安全获取原始SSDT地址 |,"\:!釜::!三三;-l互-l誊-l__lI 文/图牵着蜗牛去散步 ssDT是系统服务描述符表的简称,在w NT内核的操作系统中,它储存着NativeAPI相关 信息,在Rootkit中HookSSDT是最常用的手法之 一 ,常见的木马灰鸽子,PCShare或者说流t民软 件雅虎助手,百度搜霸,甚至每台电脑安装的 杀毒软件防火墙都离不开HookSSDT.我在黑防 三月份的杂志中讲解了如何在Ring0驱动中用 ZwQuerySy...
【doc】Ring3下安全获取原始SSDT地址
【doc】Ring3下安全获取原始SSDT地址 Ring3下安全获取原始SSDT地址 |,"\:!釜::!三三;-l互-l誊-l__lI 文/图牵着蜗牛去散步 ssDT是系统服务描述符的简称,在w NT内核的操作系统中,它储存着NativeAPI相关 信息,在Rootkit中HookSSDT是最常用的手法之 一 ,常见的木马灰鸽子,PCShare或者说流t民软 件雅虎助手,百度搜霸,甚至每台电脑安装的 杀毒软件防火墙都离不开HookSSDT.我在黑防 三月份的杂志中讲解了如何在Ring0驱动中用 ZwQuerySystemlnformation枚举进程,如果需要 检测出通过HookSSDT隐藏的进程就需要获取原 始的SSDT地址,虽然这种检测隐藏进程不 是很有吸引力,但获取原始ssDT地址可以做很 多事情,比如在lce'Sword早期版本中就是通过获 得ssDT真实地址使用ZWOPenKeY, ZwEnumerateKey,ZwQueryValueKey等API来检测 隐藏的注册表键值.随着ROOtkit技术的发展, 可能今天你会使用CmEnumerateValueKey这类更 底层的方法来枚举注册表,但目前市面上的流 t民软件还没有做得这么bI,通过原始的SSDT枚 举还是有一定市场的.用原始ssDT地址还可以 枚举出HookZwQueryDirectoryF;le隐藏的文件, 同样IceSword采用的是静态ntoskrnl文件PE结 构的方法来获取真实的ssDT地址,只是 IceSword采用的不是Ring3的CreateFile或RingO的 ZWCreateFile打开文件,而是更深的loCreate F.Je,也是为了防止再次Patch.由于文件过滤系 统驱动更复杂,同时再往下层还有FAT和NTFS 格式以及未来的WinFS格式系统级驱动,不在本 文的讨论范围,就不再赘述了. 到底IceSword是如何取得原始SSDT地址的 呢7其实国外早在2003年就公布出实现方法了, 由于系统环境和CPU核心数量之间的差异,首先 通过NtQuerySystemlnformation函数判断内核文件是 ntoskrn1.exe(单核CPU),ntkrnImp.exe(多核CPU) 还是ntkrnlpa.exe,然后通过LoadLibrary函数动态加 载分析PE结构获取映像基址(1mageBase)以及PE .TextSection中的VirtualOffset,RVAOffset,然 后获取KiServiceTable地址,最后得到每个真正的 SSDT地址和索引.如果需要判断是否为被Hook的 SSDT地址,可以通过和内存中映射的地址对比, 详细的流程如图 1所示. 首先要说明 的是本次获取的 仅仅为系统描述 表的真实地址和 索引号.由于 SSDT可以动态扩 充,如卡巴斯基 反病毒软件的部 分版本在SSDT表 尾部增加了一些 函数,所以不建 lNtQuerySystemInfofm.n] [PEsectiOnVirtual\RVAAddre5s: 旦,-, 【KiServiceTableAddressj S 【SSDT=ImageBas'e+KerneIBase】 图1 议使用硬编码,可以通过动态加载ntdl1.dll文件 来解析最终的ZWXXX函数名称.下面是如何枚 举真实SSDT地址的代码,其中使用到了网上两 个开源的函数FinclKiServiceTable()和GetHeaders (),由于结构较多这里就不浪费篇幅了. ??_?iwww.hAnkmr.c丽om.cn圈 '栏目编辑>SOCket>SOCket@hackerCOmcn 件, eXe DWORDdwKSDT 77T口bRVA DWORDdwKiServiceTable; ,,KceT=bLe PMODULESpModules(PMODULES)&pModules; DWORDdwNeededSizerc; DW0RDdwKemelBase,dwServices0; PCHARpKemelName; PDWORDpService: PIMAGEFILE_]HEADERplh; PlMAGE—DPTIONALHEADERpoh; PIMAGE—_SECT10NHEADERpsi:; //通过N1:QuerySys七e棚nformat'on取得系统内核文 判断楚rrtoskrn[.exe,ntkrnLmp.exe还楚n~krn[pa. rc-NtOaerySystemlnformation(SystemModulehffonna tion,pModules,4,&dwNeededSize); 西(rcSTATUS—INFOLENGTH…MISMATCH) //如果透回内赛不够 {pModules-(PMODULES)GlobalAl1oc(GPTR dwNeededSize)://重新分配内存,进行第二次权羊 rc-Nt(~erySystemhfformation(SystemModLfleInfonn ation,pModules,dwNeededSize,NULL); //系统内核文件是总是在第一个 } if(!NTSUCCESS(rc)) {MessageBox(~NtQuerySystemlnformation()Failed! \n);//NtQuerysyste1fo嗍tion执行失败,橙奎当 曾进程权限 return0:} dwKemelBase(DWORD)pModules>smi.Base; //im49ehlse PKeri3elName=PMOdUles>smi. ModuleNameOffset+pModules>smi.ImageName; hKernel=LoadLibraryEx(pKernelName,0. DONTRESOLvEDLL_REFERENCES);//映射nCo~rnl, if(!hKeme1)(MessageBox('Failedtoload\n"); retum0:} GlobalFree(pModules}; (!(dwKSDT-(DWORD)GetProcAddress(hKernel, "KeServiceDescriptorTableq))) //在内核文件中奎找Kesen,eDescrip铂rTable地址 {MessageBox("CantfindKeserviceDescriptor Table\n"); return0: } dwKSDT=(DWORD)hKemel; //获取KeServiceDescrlptorTabl~RVA if(!(dwKiServiceTable=FindKiServiceTable(hKemel, dwKSDT))) //获取KerveTable地址 {MessageBox(1IcantfindKiServiceTable…\n"); retumO: 阿戮 l I GetHeaders((char*)hKemet,&pfh,&poh,&psh); CStrings: intdwIndex-0; for(pService:(PDWORD)((DWORD)hKernel+ dwKiServiceTable); *pService-poh——>ImageBase<poh——>SizeOflmage; iXService++,dwServices++,dwlndex++) {s.Format("0x%03X0x%08X\n,dwlndex,*pSeradce poh>ImageBase+dwKernelBase);//S,.~T索引和地址, 但这里的索引颇冉不赛在对虚荧系 MessageBox(s); FreeLibmry(hKeme1) retuml: l 本文的代码完全运行在Ring3用户态程序 中,同时在Windows20.0/xP/20.3/Vista中测 试通过,编译本至少需要Windows2000 DDK.为了减少声明和动态引用的代码.主要 用到了ntdlI.I.b.在附件中提供了一个DrvLoader. exe驱动加载工具,加载一个我编译好的通过 HookZwQuerySystemlnformation方法来隐藏进程 的驱动文件RingO.sys,打开IceSword观察SSDT索 引号为OxB5的ZwQuerySystemlnformation函数, 已经从原始地址Ox80984B68变成了0xF7790 2D0,如图2所示. 图2 最后运行我们自己的程序,可以看见索引 号为OxB5的地址显示的是原始的Ox80g84B68, 和IceSword获取的一致,这个原始值的获取通过 本地读取内核文件解析PE结构的方式获得,所 以不受Rootkit的干扰,但要注意读取的内核文 件要防止Patch,所以lceSword采用了特殊的处 理,获取的原始ssDT地址如图3所示. 本文最大的特点就是在Ring3下完成地址获 取,运行更稳定安全,在第三期的文章中,我 .… )so … cket.;'.:==?圈l曰?圈?? 详细讲了如何在内核驱动中枚举进程,加入现 在的内容就可以检测隐藏进程了.大家可以把 获取出来真实的ssDT地址传人驱动.通过变通 可以枚举出通过HookSSDT方法隐藏的进程,注 册表或文件等,这里就不再细讲如何还原SSDT 了.还原SSDT的方法也很简单,就是在Ring0内 核态写回这些真实的地址,但还原SSDT会和部 分反病毒软件不兼容,如卡巴斯基部分版本会 造成BSOD蓝屏,所以放弃了,毕竞主流的杀毒 软件~6HookSSDT.还有就是很多人可能对驱动 程序编写比较陌生,这里告诉大家在内核中编 程的一些技巧,可以让大家少走些弯路.在内 核驱动中需要注意引用的地址是否有效,在 前置知识VB 关键讽编程,APc例程,ICeSW0rd win32中内存引用错误会提示一个友好的非法 操作窗El,点个确定就好了,但在内核驱动中 指针越界直接会造成BS0D蓝屏,然后是系统 DumP出物理内存数据,一般我们不需要调试驱 动,蓝屏重新启动一次电脑会耽误很多时间, 所以大家在测试时为代码加上try-except这样的 异常捕获机制可以阻止一些蓝屏问题同时在 Ring0中微软给了我们一个很有用的函数 MmlsAddressValid(ULONGdwAddress)用来检测 一 个内核地址是否有效,可以大大降低测试时 的蓝屏危险,示例代码如下. 本期光盘杂志相关栏目;也可以到黑防官方网 站下载)仂 也杀不掉的进 文/图陈布雨(fOX) IceSword是一款手动查杀木马和病毒超强的 辅助工具,基本上大多数恶意软件都逃不过它 的法眼,不过下面我们就给IceSword开一个小小 的玩笑,让它的结束进程功能失效. 开始之前我们先来看看一般的结束进程思 路.即首先调用OpenProcess获取进程句柄,然后利 用获取到的句柄调用TerminateProcess函数.因 此,用户态进程防杀.我们只需要钩住 OpenProcess这个API,并过滤掉需要防杀的进程 标识符《Pr0CessID)即可. 我们看一下TerminateProcess这个函数的汇编 调用就会发现,它直接调用了NatiVeAPI 鏊戴i?0圜
/
本文档为【【doc】Ring3下安全获取原始SSDT地址】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索