PTRACE_TRACEME CVE-2019-13272 本地提权漏洞解析

来源:岁月联盟 编辑:猪蛋儿 时间:2020-01-29
但是,这里的 euid 依然不是最终的结果, 还需要进入函数 security_bprm_set_creds 做进一步的安全检测
security_bprm_set_creds 函数调用的是 LSM 框架
在我分析的内核版本上, 实现 ‘bprm_set_creds’ 这个 hook 点安全检测的 lsm 框架有 5 种, 检测函数如下,
cap_bprm_set_creds
selinux_bprm_set_creds
apparmor_bprm_set_creds
smack_bprm_set_creds
tomoyo_bprm_set_creds
这里哪些 hook 检测函数会被执行,其实是跟具体的内核配置有关的, 理论上把所有 lsm 框架都启用的话,上述所有这些实现了 ‘bprm_set_creds’ hook 检测的函数都会被执行
在我的分析环境里实际运行的检测函数只有 cap_bprm_set_creds 和 selinux_bprm_set_creds 这俩
其中, 对 euid 有影响的是 ‘cap_bprm_set_creds’ 这个函数
    815 int cap_bprm_set_creds(struct linux_binprm *bprm)
    816 {
    817         const struct cred *old = current_cred();
    818         struct cred *new = bprm->cred;
    819         bool effective = false, has_fcap = false, is_setid;
    820         int ret;
    821         kuid_t root_uid;
    ===================== skip ======================
    838         /* Don't let someone trace a set[ug]id/setpcap binary with the revised
    839          * credentials unless they have the appropriate permit.
    840          *
    841          * In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
    842          */
    843         is_setid = __is_setuid(new, old) || __is_setgid(new, old); 
    844
    845         if ((is_setid || __cap_gained(permitted, new, old)) && //
    846             ((bprm->unsafe & ~LSM_UNSAFE_PTRACE) ||
    847              !ptracer_capable(current, new->user_ns))) { //
    848                 /* downgrade; they get no more than they had, and maybe less */
    849                 if (!ns_capable(new->user_ns, CAP_SETUID) ||
    850                     (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
    851                         new->euid = new->uid; //
    852                         new->egid = new->gid;
    853                 }
    854                 new->cap_permitted = cap_intersect(new->cap_permitted,
    855                                                    old->cap_permitted);
    856         }
    857
    858         new->suid = new->fsuid = new->euid;
    859         new->sgid = new->fsgid = new->egid;
    ===================== skip ======================
}
如上
行 845, 检测 euid 是否跟原有的 uid 不一致 (在函数 bprm_fill_uid 分析里我们知道,如果执行的文件是 setuid bit 的, euid 就会不一致)

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]  下一页