首页 -> 安全研究

安全研究

绿盟月刊
绿盟安全月刊->第5期->最新漏洞
期刊号: 类型: 关键词:
RedHat initscripts本地安全漏洞

主页:http://www.nsfocus.com/
日期:1999-12-14

发布日期: 1999-12-30
更新日期: 1999-12-31
受影响的系统:  initscripts-4.48-1 (RedHat 6.1缺省安装版本)
--------------------------------------------------------------------------------
描述:

    在许多系统中被广泛使用的csh.login (/etc/csh.login)文件检查目录/etc/profile.d
是否存在。如果该目录存在,便在该目录下寻找后缀名为'.csh'的文件。在这些文件中,
lang.csh文件检查是否存在/etc/sysconfig/i18n文件,如果存在则将此文件按csh语法轮换
并创建一个shell脚本。这个脚本文件存放在/tmp目录下,以当前进程ID作为后缀名。

    实例代码如下:

    sed 's|=C$|=en_US|g' /etc/sysconfig/i18n | sed "s|=| |g"  \
        | sed "s|^\([^#]\)|setenv \0|g" > /tmp/csh.$$
    source /tmp/csh.$$
    rm -f /tmp/csh.$$

    我们看到,可以猜测PID号并预先创建一个符号链接。如果被链接文件访问权限设置不
当,命令输出的重定向将覆盖该文件。只有在sed命令行结束后和下一条脚本命令(source)
前替换文件,这种攻击才有可能成功,所以机率极低。

    另一种情况,如果预先创建了临时文件,并链接到访问权限为0444这种限制写权限的
文件,sed命令行的输出重定向将失败,而下一行命令将对预先创建的文件进行转换,再下
一行命令则会试图删除它。

    需要提醒的是在这种情况下,用户登录时会看到一条关于试图重定向输出到预先创建
文件的错误信息。然而经验表明,绝大多数用户会忽略这种信息。

    RedHat 6.1(英文版)缺省完全安装将会提供以上攻击所必需的所有条件。

--------------------------------------------------------------------------------
测试程序:

警 告:以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

<http://www.l0pht.com/advisories/init.tar.gz>

    测试程序工作过程如下:

    在命令行指定要强迫用户执行的脚本。如果该脚本的访问权限未满足要求,将修改其
访问权限。必须注意的是必须提供全路径名的目标脚本。

    程序临视/etc/csh.login最近的访问时间。

    一旦访问时间改变,程序将打开/proc目录并搜寻tcsh的进程。

    每发现一个tcsh入口,将创建以该tcsh进程ID为后缀名的符号链接(到目标脚本)。

    然后监视目标文件访问时间的改变(这意味着该文件已被执行)。如果发生变化,在
/tmp目录下创建的符号链接将被删除。

    例如,在/var/tmp目录下创建demo.csh脚本文件,其内容为:

    touch /tmp/`/usr/bin/whoami`.$$

    然后运行测试程序:./init_race -f /var/tmp/demo.csh

    登录用户将看到如下错误信息:

    /tmp/csh.## : Permission denied.

    这意味着程序已”竞争“成功,在/tmp目录下将创建一个文件(文件名由用户名和
当前PID组成)。当然,攻击者可以在文件中加入恶意脚本命令,以实施攻击。

--------------------------------------------------------------------------------
建议:

    当需要在公共目录下创建临时文件时,必须非常小心。一种可能的解决方法是在公共目
录下建立安全子目录,并在该子目录下创建临时文件。同时在程序/脚本中检查mkdir命令的
返回值以确保不会出现“竞争”问题。

  mkdir --mode=700 /tmp/csh_login.$$
  if ($status != 0) then
    echo "potential problem -- directory /tmp/csh_login.$$ already
exists!"
    exit
  endif

  sed 's|=C$|=en_US|g' /etc/sysconfig/i18n | sed "s|=| |g"  | sed
"s|^\([^#]\)|setenv \0|g" > /tmp/csh_login.$$/csh.$$
    source /tmp/csh_login.$$/csh.$$
    rm -f /tmp/csh_login.$$/csh.$$
    rmdir /tmp/csh_login.$$


    diff命令的输出如下:

--- /etc/profile.d/lang.csh     Sun Sep 26 13:49:11 1999
+++ ./lang.csh.modified Sun Dec 26 20:59:25 1999
@@ -3,7 +3,14 @@
test -f /etc/sysconfig/i18n
if ($status == 0) then
-    sed 's|=C$|=en_US|g' /etc/sysconfig/i18n | sed "s|=| |g"  | sed
"s|^\([^#]\)|setenv \0|g" > /tmp/csh.$$
-    source /tmp/csh.$$
-    rm -f /tmp/csh.$$
+    /bin/mkdir --mode=700 /tmp/csh_login.$$
+    if ($status != 0) then
+      echo "potential problem -- directory /tmp/csh_login.$$ already
exists!"
+      exit
+    endif
+
+    sed 's|=C$|=en_US|g' /etc/sysconfig/i18n | sed "s|=| |g"  | sed
"s|^\([^#]\)|setenv \0|g" > /tmp/csh_login.$$/csh.$$
+    source /tmp/csh_login.$$/csh.$$
+    rm -f /tmp/csh_login.$$/csh.$$
+    /bin/rmdir /tmp/csh_login.$$

     if ($?SYSFONTACM) then


版权所有,未经许可,不得转载