Linux下防范缓冲区溢出攻击的系统安全策略

    [雨 January 15, 2008 13:43 | by ]
来源:IBM
缓冲区溢出攻击是目前黑客最常用的攻击手段之一,为了应对不断涌现的缓冲区溢出攻击,我们研究了在Linux系统下防范缓冲区溢出的方法,通过研究,总结了在Linux平台下防范缓冲区溢出攻击的安全策略,这些安全策略可以应用于一般企业内部服务器,包括web服务器、mail服务器、samba服务器、ftp服务器以及proxy服务器等。在实际使用中,我们发现通过这些安全策略的配置能够对缓冲区溢出攻击起到很好的防范措施。
在对计算机系统安全的研究中,有一种系统安全漏洞引起了我们的关注。一方面是由于这种安全漏洞的广泛性--几乎使所有的操作系统平台都受到影响。另一方面,我们为黑客基于此类安全漏洞所编写的攻击程序的隐蔽性和强大威力所吸引。这就是缓冲区溢出技术。它可以使看似安全的,正在运行常规服务(如 DNS、ftpd等)的主机在几秒钟内失去控制权。缓冲区溢出攻击是目前黑客最常用的攻击手段。在当前CERT和CIAC等发布的Internet安全事件报告中, 缓冲区溢出已成为常见的用语。缓冲区溢出攻击的目的在于扰乱具有某些特权运行的程序的功能。这样可以让攻击者取得程序的控制权,如果该程序具有足够的权限,那么整个主机就被控制了。

为了应对不断涌现的缓冲区溢出攻击,我们研究了在Linux系统下防范缓冲区溢出的方法,之所以选择Linux平台,主要有两方面的原因:(1)Linux是一个开放源码的平台,有利于我们在研究的过程中深入技术细节,由于Linux及其上面的大量应用都是基于开放源码,有很多黑客在其上进行了大量的工作,可以说Linux上的网络攻击水平代表了整个网络攻击的最高水平。(2)Linux是一个类Unix系统,同时也是在Internet中大量使用的操作系统平台,选择Linux作为研究缓冲区溢出技术的平台是非常具有代表性的,在Linux平台上取得的经验可以非常容易地移植到其他Unix或者类Unix平台上。

通过研究,我们总结了在Linux平台下防范缓冲区溢出的安全策略,这些安全策略可以应用于一般企业内部服务器,包括web服务器、mail服务器、samba服务器、ftp服务器以及proxy服务器等。我们所总结的这些安全策略如下所示:

不显示系统提示信息

如果不想让远程登录的用户看到系统的提示信息,可以改变"/etc/inetd.conf"文件中的telnet设置:
telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd -h

在末尾加上"-h"参数可以让daemon不显示任何系统信息,只显示登录提示。当然,只有在服务器上装了telnet服务器才有这样做的必要。

处理"rc.local"文件

在默认情况下,当登录装有Linux系统的计算机时,系统会告诉你Linux发行版的名字、版本号、内核版本和服务器名称。这泄露了太多的系统信息。出于安全的考虑,最好只显示一个"Login:"的提示信息。处理方法如下:

(1)编辑"/etc/rc.d/rc.local"文件,在下面这些行的前面加上"#":
# This will overwrite /etc/issue at every boot. So, make any changes you
# want to make to /etc/issue here or you will lose them when you reboot.
#echo "" > /etc/issue
#echo "$R" >> /etc/issue
#echo "Kernel $(uname -r) on $a $(uname -m)" >> /etc/issue
#
#cp -f /etc/issue /etc/issue.net
#echo >> /etc/issue


(2)删除"/etc"目录下的"issue.net"和"issue"文件:
[root@snow]# rm -f /etc/issue
[root@snow]# rm -f /etc/issue.net

"/etc/issue.net"文件是用户从网络登录计算机时(例如:telnet、SSH)看到的登录提示。同样在"/etc"目录下还有一个"issue"文件,是用户从本地登录时看到的提示。这两个文件都是文本文件,可以根据需要改变。但是,如果想删掉这两个文件,必须向上面介绍的那样把"/etc/rc.d/rc.local"脚本中的那些行注释掉,否则每次重新启动的时候,系统又会重新创建这两个文件。

禁止提供finger 服务

在Linux系统下,使用finger命令可以显示本地或远程系统中目前已登录用户的详细信息,黑客可以利用这些信息,增大侵入系统的机会。为了系统的安全,最好禁止提供finger服务,即从/usr/bin下删除finger 命令。如果要保留 finger服务,应将finger文件换名,或修改其权限,使得只允许root用户执行finger命令。

处理"inetd.conf"文件

inetd也叫作"超级服务器",其作用是根据网络请求装入网络程序。"/etc/inetd.conf"文件告诉inetd监听哪些网络端口,为每个端口启动哪个服务。把Linux系统放在任何网络环境中,第一件要做的事就是了解一下服务器到底要提供哪些服务。不需要的那些服务应该被禁止掉,最好卸载掉,这样黑客就少了一些攻击系统的机会。查看"/etc/inetd.conf"文件,了解一下inetd提供哪些服务。用加上注释的方法(在一行的开头加上#号)禁止任何不需要的服务,再给inetd进程发一个SIGHUP信号。具体操作步骤如下:

(1)把文件"/etc/inetd.conf"的许可权限改成600,只允许root来读写该文件。
[root@snow]# chmod 600 /etc/inetd.conf

(2)确定"/etc/inetd.conf"文件所有者为root。
[root@snow]# stat /etc/inetd.conf

这个命令显示出来的信息应该是:
File: "/etc/inetd.conf"
Size: 2869 Filetype: Regular File
Mode: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Device: 8,6 Inode: 18219 Links: 1
Access: Fri Apr 12 14:28:11 2002(00000.00:10:44)
Modify: Wed Apr 10 11:20:22 2002(00002.06:12:16)
Change: Wed Apr 10 11:20:22 2002(00002.06:12:16)

(3)编辑 /etc/inetd.conf文件(vi /etc/inetd.conf),禁止所有不需要的服务,如:ftp、telnet、 shell、login、exec、talk、ntalk、imap、pop-2、pop-3、finger、auth等。把不需要的服务关闭可以使系统的危险性降低很多。

(4)改变了"inetd.conf"文件之后,要给inetd进程发送一个SIGHUP信号(killall -HUP inetd)。
[root@snow /root]# killall -HUP inetd

(5)为了保证"inetd.conf"文件的安全,可以用chattr命令把它设成不可改变的。如下:
[root@snow]# chattr +i /etc/inetd.conf

这样可以防止对"inetd.conf"文件的任何修改。一个有"i"属性的文件是不能被改动的(不能删除或重命名,不能创建这个文件的链接,不能向这个文件里写数据)。唯一可以取消这个属性的人只有root。如果要修改"inetd.conf"文件,首先要取消不可修改的属性,如下:
[root@snow]# chattr -i /etc/inetd.conf

再改变了"inetd.conf"文件后,需要再把它的属性改为不可改变的。

启动系统的"rc"脚本

/etc/rc.d目录下"rc"开头的文件是用来启动系统的初始化文件的。rc系列文件与Ms- Dos系统下的autoexec.bat很类似。rc的意思是"runtime commands"。它们决定了init进程要启动哪些服务。redhat系统下,这些脚本在/etc/rc.d/rc3.d(如果系统以x为默认启动的话,就是/etc/rc.d/rc5.d)。要在启动时禁止某个服务,只需要把大写的S替换为小写的s,同时,redhat也提供一个工具来帮助你关闭服务,输入/usr/sbin/setup,然后选择"system services",就可以定制系统启动时运行哪些服务。另外一个选择是chkconfig命令,很多linux版本的系统都自带这个工具。脚本名字中的数字是启动的顺序,以大写的K开头的是用来杀死进程的。 如将S50snmpd(SNMP简单网络管理协议,远程用户能从中获得许多系统信息)改为s50snmpd,则系统启动时将不会启动这项服务。

用下列命令察看在关闭启动脚本之前有多少服务在运行:
suneagle# ps -eaf|wc -l

有两个非常有用的工具:ps -xau(输出大量的有关系统运行的信息)和netstat -vat(列出所有和网络相关的信息)。运行他们就可以知道系统在提供、运行哪些服务。

处理"services"文件

端口号和标准服务之间的对应关系在RFC1700"Assigned Numbers"中有详细的定义。"/etc/services"文件使得服务器和客户端的程序能够把服务的名字转成端口号,这张表在每一台主机上都存在,其文件名是"/etc/services"。只有"root"用户才有权限修改这个文件,而且在通常情况下这个文件是没有必要修改的,因为这个文件中已经包含了常用的服务所对应的端口号。为了提高安全性,我们可以给这个文件加上保护以避免没有经过授权的删除和改变。为了保护这个文件可以用下面的命令
[root@snow]# chattr +i /etc/services

改变"/etc/rc.d/init.d/"目录下脚本文件的访问许可

通过以下方式改变启动和停止daemon的脚本文件的权限。
[root@snow]# chmod -R 700 /etc/rc.d/init.d/*

这样只有root可以读、写和执行这一脚本,因为一般用户不需要知道脚本文件的内容。

使系统对ping没有反应

防止系统对ping请求做出反应,对于网络安全是很有好处的,因为没人能够ping你的服务器并得到任何反应。TCP/IP协议本身有很多的弱点,黑客可以利用一些技术,把传输正常数据包的通道用来偷偷地传送数据。使你的系统对ping请求没有反应,可以把这个危险减到最小。使用下面的命令:
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

运行完这个命令后,系统对ping就没有反应了。可以把这一行加到"/etc/rc.d/rc.local"文件中去,这样当系统重新启动时,该命令就会自动运行。对ping命令没有反应,至少可以把绝大多数的黑客排除到系统之外,因为黑客不可能知道你的服务器在哪里。重新恢复对ping的响应,可以使用下面的命令:
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all"


用ssh代替telnet

SSH协议在开始设计时的目的就是提供尽可能安全的远程存取方式。它可以用来进行任何基于网络的信息传递,而且适应性很强。Linux、Unix、NT等系统都可以使用。由于在和远程交互时,传递的密钥、认证信息等都是加密的,所以安全性能很好。用ssh完全取代telnet/ftp,它能够确保数据在网络中的安全传输。

取消普通用户的控制台访问权限

应该取消普通用户的控制台访问权限,比如shutdown、reboot、halt等命令。
[root@kapil /]# rm -f /etc/security/console.apps/<servicename>

其中是要注销的程序名。

Shell logging

Bash shell在"~/.bash_history"("~/"表示用户目录)文件中保存了500条使用过的命令,这样可以使你输入使用过的长命令变得容易。每个在系统中拥有账号的用户在他的目录下都有一个".bash_history"文件。bash shell应该保存少量的命令,并且在每次用户注销时都把这些历史命令删除。具体操作步骤如下:

(1)"/etc/profile"文件中的"HISTFILESIZE"和"HISTSIZE"行确定所有用户的".bash_history"文件中可以保存的旧命令条数。建议把"/etc/profile"文件中的"HISTFILESIZE"和"HISTSIZE"行的值设为一个较小的数,比如30。编辑profile文件(vi /etc/profile),把下面这行改为:
HISTFILESIZE=30
HISTSIZE=30
这表示每个用户的".bash_history"文件只可以保存30条旧命令。

(2)网络管理员还应该在"/etc/skel/.bash_logout" 文件中添加一行"rm -f $HOME/.bash_history"。这样,当用户每次注销时,".bash_history"文件都会被删除。

编辑.bash_logout文件(vi /etc/skel/.bash_logout),添加下面这行:
rm -f $HOME/.bash_history


禁止Control-Alt-Delete键盘关闭命令

在"/etc/inittab" 文件中注释掉下面这行(使用#):
ca::ctrlaltdel:/sbin/shutdown -t3 -r now

改为:
#ca::ctrlaltdel:/sbin/shutdown -t3 -r now

为了使这项改动起作用,输入下面这个命令:
[root@kapil /]# /sbin/init q


带"s"位的程序

缓冲区溢出漏洞和suid/sgid程序的关系紧密,带"s"位的程序往往是系统不安全的根源。应该尽量将不必要的带"s"位的程序删除。

用ls -l命令列出来的文件,如果文件的权限位中出现"s",则这些文件的SUID(-rwsr-xr-x)或SGID(-r-xr-sr-x)位被设定了。因为这些程序给执行它的用户一些特权,所以如果不需要用到这些特权,最好把这些程序的"s"位移去。可以用下面的这个命令"chmod a -s <文件名>"移去相应文件的"s"位。

可以清除"s"位的程序包括:从来不用的程序;不希望非root用户运行的程序;偶尔用用,但是不介意先用su命令变为root后再运行的程序。

下面加了星号(*)的程序有必要移去"s"位。注意,系统可能需要一些SUID的程序才能正常运行,所以要小心。

用下面的命令查找所有带"s"位的程序:
[root@snow]# find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -lg {}\;
*-rwsr-xr-x 1 root root 35168 Sep 22 23:35 /usr/bin/chage
*-rwsr-xr-x 1 root root 36756 Sep 22 23:35 /usr/bin/gpasswd
*-r-xr-sr-x 1 root tty 6788 Sep 6 18:17 /usr/bin/wall
-rwsr-xr-x 1 root root 33152 Aug 16 16:35 /usr/bin/at
-rwxr-sr-x 1 root man 34656 Sep 13 20:26 /usr/bin/man
-r-s--x--x 1 root root 22312 Sep 25 11:52 /usr/bin/passwd
-rws--x--x 2 root root 518140 Aug 30 23:12 /usr/bin/suidperl
-rws--x--x 2 root root 518140 Aug 30 23:12 /usr/bin/sperl5.00503
-rwxr-sr-x 1 root slocate 24744 Sep 20 10:29 /usr/bin/slocate
*-rws--x--x 1 root root 14024 Sep 9 01:01 /usr/bin/chfn
*-rws--x--x 1 root root 13768 Sep 9 01:01 /usr/bin/chsh
*-rws--x--x 1 root root 5576 Sep 9 01:01 /usr/bin/newgrp
*-rwxr-sr-x 1 root tty 8328 Sep 9 01:01 /usr/bin/write
-rwsr-xr-x 1 root root 21816 Sep 10 16:03 /usr/bin/crontab
*-rwsr-xr-x 1 root root 5896 Nov 23 21:59 /usr/sbin/usernetctl
*-rwsr-xr-x 1 root bin 16488 Jul 2 10:21 /usr/sbin/traceroute
-rwxr-sr-x 1 root utmp 6096 Sep 13 20:11 /usr/sbin/utempter
-rwsr-xr-x 1 root root 14124 Aug 17 22:31 /bin/su
*-rwsr-xr-x 1 root root 53620 Sep 13 20:26 /bin/mount
*-rwsr-xr-x 1 root root 26700 Sep 13 20:26 /bin/umount
*-rwsr-xr-x 1 root root 18228 Sep 10 16:04 /bin/ping
*-rwxr-sr-x 1 root root 3860 Nov 23 21:59 /sbin/netreport
-r-sr-xr-x 1 root root 26309 Oct 11 20:48 /sbin/pwdb_chkpwd

用下面的命令禁止上面选出来的SUID的程序:
[root@snow]# chmod a-s /usr/bin/chage
[root@snow]# chmod a-s /usr/bin/gpasswd
[root@snow]# chmod a-s /usr/bin/wall
[root@snow]# chmod a-s /usr/bin/chfn
[root@snow]# chmod a-s /usr/bin/chsh
[root@snow]# chmod a-s /usr/bin/newgrp
[root@snow]# chmod a-s /usr/bin/write
[root@snow]# chmod a-s /usr/sbin/usernetctl
[root@snow]# chmod a-s /usr/sbin/traceroute
[root@snow]# chmod a-s /bin/mount
[root@snow]# chmod a-s /bin/umount
[root@snow]# chmod a-s /bin/ping
[root@snow]# chmod a-s /sbin/netreport

创建FTP日志

对于FTP服务器,可以通过修改/etc/ftpaccess或者/etc/inetd.conf,来保证每一个ftp连接日志都能够记录下来。下面是一个修改inetd.conf的例子:

ftp  stream  tcp  nowait  root  /usr/sbin/tcpd  in.ftpd -l -L -i -o
-l:每一个ftp连接都写到syslog
-L:记录用户的每一个命令
-I:文件received,记录到xferlog
-o:文件transmitted,记录到xferlog

以上就是我们通过研究总结出来的在Linux平台下防范缓冲区溢出攻击的一些安全策略,在实际使用中,我们发现通过这些安全策略的配置能够对缓冲区溢出攻击起到一定的防范措施。当然,这些安全措施还不够完善,还需要进一步的改进。
Technology | Comments(0) | Trackbacks(0) | Reads(7409)
Add a comment
Emots
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
Enable HTML
Enable UBB
Enable Emots
Hidden
Nickname   Password   Optional
Site URI   Email   [Register]
               

Security code Case insensitive