//This plugin was written by // //PC-Anywhere authentication protocol test on Symantec PC-Anywhere 10.5 // // no memleaks found on 110425 #include "hydra-mod.h" extern char *HYDRA_EXIT; int pcadebug = 0; int send_cstring(int 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, int size) { int i; printf("size: %d, buffer:\n", size); for (i = 0; i < size; i++) { printf("%c", buffer[i]); } printf("\n"); } void clean_buffer(char *buf, int size) { int i; for (i = 0; i < size; i++) { int pos = buf[i]; if (pos < 32 || pos > 126) { // . char buf[i] = 46; } } } void print_encrypted_str(char *str) { int 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]; int i; strcpy(passwd, cleartxt); 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]; int 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); } int start_pcanywhere(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp) { char *empty = ""; char *login, *pass; char buffer[2048] = ""; char clogin[128] = ""; char cpass[128] = ""; int ret, i; char *client[4]; char *server[5]; int 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)); 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)); } } if (i == 0 || i == 3) clean_buffer(buffer, ret); /*show_buffer(buffer,ret); */ if (i == 2) { clean_buffer(buffer, ret); 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)); if (ret == -1) { return 1; } 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 == -1) { return 1; } 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, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { int run = 1, next_run = 1, sock = -1; int 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); usleep(275000); 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); port = mysslport; } if (sock < 0) { fprintf(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int) 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; } } int service_pcanywhere_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { // 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; }