LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 906|回复: 1

囚禁精灵(daemon)进程

[复制链接]
发表于 2003-7-25 16:55:06 | 显示全部楼层 |阅读模式
我是一个大懒人,所以有些东西直接复制别人已经写的了。请包涵:)
1.简介

  我们经常会听说计算机遭到基于Internet的远程攻击。通常位于攻击最前线的是一些服务器软件,例如:WEB、邮件和DNS,这些服务通常是通过监控进程(daemon,也可以叫作精灵进程)来提供的。这些服务即使是位于防火墙之后,也需要面对各种探测和攻击,以至让攻击者获得系统访问权限。大多数的恶意攻击者都会在系统安装rootkit,以便能够进行通常的系统操作。

  一般情况下,这些rootkit和病毒需要使用目标系统的可执行文件、动态连接库以及配置文件。比如:一个安装在linux主机上的rootkit可能需要访问/bin/sh或者能够读写/etc目录下的系统配置文件。而且一旦系统被攻击者侵入,攻击者获得了root权限,就可以运行修改任何自己需要的文件。最近的lion、ramen蠕虫对BIND的攻击就可以证明以上观点。

  但是如果你对精灵进程(daemon)进行限制,只允许其访问必要的文件,而不能访问整个文件系统,又将如何呢?这样就可以使我们的安全不再依赖于daemon软件开发人员的安全水平。

  幸运的是,UNIX系统能够提供这样一种机制实现上面这种想法。在最近的BIND攻击中,Thaumaturgix, Inc的IT管理员William Cox提出了“在chrooted的环境中运行服务器进程,减小你的暴露程度(The best way to limit your exposure is to run the server in a 'chrooted' environment))。这种chrooted环境通常叫作一个chroot牢笼(jail),实际上这种概念已经存在了很长时间了,但是一直没有被软件开发人员和系统管理人员充分利用。

2.chroot牢笼(jail)概念综述

  实现一个chroot jail包括两种方式:

限制进程只能访问整个文件系统的一个子集。
以较低的权限运行服务进程。
  这两种方式是由一些标准的系统调用来提供的。首先,是chroot(),这个系统调用能够限制进程对文件系统的访问。即使某个进程是以root的权限运行的,它对文件/目录的访问也都是相对于chroot()系统调用限制的整个文件系统的子目录。

  例如,如果一个进程以/var/sample/jail为参数执行了chroot()系统调用,现在它要访问一个文件:/etc/passwd,但是操作系统最后会把这个访问请求替换为对 /var/sample/jail/etc/passwd的访问。chroot系统调用只能以root权限调用。

  降低进程权限的系统调用主要包括:setuid()、setgid()和setgroups()。setuid()指定进程的实际和有效用户权限;而setgid()指定进程的实际和有效组权限。setuid()系统非常重要,一旦通过它进入较低的权限运行,进程将无法自己重新获得root权限。setgroups()定义进程的追加组成员关系。除此之外,还有一些其它的相关系统调用,用户可以从自己系统的手册页中获得相关文档。

  其它种类的操作系统可能还有另外的进程束缚方法。例如在FreeBSD中就有一个jail()函数。为了使你更好地体会到jailing的好处,我将通过一个典型的rootkit加以说明,在不同的权限下以及有没有被限制在jail环境中rootkit对系统的危害是不同的。在此,要时刻记住一件事情,当一个服务被侵入,攻击者就能够拥有服务进程所具有的权限。请看下面这个表格:

运行于(a)类(进程以root权限运行并且可以访问整个文件系统)状态下的进程是rootkit的首选目标,侵入这样的服务,攻击者可以修改二进制可执行文件,例如:/bin/ps、/bin/netstat等,打开特权网络端口,读取任意的系统文件包括:/etc/shadow文件。最糟糕的是,他们能够对系统进行完全的破坏,比如:rm -rf /。运行于这种状态,最为常见的一个例子就是sendmail(http://www.sendmail.org。
如果服务进程处于(b)类(root权限、牢笼环境)状态下,一般的rootkit就可能无法正常操作,因为它们一般需要一个shell(/bin/sh)和一些基本的命令,例如:/bin/rm和/bin/cp。然而,在这种状态下,rootkit照样可以打破牢笼(jail)。因为服务进程以root权限运行,攻击者可以通过攻击代码直接执行一些允许root执行的操作(例如:直接引用牢笼之外文件系统的索引节点)。因此,这种状态虽然比(a)类状态安全(门槛高的多),但是也无法对服务提供足够的保护。
服务进程处于(c)类(非root权限,可以访问整个文件系统)状态下,对整个系统的威胁比(a)状态小,因为毕竟攻击者无法直接获得root权限。但是,如果服务进程处于这种状态下,攻击者一旦侵入这个服务,就可以执行一些命令,获得一个shell进行交互,然后很可能通过本地攻击获得root权限。即使攻击者不能获得root权限,也可以访问到系统的绝大多数配置文件和其它信息,例如:用户的电子邮件帐户信息(大量的垃圾邮件将蜂拥而至)。
最后,处于(d)类(非root权限,jail环境)状态下的服务进程受到的限制最为苛刻,这样攻击者根本没有机会执行shell,也不可能获得大量的系统信息。而且,对系统进行的所有破坏都被限制在jail环境中。在这种状态下,最大的威胁就是攻击者在这个jail环境中防止一个可以被jail环境之外的进程访问的可执行文件,从而使攻击代码扩散出jail环境。因此,你应该经常监视你的牢笼,看一下里面的囚犯是否逃出来了
以上部分转自囚禁你的精灵(daemon)进程
By Wing, 出处:http://www.sans.org

chroot apache
准备一个将要chroot的文件系统
1. 在任何地方设置一树目录(最好是另外一个磁盘或者无文件系统的分区
但是我使用符号连接(比如/www)来指向它。
#mkdir /export/misc/www
#ln -s /export/misc/www /www

2.创建一个基本目录;bin 连接到usr/bin
特别注意!这里没有斜杠,除非是我从真正的文件系统里拷贝文件过来。不要把chroot的目录和你真正的“/”根目录混淆!
我用红色表示
#cd /www
#mkdir -p usr/bin usr/lib lib etc tmp dev webhome
#ln -s usr/bin bin

3. /tmp是比较特殊的
#chmod 777 tmp
#chmod +t tmp   


4.创建特殊的设备 /dev/null
#mknod -m 666 dev/null c 1 3

5.设置时间区域信息
#mkdir -p usr/share/zoneinfo
#cp -pi /usr/share/zoneinfo/MET usr/share/zoneinfor/
#ln -s ../usr/share/zoneinfo/MET localtime
#cd ..

6.你会发现perl或者mod_perl模块会报告缺少设置。为了解决这个问题,安装你的locale文件在chroot目录下。
#set |grep LANG
LANG=en_US
#mkdir /www/usr/share/locale
#cp -a /usr/share/locale/en_US /www/usr/share/locale/

7.现在复制共享库以提供一个基本的chroot文件系统环境
#cp -pi /lib/libtermcap.so.2 /lib/ld-linux.so.2 /lib/libc.so.6 lib/
另外请复制libnss_files-2.2.93.so和libnss_dns-2.2.93.so到相关目录下并用ln -s做联结(详细请用ldd命令查看)

8.测试你的目录(马上'apachectl'脚本会需要'cat',但是不是一定要求)
#cp -pi /bin/ls /bin/sh /bin/cat bin/
#chroot /www /bin/ls -l /

lrwxrwxrwx   1 0        0            7 Jan 29 09:24 bin -> usr/bin
drwxr-xr-x     2 0        0            1024 Jan 29 09:28 dev
drwxr-xr-x     2 0        0            3072 Jan 29 13:17 etc
drwxr-xr-x     2 0        0            1024 Jan 29 13:12 lib
drwxrwxrwt   2 0        0            1024 Jan 29 09:23 tmp
drwxr-xr-x     5 0        0            1024 Jan 29 09:23 usr
drwxr-xr-x     2 0        0            1024 Jan 29 10:41 webhome


9.现在你可以删除ls命令了。它只是用来测试的。
#rm bin/ls


准备一个用户和域名服务

1.创建一个新的用户,给这个用户特殊的名字(比如www)和用户id(比如888)。注意,在真正的鉴别文件(/etc/passwd /etc/group)中不需要这个用户和组。
#cd /www
#touch etc/passwd etc/group etc/shadow
#chmod 400 etc/shadow

2.编辑这三个文件。由于本例的缘故,我只是插入这些数据到文件里:
#echo 'www:x:888:888:Web Account:/webhome:/usr/bin/False' > etc/passwd
# echo 'www:x:888:' > etc/group
# echo 'www:*:10882:-1:99999:-1:-1:-1:134537804' > etc/shadow

3.我已经使得这用户不能登陆、无shell。
# echo 'int main(int argc, char *argv[]) { return(1); }' > /tmp/False.c
# cc -o /www/usr/bin/False /tmp/False.c

4.标记目录为只能执行
#chmod 111 usr/bin/*

5.我们将需要域名服务。glibc和域名服务所需要的库也要准备好。详细请使用man nsswitch。
即使我已经运行了nis服务在我的机器上,但是我还是选择依靠文件和dns。
注意:这些库文件也是需要的(这会是显而易见的在php安装的时候)
# cp -pi /lib/libnss_files.so.2 lib/
# cp -pi /lib/libnss_dns.so.2 lib/

6.要完全配置域名服务,我们需要3个文件。这些文件的内容需要依靠你的ip和dns设置。这里我们假设web服务器的名字是ns.mynet.home,使用的ip是192.168.196.2(它也确实是我的域名服务器)
# ---- Contents of    etc/nsswitch.conf ----#
passwd: files
shadow: files
group: files
hosts: files dns

# ---- Contents of    etc/resolv.conf ----#
domain mynet.home
## use the IP address of your naming server
## if bind is not installed on your web server
#nameserver 192.168.196.xxx
## use this if your web server is a (caching) name server
nameserver 127.0.0.1

# ---- Contents of    etc/hosts ----#
127.0.0.1 localhost loopback
192.168.196.2 ns.mynet.home ns www
也可以把上述三个文件从/etc下拷贝到chroot目录下的etc下
我把etc目录下的所有文件都用chattr +i 设成不可改变,如果需要也可以先把权限改成其他人不能读写

编译和安装apache

1.修改apache安装的根目录并且在实际的树目录里建立连接到它的字符联结
# mkdir /www/apache
# ln -s /www/apache /apache

2.我一般编译安装用一个普通用户(比如这个例子里的softs),而不是root用户。注意,apache的安装必须是以root用户的(请查阅apache的在线帮助文当)
在这里事例中我编译源文件在/usr/local/src/chr目录下,属于softs用户和softs组
$ cd /usr/local/src/chr
$ tar zxf /path/to/apache_1.3.12.tar.gz
$ cd apache_1.3.12

3.编辑config.layout文件以便他包含一个特殊布局叫做chroot
#   chroot layout.
<Layout chroot>
   prefix:        /apache
   exec_prefix:   $prefix
   bindir:        $exec_prefix/bin
   sbindir:       $exec_prefix/bin
   libexecdir:    $exec_prefix/libexec
   mandir:        $prefix/man
   sysconfdir:    $prefix/conf
   datadir:       $prefix
   iconsdir:      $datadir/icons
   htdocsdir:     $datadir/htdocs
   cgidir:        $datadir/cgi-bin
   includedir:    $prefix/include
   localstatedir: $prefix/var
   runtimedir:    $localstatedir/logs
   logfiledir:    $localstatedir/logs
   proxycachedir: $localstatedir/proxy
</Layout>

4.配置
无-DSO:
$ ./configure --with-layout=chroot \
--enable-module=most --enable-module=so
使用enable-module参数so你可能使用外加的第3放模块安装apache
DSO:
$ ./configure --with-layout=chroot \
--enable-module=most --enable-shared=max

$ make
# make install
作为root用户执行

5.复制其他在本例中配置apache需要的共享库。注意其他的一些配置也许需要其他库文件(请使用ldd命令查看)
# cd /www
# cp -pi /lib/libm.so.6 /lib/libcrypt.so.1 /lib/libdb.so.3 lib/
# cp -pi /lib/libdl.so.2 lib/

6.做一个简单的测试看看它是否工作正常。简单的配置/www/apache/conf/httpd.conf文件:
User www
Group www
ServerName yourserver.yourdomain.here
Port 8088  
请根据你的需要配置

7.启动进程(需要root权限)
# chroot /www /apache/bin/apachectl start

8.测试url地址:
$ lynx -dump http://yourserver/
如果有其他端口比如: 8088。请这样测试
$ lynx -dump http://yourserver:8088/
由于原文作者的命令拼错了,我也一下想不起来。我这么做的
#ps -ef|grep http
#cd /proc/你看到的任意一个http进程的pid/root/
#ls -la
如果看到的chroot的那个目录结构,恭喜做成了
9.现在是时间去改变下htdocs目录的所有者了
#chown -R 888:888 /www/apache/htdocs
以上部分出自Deatrich, Denice. "How to 'chroot' an Apache tree with Linux and Solaris." February 2001.
发表于 2003-7-27 14:58:15 | 显示全部楼层
呵呵,不错啊!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表