囚禁精灵(daemon)进程

由 dancingpig 在 07-25-2003 16:55 发表:

囚禁精灵(daemon)进程

我是一个大懒人,所以有些东西直接复制别人已经写的了。请包涵:)

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环境。因此,你应该经常监视你的牢笼,看一下里面的囚犯是否逃出来了:P。

以上部分转自囚禁你的精灵(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 e tc/shadow

2.编辑这三个文件。由于本例的缘故,我只是插入这些数据到文件里:

#echo 'www❌888:888:Web Account:/webhome:/usr/bin/False' > etc/passwd

echo 'www❌888:' > etc/group

echo 'www:*:10882:-1:99999:-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 设成不可改变,如果需要也可

Published At
Categories with 服务器类
Tagged with
comments powered by Disqus