漏洞概述
Ubuntu 16.04 本地提权漏洞,该漏洞存在于Linux内核带有的eBPF bpf(2)系统调用中,当用户提供恶意BPF程序使eBPF验证器模块产生计算错误,导致任意内存读写问题。
影响版本:
Linux Kernel Version 4.4 ~ 4.14
Ubuntu版本:16.04.01~ 16.04.04
复现环境:
ubuntu-16.04.2-desktop-amd64.iso
Linux ubuntu 4.8.0-36-generic #36~16.04.1-Ubuntu SMP
漏洞原理
众所周知,linux的用户层和内核层是隔离的,想让内核执行用户的代码,正常是需要编写内核模块,当然内核模块只能root用户才能加载。而BPF则相当于是内核给用户开的一个绿色通道:BPF(Berkeley Packet Filter)提供了一个用户和内核之间代码和数据传输的桥梁。用户可以用eBPF指令字节码的形式向内核输送代码,并通过事件(如往socket写数据)来触发内核执行用户提供的代码;同时以==map==(key,value)的形式来和内核共享数据,用户层向map中写数据,内核层从map中取数据,反之亦然。BPF设计初衷是用来在底层对网络进行过滤,后续由于他可以方便的向内核注入代码,并且还提供了一套完整的安全措施来对内核进行保护,被广泛用于抓包、内核probe、性能监控等领域。
Bpf指令的校验是在函数do_check中,代码路径为kernel/bpf/verifier.c。do_check通过一个无限循环来遍历我们提供的bpf指令。
简言之,eBPF提供了一种用户往内核传递代码并进行数据交互的途径。当然,内核会对用户注入的BPF指令进行安全校验(类似于虚拟执行)。本漏洞即利用一个符号扩展的bug,导致一个本应永真的布尔表达式会在实际执行时判断为false。因而,如果把shellcode放在这个所谓的“false”分支就可以跳过eBPF的安全检查(不会检查永假的分支),从而达到往内核注入任意代码的目的,提权就水到渠成了。
1 | if <false_true_expression> //检查时为true,实际执行为false : <(u32)0xFFFFFFFF == -1> |
exploit详解
根据上节,相当于通过一个漏洞,我们可以通过eDPF向内核注入任意代码,并且可以在内核和用户态间传递信息。
那么如何利用这些达成一次exploit呢。这里我们的目标是本地提权:
思路:
- 获取到==内核的栈地址==(:shellcode获取内核栈地址+读取到用户态)
- ==current的地址==(:常规操作)
- ==task_struct的地址==(读current结构体的第一个成员:需要一个对指定地址的读操作+传到用户态)
- 然后定位到==cred的地址==,然后定位到==uid的地址==(:常规操作)
- 然后直接将uid的值改为0(:一个针对指定地址的写操作),
- 然后启动/bin/bash(已经提权,直接进行)
shellcode(eBPF代码)
那么由上可知,我们要求shellcode做到:
- 与用用户态进行信息交互(通过map实现)
- 指令A:==读取==内核栈地址,传给map
- 指令B:从map读取地址,==读取==该地址的值,传给map
- 指令C:从map读取一个值和地址,将该值==写==到该地址
- 根据用户态程序,选择性执行指令A或B、C
用户态漏洞程序
同时我们构造这样的用户程序:
- 将shellcode通过eBPF送入内核
- 执行shellcode进行指令A,得到内核栈地址
- 计算current的地址address_c
- 传入address_c,执行shellcode进行指令B,得到task_struct的地址
- 计算cred的地址,uid的地址address_uid
- 传入address_uid和值0,执行shellcode进行指令C,提权成功!
- root下启动/bin/bash
参考链接:
- UBUNTU 16.04 EBPF ARBITRARY READ/WRITE 漏洞分析 https://whereisk0shl.top/post/2018-03-21
- Linux内核调试环境搭建:http://advdbg.org/blogs/advdbg_system/articles/7147.aspx
- 关于BPF:http://blog.csdn.net/ljy1988123/article/details/50444693
- 关于内核栈:http://blog.csdn.net/tiankong_/article/details/75647488
- [漏洞复现] CVE-2017-16995 Ubuntu16.04漏洞复现 http://blog.51cto.com/chenxinjie/2093654
- 深入分析Ubuntu本地提权漏洞—【CVE-2017-16995】 https://xz.aliyun.com/t/2212#toc-0