基于taskmgr的应用层进程隐藏技术

前言

目前进程隐藏技术网上流程的主要是在驱动层进行挂钩,但是由于win7之后,windows操作系统权限管理之类越来越严格,win7之后加载驱动首先需要管理员权限,另外windows加载驱动同时还需要有微软签发的驱动证书,这对于土八路来说基本是一个无解的难题,基本难以弄到正规公司的签证,同时,逆向windows的签证管理系统工作量太大,目前网上也没有签证伪造技术流传。

相对驱动层来说,直接hook的ssdt表或者直接修改内核函数都较为方便,在应用层的话,其原理也是改写功能实现函数,从思路角度说,可以改写taskmgr.exe的txt段,导入表,对dll的函数代码进行hook等手法等三种。

无论哪种方法,可能都需要逆向一下Taskmgr.exe,分析一下其显示进程信息的相关原理。就win7而言,251kb大小,同时作为一款窗口进程,如何快速的我们感兴趣的功能尽快找到,并逆向出其工作原理,也算是一个难点。

图片1

Taskmgr.exe的快速逆向方法

这里要介绍一种快速逆向的方法,可以快速得到指定功能的实现原理。

1,将taskmgr.exe拖进ida中进行逆向,查看导入表信息

图片2

寻找所有相关进程查询的api,之后再bdg中下函数断点,下断函数为ZwQuerySystemInformation,很快可以定位到进程查询的相关代码。这是逆向的第二层境界,根据正向思路来逆向,逆向修炼在进一步的就是编写驱动监视cpu执行流程,io,总线活动之类来逆向。

图片5

当rcx参数为5时,ZwQuerySystemInformation执行的就是对进程链表的查询功能。

在ida可以看到进程信息查询的汇编代码:

图片6

Hook的三种方案

对于修改windows的进程管理器,肯定是要对taskmgr进行hook,通常hook是对软件的代码执行路径上的必经之路上下hook函数,在应用层上来说一共三个节点是必须要经过的,1,taskmgr代码中调用ZwQuerySystemInformation函数进行进程信息查询的函数,2,pe导入表的ZwQuerySystemInformation地址所在表项,3,ntdll中ZwQuerySystemInformation所在位置。对应的,有三种下钩子函数的手法。

程序中查询进程信息函数——–>PE导入表———->Ntdll.dll中ZwQuerySystemInformation的实现。

taskmgr.exe的txt段的代码改写:

很容易寻找到相关的进程信息查询部分,这时,根据64位fast传参规则,rdx指向的就是进程信息接收指针所在的位置,此时可以直接使用汇编改写进程信息查询函数,在结束ZwQuerySystemInformation函数的调用之后,可以对接收到的进程信息,抹去需要隐藏的进程信息后提交给原程序的处理流程。此方法的问题在于windows各个版本的进程管理器都略有差别,此方法需要大量使用汇编代表,难以实现兼容。

taskmgr.exe的pe导出表的指针改写:

在之前的逆向分析中得知,获取到进程信息的函数为ZwQuerySystemInformation,可以根据pe+信息(32位pe文件,64位pe+文件),寻找到pe+文件的导入表信息,将ZwQuerySystemInformation函数的导入地址修改,改为自己已经编写好的函数地址,再调用ZwQuerySystemInformation函数,将接受到内核层返回数据之后,再做屏蔽相关的进程信息。这种方法可能是最佳的方法,其优点在于可以直接使用c语言编写代码,而不需要使用汇编,汇编是一种十分依赖硬件环境的语言,此例中只需要对文件的导入表修改8字节大小即可,且,pe+文件的导入表是拥有可读可写可执行权限的,动作最小,但由于此种手法为病毒常用手法之一,被杀软重点关注,故并未使用此手法。计算机病毒防范艺术一书中,讲述文件病毒的一种中专门有一节论述此技术以及升级手法,不做太多描述,手法较为常规不太好用其实。

对ntdll.dll进行hook:

在api调用过程之中,大多说功能型api,都是要进入内核层进行执行功能,api经过ntdll进行封装,变成Ntxxxxx/Zwxxxxx类型名字之后,调用同名系统调用表,经过内核的参数验证后执行功能返回,通常而言,是通过syscall指令执行快速系统调用进入内核层,在xp时代使用的是sysentry指令。这里查询进程信息使用的ZwQuerySystemInformation函数,就是使用的nt函数,此函数直接调用系统调用,若在taskmgr进程直接调用nt函数时,将其挂钩时也能做到隐藏进程。需要改下字节最少需要13字节。

进程隐藏实现

本次使用的是挂钩dll的方法,在windows7之后,许多非常规手段的使用都不再简单,windows系统机制中加入了各种各样的防御手段。这里是指session 0隔离,以及内存权限控制。

Session 0隔离:

所有的服务以及dll都存在于session 0中,而用户登录,第一个登录位于session 1,后面的用户登录使用的是 seesion 2,依次类推,常规的VirtualAllocEx,WriteProcessMemory函数调用,将无法写入dll所在的内存空间之中,因为此类API在实现功能之前会对session 进行校验。挂钩时,必须手动操作指针进行写入读取操作。

内存权限保护:

起源于xp时代的dep技术,原本计算机另外的一个名字叫做图灵机,在图灵机模型中数据代码没有明确间隔,但在现代操作系统的内存分割机制下,在内存中,内存拥有读写执行权限,对于一块只读内存区间,是不可以进行写入操作,同时也不允许进行执行操作。在进行挂钩时,必须赋予需要改写的地址可读可写权限,同时,如果被挂钩位置需要执行,还需要赋予可执行权限。更改内存权限需要管理员权限,这是最大的一个缺陷。

NATIVE函数的调用:

WINDOWS编程技巧中有一种技巧是直接调用NTXXXXX/ZWXXXX函数,此类函数之间调用同名系统,通常不被导出,但可在WINDOWS的WDK帮助文档中查询到一些,此类函数由于接近底层,常可用作一些底层操作,同时由于使用量少,网上资料也不多,此类技巧大量被应用于病毒以及安全软件,在挂钩中也经常被使用来突破SESSION 0隔离,内存保护等,但由于此类函数相关介绍不多,在使用时常常会有各种问题出现,如函数ZWPROTECTVIRTUALMEMORY会将函数参数值做一个字节修改,这也是编写安全类软件一大挑战,相关资料可以查询WINDOWS NT 2000 NATIVE API REFERENCE 一书。

详细步骤为:

  1. 获取taskmgr.exe进程信息,如pid号
  2. 获取注入恶意代码
  3. 恶意代码修改需要hook的目标内存地址的权限
  4. 对目标地址进行修改代码执行流程
  5. 新的执行流程将查询信息返回后屏蔽指定进程后返回

此方法难点在于对ZwQuerySystemInformation函数代码的改下,此函数为 Native Api,为直接调用系统调用的api,在不同版本的操作系统中,系统调用号并不相同。存在需要处理的兼容性问题,另外ZwQuerySystemInformation对于windows7来说,总共只有16个字节,而对x64位系统而言,仅仅一个地址就需要8个字节,另外,jmp指令最多只允许跳转跨越4Gb的内存跨度,但在windows7中,ZwQuerySystemInformation与MyQuerySystemInformation(新流程函数,屏蔽需隐藏进程信息函数)函数地址间距由于dll的内存布局问题,两个函数直接跨度超越4Gb大小,需要挂钩时整体考虑,另外,在x64位编程中,内嵌汇编代码也不是一件简单的事情。

图片7

图片8

这里两幅图片分别是win10以及win7中的ZwQuerySystemInformation函数代码,可以看出系统调用号不一致,于此同时,在win7中ZwQuerySystemInformation函数代码非常之小。

在windows 10的挂钩过程中,我曾试用常规挂钩手法:E9 off相对偏移,然而在迁移过程中发现,ZwQuerySystemInformation与MyQuerySystemInformation之间的内存地址差距远大于4Gb,需要8字节大小描述距离,然而,jmp指令不支持此类超远距离长度的跳转。

这里,我选取的挂钩代码为:

  • Mov rax,offset: ZwQuerySystemInformation
  • Push rax
  • Ret

效果图为:

图片9

 

*作者:冷风@天融信阿尔法实验室,转载请注明来自MottoIN

原创文章,作者:天融信阿尔法实验室,如若转载,请注明出处:http://www.mottoin.com/article/system/94800.html

发表评论

登录后才能评论

联系我们

021-62666911

在线咨询:点击这里给我发消息

邮件:root@mottoin.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code