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

openbsd remote exploit
SMART_READER_LITE
LIVE PREVIEW

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()


slide-1
SLIDE 1

OpenBSD Remote Exploit

”Only two remote holes in the default install”

Alfredo A. Ortega June 30, 2007

slide-2
SLIDE 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.

mbuf1 mbuf2 mbuf3 mbuf4 End of overflow Copy direction

Figure: mbuf chain overflow direction

The function m freem() crashed...

slide-3
SLIDE 3

Searching for a way to gain code execution

slide-4
SLIDE 4

Searching for a way to gain code execution

slide-5
SLIDE 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)

slide-6
SLIDE 6

IcmpV6 packets

Attack vector

We use two IcmpV6 packets as the attack vector

Header

Fragmentation Header IPv6 Header

Mbuf chain Fragment 2

Icmpv6

Icmpv6 Header Trampoline ShellCode SyscallHook Payload

Header mbuf 2 mbuf 1 Header mbuf 3

Hop−by−Hop Header Fragmentation Header IPv6 Header

Fragment 1

Figure: Detail of IcmpV6 fragments

slide-7
SLIDE 7

Where are we?

Code execution

We really don’t know where in kernel-land we are. But ESI is pointing to our code.

User process Hooked syscall ShellCode Kernel Ring 0 Ring 3 Kernel Int 0x80 ShellCode ? ? ? ? ? ? ? ? ? ? ?

Initial situation Final situation

iret Where we are? Ring 0 ESI

Figure: Initial and final situations

slide-8
SLIDE 8

Now what?

Hook (remember DOS TSRs?)

We hook the system call (Int 0x80)

User process INT 0x80 Kernel return Hook Hooked syscall User process INT 0x80 Kernel Ring 3 Ring 0 return Normal syscall

Normal System Call Hooked System Call

Figure: System call hook

Note: If the OS uses SYSENTER for system calls, the operation is slightly different.

slide-9
SLIDE 9

New syscall pseudo-code

  • 1. Adjust segment selectors DS and ES (to use movsd

instructions)

slide-10
SLIDE 10

New syscall pseudo-code

  • 1. Adjust segment selectors DS and ES (to use movsd

instructions)

  • 2. Get curproc variable (current process)
slide-11
SLIDE 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)
slide-12
SLIDE 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

slide-13
SLIDE 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)
slide-14
SLIDE 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
slide-15
SLIDE 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.

Extension Extension User Code Segment (CS) User Data Segment (DS) 0x00000000 0xffffffff 4 GB 512 MB stack

.so .text stack heap .so

Figure: OpenBSD selector scheme and extension

slide-16
SLIDE 16

Defeating WˆX from ring0

Our algorithm, independent of the Kernel: s l d t ax ; Store LDT index

  • n 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 mov edx , [ ebx+eax ] mov ecx , [ ebx+eax+0x4 ] shr edx ,16 ; base low− − >edx mov eax , ecx s h l eax ,24 ; base middle − − > edx shr eax ,8

  • r

edx , eax mov eax , ecx ; b a s e h i g h − − > edx and eax ,0 xff000000

  • r

edx , eax mov ebx , edx ; ldt− − > ebx ; Extend CS s e l e c t o r

  • r

dword [ ebx+0x1c ] , 0 x000f0000 ; Extend DS s e l e c t o r

  • r

dword [ ebx+0x24 ] , 0 x000f0000

slide-17
SLIDE 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:

Ring 3 User Stack Ring 3 User Stack

  • 1. fork()

2.mmap() 3.copy 4.jmp to mmaped mprotect() extends CS permanently

  • 1. mprotect()

2.fork() From kernel... From kernel...

Turning off W^X (from usermode) Creating a W+X section

3.Standard

  • 5. Standard

user−mode code user−mode code

Figure: Payload injection options

slide-18
SLIDE 18

Questions before going on?

Now we are executing standard user-mode code, and the system has been compromised.

slide-19
SLIDE 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

kernel

0xD0000000 0xD1000000 Kernel Code Segment (CS) Kernel Data Segment (DS)

CS shrink

mbuf chains, etc

Figure: OpenBSD Kernel CS selector shrink

slide-20
SLIDE 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)

slide-21
SLIDE 21

Conclusions

In this article we presented:

  • 1. Generic kernel execution code and strategy
  • 2. Possible security improvement of the kernel
slide-22
SLIDE 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
slide-23
SLIDE 23

Final Questions?

Thanks to: Gerardo Richarte: Exploit Architecture Mario Vilas and Nico Economou: Coding support