Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

52
Libra: A Compatible Method for Defending Against Arbitrary Memory Overwrite

description

http://adl.tw/~jeremy/slides/presentation2.pptx Attached detailed Analysis of CVE-2013-2094 (&on x86-32). Exploit the CVE-2013-2094 with animation There have been more vulnerabilities in the Linux Kernel in 2013 than there had been in the previous decade. In this paper, the research was focused on defending against arbitrary memory overwrites in Privilege Escalation. To avoid malicious users getting root authority. The easiest way is to set the sensitive data structure to read-only. But we are not sure the sensitive data structure will never be modified by legal behavior from a normal device driver; thus, we posed a compatible solution between read-only solutions and writable solutions to enhance compatibility. The main idea that we posed not only solves the above problem, but also the general problem which is ensuring that important memory values can only be changed within a safe range. It is not just set to read-only. Key Word : Linux Kernel Vulnerabilities、exploit、Privilege Escalation

Transcript of Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

Page 1: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

Libra: A Compatible Method for Defending Against Arbitrary Memory Overwrite

Page 2: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

2

Outline• Chapter1 Introduction

– Statistics of Vulnerabilities and Exploits– Attack Principle

• Chapter2 Mechanism of Attack and Example– At the Second Step …– Kernel Data Structures to Overwrite

• Chapter3 Proposed Solution– Background Knowledge– Compatible Solution– Characteristics

• Chapter4 Implementation• Chapter5 Evaluation

– Compatible Comparison– Performance– Stability Testing– False Positive & Negative Positive

• Appendix– A Case Study : CVE-2013-2094

Page 3: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

3

Statistics of Linux Kernel Vulnerabilities

From : www.cvedetails.com

Page 4: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

4

Statistics of Vulnerabilities in 2013

From : www.cvedetails.com

Page 5: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

5

Statistics of Exploits

Page 6: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

6

Attack Principle• A typical exploit for arbitrary memory

overwrite of Privilege Escalation is described as following:1. Triggering the vulnerabilities for arbitrary

memory overwrite.

User spaceUser space

Kernel spaceNormal function

Function pointer(addr1)

addr1

Page 7: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

7

Attack Principle

2. Overwriting any kernel function pointer, to make the pointer pointing to the payload address in user space.

Payload addr2

Kernel space

User space

Normal function

Function pointer(addr2)

addr1

Page 8: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

8

Attack Principle3. Because the overwritten kernel function can be easily used when serving user requests, an unauthorized attacker can get the root access when the modified kernel function was used.

1. A Case Study : CVE-2013-20942. CVE-2013-2094 on x86-32

commit_creds(prepare_kernel_cred(NULL));

Payload addr2

Kernel space

User space

Normal function

Function pointer(addr2)

addr1

Page 9: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

9

Kernel Data Structures Can Be Overwritten

• IDT table• ptmx_fops• …

Page 10: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

10

Proposed Solution :Background knowledge

The interrupt handler address fields in an IDT table entry are composed of low_offset field, middle_offset field, and high_offset field.

Page 11: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

11

ptmx_fops ?

pty (pseudo-teletype) is a pair of virtual character devices that provide a bidirectional communication channel. Pty consists of ptmx and pts.

For example:

USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATxue pts/0 61.66.243.96 Mon16 17:24m 0.21s 0.04s ssh [email protected] pts/1 36-231-101-220.d 10:27 0.00s 0.19s 0.01s w

Page 12: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

12

Linux Device Driver Architecture

Page 14: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

14

Ways to Find Addresses of Related Kernel Data Structures

• Use the assembly instruction - sidt• Search– system.map – /proc/kallsyms

Page 15: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

15

Example

• grep ptmx_fops /boot/System.map-$(uname -r)

• grep ptmx_fops /proc/kallsyms• /* 56 is offset of fsync in struct file_operations on x86-32 */

int target = pmtx_ops + 56 //target is a kernel pointer

Page 16: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

16

Hiding the Kernel Function Addresses

• #chmod o-r /boot/System.map-3.0.42-0.7-default

• #sysctl -w kernel.kptr_restrict=1

Page 17: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

17

Kees Cook’s patch (Linux official patch)

__set_fixmap(FIX_RO_IDT,_pa_symbol(idt_table),PAGE_KERNEL_RO);

idt_descr.address = fix_to_virt(FIX_RO_IDT);

Compatibility: We are not sure that IDT table will be modified.

Page 18: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

18

Proposed Solution

memoryImportant value : x Let 15

5 If x=1, it is ok.

If x=6, it will fail.

1Read-only

Page fault handler helps us to modify value (x=1)

Page 19: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

19

Page fault error code bits

• The CPU pushes an error code on the stack before firing a page fault exception.

• The error code must be analyzed by the exception handler to determine how to handle the exception. http://wiki.osdev.org/Paging

Page 20: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

20

Meaning of “error code = 3”

– bit 0 == 0: no page found 1: protection fault– bit 1 == 0: read access 1: write access– bit 2 == 0: kernel-mode access 1: user-mode access

Page 21: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

21

Flowchart of Linux Page fault handlerAccess to

kernel space

Access in Kernel Mode

Noncontiguous memory area

address

Address is a wrongSystem call parameter

Compatiblesolution

Page 22: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

22

Flowchart of Libra for IDT TableInvalid address= read_cr2

Page fault handler executes no_context()

Does the invalid address fall into the IDT table address

range?

Is the error_code equal to 3?

Continuing to execute no_context() YES

No

NoYES

Page 23: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

23

Flowchart of Libra for IDT Table

Is the new value in Kernel space?

Close the Read-only attribute of IDT tableModify the value

Open the Read-only attribute of IDT tableUpdate the program counter

Page fault handler returns to the program that

needs to change IDT table

YESNo

Page 24: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

24

Flowchart of Libra for ptmx_fopskallsyms_lookup_name("ptmx_fops")

;Invalid address = read_cr2();

Is the invalid address in the ptmx_fops

structure ?

Error code == 3 ? &&Modified value >

0xffffffff80000000

Continuing to execute

no_context() Yes

NO

Page 25: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

25

Close the read-only attribute of ptmx_fopsModify the value

Open the read-only attribute of ptmx_fopsUpdate the program counter

Page fault returns to the program that needs

change ptmx_fops

Page 26: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

26

Characteristics of Libra

– It is a software solution that does not require any extra hardware cost.

– It is a compromised solution between read-only solutions and writable solutions to enhance compatibility.

– It is a response-oriented security solution to avoid spending CPU resource for monitoring.

Page 27: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

27

Implementation

• On Ubuntu 13.04 (Kernel version: 3.10.15) • On x86-64 architecture. • Intel(R) Pentium(R) D CPU 3.00GHz, 1GB RAM• [patch]x86: Use a read-only IDT alias on all

CPUs, by Kees Cook.

Page 28: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

28

Evaluation:Compatible Comparison

• Adding a system call for compatible comparison idt_table2 = ((gate_desc *) idtr.address); idt_table2[i].offset_low = 0xbeef; idt_table2[i].offset_middle = 0xdead; idt_table2[i].offset_high = 0x12345678;

• Original zeroth entry of IDT table :*0xffffffffff57a008 (high_offset)= ffffffff*0xffffffffff57a000 (low_offset)=4df0*0xffffffffff57a004 (middle_offset)=816a

Page 29: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

29

Evaluation:Compatible Comparison

• Kees cook’s solution led to this result that is as follow:• [131360.581351] pte_write(8000000001e22161):0• [131360.581355] *0xffffffffff57a008 (offset_high)= ffffffff• [131360.581358] *0xffffffffff57a000 (offset_low)=4df0• [131360.581360] *0xffffffffff57a004 (offset_middle)=816a

Page 30: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

30

Evaluation:Compatible Comparison

• Libra solution led to this result that is as follow:• [11679.083463] pte_write(8000000001e22161):0• [11679.083466] *0xffffffffff57a008 (offset_high)= ffffffff

• [11679.083469] *0xffffffffff57a000 (offset_low)=beef

• [11679.083472] *0xffffffffff57a004 (offset_middle)=dead

Page 31: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

31

Evaluation:Compatible Comparison

Kees Cook’s solution

LibraSolution

offset_low Read-only Writable

offset_middle Read-only Writable

offset_high Read-only Read-only

Page 32: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

32

Evaluation:Compatible Comparison

•[ 146.215132] flush: (null)

• [ 146.215132] release value:ffffffff813e5880• [ 146.215132] fsync value: (null)• [ 146.215132] aio_fsync value: (null)• [ 146.215132] fasync value:ffffffff813e4430• [ 146.215132] Jeremy, cr2 = ffffffffff577060• [ 146.215132] Jeremy, page fault handler in kernel space is trigger!!!• [ 146.215132] address 0xffffffffff577060 in CR2• [ 146.215132] error_code = 3• [ 146.215132] page fault run to line 1068• [ 146.215132] page fault run to line 772• [ 146.215132] Jeremy, *kallsyms_lookup_name(ptmx_fops) : ffffffffff577000 in fault.c• [ 146.215132] The modified value at ptmx_fops : ffffffff8100beef• [ 146.215132] address : ffffffffff577060

•[ 146.236822] flush:ffffffff8100beef

Before modifing

After modifing

Page 33: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

33

Evaluation:Performance

• We do performance testing through perf that is in Linux Kernel source code.

• “perf stat –r 100000 ./test_modify_idt 0”• The performance of Kees Cook’s solution :

Page 34: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

34

Evaluation:Performance

• The performance of compatible solution :

Page 35: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

35

Evaluation:Performance

Kees Cook solution Compatible solution0.058

0.0585

0.059

0.0595

0.06

0.0605

0.061

0.0615

Seconds

seconds

(+- 0.02%)

Page 36: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

36

Evaluation:Stability testing

• “The Linux™ Test Project (LTP)is a joint project started by SGI™ and maintained by IBM®, that has a goal to deliver test suites to the open source community that validate the reliability, robustness, and stability of Linux.” -http://linux-test-project.github.io/

Page 37: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

37

Evaluation:Stability testing

• Total Tests: 1424

Original Ubuntu

LibraUbuntu

Total Skipped Tests 117 138Total Failures 59 80Kernel Version 3.8.0-19-generic 3.10.15

Page 38: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

38

Evaluation:False Positives & False Negatives

• False Positives : – Run four months.– Firefox, LibreOffice, OpenSSH, LXR website,

MSMBuilder.

Page 39: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

39

Evaluation:False Positives & False Negatives

• False Negatives :– Linux PERF_EVENTS - Local Root Exploit • Sd, wzt, Vitaly Nikolenko, sorbo

– FreeBSD 9.0 Intel SYSRET Kernel Privilege Escalation exploit

– Nvidia Linux driver Privileges Escalation– CVE-2010-3081 & CVE-2010-3301: Linux kernel

COMPAT Privilege Escalation

Page 40: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

40

Related Work• RGBDroid: A Novel Response-based Approach to Android Privilege Escalation Attacks.• Kees Cook’s patch: x86: Use a read-only IDT alias on all CPUs

• 2014-05-31, Vitaly Nikolenko’s exploit * Supported targets: * [0] Ubuntu 12.04.0 - 3.2.0-23-generic * [1] Ubuntu 12.04.1 - 3.2.0-29-generic * [2] Ubuntu 12.04.2 - 3.5.0-23-generic• uint64_t targets[3][3] =            {{0xffffffff81ef67e0,  // perf_swevent_enabled              0xffffffff81091630,  // commit_creds              0xffffffff810918e0}, // prepare_kernel_cred             {0xffffffff81ef67a0,               0xffffffff81091220,              0xffffffff810914d0},             {0xffffffff81ef5940,              0xffffffff8107ee30,              0xffffffff8107f0c0}        };• Kernel address space layout randomization, Kees Cook, October 9, 2013, Linux Security Summit

Page 41: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

41

Any Questions?

Thank you~

Page 42: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

42

Appendix A

• A Case Study : CVE-2013-2094• A Case Study : CVE-2013-2094 on x86-32

Page 43: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

43

Integer issues - Sign conversion issues (CVE-2013-2094)

• int fd = syscall(__NR_perf_event_open, ,…)

• After executing perf_swevent_init, an attacker can increase the content of any kernel address by 1.

after close(fd)

• After executing sw_perf_event_destroy, an attacker can decrease the content of any user address by 1.

Page 44: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

44

A case study : CVE-2013-2094• /kernel/events/core.c1.static int perf_swevent_init(2. )3.{4.  int event_id = event->attr.config;5. 6.  /* ... */7. 8.  if (event_id >= PERF_COUNT_SW_MAX)9.    return -ENOENT;10.  // PERF_COUNT_SW_MAX == 911.  /* ... */12. 13.  atomic_inc(&perf_swevent_enabled[event_id]);

Page 45: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

45

A case study : CVE-2013-2094

/kernel/events/core.c1.static void sw_perf_event_destroy(2. )3.{4.  u64 event_id = event->attr.config;5. 6.  /* ... */7. 8.atomic_dec(&perf_swevent_enabled[event_id]);9. 10.  /* ... */

Page 46: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

46

Physical memoryUserSpace

0x00000000 00000000

0x00007fff ffffffff

Virtual memory

128 TB

64 TB

0xffff8000 00000000guard hole

0xffff8800 00000000__PAGE_OFFSET

0xffffffff 80000000__START_KERNEL_map

Kernel text 512MB

8MBVSYSCALL

4KB (a page size)FIXADDR_TOPFIXADDR_START

Page 47: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

47

Linux 64-bit memory layout

0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mmhole caused by [48:63] sign extension

ffff800000000000 - ffff80ffffffffff (=40 bits) guard holeffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memoryffffc80000000000 - ffffc8ffffffffff (=40 bits) holeffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap spaceffffe90000000000 - ffffe9ffffffffff (=40 bits) holeffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)... unused hole ...ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping spaceffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscallsffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole• From (Documentation/x86/x86_64/mm.txt)

Page 48: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

48

Integer issues - Sign conversion issues(CVE-2013-2094)

In perf_swevent_init$ cat /boot/System.map-2.6.32-358.el6.x86_64 | grep perf_swevent_enabledffffffff81f360c0 B perf_swevent_enabled

P.S : signed extension because of int typeint event_id == 0xffffffff == -1 == 0xffffffffffffffff (x86-64)

perf_swevent_enabled[-1] ==0xffffffffffffffff * 4 + 0xffffffff81f360c0 == 0xFFFFFFFF81F360BC

int event_id == 0xfffffffe == -2 -->perf_swevent_enabled[-2] ==0xfffffffffffffffe * 4 + 0xffffffff81f360c0 == 0xFFFFFFFF81F360B8

Page 49: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

49

Integer issues - Sign conversion issuesIn sw_perf_event_destroy()

Let's assume again event->attr.config == 0xffffffff --> P.S. No signed extension

0xffffffff [32bit] => 0x00000000ffffffff [64bit]

• perf_swevent_enabled[-1] address in sw_perf_event_destroy:– 0x00000000ffffffff * 4 + 0xffffffff81f360c0 == 0x00000003 81f360bc

• perf_swevent_enabled[-1] address in perf_swevent_init:– 0xffffffffffffffff * 4 + 0xffffffff81f360c0 == 0xffffffff 81f360bc

Even though the addresses of perf_swevent_enabled[-1] in sw_perf_event_destroy() and perf_swevent_init() are different, the 6 MSBs of their last 8 hex digitals are the same.

Page 50: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

50

Perf_swevent_enabled[0]

0xffff ffff +1

Perf_swevent_enabled[-2]Perf_swevent_enabled[-1]

user

Kernel

NOP + Shellcode<-0x00000000 81000000

<- 0xffffffff 81734000

<-0x00000003 80000000

<- 0xffffffff 81734048 Hijackedidt.addr

Offset1----------->

idt.addr + 0x48

0000….

-1 by destroy(-2)

<-0x00000003 90000000

-1 by destroy(-1)

1.Allocate red region & green region.

2. Trigger vulnerability for measuringperf_event_open(-1)perf_event_open(-2)

<- 0xffffffff 817e1340

<-0x00000003 817e1338 <-0x00000003 817e133c

4.asm(“int $0x4”); root got!

<- 0xffffffff 80000008

sw_perf_event_destroy()a.k.a destroy()

offset2

offset3(0x48)

offset1

+=1 by init(-2)+=1 by init(-1)

idt table

perf_swevent_init() a.k.a init()

Offst1----------->

0x0000 0000

3. perf_event_open(- i + (((idt.addr&0xffff ffff)-0x80000000)/4)+16)

offset1 offset24 offset34

Page 51: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

51

Modify the ptmx_fops In exploit// 56 is offset of fsync in struct file_operations int target = pmtx_ops + 56; int payload = -((perf_swevent_enabled - target)/4); perf_swevent_enabled + (payload*4) Trigger int ptmx = open("/dev/ptmx", O_RDWR);fsync(ptmx);

Source code : cve-2013-2094 port to x86-32

Page 52: Libra : A Compatible Method for Defending Against Arbitrary Memory Overwrite

52

4. Trigger vulnerability . fsync(ptmx); root got!

4. Create a lot of child process. Each process executes Perf_event_open(Offset) 256 times. Total 256 processes.( 256*256= 65536)

1. Allocate 0x10000 for payload

<-0xC0000000

<-fsync

Payload

Null

<-ptmx_fops

Perf_swevent_enabled->

3.Offset=(Perf_swevent_enabled -fsync)/4;

56

<-0x00010000

12

2. Find perf_swevent_enabled & ptmx_fops by system.map

3…65536(0x10000)