Codebase list hydra / HEAD hydra-pcanywhere.c
HEAD

Tree @HEAD (Download .tar.gz)

hydra-pcanywhere.c @HEAD

26e80c3
81f7175
26e80c3
81f7175
175852b
81f7175
 
 
 
 
cd4c20e
175852b
cd4c20e
175852b
 
81f7175
 
175852b
 
81f7175
175852b
81f7175
 
 
175852b
81f7175
 
cd4c20e
 
175852b
 
 
 
81f7175
 
 
 
cd4c20e
 
175852b
 
cd4c20e
175852b
 
 
 
 
 
81f7175
 
615a27c
cd4c20e
81f7175
175852b
 
 
 
 
81f7175
 
615a27c
175852b
cd4c20e
175852b
7403d1e
 
175852b
 
 
 
 
 
 
81f7175
 
615a27c
175852b
cd4c20e
175852b
 
 
 
 
 
 
 
 
 
615a27c
175852b
 
81f7175
 
26e80c3
81f7175
 
 
175852b
 
cd4c20e
81f7175
 
 
cd4c20e
175852b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81f7175
 
 
175852b
81f7175
175852b
 
81f7175
 
 
 
175852b
81f7175
 
 
 
7403d1e
81f7175
175852b
81f7175
 
175852b
 
 
7403d1e
175852b
81f7175
 
7403d1e
 
 
175852b
 
 
26e80c3
 
175852b
 
 
7403d1e
175852b
26e80c3
 
4c61e48
175852b
 
 
 
 
 
 
 
81f7175
175852b
81f7175
175852b
81f7175
 
7403d1e
 
175852b
 
7403d1e
175852b
 
 
 
 
81f7175
 
175852b
81f7175
 
175852b
81f7175
7403d1e
175852b
7403d1e
 
175852b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81f7175
 
 
 
26e80c3
cd4c20e
 
175852b
 
 
 
 
 
 
26e80c3
175852b
 
0e33f1c
175852b
 
 
 
 
 
 
 
0e2a057
175852b
 
 
26e80c3
 
175852b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c61e48
175852b
 
 
 
81f7175
47478a7
26e80c3
47478a7
 
 
 
 
26e80c3
47478a7
 
 
 
 
 
// This plugin was written by <david dot maciejak at kyxar dot fr>
//
// PC-Anywhere authentication protocol test on Symantec PC-Anywhere 10.5
//
// no memleaks found on 110425

#include "hydra-mod.h"

extern char *HYDRA_EXIT;

int32_t pcadebug = 0;

int32_t send_cstring(int32_t s, char *crypted_string) {
  char buffer2[100], *bptr = buffer2;
  char clientcryptheader[] = "\x06";

  memset(buffer2, 0, sizeof(clientcryptheader));
  bptr = buffer2;
  buffer2[0] = 6;
  bptr++;
  buffer2[1] = strlen(crypted_string);
  bptr++;
  strcpy(bptr, crypted_string);

  return hydra_send(s, buffer2, 2 + strlen(crypted_string), 0);
}

void show_buffer(char *buffer, int32_t size) {
  int32_t i;

  printf("size: %d, buffer:\n", size);
  for (i = 0; i < size; i++) {
    printf("%c", buffer[i]);
  }
  printf("\n");
}

void clean_buffer(char *buf, int32_t size) {
  int32_t i;

  for (i = 0; i < size; i++) {
    int32_t pos = buf[i];

    if (pos < 32 || pos > 126) {
      // . char
      buf[i] = 46;
    }
  }
}

void print_encrypted_str(char *str) {
  int32_t i;

  printf("encode string: ");
  for (i = 0; i < strlen(str); i++) {
    printf("%x ", str[i]);
  }
  printf("\n");
}

void pca_encrypt(char *cleartxt) {
  char passwd[128];
  int32_t i;

  strncpy(passwd, cleartxt, sizeof(passwd) - 1);
  passwd[sizeof(passwd) - 1] = 0;
  if (strlen(cleartxt) > 0) {
    passwd[0] = (passwd[0] ^ 0xab);
    for (i = 1; i < strlen(passwd); i++)
      passwd[i] = passwd[i - 1] ^ passwd[i] ^ (i - 1);
    passwd[strlen(passwd)] = '\0';
    strcpy(cleartxt, passwd);
  }
}

void pca_decrypt(char *password) {
  char cleartext[128];
  int32_t i;

  if (strlen(password) > 0) {
    cleartext[0] = password[0] ^ 0xab;
    for (i = 1; i < strlen(password); i++)
      cleartext[i] = password[i - 1] ^ password[i] ^ (i - 1);
    cleartext[strlen(password)] = '\0';
    strcpy(password, cleartext);
  }
}

void debugprintf(char *msg) {
  if (pcadebug)
    printf("debug: %s\n", msg);
}

int32_t start_pcanywhere(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
  char *empty = "";
  char *login, *pass;
  char buffer[2048] = "";
  char clogin[128] = "";
  char cpass[128] = "";
  int32_t ret, i;

  char *client[4];
  char *server[5];
  int32_t clientsize[4];

  client[0] = "\x00\x00\x00\x00";
  clientsize[0] = 4;
  client[1] = "\x6F\x06\xff";
  clientsize[1] = 3;
  client[2] = "\x6f\x61\x00\x09\x00\xfe\x00\x00\xff\xff\x00\x00\x00\x00";
  clientsize[2] = 14;
  client[3] = "\x6f\x62\x01\x02\x00\x00\x00";
  clientsize[3] = 7;

  server[0] = "nter";
  server[1] = "\x1B\x61";
  server[2] = "\0x1B\0x62";
  server[3] = "Enter login name";
  server[4] = "denying connection";

  if (strlen(login = hydra_get_next_login()) == 0)
    login = empty;
  if (strlen(pass = hydra_get_next_password()) == 0)
    pass = empty;

  debugprintf("dans pcanywhere start");

  /*printf("testing %s:%s\n",login,pass); */

  strcpy(clogin, login);
  strcpy(cpass, pass);

  pca_encrypt(clogin);
  pca_encrypt(cpass);

  for (i = 0; i < 4; i++) {
    if (hydra_send(s, client[i], clientsize[i], 0) < 0) {
      return 1;
    }

    ret = hydra_recv(s, buffer, sizeof(buffer) - 1);
    if (ret == -1) {
      return 1;
    }

    if (i == 3) {
      if (ret == 3) {
        /*one more to get the login prompt */
        ret = hydra_recv(s, buffer, sizeof(buffer) - 1);
      }
    }

    if (ret >= 0)
      buffer[ret] = 0;

    if (i == 0 || i == 3)
      clean_buffer(buffer, ret);

    if (debug)
      show_buffer(buffer, ret);

    if (i == 2) {
      clean_buffer(buffer, ret);
      buffer[sizeof(buffer) - 1] = 0;
      if (strstr(buffer, server[i + 2]) != NULL) {
        fprintf(stderr, "[ERROR] PC Anywhere host denying connection because "
                        "you have requested a lower encrypt level\n");
        return 3;
      }
    }

    if (strstr(buffer, server[i]) == NULL) {
      if (i == 3) {
        debugprintf("problem receiving login banner");
      }
      return 1;
    }
  }

  if (send_cstring(s, clogin) < 0) {
    return 1;
  }
  ret = hydra_recv(s, buffer, sizeof(buffer) - 1);
  if (ret < 0) {
    return 1;
  }
  buffer[ret] = 0;
  clean_buffer(buffer, ret);
  /*show_buffer(buffer,ret); */
  if (strstr(buffer, "Enter password:") == NULL) {
    debugprintf("problem receiving password banner");
    return 1;
  }

  if (send_cstring(s, cpass) < 0) {
    return 1;
  }

  ret = hydra_recv(s, buffer, sizeof(buffer));
  if (ret < 0)
    return 1;
  else
    buffer[ret] = 0;

  clean_buffer(buffer, ret);
  /*show_buffer(buffer,ret); */

  if ((strstr(buffer, "Invalid login") != NULL) || (strstr(buffer, "Enter password") != NULL)) {
    debugprintf("login/passwd wrong");

    hydra_completed_pair();
    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
      return 3;
    return 2;
  } else {
    debugprintf("cool find login/passwd");

    hydra_report_found_host(port, ip, "pcanywhere", fp);
    hydra_completed_pair_found();
    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
      return 3;
    return 2;
  }
  return 1;
}

void service_pcanywhere(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
  int32_t run = 1, next_run = 1, sock = -1;
  int32_t myport = PORT_PCANYWHERE, mysslport = PORT_PCANYWHERE_SSL;

  hydra_register_socket(sp);
  if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
    return;

  while (1) {
    switch (run) {
    case 1: /* connect and service init function */
      if (sock >= 0)
        sock = hydra_disconnect(sock);
      usleepn(275);
      if ((options & OPTION_SSL) == 0) {
        if (port != 0)
          myport = port;
        sock = hydra_connect_tcp(ip, myport);
        port = myport;
      } else {
        if (port != 0)
          mysslport = port;
        sock = hydra_connect_ssl(ip, mysslport, hostname);
        port = mysslport;
      }
      if (sock < 0) {
        if (quiet != 1)
          fprintf(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int32_t)getpid());
        hydra_child_exit(1);
      }

      next_run = 2;
      break;

    case 2:

      next_run = start_pcanywhere(sock, ip, port, options, miscptr, fp);
      break;
    case 3:

      if (sock >= 0)
        sock = hydra_disconnect(sock);
      hydra_child_exit(0);
      return;

    default:

      fprintf(stderr, "[ERROR] Caught unknown return code, exiting!\n");
      hydra_child_exit(0);
    }
    run = next_run;
  }
}

int32_t service_pcanywhere_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
  // called before the childrens are forked off, so this is the function
  // which should be filled if initial connections and service setup has to be
  // performed once only.
  //
  // fill if needed.
  //
  // return codes:
  //   0 all OK
  //   -1  error, hydra will exit, so print a good error message here

  return 0;
}