The security research team at Qualys has discovered multiple vulnerabilities in guard-page implementations in various Linux versions. This bug can be exploited by local users to gain root privileges by compromising memory regions pertaining to other application and shared libraries. Qualys has disclosed these vulnerabilities to vendors and has been working with them for a coordinated patch and signature release.
Background:
Operating systems use stacks to keep track of process executions and heaps for dynamic memory allocations. In general by design the stack grows from higher addresses to lower, and heaps are usually not bound to such a frame of reference. If the stack is exhausted the process in question can request for more space by raising a PAGE_FAULT exception. Stack-Clash refers to the incident where the these two memory structures collide/overlap. To avoid this scenario guard-pages are implemented at the start of the stack, if the stack pointer breaches the guard page then either a PAGE-FAULT exception is raised or the process in question is terminated via SIGSEGV signal. Guard pages are also used in the Windows operating systems for similar memory protection checks.
Vulnerability:
As mentioned in the previous section, guard-page prevents stacks from overflowing. However if the stack can avoid breaching the guard-page by moving the stack pointer it does not raise a page fault and can continue expanding into other memory regions. This means we can overwrite memory regions mapped directly below the stack. The vulnerabilities in the current guard-page implementation allows us to achieve this. This can result in stack smashing or memory smashing. Please refer the Qualys Security Advisory for more details and history behind this vulnerability.
Exploitation:
At present the target machines can be exploited locally and remote exploitation may be possible in some scenarios. The steps described below are for a traditional stack-clash, all steps need not be applicable for every target OS.
The exploitation process is roughly divided into 4 steps:
Step 1: Clash
– Keep allocating memory till the stack reaches another memory region. These allocations are not freed.
Step 2: Run
– After successful allocation move the stack pointer to the lower end of the stack allocated memory.
Step 3: Jump
– Move the stack pointer from the current stack memory into the memory region without breaching the guard-page. Effectively we are executing in the address space of another process.
Step 4: Smash
– At this point we can either choose to overwrite the stack or overwrite the memory region currently clashing with the stack, this is used for application specific exploitation.
Please refer the Qualys Security Advisory for more details about the exploit and how to check if a machine is vulnerable. Many CVE’s were uncovered during this research.
CVE | OS | Description |
---|---|---|
CVE-2017-1084 | FreeBSD | Stack guard-page is ineffective if memory region mapped below grows up and clashes with the stack. |
CVE-2017-1083 | Stack guard-page disabled by default. | |
CVE-2017-1085 | Increasing RLIMIT_STACK and call to vm_map_protect() may turn read-only memory region below the stack into a read-write region. | |
CVE-2017-1000374 | NetBSD | Setting RLIMIT_STACK to MAXSSIZ eliminates the PROT_NONE part of the stack region which disables guard-page protection.(* remote exploitation not possible) |
CVE-2017-1000369 | Debian | EoP in Exim. |
Ubuntu | ||
CVE-2017-1000376 | Debian | EoP in Exim. |
CVE-2017-1000367 | Debian | local-root EoP vulnerability in Sudo’s get_process_ttyname() for Linux. |
Ubuntu | ||
SUSE Enterprise Linux | ||
Oracle enterprise Linux | ||
Fedora | ||
CentOS | ||
CVE-2017-1000366 | Debian (x86 and amd64) | Vulnerability in ld.so and ld-linux.so* part if glibc allowing EoP. |
Fedora | ||
CentOS | ||
Amzon Linux | ||
OpenSUSE | ||
SUSE Enterprise Linux | ||
Oracle Solaris | ||
SELinux-enabled | ||
RHEL | ||
CVE-2017-1000370 | Debian | Vulnerability in the offset2lib patch allowing local-root EoP. |
Fedora | ||
CentOS | ||
CVE-2017-1000371 | Debian | Vulnerability in the offset2lib patch allowing local-root EoP. |
Fedora | ||
CentOS | ||
CVE-2017-1000365 | Debian | Linux,kernel (/bin/su) enforces size limits on command-line arguments and environment variables but not on argv[] and envp[] pointers. |
CVE-2017-1000377 | Linux | The 64KB grsecurity/PaX stack guard-page is not large enough and can be jumped over with ld.so or gettext(). This can be used to control EIP |
Amazon Linux | ||
CVE-2017-1000379 | Debian (amd64) | The minimum initial mmap-stack distance is only 128MB. |
Fedora (amd64) | ||
CentOS (amd64) | ||
Ubuntu (amd64) | ||
Red Hat (amd64) | ||
CVE-2017-1000372 | OpenBSD | Setting RLIMIT_STACK to MAXSSIZ eliminates the PROT_NONE part of the stack region which disables guard-page protection.(* remote exploitation not possible) |
CVE-2017-1000373 | OpenBSD | qsort() function is not randomized, an attacker can construct a pathological input array of N elements that causes qsort() to deterministically recurse N times. This allows for continuous memory allocation. |
CVE-2017-1000375 | NetBSD | Maps the run-time link-editor ld.so directly below the stack region, even if ASLR is enabled. |
CVE-2017-3630 | Solaris 11 | With or without ASLR runtime linker ld.so is mapped below the guard-page.(With ASLR ld.so is mapped at a random distance from the guard-page) |
CVE-2017-3629 | Even with ASLR the distance between the end of ld.so’s,read-write segment a nd the start of the stack is exactly 8KB | |
CVE-2017-3631 | Forced-Privilege protection is based on the pathname of SUID-root binaries, which can be execve()d through hard-links under different pathnames. | |
CVE-2017-1000364 | SUSE | A 4k stack guard page is not sufficiently large and can be “jumped” over |
Red Hat | ||
Linux Kernel =<4.11.5 | ||
Debian | ||
Ubuntu | ||
Oracle Enterprise Linux | ||
Amazon Linux | ||
OpenBSd | ||
FreeBSD | ||
NetBSD | ||
Fedora | ||
CentOS | ||
CVE-2017-1000378 | NetBSD | qsort() function is not randomized, an attacker can construct a pathological input array of N elements that causes qsort() to deterministically recurse N times. This allows for continuous memory allocation. |
CVE-2017-1082 | FreeBSD |
Mitigation:
Qualys has been working with various vendors to ensure effective patch development. The fix is not straightforward as it requires patching the kernel and also the individual affected components like glibc and other applications. Vendors will start releasing their corresponding patches from June 19 2017. We request organizations to scan their network with the corresponding QID’s to detect vulnerable machines.
Please continue to follow ThreatProtect for more coverage on this issue.
Update:
– The PoC for CVE-2017-1000367 has been made public.
– Qualys PoC availble here
References:
Qualys Security Advisory
The Stack Clash
CVE-2017-1000367
Red Hat:Stack Guard Page Circumvention Affecting Multiple Packages