APP下载

一种有效的进程隐藏方案实现

2020-04-24任雁军

电脑知识与技术 2020年5期

任雁军

摘要:該文从Windows操作系统的进程的运行机制出发,简要介绍了Windows操作系统的进程的分类及管理机制,对常见的基于Windows操作系统的进程隐藏技术进行了概要的介绍并对各类隐藏技术的优势和不足进行的分析阐述,最后从实用的角度出发,结合几种不同的进程隐藏技术的特点与优势,给出了一种有效的进程隐藏方案,并详细地分析解读了实现这一方案的主要技术方法。

关键词:进程隐藏;动态链接库;DLL劫持

中图分类号:TP393 文献标识码:A

文章编号:1009-3044(2020)05-0244-02

开放科学(资源服务)标识码(OSID):

进程是操作系统中正在运行的一个应用程序,是系统进行资源分配和调度的基本单位,微软的Windows是目前在PC机上应用最广的多用户操作系统,Window系统的进程大致可分为:系统核心进程、系统进程、服务进程及用户进程。使用Win-dows自带动任务管理器可以查看并管理一部分显式存在的进程,然而还有很多进程则是以隐性的方式存在的,无法用任务管理器或其他工具对其进行查看、终止及删除。

1 常见进程隐藏技术

所谓的进程隐藏,通俗地讲就是让可执行程序以隐蔽的方式被加载并且使其进程尽可能地长期驻留在内存中的方法。

1.1 进程伪装

1)简单地将程序改名与系统进程相同或者相似,早期的木马或病毒多使用这种方法隐身,显然很容易被识别。

2)将自身注册为DLL模式的系统服务这样在系统进程列表中就能实现隐身,这种方法虽简单,但需要较高的权限。

3)借助系统程序Rund1132.exe启动dll程序也能实现简单的进程隐藏,但隐身的强度不高。

4)通过修改进程PEB中的命令行参数实现伪装,这种方法容易被杀毒软件查杀。

1.2代码注入

将自身代码动态地写入目标进程的内存而实现隐身,这种方法用在系统进程中很难实现,在一般进程中的存活时间取决于目标进程的存活期,极易被杀毒软件查杀。

1.3 HOOK隐藏

使用API HOOK函数捕获系统消息而实现进程隐藏,这种方法需要较高的权限,也是杀毒软件紧盯的目标。

1.4 DLL劫持

利用系统加载DLL的顺序,将伪造的同名Dll插在目标Dll之前被加载,这种方法很巧妙,但随着windows系统安全防护性能的不断改进,在win7之后已经很难找到可以劫持的系统关键Dll了。

可见前面介绍的每一种进程隐藏方法都有自身的优势和缺陷,在现实中那些与系统进程密切接触的方法(比如HOOK和注入等)已经成了杀毒软件紧盯的目标,正确的做法是:让你的动作尽量接近正常!同时综合使用多种方法和策略,也能达到取长补短的效果。

2 一种进程隐藏方案实现

2.1实现原理

1) Dll劫持原理:Windows可执行文件输入表中列出的函数名实体存身在不同的动态链接库(Dynamic Link Library,缩写为DLL)文件中,只有当函数被调用时,系统才加载所需的DLL文件到内存中,由于输入表只指定了DLL文件名而没有指定具体路径,所以系统加载器按照:当前目录一系统目录一环境路径的顺序查找并加载同名DLL文件。如果将含有相同输出表的同名DLL文件放在可执行文件所在的目录下就可抢先加载这个伪DLL文件,当然之后还需将原DLL加载以免系统报错。

2)劫持Version.dll实现加载并存活:由于Windows安全防护机制的不断进步,win7之后系统关键DLL(如:kerne132.dll、ws2_32.dll、lpk.dll等)已经无法劫持了,所以被劫持的DLL文件的选择需要满足两个条件:非系统关键文件并且使用率较高。本方案选择Version.dll作为被劫持对象,常见用户进程(比如IE、WINWord等)都会调用它,可以保证“伪Version.dll”的加载成功,当然“伪Version.dll”会伴随调用它的用户进程的终止而退出。

3)利用Rund1132隐身:在“伪Version.dll”中创建一个独立的Rund1132进程加载真正需要隐身的xx. dll进程。命令行参数为:Rund1132 xx,函数名。

2.2 实现示意图

图1进程隐藏方案实现示意图

2.3 主要代码

A>使用预处理命令向原Version.dll直接转发导出函数

#pragma comment(linker, "/EXPORT: VerFindFileA=version-Org.VerFindFileA,@1”)

#pragma comment(linker, "/EXPORT:VerFindFileW=version-Org.VerFindFileW,@2")

….

#pragma comment(linker, "/EXPORT: VerInstaIIFileA=_AheadLib_VerInstaIIFileA,@8”)

#pragma comment(linker, "/EXPORT: VerInstaIIFileW=_AheadLib_VerInstaIIFileW,@9")

….‘

#pragma comment(linker, "/EXPORT: VerLanguageNameA=_AheadLib_VerLanguageNameA, @12 ")

#pragma comment(linker, "/EXPORT: VerLanguageNameW=_AheadLib_VerLanguageNameW, @13 ")