首页 > 代码库 > 内核提权姿势笔记

内核提权姿势笔记

方法一:

通过寻找进程的thread_info结构,搜索匹配进程的cred结构,并修改其值获得root权限。thread_info(arch arm)结构如下:

   /* Linux/arch/arm/include/asm/thread_info.h*/
   20 #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) // THREAF_SIZE=8192
 49 struct thread_info { 50         unsigned long           flags;          /* low level flags */ 51         int                     preempt_count;  /* 0 => preemptable, <0 => bug */ 52         mm_segment_t            addr_limit;     /* address limit */ 53         struct task_struct      *task;          /* main task structure */ 54         __u32                   cpu;            /* cpu */ 55         __u32                   cpu_domain;     /* cpu domain */ 56         struct cpu_context_save cpu_context;    /* cpu context */ 57         __u32                   syscall;        /* syscall number */ 58         __u8                    used_cp[16];    /* thread used copro */ 59         unsigned long           tp_value[2];    /* TLS registers */ 60 #ifdef CONFIG_CRUNCH 61         struct crunch_state     crunchstate; 62 #endif 63         union fp_state          fpstate __attribute__((aligned(8))); 64         union vfp_state         vfpstate; 65 #ifdef CONFIG_ARM_THUMBEE 66         unsigned long           thumbee_state;  /* ThumbEE Handler Base register */ 67 #endif 68 }; 69 
 

thread_info保存在栈的最低端,addr_limit表示进程可访问的地址空间,修改为0xffffffff可访问任意内核地址,task_struct保存进程权限值,修改权限值来达到提权的目的;

因为THREAD_SIZE为8192,因此thread_info=栈地址&0xffffe000(~(THREAD_SIZE - 1) = 0xfffe000),以下函数用于获取thread_info地址,其原理就是把esp的最后n(THREAD_SIZE栈大小的位数)位清空,那么就是基地址了,也就是thread_info的值:

static inline struct thread_info *current_thread_info(void) {    return (struct thread_info *)(current_stack_pointer & ~(THREAD_SIZE - 1));}

那么根据& addr_limit = * thread_info + 8修改其值为0xffffffff;

内核3.x 在task_struct找不到security成员了,原来是将安全相关的信息剥离到一个叫做 cred 的结构体中,由cred负责保存进程安全上下文。根据task_struct=*(int*)(((int)&v)&0xffffe000)+0xc),找到task_struct结构体//v为内核定义的变量

然后通过thread_info.task_struct -> cred -> secutiry,修改以下值获取root权限:

credbuf.uid = 0;credbuf.gid = 0;credbuf.suid = 0;credbuf.sgid = 0;credbuf.euid = 0;credbuf.egid = 0;credbuf.fsuid = 0;credbuf.fsgid = 0;credbuf.cap_inheritable.cap[0] = 0xffffffff;credbuf.cap_inheritable.cap[1] = 0xffffffff;credbuf.cap_permitted.cap[0] = 0xffffffff;credbuf.cap_permitted.cap[1] = 0xffffffff;credbuf.cap_effective.cap[0] = 0xffffffff;credbuf.cap_effective.cap[1] = 0xffffffff;credbuf.cap_bset.cap[0] = 0xffffffff;credbuf.cap_bset.cap[1] = 0xffffffff;securitybuf.osid = 1;securitybuf.sid = 1;taskbuf.pid = 1;

附:task_struct:http://lxr.linux.no/#linux+v2.6.30.5/include/linux/sched.h#L1117

      cred:http://lxr.linux.no/#linux+v2.6.30.5/include/linux/cred.h#L115

 

内核提权姿势笔记