/*
 * getHEMP v0.2  -- by ca0s && s0t4ipv6
 *
 * ca0s@getrewted.com.ar - http://www.getrewted.com.ar
 * s0t4ipv6@shellcode.com.ar - http://www.shellcode.com.ar
 *
 * Tool to map the internal network of a cisco router.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>

#define PROGRAM            "getHEMP"
#define VERSION		   "v0.2"
#define AUTHOR             "ca0s && s0t4ipv6"

#define DEFAULT_PORT       23
#define CONNBUFF           1000
#define	FMIP		   20

char 	*optarg;
int 	sock_stat;

void usage(char *prgname) {
  printf("%s %s (c) 2002 by %s
Usage: %s [t HOST:PORT] [<-u LOGIN> <-p PASS>] [-n NETWORK] <-o FILE>\n",
PROGRAM, VERSION, AUTHOR, prgname);
  printf("\nOptions:");
  printf("
   -t HOST[:PORT]  HOST and PORT to connect to. (default PORT is 23)
   -u LOGIN        login with LOGIN name.
   -p PASS         use password PASS.
   -n NETWORK      scan this NETWORK. (ex.: 10.10.10.0-100)
   -o FILE         write found login/password to FILE instead of stdout.

\n", PROGRAM);
  exit(-1);
}


int banner(void) {
  printf("\n%s %s (c) 2002 by %s \n\n", PROGRAM, VERSION, AUTHOR); 
}


void fail(char *message) {
  fprintf(stderr, "(!) error: %s\n", message);
  exit(-1);
}


int log_found(char *host, char *file) {
  FILE *fd;
  
  if ((fd = fopen(file, "a")) == NULL) {
    fail("unable to open the logfile.");
  }
  fprintf(fd, "Target UP -> [%s]\n", host);

  fclose(fd);
}


int enlace(char *host, int port) {
  int err;
  struct sockaddr_in addr;
  struct hostent *hp;

  if ((hp = gethostbyname(host)) == NULL)
    fail("failed to resolve host.");
  
  if ((sock_stat = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    fail("error opening socket.");

  addr.sin_family = PF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = inet_addr(host);

  if ((err = connect(sock_stat, (struct sockaddr *) &addr, sizeof(addr))) < 0)
    fail("error opening connection.");

  printf("* attemping connection to [%s:%d].\n", host, port);
}


int sendlogin(char *user, char *pass) {
  int mode = 0;
  char *input;

  if ((input=(char*)calloc(CONNBUFF + 1 , sizeof(char))) == NULL) 
    fail("can't allocate memory.");

  while (read(sock_stat, input, CONNBUFF) > 0) {      
    if (strstr(input,"ogin:") || strstr(input,"sername:")) {  
      printf("* login requested.\n");
      if (!strcmp(user, "nologin"))
        fail("can't continue whitout a username."); 
        mode = 1;
        break;
    } 
    if (strstr(input,"assword:")) {
      printf("* only password needed.\n");
      break;
    } 
  }

  memset(input, 0x00, CONNBUFF);

  if (mode == 1) {
    printf("* sending [%s] and [%s].\n", user, pass);
    write(sock_stat, user, strlen(user)); 
    write(sock_stat, "\r\n", 2);
    while(read(sock_stat, input, CONNBUFF) > 0) {
      if(strstr(input,"assword")) {
        memset(input, 0x00, CONNBUFF);
	break;
      }
    }
    write(sock_stat, pass, strlen(pass)); 
    write(sock_stat, "\r\n", 2);
  }
  else {
    printf("* sending [%s].\n", pass);
    write(sock_stat, pass, strlen(pass)); 
    write(sock_stat, "\r\n", 2);
  }
  
  sleep(3);
  memset(input, 0x00, CONNBUFF);
  
  while (read(sock_stat, input, CONNBUFF) > 0) {

    if (strstr(input,"ogin:") || strstr(input,"sername:")) {
      printf("* authentication failed.\n");
      return (0);
    }
    else if (strstr(input,"assword:")) {
      printf("* authentication failed.\n");
      return (0);
    }
    else if (strchr(input,'\x3e')) {
      printf("* seems we are logged in.\n");
      return (1);
    }
  }
}


int mapnet(char *net, char *logfile) {
        char    getin;
        char    *dinamica, *mande;
        char    *p_tok;
        int     toks[4];
        int     i, min, max;

        /* set default min */
        min = 1 ;

        if ( ( p_tok = (char *)calloc(8, sizeof(char))) == NULL )
                { fail ("can't allocate memory."); }

        /* parse network form */
        for (i = 0 ; i < 3 ; i++) {
                memccpy(p_tok, net, 0x2e, 8);   net+=strlen(p_tok);
                toks[i] = atoi(p_tok);          memset(p_tok, 0x0, 8);
        }

        memccpy(p_tok, net, 0x2d, 8);   
	net+=strlen(p_tok); 			// *address + length(p_tok) 

        if ( atoi(p_tok) ) min = atoi(p_tok);

        /* set default max */
        if ( min > (max = atoi(net)) ) { max = min ; }

        /* check limit */

        if ( (toks[0] <= 0 || toks[0] > 255) ||
             (toks[1] < 0  || toks[1] > 255) ||
             (toks[2] < 0  || toks[2] > 255) ||
             (min < 0 || min > 255) ||
             (max < 0 || max > 255) )
                { fail ("bad network range."); }

	printf("* set range to %d.%d.%d.%d-%d\n", toks[0], toks[1], toks[2], min, max);

        if ( (mande = (char *)calloc(FMIP + 1, sizeof(char))) == NULL )
                { fail ("can't allocate memory."); }
        if ( (dinamica = (char *)calloc( FMIP + 6 , sizeof(char)) ) == NULL )
                { fail ("can't allocate memory."); }

        for ( i = min ; i <= max ; i++ ) {
                snprintf(dinamica, FMIP + 6 , "ping %d.%d.%d.%d\n" ,toks[0],toks[1], toks[2], i);
		snprintf(mande, FMIP + 1, "%d.%d.%d.%d", toks[0], toks[1] , toks[2], i);

		  send(sock_stat, dinamica, strlen(dinamica), 0);
		  printf ("\n* Pinging %s ...", mande);

		  while ( read(sock_stat, &getin , 1) > 0 ) { 
		   if ( (int)getin == 33 ) { 
			if ( logfile != NULL ){ log_found(mande, logfile); }
			printf ("\tUP !"); 
			break;
		  	}
		   if ( (int)getin == 62) break ;
        	  }
		  if ( (int)getin != 62) {
		  	do {
				read(sock_stat, &getin, 1) ;
		  	} while ( (int)getin != 62 );
		  }
	}
}


int main(int argc, char *argv[]) {
  FILE *ofp;
  char *target = NULL, *logfile = NULL, *pass = NULL,
       *temp, *login = NULL, *net = NULL;
  int option, port;

  if (argc < 3)
    usage(argv[0]);
  
  banner();
  
  while ((option = getopt(argc, argv, "t:u:p:n:o:")) >= 0) {
    switch (option) {
      case 't': target = optarg; break;
      case 'u': login = optarg; break;
      case 'p': pass = optarg; break;
      case 'n': net = optarg; break;
      case 'o': logfile = optarg; break;
      default: usage(argv[0]);
    }
  }

  if (strstr(target, ":") != NULL) {
    temp = target;
    while (*target != ':') target++;
    *target = '\0';
    target++;
    port = atoi(target);
    target = temp;
    if (port < 1 || port > 65535)
      fail("port is out of range.");
  } else
    port = DEFAULT_PORT;

  if (pass == NULL)
    fail("options -p or -P are needed.");

  if (login == NULL) {
    login = malloc(strlen("nologin"));
    memcpy(login, "nologin", strlen("nologin"));
  }

  if (net == NULL)
    fail("option -n is needed.");
  
  if (logfile != NULL) {
    if ((ofp = fopen(logfile, "w")) == NULL)
      fail("unable to open the logfile.");
    fprintf(ofp, "%s %s (c) 2002 by %s\n\n", PROGRAM, VERSION, AUTHOR);
    fclose(ofp);
  }

  enlace(target, port);
  if (sendlogin(login, pass))
    	mapnet(net, logfile);

  printf("\n\n%s finished.\n\n", PROGRAM);
  exit(0);
}
