免费教程_免费网赚教程_破解版软件-寂涯网络学习基地

当前位置: 主页 > 系统综合 > 各类编程 > Linux下内核漏洞利用几种方法

Linux下内核漏洞利用几种方法

时间:2012-04-01 22:46来源:未知 整理:寂涯网络 点击:

系统内核因包含大量关键资源的分配与调度,如用于进程、资源和内存分配的处理、通 信协议的实现等,故其安全性是至关重要的。然而,内核设计的复杂性却造就了多样化和有 趣的逻辑错误,系统内核包含许多子系统模块的实现代码,子系统之间通过复杂的接口交互; 另外,系统内核还包含大量的用户数据接入点,如系统调用、IOCTLs、文件系统及网络连接 等,允许可控的用户数据成功访问到内核中的重要代码区,这些都是可能被黑客利用的漏洞。 Google 两位工程师 Julien Tinnes 和 Tavis Ormandy 在过去几年间发现了近 20 余个内核级 bug,其中大部分至今仍未修复。Tinnes 称,Linux 内核中存在一些内存破坏错误、六个经 典的缓冲区溢出错误以及空指针引用,它指向存储在机器内存中的数据。本文将深入分析 Linux 系统内核主流版本存在的一些安全漏洞。
NULL 指针解引用漏洞

NULL 指针解引用是最常见的漏洞之一。指针即包含内存中某一变量的地址值,当指针 解引用时,即可获取内存地址中存放的变量值。一个静态未初始化的指针,其内容为 NULL 即(0x0).在内核代码中 NULL 值常在变量初始化、设置为缺省值或者作为一个错误返回值 时使用。在系统中,虚拟地址空间分为两个部分,分别称为内核空间和用户进程空间,当内 核尝试解引用一个 NULL 指针时,若用户又允许映射 NULL 地址(如首个页面包含 0 地址), 则可直接或间接控制内核代码路径。(注:NULL 指针引用 BUG 主要是因进程在执行指针解引 用时,没有检查其合法性造成的,若待解引用的地址为 NULL,则在内核态访问 NULL 指针时 会引发 Oops,此时若黑客在用户态将 NULL 地址设置为可执行并注入恶意代码,则内核代码 将会执行 NULL 地址的恶意指令。下面将具体分析 Linux 内核是如何处理空指针引用的。
在程序的执行过程中,因某种原因使 CPU 无法访问到相应的物理内存单元,即无法完成 从虚拟地址到物理地址映射时,CPU 会产生一次缺页异常,从而进行相应的缺页异常处理, 如目标页面不存在(页表项全 0,即该线性地址与物理地址尚未建立映射或者已经撤销)或 者相应的物理页面不在内存中(如在 swap 分区或磁盘文件上)等。当 CPU 捕获到这个异常的 时候就会引发一次缺页异常中断,并调用 do_page_fault()函数来判断和处理这些异常。
下面我们具体分析内核是如何处理引用 NULL pointer 异常的,do_page_fault()函数源 码部分实现如下:(注:感兴趣的读者也可参见源码 arch\i386\mm\fault.c 程序文件中此函 数的具体实现)
fastcall void  kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code){
struct task_struct *tsk;
struct mm_struct *mm;
struct vm_area_struct * vma; unsigned long address; unsigned long page;
int write, si_code;
/* 通过 cr2 寄存器得到引发异常的线性地址 */
address = read_cr2();
tsk = current;
si_code = SEGV_MAPERR;
******
switch (handle_mm_fault(mm, vma, address, write)) {
case VM_FAULT_SIGBUS:  /*0,向进程发送 SIGBUS 信号*/
goto do_sigbus;
case VM_FAULT_OOM:  /*没有足够的内存*/
goto out_of_memory;
default: BUG();
}
no_context:
/* 代码跳到一段“修正代码”处,这段代码的典型操作就是向当前进程发送 SIGSEGV
信号,或用一个适当的出错码终止系统调用处理程序 */
if (fixup_exception(regs))  return;
if (is_prefetch(regs, address, error_code))  return;
/* 如果是由于内核自己访问了用户空间的无效地址,则就会引发 0ops,即内核级
的 Segmentation Fault */
if (oops_may_print()) {
/* 如果这个地址小于 PAGE_SIZE, 一般为 4096 字节,内核就认为这是一次空指针
操作,开始打印 OOPS 信息 */
if (address < PAGE_SIZE)
printk(KERN_ALERT "BUG: unable to handle kernel NULL " "pointer dereference");
else
printk(KERN_ALERT "BUG: unable to handle kernel paging" " request");
printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip);
}
page = read_cr3();
page = ((unsigned long *)  va(page))[address >> 22];
if (oops_may_print())
printk(KERN_ALERT "*pde = %08lx\n", page);
tsk->thread.cr2 = address;
tsk->thread.trap_no = 14;
tsk->thread.error_code = error_code;
die("Oops", regs, error_code);
bust_spinlocks(0);

本页地址 http://www.jybase.net/biancheng/20120330813.html

百度搜索更多

谷歌搜索更多

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------

评价:
昵称: 验证码:点击我更换图片
推荐内容
赞助商
赞助商


关于本站免责声明视频更新google百度地图视频地图RRS订阅

如有什么问题请在本站留言,或发邮件到 hxt167#foxmail.com