一、什么是rootkit
简单地说,rootkit是一种能够隐身的恶意程序,也就是说,当它进行恶意活动的时候,操作系统根本感觉不到它的存在。想象一下,一个程序能够潜入到当前操作系统中,并且能够主动在进程列表中隐藏病毒,或者替换日志文件输出,或者两者兼而有之——那它就能有效地清除自身存在的证据了。此外,它还可以从受保护的内存区域中操纵系统调用,或将接口上的数据包导出到另一个接口。本教程将重点介绍如何通过hooking系统调用来进行这些活动。在本教程的第一部分,我们将打造自己的系统调用,然后打造一个hook到我们创建的系统调用上面的rootkit。在最后一部分,我们将创建一个rootkit来隐藏我们选择的进程。
二、用户空间与内核空间
我们之所以上来就打造一个系统调用,其目的就是为了更好地理解在内核空间与用户空间中到底发生了些什么。在用户空间中运行的进程,对内存的访问将受到一定限制,而在内核空间运行的进程则可以访问所有内存空间。但是,用户空间的代码可以通过内核暴露的接口来访问内核空间,这里的所说的接口就是系统调用。如果你曾经用C语言编程,并且摆弄过Linux的话(是的,我们将用C编程,但不用担心,因为这里介绍的例子会非常简单),那么你很可能已经用过系统调用了,只不过你没有意识到罢了。read()、write()、open()就是几个比较常见的系统调用,只不过我们通常都是通过诸如fopen()或fprintf()之类的库函数来调用它们而已。
当你以root身份运行进程的时候,不见得它们就会运行在内核空间。因为root用户进程仍然是一个用户空间的进程,只不过root用户的进程的UID = 0,内核验证过其身份后会赋予其超级用户权限罢了。但是,即使拥有超级用户权限,仍然需要通过系统调用接口才能请求内核的各种资源。我希望大家能够明确这一点,这对进一步阅读下面的内容非常重要。
好了,闲话少说,下面切入正题。
三、所需软硬件
linux内核(我使用debian的最小化安装,内核版本为3.16.36)
虚拟机软件(VMware、Virtualbox、ESXi等)
我建议给VM配置2个CPU内核,至少4GB内存,但1核和2GB也能对付。
需要强调的是︰
1. 我不会对示例代码进行详尽的介绍,因为代码都自带了注释。这样做好处是,可以督促读者自行深入学习。
2. 我的VM使用的是Debian最小化安装,因为我发现内核的版本越旧,打造自己的系统调用时就越容易,这就是选择3.16.36的原因。
3. 文中的所有命令都是以root帐户在VM中运行的。
四、系统调用:pname
启动VM,让我们先从一个内核源码开始玩起。实际上,介绍如何打造自己的系统调用的教程已经有许多了。如果你想打造一个简单的“hello world”系统调用的话,请参考这篇文章:。
通过下面的命令,获取内核源码的副本,并将其解压缩到/usr/src目录下面:
pname (进程名称):
现在,让我们从一个简单的系统调用开始入手:当向它传递一个进程名称时,它会将该进程对应的PID返回到启动该系统调用的终端上面。首先,创建目录pname,然后通过cd命令切换到该目录下面:
然后,创建头文件:
接下来,创建一个Makefile:
在里面,添加如下内容:
保存并退出。
将pname目录添加到内核的Makefile中:
回到/usr/src/linux-3.16.36目录,并编辑Makefile
您要查找core-y += kernel/mm/fs/ipc/security/crypto/block/所在的行。
然后
将pname目录添加到此行的末尾(不要忘记“/”):
当我们编译这个文件的时候,编译器就会知道从哪里寻找创建新的系统调用所需的源文件了。
将pname和sys_process_name添加到系统调用表中:
请确保仍然位于/usr/src/linux-3.16.36目录中。接下来,我们需要将新建的系统调用添加到系统调用表中。如果您使用的是64位系统,那么它将会添加到syscall_64.tbl文件的前#300之后(将64位和32位系统调用隔离开来)。此前,我的64位系统调用最后一个是#319,所以我的新系统调用将是#320。如果它是一个32位系统,那么你可以在syscall_32.tbl文件结尾处进行相应的编辑。
添加新的系统调用:
将sys_process_name(char * process_name)添加到syscall头文件中:

最后,头文件必须提供我们函数的原型,因为asmlinkage用于定义函数的哪些参数可以放在堆栈上。它必须添加到include / linux / syscalls.h文件的最底部:
编译新内核(这个过程需要一段时间,请稍安勿躁):
这将需要很长时间,大概需要1-2小时或更多,具体取决于这个VM所拥有的资源的多寡。然后,从源代码文件夹/usr/src/linux-3.16.36中输入下列命令:
通过方向键选中保存选项,按回车键,然后退出。
如果您正在运行的虚拟机具有2个内核,则可以使用下列命令:
否则的话,只需输入下列命令即可:
现在,耐心等待它运行结束。
安装新编译的内核:
完成上述操作后(希望没有任何错误),还必须进行安装操作,然后重新启动。
测试新的pname系统调用:
还记得使用哪个数字把我们的系统调用中添加到系统调用表中的吗?我使用的数字为320,这意味着系统调用号为320,同时,我们必须以字符串的形式来传递进程名称。下面,让我们测试一下这个新的系统调用。
由于我使用ssh配置我的VM,我将进入进程sshd。我打开了另一个终端来查看所有通过sshd运行的进程,然后运行该可执行文件:
该系统调用通过遍历进程列表发现了3个sshd进程(grep sshd不是正在运行的sshd进程),并通过TTY将其输出到调用它的终端上,最后成功退出(状态值为0)。
现在,您已经有权在内核(受保护的内存区)空间中查找进程了。这个进程列表中,你不会发现这个系统调用——尽管它正在运行,但你会发现testPname可执行文件正在运行:
如何才能找到我们的新系统调用呢? 很简单:使用strace工具。
针对可执行文件运行strace时,它将暂停以读取用户输入(可以通过系统调用read()来读入,但是需要注意的是,在我们的测试程序中使用的是来自stdio.h库的scanf()函数)。这时,输入你喜欢的任何进程即可。
在下面,从read()系统调用到程序退出的代码都进行了突出显示:
只要把bash的进程名称传递给strace,它就会立刻找出该进程所使用的系统调用——我们的syscall_320。你也可以使用该工具来检查我们运行的程序用到的所有其他系统调用,例如mmap(内存映射)和mprotect(内存保护)等。我建议大家逐一研究这些系统调用,以充分了解它们都可以做哪些事情,并仔细考虑攻击者能够用它们来干什么。
此后,我们将hooking系统调用open(),但是就目前来说,不妨先用我们的第一个rootkit来“钩取”系统调用syscall_320
五、利用Rootkit“钩取”Pname
首先要弄清楚的一件事情是,现在我们要以hook的形式来打造一个内核模块,而不是借助系统调用。这些模块可以随时通过insmod和rmmod命令(前提是您已经获得了相应的权限)加载到内存和从内核中删除。为了查看当前正在运行的所有模块,您可以使用lsmod命令。就像我们的新程序将成为一个模块一样,从技术上讲,它可以被定义为一个hook,因为我们将“hooking”到之前创建的pname系统调用上。
在研究过程中,我在发现了一篇非常棒的文章,它深入浅出地介绍了打造hook的方法。请选择一个存储hook的目录并利用cd命令切换到这个目录下面,这里我选择的是root目录。
查找sys_call_table地址:
我们首先要做的事情就是找到系统调用表地址,因为一旦找到了这个地址,我们就能够对其进行相应的处理,进而hook系统调用了。为了找到这个地址,我们只需在终端中键入:
将这个地址复制到我们的代码中。
注意:有许多方法可以用来动态搜索sys_call_table,我强烈建议您使用这些方法而不是硬编码。然而,为了便于学习,这里就不那么讲究了。我打算将来编写一个更高级的rootkit,让它也支持动态搜索能力。如果你想提前了解这方面的知识并亲自尝试一下的话,我建议阅读下面的文章:
Hook! Hook! Hook!
以下是我的captainhook.c代码:
你可能已经注意到__NR_pname,它代表数字,即pname的系统调用的编码。别忘了我们已经将该系统调用添加到syscall_64.tbl(tbl = table duhh)中。 我们赋予它一个数字、一个名称和函数名。在这里,我们使用的是其名称(pname)。它将拦截pname系统调用,并且每成功一次就打印一次dmesg。
创建Makefile:
我们必须创建另一个Makefile,具体方法就像我们在创建系统调用时所做的一样,但由于这里是一个模块,所以会有一点不同:
在加载到运行中的内核后测试该hook:
现在万事俱备,只剩下编译了。对其进行编译的时候,绝对不会像编译内核那样费时,因为它只是一个模块而已。为此,只需键入下列命令:
很好,你现在应该多了一些其他文件,而我们想要的是.ko文件:
现在打开另一个终端,键入以下命令以清除dmesg,然后插入该模块并运行testPname,并跟踪其输出:
第一个终端:
第二个终端:
经过一番努力,终于成功地创建了一个可以抓取系统调用(也就是rootkit)的钩子!想象一下,如果你的__NR_ pname是__NR_open或__NR_read会怎样? 您可以自己尝试一下,或继续阅读下一部分。不过,就这一点来说,有很多其他教程可资利用,例如:
六、对系统管理命令“ps”隐身
现在,让我们通过编程技术来实现对ps命令隐藏进程。首先,找到你想要隐藏的进程的PID,并想清楚你想让它伪装成哪个进程。就本例而言,我将用一个bash进程给su(sudo)进程打掩护,以便系统管理员看不到有人正在使用超级用户权限运行。
注意:Linux中的一切皆文件。例如“/proc/cpuinfo”文件存放的是CPU信息,内核版本位于“/proc/version”文件中。而“/proc/uptime”和“/proc/stat”文件则分别用来存放系统正常运行时间和空闲时间。当运行ps命令时,它实际上是打开进程的文件,以使用open()系统调用查看相关信息。当进程首次启动时,会使用系统调用write()将其写入具有相应PID#的文件中。针对ps命令运行strace就能查找它们,或者查看它使用了哪些系统调用。
这里,我们将使用captainHook.c作为样板:
复制前面使用的Makefile,同时将顶部的”captainHook.o”替换为“phide.o”。
然后,输入下列命令
以及
如您所见,这里成功实现了隐身!除此之外,还可以使用这里介绍的方法来隐藏多个进程。
七、如何防御?
你可能注意到了,我这里只是使用另一个正在运行的进程来隐藏我们的进程。所以在PS表中会有重复的PID。这很容易被发现,但有一些方法可以完全隐藏它,我计划在未来的rootkit文章中加以介绍。
记得早些时候我提到的lsmod命令吗? 它就可以列出在内核上运行的模块,效果具体如下图所示。
要想查看所有模块,可以使用:
因为rootkits通常在内存中待命,所以最好使用一个可以主动寻找rootkit的程序,例如:
八、结束语
我们希望本文能够帮您了解系统调用、内核空间和用户空间方面的相关知识。最重要的是,通过阅读本文,可以让您意识到钩住系统调用其实非常简单的事情,同时,也让您意识到只需少的可怜的编程技巧就足以让你为所欲为。当然,还有一些非常先进的rootkits类型,我们将后续的文章中陆续加以介绍。在下一篇文章中,我们介绍如何在无需查找PID的情况下隐藏进程。
如果QQ空间中了病毒,要怎样才能查杀?
开机按F8,进入安全模式杀毒!推荐超级巡警4.0beta8标准版1.它可以专门查杀并可辅助查杀各种木马、流氓软件、利用Rootkit技术的各种后门和其它恶意代码(间谍软件、蠕虫病毒)等等。 2.它提供了多种专业工具,提供系统/IE修复、隐私保护和安全优化功能,提供了全面的系统监测功能,使你对系统的变化了如指掌。 3.只要你配合手动分析可近100%的查杀未知恶意代码!国内第一个发现熊猫烧香病毒的就是它!而且可以自动升级!完全免费!下载页地址:
超级巡警怎么样?杀毒防毒能力强吗?
它本身就是防木马辅助软件 超级巡警(Anti-Spyware Toolkit) 1、 软件简介: 专门查杀并可辅助查杀各种木马、流氓软件、利用Rootkit技术的各种后门和其它恶意代码(间谍软件、蠕虫病毒)等等。 提供了多种专业工具,提供系统 /IE修复、隐私保护和安全优化功能,提供了全面的系统监测功能,使你对系统的变化了如指掌,配合手动分析可近100%的查杀未知恶意代码! 2、主要特色: 1)通用的自动化Rootkit解决方案,不使用传统特征码,即可检测各种利用Rootkit技术隐藏的木马、后门。 2)全面检测隐藏进程、隐藏服务、隐藏端口。 3)自动检测和修复Winsock SPI链的相关错误。 4)系统内核服务描述表恢复,显示和摘除被Hook的内核函数,自动还原被Inline hook的内核函数。 5)独创的快速匹配算法,在最小的系统资源占用级别上进行最快的扫描检测。 6)扫描模块和实时监控共用引擎和库在内存中的同一份拷贝,大大降低系统资源占用,模块间高效协同工作。 7)内存扫描和静态分析预警系统有机结合。 8)立足于病毒家族的广谱特征,强力提高病毒检测率。 9)前瞻性的主动防御监测体系,全面检测未知木马。 10)国内首个支持NTFS数据流扫描,使检测更彻底。 11)纯绿色软件,解压即可使用。 3、主要功能: 启发预警,启动管理,IE插件管理,SPI链自动检测与修复,Rootkit检测,服务管理,隐藏服务检测,过滤微软默认服务,服务增加和删除, SSDT (服务描述表)恢复,进程管理,隐藏进程检测,DLL模块强制卸载,检测隐藏端口,断开连接,定位远程IP,WHOIS查询,关闭端口,IE修复,流氓插件免疫,恶意网站屏蔽,系统垃圾清理,智能扫描,文件粉碎机,软件卸载,系统优化,系统修复,漏洞检查和修复,右键查毒,漏洞检查和修复,系统诊断报告,论坛救援,启发扫描,NTFS数据流扫描,签名分析,全面扫描,内存扫描,目录扫描,信任列表,实时监控,智能升级。
ladder stitch是什么意思
ladder stitch英[ˈlædə stitʃ]美[ˈlædɚ stɪtʃ][释义]梯缝;[例句]Pick up a dropped stitch in knitting by using a crochet hook to pick up the first rung on the ladder and pulling it through the dropped stitch.拿起一个通过使用一拿起钩针钩上的第一个阶梯,并通过它被丢弃的针拉针针织下降。 stitch英[stɪtʃ]美[stɪtʃ]n.(缝纫或编织中的) 一针; 缝法; 衣服; (缝合伤口的) 缝线;vt.缝; 缝补; 缝合裂口; 缝缀;vi.缝针,缝纫;[例句]CONtinue to work back and forth, wrapping and turning one stitch before the previous wrap on each end.继续工作来回转动一针,包装,在以前的包装对各个末端。 [其他]第三人称单数:stitches 复数:stitches 现在分词:stitching过去式:stitched 过去分词:stitched 形近词: smitch switch skitch双语例句 柯林斯词典 常用短语 同反义词相关单词:Stitch 神庙丝蒂其
发表评论