频道栏目
首页 > 资讯 > 系统安全 > 正文

Linux内核安全研究之Stack Overflow溢出

11-01-05        来源:[db:作者]  
收藏   我要投稿

Linux内核安全研究之Stack Overflow溢出

by wzt        <wzt.wzt@gmail.com>


一、背景:
 
   Stack overflow与我之前发过的Stack buffer overflow是两个不同的概念, 它们都是发生在内核stack中的溢出。
   Jon Oberheide在他的blog中提到了一种新的stack overflow溢出攻击方式, 大致说了下溢出原理,没给出poc,我尝试研究了一下,
   把这几天的调试方法总结下。

二、理解内核堆栈:

   当user space的程序通过int 0x80进入内核空间的时候,CPU自动完成一次堆栈切换, 从user space的stack切换到kernel space的stack。
   在这个进程exit之前所发生的所有系统调用所使用的kernel stack都是同一个。kernel stack的大小一般为4096/8192,我画了个内核堆栈示意图帮助大家理解:

   内存低址                                                              内存高址
                      |                 |<-----------------------------esp|   
   +-----------------------------------4096-------------------------------+
   |        72        |     4           |       x < 4016    |     4       |
   +------------------+-----------------+---------------------------------+
   |thread_info  |    | STACK_END_MAGIC |   var/call chain  |stack_canary |
   +------------------+-----------------+---------------------------------+
   |     28      | 44 |                 |                                 |
                 V    |                                                   |
             restart_block                                                V

esp+0x0                                                                   +0x40
    +---------------------------------------------------------------------------+
    |ebx|ecx|edx|esi|edi|ebp|eax|ds|es|fs|gs|orig_eax|eip|cs|eflags|oldesp|oldss|
    +---------------------------------------------------------------------------+
    |             kernel完成                          |         cpu自动完成       |
 

    在老的内核中, 用struct task_struct来描述一个进程结构, 在新的内核里, task_struct结构又被包装在struct thread_info里:
struct thread_info {
        struct task_struct      *task;          /* main task structure */
        struct exec_domain      *exec_domain;   /* execution domain */
        __u32                   flags;          /* low level flags */
        __u32                   status;         /* thread synchronous flags */
        __u32                   cpu;            /* current CPU */
        int                     preempt_count;  /* 0 => preemptable,
                                                   <0 => BUG */
        mm_segment_t            addr_limit;
        struct restart_block    restart_block;
        void __user             *sysenter_return;
#ifdef CONFIG_X86_32
        unsigned long           previous_esp;   /* ESP of the previous stack in
                                                   case of nested (IRQ) stacks
                                                */
        __u8                    supervisor_stack[0];
#endif
        int                     uaccess_err;
};
它的第一个字段就指向当前进程的task_stuct指针, 注意是指针, 而不是一个结构体,task_struct在我的2.6.36.2内核中的大小是1196字节,而thread_info
大小为72字节, 所以保存一个指针将会非常节省内核堆

相关TAG标签
上一篇:CC_STACKPROTECTOR防止内核stack溢出补丁分析
下一篇:weedcms 5.0 getshell 0day及修复
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站