openbsd remote exploit
play

OpenBSD Remote Exploit Only two remote holes in the default install - PowerPoint PPT Presentation

OpenBSD Remote Exploit Only two remote holes in the default install Alfredo A. Ortega June 30, 2007 Mbuf buffer overflow Buffer overflow Researching the OpenBSD 008: RELIABILITY FIX a new vulnerability was found: The m dup1()


  1. OpenBSD Remote Exploit ”Only two remote holes in the default install” Alfredo A. Ortega June 30, 2007

  2. Mbuf buffer overflow Buffer overflow Researching the “OpenBSD 008: RELIABILITY FIX” a new vulnerability was found: The m dup1() function causes an overflow on the mbuf structure, used by the kernel to store network packets. Copy direction mbuf1 mbuf2 mbuf3 mbuf4 End of overflow Figure: mbuf chain overflow direction The function m freem() crashed...

  3. Searching for a way to gain code execution

  4. Searching for a way to gain code execution

  5. C code equivalent / s y s /mbuf . h #d e f i n e MEXTREMOVE(m) do { \ i f (MCLISREFERENCED(m)) { \ MCLDEREFERENCE(m) ; \ } e l s e i f ((m ) − > m f l a g s & M CLUSTER) { \ p o o l p u t (&mclpool , (m ) − > m ext . e x t b u f ) ; \ } e l s e i f ((m ) − > m ext . e x t f r e e ) { \ ( ∗ ((m ) − > m ext . e x t f r e e ) ) ( (m ) − > m ext . ext buf , \ (m ) − > m ext . e x t s i z e , (m ) − > m ext . e x t a r g ) ; \ } { \ e l s e f r e e ((m ) − > m ext . ext buf , (m ) − > m ext . e x t t y p e ) ; \ } \ (m ) − > m f l a g s &= ˜(M CLUSTER | M EXT ) ; \ (m ) − > m ext . e x t s i z e = 0; / ∗ why ??? ∗ / \ } while (/ ∗ CONSTCOND ∗ / 0)

  6. IcmpV6 packets Attack vector We use two IcmpV6 packets as the attack vector Mbuf chain Fragment 1 Fragment 2 Header IPv6 Header IPv6 Header mbuf 1 Hop−by−Hop Header Fragmentation Header Fragmentation Header Icmpv6 Icmpv6 Header Header Trampoline mbuf 2 ShellCode SyscallHook Payload Header mbuf 3 Figure: Detail of IcmpV6 fragments

  7. Where are we? Code execution We really don’t know where in kernel-land we are. But ESI is pointing to our code. Initial situation Final situation User process Kernel ? Ring 3 ? Hooked syscall Ring 0 ? ? ? ? ShellCode ESI ShellCode iret Int 0x80 ? ? ? ? Kernel Ring 0 ? Where we are? Figure: Initial and final situations

  8. Now what? Hook (remember DOS TSRs?) We hook the system call (Int 0x80) Normal System Call Hooked System Call User process User process Ring 3 Normal syscall Hooked syscall INT 0x80 INT 0x80 return return Kernel Kernel Ring 0 Hook Figure: System call hook Note: If the OS uses SYSENTER for system calls, the operation is slightly different.

  9. New syscall pseudo-code 1. Adjust segment selectors DS and ES (to use movsd instructions)

  10. New syscall pseudo-code 1. Adjust segment selectors DS and ES (to use movsd instructions) 2. Get curproc variable (current process)

  11. New syscall pseudo-code 1. Adjust segment selectors DS and ES (to use movsd instructions) 2. Get curproc variable (current process) 3. Get user Id (curproc − > userID)

  12. New syscall pseudo-code 1. Adjust segment selectors DS and ES (to use movsd instructions) 2. Get curproc variable (current process) 3. Get user Id (curproc − > userID) 4. If userID == 0 : 4.1 Get LDT position 4.2 Extend DS and CS on the LDT (This disables WˆX!) 4.3 Copy the user-mode code to the the stack of the process 4.4 Modify return address for the syscall to point to our code

  13. New syscall pseudo-code 1. Adjust segment selectors DS and ES (to use movsd instructions) 2. Get curproc variable (current process) 3. Get user Id (curproc − > userID) 4. If userID == 0 : 4.1 Get LDT position 4.2 Extend DS and CS on the LDT (This disables WˆX!) 4.3 Copy the user-mode code to the the stack of the process 4.4 Modify return address for the syscall to point to our code 5. Restore the original Int 0x80 vector (remove the hook)

  14. New syscall pseudo-code 1. Adjust segment selectors DS and ES (to use movsd instructions) 2. Get curproc variable (current process) 3. Get user Id (curproc − > userID) 4. If userID == 0 : 4.1 Get LDT position 4.2 Extend DS and CS on the LDT (This disables WˆX!) 4.3 Copy the user-mode code to the the stack of the process 4.4 Modify return address for the syscall to point to our code 5. Restore the original Int 0x80 vector (remove the hook) 6. Continue with the original syscall

  15. OpenBSD WˆX internals WˆX: Writable memory is never executable i386: uses CS selector to limit the execution. To disable WˆX, we extend CS from ring0. 0x00000000 0xffffffff 4 GB .text .so .so heap stack 512 MB User Code Segment (CS) Extension User Data Segment (DS) stack Extension Figure: OpenBSD selector scheme and extension

  16. Defeating WˆX from ring0 Our algorithm, independent of the Kernel: s l d t ax ; Store LDT index on EAX sub esp , byte 0 x7f sgdt [ esp +4] ; Store g l o b a l d e s c r i p t o r t a b l e mov ebx , [ esp +6] add esp , byte 0 x7f push eax ; Save l o c a l d e s c r i p t o r t a b l e index edx , [ ebx + eax ] mov ecx , [ ebx + eax +0x4 ] mov edx ,16 ; base low − − > edx shr eax , ecx mov eax ,24 ; base middle − − edx s h l > eax ,8 shr edx , eax or eax , ecx ; b a s e h i g h − − > edx mov eax ,0 xff000000 and edx , eax or mov ebx , edx ; ldt − − > ebx ; Extend CS s e l e c t o r or dword [ ebx +0x1c ] , 0 x000f0000 ; Extend DS s e l e c t o r or dword [ ebx +0x24 ] , 0 x000f0000

  17. Injected code WˆX will be restored on the next context switch, so we have two choices to do safe execution from user-mode: Turning off W^X (from usermode) Creating a W+X section From kernel... From kernel... User User Stack Stack 1. mprotect() 1. fork() Ring 3 Ring 3 mprotect() extends 2.fork() 2.mmap() CS permanently 3.Standard 3.copy user−mode code 4.jmp to mmaped 5. Standard user−mode code Figure: Payload injection options

  18. Questions before going on? Now we are executing standard user-mode code, and the system has been compromised.

  19. Proposed protection Limit the Kernel CS selector The same strategy than on user-space. Used on PaX (http://pax.grsecurity.net) for Linux. 0x00000000 0xffffffff 4 GB 0xD0000000 0xD1000000 kernel mbuf chains, etc CS shrink Kernel Code Segment (CS) Kernel Data Segment (DS) Figure: OpenBSD Kernel CS selector shrink

  20. A third remote vulnerability? IPv6 Routing Headers Uninitialized variable on the processing of IPv6 headers. 1. DoS or Code Execution (depending who you ask!) 2. Present on CVS from January to March of 2007 (very few systems affected)

  21. Conclusions In this article we presented: 1. Generic kernel execution code and strategy 2. Possible security improvement of the kernel

  22. Conclusions In this article we presented: 1. Generic kernel execution code and strategy 2. Possible security improvement of the kernel 3. A third bug - No software is perfect

  23. Final Questions? Thanks to: Gerardo Richarte: Exploit Architecture Mario Vilas and Nico Economou: Coding support

Recommend


More recommend