diff -uN hydra-2.4/configure hydra-2.4-m0j0/configure --- hydra-2.4/configure 2003-08-14 10:35:08.000000000 -0500 +++ hydra-2.4-m0j0/configure 2003-10-01 10:22:47.000000000 -0500 @@ -25,8 +25,20 @@ MANDIR="" LIBDIRS=`cat /etc/ld.so.conf 2> /dev/null` PREFIX=`echo "$1"|sed 's/.*--prefix=//'` +LIBDES="" echo +echo "Checking for libdes ..." +for i in $LIBDIRS /lib /usr/lib /usr/local/lib /opt/local/lib +do + if [ "X" = "X$LIBDES" ]; then + if [ -f "$i/libdes.a" ]; then + LIBDES="$i/libdes.a" + fi + fi +done + + echo "Checking for openssl ..." for i in $LIBDIRS /lib /usr/lib /usr/local/lib /opt/local/lib \ /*ssl /usr/*ssl /opt/*ssl /usr/local/*ssl /opt/local/*ssl \ @@ -164,6 +176,7 @@ echo "XLIBPATHS=$XLIBPATHS" >> Makefile.in echo "XIPATHS=$XIPATHS" >> Makefile.in echo "PREFIX=$PREFIX" >> Makefile.in +echo "LIBDES=$LIBDES" >> Makefile.in echo >> Makefile.in echo "Generating Makefile ..." diff -uN hydra-2.4/hydra.c hydra-2.4-m0j0/hydra.c --- hydra-2.4/hydra.c 2003-08-20 04:43:42.000000000 -0500 +++ hydra-2.4-m0j0/hydra.c 2003-10-14 15:37:08.000000000 -0500 @@ -2,6 +2,8 @@ * hydra v2.4 (c) 2001-2003 by van Hauser / THC * http://www.hackerschoice.com * + * Parallel host scanning by m0j0.j0j0 [m0j0@foofus.net] + * * Parallized network login hacker. Do only use for legal purposes. */ @@ -11,7 +13,7 @@ #include "hydra.h" -extern void service_telnet(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); +extern void service_telnet(unsigned long int ip, int sp, unsigned char options, char *iscptr, FILE *fp, int port); extern void service_ftp(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); extern void service_pop3(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); extern void service_imap(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); @@ -26,23 +28,26 @@ extern void service_icq(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); extern void service_pcnfs(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); extern void service_smb(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); +extern void service_smbnt(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); extern void service_mysql(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port); // ADD NEW SERVICES HERE -#define SERVICES "telnet ftp pop3 imap smb http https cisco cisco-enable ldap mysql nntp vnc rexec socks5 icq pcnfs" +#define SERVICES "telnet ftp pop3 imap smb smbnt http https cisco cisco-enable ldap mysql nntp vnc rexec socks5 icq pcnfs" // ADD NEW SERVICES HERE -#define MAXBUF 264 +#define MAXBUF 264 #define MAXTASKS 255 +#define MAXSERVERS 255 #define PROGRAM "Hydra" #define VERSION "v2.4" -#define AUTHOR "van Hauser / THC" -#define EMAIL "" +#define AUTHOR "van Hauser / THC" +#define EMAIL "" #define RESSOURCE "http://www.thc.org" -#define DEBUG 0 +#define DEBUG 0 #define WAITTIME 30 -#define TASKS 4 +#define TASKS 4 +#define SERVERS 1 char *prg, *tmp; extern char HYDRA_EXIT[5]; @@ -54,102 +59,108 @@ int killed = 0; static pid_t pids[MAXTASKS]; +static pid_t addr_pids[MAXSERVERS]; void help() { - printf("%s %s (c) 2003 by %s %s " \ - "Syntax: %s [[[-l LOGIN|-L FILE] [-p PASS|-P FILE]] | " \ - "[-C FILE]] [-o FILE] [-t TASKS] [-g TASKS] [-w TIME] " \ - "[-f] [-e ns] [-s PORT] [-S] server service [OPT]\n", \ - PROGRAM,VERSION,AUTHOR,EMAIL,prg); - printf("\nOptions:\n"); + printf("%s %s (c) 2003 by %s %s " \ + "Syntax: %s [[[-l LOGIN|-L FILE] [-p PASS|-P FILE]] | " \ + "[-C FILE]] [-o FILE] [-t TASKS] [-g TASKS] [-T SERVERS] " \ + "[-w TIME] [-f] [-e ns] [-s PORT] [-S] server service [OPT]\n", \ + PROGRAM,VERSION,AUTHOR,EMAIL,prg); + printf("\nOptions:\n"); #ifdef OPENSSL - printf(" -S connect via SSL\n"); + printf(" -S connect via SSL\n"); #endif - printf(" -s PORT if the service is on a different default port, " \ - "define it here\n" \ - " -l LOGIN or -L FILE login with LOGIN name, or load " \ - "several logins from FILE\n" \ - " -p PASS or -P FILE try password PASS, or load several " \ - "passwords from FILE\n" \ - " -e ns additional checks, \"n\" for null password, \"s\" " \ - "try login as pass\n" \ - " -C FILE colon seperated \"login:pass\" format, instead of " \ - "-L/-P option\n" \ - " -o FILE write found login/password pairs to FILE instead " \ - "of stdout\n" \ - " -f exit after the first found login/password pair\n" \ - " -t TASKS run TASKS number of connects in parallel " \ - "(default: %d)\n" \ - " -g TASKS start TASKS number per second until -t TASKS are" \ - "reached\n" \ - " -w TIME in seconds, defines the max wait reply time " \ - "(default: %d)\n" \ - " server the target server\n" \ - " service the service to crack. Supported protocols: [%s]\n" \ - " OPT some service modules need additional input, put " \ - "it here\n" \ - "\n%s is a tool to guess valid login/password pairs on a "\ - "target server.\nYou can always find the newest version at %s\n" \ - "Use this tool only for legal purposes!\n", \ - TASKS,WAITTIME,SERVICES,PROGRAM,RESSOURCE); - exit(-1); + printf(" -s PORT if the service is on a different default port, " \ + "define it here\n" \ + " -l LOGIN or -L FILE login with LOGIN name, or load " \ + "several logins from FILE\n" \ + " -p PASS or -P FILE try password PASS, or load several " \ + "passwords from FILE\n" \ + " -e ns additional checks, \"n\" for null password, \"s\" " \ + "try login as pass\n" \ + " -C FILE colon seperated \"login:pass\" format, instead of " \ + "-L/-P option\n" \ + " -M FILE file containing server list\n" \ + " -o FILE write found login/password pairs to FILE instead " \ + "of stdout\n" \ + " -f exit after the first found login/password pair\n" \ + " -X show username/password for login attempts\n" \ + " -m misc options for some modules\n" \ + " -t TASKS run TASKS number of connects in parallel " \ + "(default: %d)\n" \ + " -T SERVERS run SERVERS number of hosts in parallel " \ + "(default: %d)\n" \ + " -g TASKS start TASKS number per second until -t TASKS are" \ + "reached\n" \ + " -w TIME in seconds, defines the max wait reply time " \ + "(default: %d)\n" \ + " server the target server\n" \ + " service the service to crack. Supported protocols: [%s]\n" \ + " OPT some service modules need additional input, put " \ + "it here\n" \ + "\n%s is a tool to guess valid login/password pairs on a "\ + "target server.\nYou can always find the newest version at %s\n" \ + "Use this tool only for legal purposes!\n", \ + TASKS,SERVERS,WAITTIME,SERVICES,PROGRAM,RESSOURCE); + exit(-1); } void bail(char *text) { - fprintf(stderr, "Error: %s\n", text); - exit(-1); + fprintf(stderr, "Error: %s\n", text); + exit(-1); } void killed_childs(int signo) { - killed++; - (void) wait3(NULL, WNOHANG, NULL); + killed++; + (void) wait3(NULL, WNOHANG, NULL); } void kill_children(int signo) { - int i; - for (i = 0; i < MAXTASKS; i++) - if (pids[i] > 0) - kill(pids[i], SIGTERM); - sleep(1); - if (pids[i] > 0) - kill(pids[i], SIGKILL); - exit(0); + int i; + for (i = 0; i < MAXSERVERS; i++) + if (addr_pids[i] > 0) + kill(addr_pids[i], SIGTERM); + sleep(1); + if (addr_pids[i] > 0) + kill(addr_pids[i], SIGKILL); + exit(0); } unsigned long int countlines(FILE *fp) { - size_t lines = 0, size = 0; - char *buf = malloc(MAXBUF); - while (!feof(fp)) { - if (fgets(buf, MAXBUF, fp) != NULL) { - if (buf[0] != 0) { - size += strlen(buf); - lines++; - } - } - } - rewind(fp); - size++; - extra = size; - return lines; + size_t lines = 0, size = 0; + char *buf = malloc(MAXBUF); + while (!feof(fp)) { + if (fgets(buf, MAXBUF, fp) != NULL) { + if (buf[0] != 0) { + size += strlen(buf); + lines++; + } + } + } + rewind(fp); + size++; + extra = size; + return lines; } void fill_mem(char *ptr, FILE *fp) { - char tmp[MAXBUF + 4] = ""; - while (! feof(fp)) { - if (fgets(tmp, MAXBUF, fp) != NULL) { - if (tmp[0] != 0) { - if (tmp[strlen(tmp)-1] == '\n') - tmp[strlen(tmp)-1] = '\0'; - if (tmp[strlen(tmp)-1] == '\r') - tmp[strlen(tmp)-1] = '\0'; - memcpy(ptr, tmp, strlen(tmp)); - ptr += strlen(tmp); - *ptr = '\0'; - ptr++; - } - } + char tmp[MAXBUF + 4] = ""; + while (! feof(fp)) { + if (fgets(tmp, MAXBUF, fp) != NULL) { + if (tmp[0] != 0) { + if (tmp[strlen(tmp)-1] == '\n') + tmp[strlen(tmp)-1] = '\0'; + if (tmp[strlen(tmp)-1] == '\r') + tmp[strlen(tmp)-1] = '\0'; + memcpy(ptr, tmp, strlen(tmp)); + ptr += strlen(tmp); + *ptr = '\0'; + ptr++; + } } - fclose(fp); + } + fclose(fp); } @@ -158,519 +169,674 @@ #else int hydra_main(int soc, void *nessus, int argc, char *argv[]) { #endif - unsigned int tasks = 1, exit_found = 0; - unsigned int ssl = 0, group = MAXTASKS + 1; - unsigned char options = 0; - int try_password_same_as_login = 0, try_null_password = 0; - char *login = NULL, *loginfile = NULL, *pass = NULL, *passfile = NULL; - char *colonfile = NULL, *outfile_ptr = NULL; - char *miscptr = NULL, *server, *service; - - char *login_ptr, *pass_ptr = "", *pass_ptr_save, *csv_ptr; - FILE *lfp, *pfp, *cfp, *ofp = stdout; - unsigned int socketpairs[MAXTASKS][2]; - size_t countlogin = 1, sizelogin = 0, countpass = 0, sizepass = 0; - unsigned long int math2, todo, sent = 0; - struct hostent *target; - unsigned long int ip; - struct in_addr in; - int i, j; -#ifdef NESSUS_PLUGIN - char * svc_kb_name; - char * asc_port; + unsigned int tasks = 1, servers = 1, exit_found = 0; + unsigned int ssl = 0, group = MAXTASKS + 1; + unsigned char options = 0; + int try_password_same_as_login = 0, try_null_password = 0; + char *login = NULL, *loginfile = NULL, *pass = NULL, *passfile = NULL; + char *colonfile = NULL, *outfile_ptr = NULL, *infile_ptr = NULL; + char *miscptr = NULL, *server, *service; + + char *login_ptr, *pass_ptr = "", *csv_ptr, *ipaddr_ptr; + FILE *lfp, *pfp, *cfp, *ifp, *ofp = stdout; + unsigned int addr_socketpairs[MAXSERVERS][2]; + size_t countlogin = 1, sizelogin = 0, countpass = 0, sizepass = 0; + size_t countinfile = 1, sizeinfile = 0; + unsigned long int math2, todo; + struct hostent *target; + unsigned long int ip; + struct in_addr in; + int i, j, sID; +#ifdef NESSUS_PLUGIN + char * svc_kb_name; + char * asc_port; #endif - - char empty_login[2] = ""; - prg = argv[0]; - debug = 0; - verbose = 0; - waittime = WAITTIME; - port = 0; - tasks = TASKS; - if (argc < 4) help(); - tmp = malloc(MAXBUF); - - while ((i = getopt(argc, argv, "de:vl:fg:L:p:P:o:C:t:m:w:s:S")) >= 0) { - switch (i) { - case 'd': debug = 1; verbose++; break; - case 'e': i = 0; - while (i < strlen(optarg)) { - switch(optarg[i]) { - case 'n': try_null_password = 1; break; - case 's': try_password_same_as_login = 1; break; - default: fprintf(stderr,"Error: unknown mode %c for option -e, only supporting \"n\" and \"s\"\n", optarg[i]); - exit(-1); - } - i++; - } - break; - case 'v': verbose = 1; break; - case 'l': login = optarg; break; - case 'L': loginfile = optarg; break; - case 'p': pass = optarg; break; - case 'P': passfile = optarg; break; - case 'f': exit_found = 1; break; - case 'g': group = atoi(optarg); break; - case 'o': outfile_ptr = optarg; break; - case 'C': colonfile = optarg; break; - case 't': tasks = atoi(optarg); break; - case 'm': miscptr = optarg; break; - case 'w': waittime = atoi(optarg); break; - case 's': port = atoi(optarg); break; - case 'S': + + char empty_login[2] = ""; + int showAttempt = 0; + prg = argv[0]; + debug = 0; + verbose = 0; + waittime = WAITTIME; + port = 0; + tasks = TASKS; + if (argc < 4) help(); + tmp = malloc(MAXBUF); + + while ((i = getopt(argc, argv, "de:vXl:fg:L:p:P:o:M:C:t:T:m:w:s:S")) >= 0) { + switch (i) { + case 'd': debug = 1; verbose++; break; + case 'e': i = 0; + while (i < strlen(optarg)) { + switch(optarg[i]) { + case 'n': try_null_password = 1; break; + case 's': try_password_same_as_login = 1; break; + default: fprintf(stderr,"Error: unknown mode %c for option -e, only supporting \"n\" and \"s\"\n", optarg[i]); + exit(-1); + } + i++; + } + break; + case 'v': verbose = 1; break; + case 'X': showAttempt = 1; break; + case 'l': login = optarg; break; + case 'L': loginfile = optarg; break; + case 'p': pass = optarg; break; + case 'P': passfile = optarg; break; + case 'f': exit_found = 1; break; + case 'g': group = atoi(optarg); break; + case 'o': outfile_ptr = optarg; break; + case 'M': infile_ptr = optarg; break; + case 'C': colonfile = optarg; break; + case 't': tasks = atoi(optarg); break; + case 'T': servers = atoi(optarg); break; + case 'm': miscptr = optarg; break; + case 'w': waittime = atoi(optarg); break; + case 's': port = atoi(optarg); break; + case 'S': #ifndef OPENSSL - fprintf(stderr, "Sorry, hydra was compiled without SSL support. Install openssl and recompile!\n"); - ssl = 0; break; + fprintf(stderr, "Sorry, hydra was compiled without SSL support. Install openssl and recompile!\n"); + ssl = 0; break; #else - ssl = 1; break; + ssl = 1; break; #endif - default: fprintf(stderr,"Error: unknown option -%c\n", i); help(); - } + default: fprintf(stderr,"Error: unknown option -%c\n", i); help(); } - if (optind + 2 != argc && optind + 3 != argc) help(); + } + + if (argv[optind +1] == NULL && infile_ptr != NULL) { + server = NULL; + service = argv[optind]; + if (optind + 2 == argc) miscptr = argv[optind + 1]; + } else if (optind + 2 != argc && optind + 3 != argc) { + server = NULL; + service = NULL; + help(); + } else { server = argv[optind]; service = argv[optind + 1]; if (optind + 3 == argc) miscptr = argv[optind + 2]; - - i = 0; - if (strcmp(service, "telnet") == 0) i = 1; - if (strcmp(service, "ftp") == 0) i = 1; - if (strcmp(service, "pop3") == 0) i = 1; - if (strcmp(service, "imap") == 0) i = 1; - if (strcmp(service, "rexec") == 0) i = 1; - if (strcmp(service, "nntp") == 0) i = 1; - if (strcmp(service, "socks5") == 0) i = 1; - if (strcmp(service, "icq") == 0) i = 1; - if (strcmp(service, "mysql") == 0) i = 1; + } + + i = 0; + if (strcmp(service, "telnet") == 0) i = 1; + if (strcmp(service, "ftp") == 0) i = 1; + if (strcmp(service, "pop3") == 0) i = 1; + if (strcmp(service, "imap") == 0) i = 1; + if (strcmp(service, "rexec") == 0) i = 1; + if (strcmp(service, "nntp") == 0) i = 1; + if (strcmp(service, "socks5") == 0) i = 1; + if (strcmp(service, "icq") == 0) i = 1; + if (strcmp(service, "mysql") == 0) i = 1; // ADD NEW SERVICES HERE - if (strcmp(service, "smb") == 0) { - if (tasks > 1) { - fprintf(stderr, "Reduced number of tasks to 1 (smb does not like parallel connections)\n"); - tasks = 1; - } - i = 1; - } - if (strcmp(service, "pcnfs") == 0) { - i = 1; - if (port == 0) { - fprintf(stderr, "Error: You must set the port for pcnfs with -s (run \"rpcinfo -p %s\" and look for the pcnfs v2 UDP port)\n", server); - exit(-1); - } - } - if (strcmp(service, "cisco") == 0) { - i = 2; - login = empty_login; - if (tasks > 4) - printf("Warning: you should set the number of parallel task to 4 for cisco services.\n"); - } - if (strcmp(service, "ldap") == 0) { - i = 1; - if ((miscptr != NULL && login != NULL) || (miscptr != NULL && loginfile != NULL) || (login != NULL && loginfile != NULL)) - bail("Error: you may only use one of -l, -L or -m (or none)\n"); - if (login == NULL && loginfile == NULL && miscptr == NULL) - fprintf(stderr, "Warning: no DN to authenticate to defined, using DN of null (use -m, -l or -L to define DNs)\n"); - if (login == NULL && loginfile == NULL) { - i = 2; - login = empty_login; - } - } - if (strcmp(service, "cisco-enable") == 0) { - i = 2; - login = empty_login; - if (miscptr == NULL) { - bail("Error: You must supply the inial password to logon via the -m option\n"); - } - if (tasks > 4) - printf("Warning: you should set the number of parallel task to 4 for cisco enable services.\n"); - } - if (strcmp(service, "vnc") == 0) { - i = 2; - login = empty_login; - if (tasks > 4) - printf("Warning: you should set the number of parallel task to 4 for vnc services.\n"); - } - if (strcmp(service, "www") == 0 || strcmp(service, "http") == 0) { - i = 1; - if (miscptr == NULL) bail("You must supply the web page as an additional option or via -m"); - if (*miscptr != '/') bail("The web page you supplied must start with a \"/\", e.g. \"/protected/login\""); - strcpy(service, "www"); - } + if (strcmp(service, "smb") == 0) { + if (tasks > 1) { + fprintf(stderr, "Reduced number of tasks to 1 (smb does not like parallel connections)\n"); + tasks = 1; + } + i = 1; + } + if (strcmp(service, "smbnt") == 0) { + if (tasks > 1) { + fprintf(stderr, "Reduced number of tasks to 1 (smb does not like parallel connections)\n"); + tasks = 1; + } + i = 1; + } + if (strcmp(service, "pcnfs") == 0) { + i = 1; + if (port == 0) { + fprintf(stderr, "Error: You must set the port for pcnfs with -s (run \"rpcinfo -p %s\" and look for the pcnfs v2 UDP port)\n", server); + exit(-1); + } + } + if (strcmp(service, "cisco") == 0) { + i = 2; + login = empty_login; + if (tasks > 4) + printf("Warning: you should set the number of parallel task to 4 for cisco services.\n"); + } + if (strcmp(service, "ldap") == 0) { + i = 1; + if ((miscptr != NULL && login != NULL) || (miscptr != NULL && loginfile != NULL) || (login != NULL && loginfile != NULL)) + bail("Error: you may only use one of -l, -L or -m (or none)\n"); + if (login == NULL && loginfile == NULL && miscptr == NULL) + fprintf(stderr, "Warning: no DN to authenticate to defined, using DN of null (use -m, -l or -L to define DNs)\n"); + if (login == NULL && loginfile == NULL) { + i = 2; + login = empty_login; + } + } + if (strcmp(service, "cisco-enable") == 0) { + i = 2; + login = empty_login; + if (miscptr == NULL) { + bail("Error: You must supply the inial password to logon via the -m option\n"); + } + if (tasks > 4) + printf("Warning: you should set the number of parallel task to 4 for cisco enable services.\n"); + } + if (strcmp(service, "vnc") == 0) { + i = 2; + login = empty_login; + if (tasks > 4) + printf("Warning: you should set the number of parallel task to 4 for vnc services.\n"); + } + if (strcmp(service, "www") == 0 || strcmp(service, "http") == 0) { + i = 1; + if (miscptr == NULL) bail("You must supply the web page as an additional option or via -m"); + if (*miscptr != '/') bail("The web page you supplied must start with a \"/\", e.g. \"/protected/login\""); + strcpy(service, "www"); + } #ifdef OPENSSL - if (strcmp(service, "ssl") == 0 || strcmp(service, "https") == 0) { - i = 1; - if (miscptr == NULL) bail("You must supply the web page as an additional option or via -m"); - if (*miscptr != '/') bail("The web page you supplied must start with a \"/\", e.g. \"/protected/login\""); - ssl = 1; - strcpy(service, "www"); - } + if (strcmp(service, "ssl") == 0 || strcmp(service, "https") == 0) { + i = 1; + if (miscptr == NULL) bail("You must supply the web page as an additional option or via -m"); + if (*miscptr != '/') bail("The web page you supplied must start with a \"/\", e.g. \"/protected/login\""); + ssl = 1; + strcpy(service, "www"); + } #endif // ADD NEW SERVICES HERE - if (i == 0) bail("Unknown service"); + if (i == 0) bail("Unknown service"); - if (i == 2 && ((login != NULL && strlen(login) > 0) || loginfile != NULL || colonfile != NULL)) - bail("The cisco, cisco-enable and vnc crack modes are only using the -p or -P option, not login (-l, -L) or colon file (-C).\nUse the normal telnet crack mode for cisco using \"Username:\" authentication.\n"); - if (i == 1 && login == NULL && loginfile == NULL && colonfile == NULL) - bail("I need at least either the -l, -L or -C option to know the login"); - if (colonfile != NULL && ((login != NULL || loginfile != NULL) || (pass != NULL && passfile != NULL))) - bail("The -C option is standalone, dont use it with -l/L and -p/P !"); - if (try_password_same_as_login == 0 && try_null_password == 0 && pass == NULL && passfile == NULL && colonfile == NULL) - bail("I need at least the -e, -p or -P option to have some passwords!"); - if (tasks < 1 || tasks > MAXTASKS) { - fprintf(stderr, "Option -t needs to be a number between 1 and %d", MAXTASKS); - exit(-1); - } - - if (loginfile != NULL) { - if ((lfp = fopen(loginfile, "r")) == NULL) - bail("File for logins not found!"); - countlogin = countlines(lfp); - sizelogin = extra; - if (countlogin == 0) - bail("File for logins is empty!"); - login_ptr = malloc(sizelogin); - fill_mem(login_ptr, lfp); - } else - login_ptr = login; - if (passfile != NULL) { - if ((pfp = fopen(passfile, "r")) == NULL) - bail("File for passwords not found!"); - countpass = countlines(pfp); - sizepass = extra; - if (countpass == 0) - bail("File for passwords is empty!"); - pass_ptr = malloc(sizepass); - fill_mem(pass_ptr, pfp); - } else { - if (pass != NULL) { - pass_ptr = pass; - countpass = 1; - } - } - if (colonfile != NULL) { - if (try_password_same_as_login + try_null_password > 0) - bail("Error: the -C option may not be used together with the -e option\n"); - if ((cfp = fopen(colonfile, "r")) == NULL) - bail("File with login:password information not found!"); - countlogin = countlines(cfp); - sizelogin = extra; - if (countlogin == 0) - bail("File for login:password information is empty!"); - csv_ptr = malloc(sizelogin); - fill_mem(csv_ptr, cfp); - countpass = 1; - pass_ptr = login_ptr = csv_ptr; - while(*pass_ptr != '\0' && *pass_ptr != ':') pass_ptr++; - if (*pass_ptr == ':') { - *pass_ptr = '\0'; - pass_ptr++; - } else { - fprintf(stderr, "Invalid line in colonfile: %s\n", login_ptr); - pass_ptr = HYDRA_EXIT; - } - } + if (i == 2 && ((login != NULL && strlen(login) > 0) || loginfile != NULL || colonfile != NULL)) + bail("The cisco, cisco-enable and vnc crack modes are only using the -p or -P option, not login (-l, -L) or colon file (-C).\nUse the normal telnet crack mode for cisco using \"Username:\" authentication.\n"); + if (i == 1 && login == NULL && loginfile == NULL && colonfile == NULL) + bail("I need at least either the -l, -L or -C option to know the login"); + if (colonfile != NULL && ((login != NULL || loginfile != NULL) || (pass != NULL && passfile != NULL))) + bail("The -C option is standalone, dont use it with -l/L and -p/P !"); + if (try_password_same_as_login == 0 && try_null_password == 0 && pass == NULL && passfile == NULL && colonfile == NULL) + bail("I need at least the -e, -p or -P option to have some passwords!"); + if (tasks < 1 || tasks > MAXTASKS) { + fprintf(stderr, "Option -t needs to be a number between 1 and %d", MAXTASKS); + exit(-1); + } - countpass += try_password_same_as_login + try_null_password; - math2 = countlogin * countpass; - if (math2 < tasks) { - tasks = math2; - fprintf(stderr, "Warning: More tasks defined than login/pass pairs exist. Tasks reduced to %d.\n",tasks); - } - todo = math2; - - // set options (bits!) - options = 0; - if (ssl) - options = options | OPTION_SSL; - - printf("%s %s (c) 2003 by %s - use allowed only for legal purposes.\n", PROGRAM, VERSION, AUTHOR); - printf("%s is starting! [parallel tasks: %d, login tries: %lu (l:%d/p:%d)]\n",PROGRAM,tasks,todo,countlogin,countpass); - - math2 = math2 / tasks; - if (verbose) - printf("Approx. login tries per task: %lu (%d tasks)\n",math2,tasks); - - /* resolve target */ - // if ((ip = inet_addr(server)) == -1) { //deprecated - if (inet_pton(AF_INET, server, &in) <= 0) { - if ((target = gethostbyname(server)) == NULL) { - perror(server); - exit(-1); - } - memcpy(&ip, target->h_addr, 4); + if (loginfile != NULL) { + if ((lfp = fopen(loginfile, "r")) == NULL) + bail("File for logins not found!"); + countlogin = countlines(lfp); + sizelogin = extra; + if (countlogin == 0) + bail("File for logins is empty!"); + login_ptr = malloc(sizelogin); + fill_mem(login_ptr, lfp); + } else + login_ptr = login; + if (passfile != NULL) { + if ((pfp = fopen(passfile, "r")) == NULL) + bail("File for passwords not found!"); + countpass = countlines(pfp); + sizepass = extra; + if (countpass == 0) + bail("File for passwords is empty!"); + pass_ptr = malloc(sizepass); + fill_mem(pass_ptr, pfp); + } else { + if (pass != NULL) { + pass_ptr = pass; + countpass = 1; + } + } + if (colonfile != NULL) { + if (try_password_same_as_login + try_null_password > 0) + bail("Error: the -C option may not be used together with the -e option\n"); + if ((cfp = fopen(colonfile, "r")) == NULL) + bail("File with login:password information not found!"); + countlogin = countlines(cfp); + sizelogin = extra; + if (countlogin == 0) + bail("File for login:password information is empty!"); + csv_ptr = malloc(sizelogin); + fill_mem(csv_ptr, cfp); + countpass = 1; + pass_ptr = login_ptr = csv_ptr; + while(*pass_ptr != '\0' && *pass_ptr != ':') pass_ptr++; + if (*pass_ptr == ':') { + *pass_ptr = '\0'; + pass_ptr++; } else { - memcpy(&ip, &in.s_addr, 4); + fprintf(stderr, "Invalid line in colonfile: %s\n", login_ptr); + pass_ptr = HYDRA_EXIT; } + } - if (outfile_ptr != NULL) { - char datetime[24]; - struct tm *the_time; - time_t epoch; - if ((ofp = fopen(outfile_ptr, "a+")) == NULL) { - bail("Error creating outputfile"); - } - time(&epoch); - the_time = localtime(&epoch); - strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", the_time); - fprintf(ofp, "# %s %s run at %s on %s %s ( ", PROGRAM, VERSION, datetime, server, service); - if (login != NULL) fprintf(ofp, "-l %s ", login); - if (pass != NULL) fprintf(ofp, "-p %s ", pass); - if (colonfile != NULL) fprintf(ofp, "-C %s ", colonfile); - if (loginfile != NULL) fprintf(ofp, "-L %s ", loginfile); - if (passfile != NULL) fprintf(ofp, "-P %s ", passfile); - if (try_password_same_as_login) fprintf(ofp, "-e s "); - if (try_null_password) fprintf(ofp, "-e n "); - fprintf(ofp, ")\n"); - } - - /* we have to flush all writeable buffered file pointers before forking */ - fflush(stdout); - fflush(stderr); - fflush(ofp); - -#ifdef NESSUS_PLUGIN - svc_kb_name = malloc(40 + strlen(service)); - if(strcmp(service, "http") == 0) - strcpy(svc_kb_name, "Services/www"); - else - sprintf(svc_kb_name, "Services/%s", service); - asc_port = plug_get_key(nessus, svc_kb_name); - if (asc_port)port = atoi(asc_port); - free(svc_kb_name); - if(port && host_get_port_state(nessus, port) == 0) - return 0; - if (port && IS_ENCAPS_SSL(plug_get_port_transport(nessus, port))) + countpass += try_password_same_as_login + try_null_password; + math2 = countlogin * countpass; + if (math2 < tasks) { + tasks = math2; + fprintf(stderr, "Warning: More tasks defined than login/pass pairs exist. Tasks reduced to %d.\n",tasks); + } + todo = math2; + + // set options (bits!) + options = 0; + if (ssl) + options = options | OPTION_SSL; + + printf("%s %s (c) 2003 by %s - use allowed only for legal purposes.\n", PROGRAM, VERSION, AUTHOR); + printf("%s is starting! [parallel tasks: %d, login tries: %lu (l:%d/p:%d)]\n",PROGRAM,tasks,todo,countlogin,countpass); + + math2 = math2 / tasks; + if (verbose) + printf("Approx. login tries per task: %lu (%d tasks)\n",math2,tasks); + + if (outfile_ptr != NULL) { + char datetime[24]; + struct tm *the_time; + time_t epoch; + if ((ofp = fopen(outfile_ptr, "a+")) == NULL) { + bail("Error creating outputfile"); + } + time(&epoch); + the_time = localtime(&epoch); + strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", the_time); + fprintf(ofp, "# %s %s run at %s on %s %s ( ", PROGRAM, VERSION, datetime, server, service); + if (login != NULL) fprintf(ofp, "-l %s ", login); + if (pass != NULL) fprintf(ofp, "-p %s ", pass); + if (colonfile != NULL) fprintf(ofp, "-C %s ", colonfile); + if (loginfile != NULL) fprintf(ofp, "-L %s ", loginfile); + if (passfile != NULL) fprintf(ofp, "-P %s ", passfile); + if (try_password_same_as_login) fprintf(ofp, "-e s "); + if (try_null_password) fprintf(ofp, "-e n "); + fprintf(ofp, ")\n"); + } + + if (infile_ptr != NULL) { + if ((ifp = fopen(infile_ptr, "r")) == NULL) + bail("File for IP Addresses not found!"); + countinfile = countlines(ifp); + sizeinfile = extra; + if (countinfile == 0) + bail("File for IP Addresses is empty!"); + ipaddr_ptr = malloc(sizeinfile); + fill_mem(ipaddr_ptr, ifp); + } else + ipaddr_ptr = server; + + /* we have to flush all writeable buffered file pointers before forking */ + fflush(stdout); + fflush(stderr); + fflush(ofp); + +#ifdef NESSUS_PLUGIN + svc_kb_name = malloc(40 + strlen(service)); + if(strcmp(service, "http") == 0) + strcpy(svc_kb_name, "Services/www"); + else + sprintf(svc_kb_name, "Services/%s", service); + asc_port = plug_get_key(nessus, svc_kb_name); + if (asc_port)port = atoi(asc_port); + free(svc_kb_name); + if(port && host_get_port_state(nessus, port) == 0) + return 0; + if (port && IS_ENCAPS_SSL(plug_get_port_transport(nessus, port))) options |= OPTION_SSL; - if (soc >= 0) - ofp = fdopen(soc, "r+"); + if (soc >= 0) + ofp = fdopen(soc, "r+"); #endif - /* fork attack processes */ - signal(SIGCHLD, killed_childs); - signal(SIGTERM, kill_children); - signal(SIGSEGV, kill_children); - signal(SIGHUP, kill_children); - for(i = 0; i < tasks; i++) { - if (socketpair(PF_UNIX, SOCK_STREAM, 0, socketpairs[i]) != 0) { - perror("socketpair failed"); - socketpairs[i][0] = -1; - } else { - if ((pids[i] = fork()) == 0) { - signal(SIGTERM, exit); - signal(SIGHUP, exit); - if (strcmp(service, "telnet") == 0) service_telnet(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "ftp") == 0) service_ftp(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "pop3") == 0) service_pop3(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "imap") == 0) service_imap(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "ldap") == 0) service_ldap(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "www") == 0) service_http(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "cisco") == 0) service_cisco(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "cisco-enable") == 0) service_cisco_enable(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "socks5") == 0) service_socks5(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "vnc") == 0) service_vnc(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "rexec") == 0) service_rexec(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "nntp") == 0) service_nntp(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "icq") == 0) service_icq(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "pcnfs") == 0) service_pcnfs(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "smb") == 0) service_smb(ip, socketpairs[i][1], options, miscptr, ofp, port); - if (strcmp(service, "mysql") == 0) service_mysql(ip, socketpairs[i][1], options, miscptr, ofp, port); -// ADD NEW SERVICES HERE - return 0; - } - if (pids[i] > 0) { - write(socketpairs[i][1], "N", 1); - fcntl(socketpairs[i][0], F_SETFL, O_NONBLOCK); - } else { - perror("Fork for children failed"); + /* fork attack processes */ + signal(SIGCHLD, killed_childs); + signal(SIGTERM, kill_children); + signal(SIGSEGV, kill_children); + signal(SIGHUP, kill_children); + if (servers > countinfile) + servers = countinfile; + for (sID = 0; sID < servers; sID++) { // PARALLEL HOSTS THREADS + if (socketpair(PF_UNIX, SOCK_STREAM, 0, addr_socketpairs[sID]) != 0) { + perror("socketpair failed"); + addr_socketpairs[sID][1] = -1; + } + if ((addr_pids[sID] = fork()) == 0) { + close(addr_socketpairs[sID][1]); + char rc; + unsigned int socketpairs[MAXTASKS][2]; + unsigned long int sent; + unsigned long int t_ip; + char t_ipaddr_str[INET_ADDRSTRLEN]; + char *t_login_ptr; + char *t_pass_ptr; + char *t_pass_ptr_save; + int gkilled = 0; + + void killed_gchilds(int signo) { + gkilled++; + (void) wait3(NULL, WNOHANG, NULL); + } + + void kill_gchildren(int signo) { + int i; + for (i = 0; i < MAXTASKS; i++) + if (pids[i] > 0) + kill(pids[i], SIGTERM); + sleep(1); + if (pids[i] > 0) + kill(pids[i], SIGKILL); + exit(0); + } + + signal(SIGCHLD, killed_gchilds); + signal(SIGTERM, kill_gchildren); + signal(SIGSEGV, kill_gchildren); + signal(SIGHUP, kill_gchildren); + + while (1) { // Wait for Address + wait_addr: + if (read(addr_socketpairs[sID][0], &rc, 1) > 0) { + if (rc == 'N') { + write(addr_socketpairs[sID][0], "N", 1); + sleep(1); + } else if (rc == 'Q') { + exit(0); + } else if (rc == 'Y') { + read(addr_socketpairs[sID][0], &t_ip, sizeof(t_ip)); + inet_ntop(AF_INET, &t_ip, t_ipaddr_str, sizeof(t_ipaddr_str)); + + t_login_ptr = login_ptr; + t_pass_ptr = pass_ptr; + sent = 0; + gkilled = 0; + + for(i = 0; i < tasks; i++) { // PARALLEL LOGIN THREADS + if (socketpair(PF_UNIX, SOCK_STREAM, 0, socketpairs[i]) != 0) { + perror("socketpair failed"); socketpairs[i][0] = -1; + } else { + if ((pids[i] = fork()) == 0) { + signal(SIGTERM, exit); + signal(SIGHUP, exit); + if (strcmp(service, "telnet") == 0) service_telnet(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "ftp") == 0) service_ftp(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "pop3") == 0) service_pop3(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "imap") == 0) service_imap(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "ldap") == 0) service_ldap(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "www") == 0) service_http(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "cisco") == 0) service_cisco(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "cisco-enable") == 0) service_cisco_enable(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "socks5") == 0) service_socks5(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "vnc") == 0) service_vnc(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "rexec") == 0) service_rexec(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "nntp") == 0) service_nntp(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "icq") == 0) service_icq(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "pcnfs") == 0) service_pcnfs(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "smb") == 0) service_smb(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "smbnt") == 0) service_smbnt(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + if (strcmp(service, "mysql") == 0) service_mysql(t_ip, socketpairs[i][1], options, miscptr, ofp, port); + // ADD NEW SERVICES HERE + return 0; + } + if (pids[i] > 0) { + write(socketpairs[i][1], "N", 1); + fcntl(socketpairs[i][0], F_SETFL, O_NONBLOCK); + } else { + perror("Fork for children failed"); + socketpairs[i][0] = -1; + } + } + if ((((i+1) % group) == 0) && ((i+1) != tasks)) sleep(1); } - } - if ((((i+1) % group) == 0) && ((i+1) != tasks)) sleep(1); - } - /* feed the children with login/pass data - be a good mom */ - { - int a, b, c, done, length; - char sb[MAXBUF], rc; - pass_ptr_save = pass_ptr; - - for (a = 0; a < countlogin; a++) { - for (b = 0; b < countpass; b++) { - done = 0; - if ((char *) pass_ptr != (char *) &HYDRA_EXIT) { + /* feed the (grand)children with login/pass data - be a good mom */ + { + int a, b, c, done, length; + char sb[MAXBUF], rc; + t_pass_ptr_save = t_pass_ptr; + + for (a = 0; a < countlogin; a++) { + for (b = 0; b < countpass; b++) { + done = 0; + if ((char *) t_pass_ptr != (char *) &HYDRA_EXIT) { while(! done) { - i = 0; - for(c = 0; c < tasks; c++) { - if (! done && socketpairs[c][0] >= 0) { - if (read(socketpairs[c][0], &rc, 1) > 0) { - if (rc == 'F') { - char *cracked_login = malloc(MAXBUF); - if (exit_found) { - sleep(1); - for (i = 0; i < tasks; i++) - if (pids[i] > 0) - (void) kill(pids[i], SIGTERM); - sleep(1); - fclose(ofp); - printf("%s Finished.\n", PROGRAM); - exit(0); - } - memset(cracked_login, 0, MAXBUF); - read(socketpairs[c][0], cracked_login, MAXBUF); - if (colonfile == NULL) { - if (strcmp(cracked_login, login_ptr) == 0) { - a++; - if (a < countlogin) { - while (*login_ptr != '\0') login_ptr++; - login_ptr++; - pass_ptr = pass_ptr_save; - sent += countpass - b; - b = 0; - } else { - rc = 'X'; - b = countpass; - sent = todo; - done = 1; - } - if (verbose) - printf("The password for \"%s\" was found, skipping to next login (pairs already sent to childrens will still be tried)\n", cracked_login); - } - } - } - if (rc == 'N' || rc == 'F') { - done = 1; - sent++; - memset(&sb, 0, sizeof(sb)); - length = strlen(login_ptr) + 1; - strcpy(sb, login_ptr); - if (b < try_password_same_as_login + try_null_password) { - if (try_null_password && b == 0) { - length += 1; - } - if (try_password_same_as_login && ((b == 0 && try_null_password == 0) || (b == 1 && try_null_password))) { - strcpy(sb + length, login_ptr); - length += strlen(login_ptr) + 1; - } - } else { - while (((try_password_same_as_login && strcmp(pass_ptr, login_ptr) == 0) - || - (try_null_password && strlen(pass_ptr) == 0)) && b < countpass) { - if (verbose) - printf("Detected double with -e n|s option, skipping double password try. %s <-> %s\n", login_ptr, pass_ptr); - pass_ptr += strlen(pass_ptr) + 1; - b++; - sent++; - } - if (b == countpass) { - strcpy(sb + length, "THChydra"); - length += 9; - b = countpass - 1; - if (sent > todo) - sent = todo; - } else { - strcpy(sb + length, pass_ptr); - length += strlen(pass_ptr) + 1; - } - } - if (verbose) - printf("New pair: login \"%s\" - pass \"%s\" \t(%lu of %lu completed)\n", sb, sb + strlen(sb) + 1, sent, todo); - write(socketpairs[c][0], sb, length); - if (debug) printf("Pair sent to process %d\n", pids[c]); - } else { - if (debug) printf("Process %d reported it quit\n",pids[c]); - socketpairs[c][0] = -1; - pids[c] = 0; - i++; - (void) wait3(NULL, WNOHANG, NULL); - } + i = 0; + for(c = 0; c < tasks; c++) { + if (! done && socketpairs[c][0] >= 0) { + if (read(socketpairs[c][0], &rc, 1) > 0) { + if (rc == 'F') { + char *cracked_login = malloc(MAXBUF); + if (exit_found) { + sleep(1); + for (i = 0; i < tasks; i++) + if (pids[i] > 0) + (void) kill(pids[i], SIGTERM); + printf("%s Finished scan for %s\n", PROGRAM, t_ipaddr_str); + write(addr_socketpairs[sID][0], "Q", 1); + goto wait_addr; + } + memset(cracked_login, 0, MAXBUF); + read(socketpairs[c][0], cracked_login, MAXBUF); + if (colonfile == NULL) { + if (strcmp(cracked_login, t_login_ptr) == 0) { + a++; + if (a < countlogin) { + while (*t_login_ptr != '\0') t_login_ptr++; + t_login_ptr++; + t_pass_ptr = t_pass_ptr_save; + sent += countpass - b; + b = 0; + } else { + rc = 'X'; + b = countpass; + sent = todo; + done = 1; + } + if (verbose) + printf("The password for \"%s\" was found, skipping to next login (pairs already sent to childrens will still be tried)\n", cracked_login); + } + } + } + if (rc == 'N' || rc == 'F') { + done = 1; + sent++; + + if ((verbose) || (showAttempt)) { + if (b < try_null_password + try_password_same_as_login) { + if (try_null_password && b == 0) + printf("New pair: host: \"%s\"\t login \"%s\" - pass \"\" \t(%lu of %lu completed)\n", t_ipaddr_str, t_login_ptr, sent, todo); + if (try_password_same_as_login && ((b == 0 && try_null_password == 0) || (b == 1 && try_null_password))) + printf("New pair: host: \"%s\"\t login \"%s\" - pass \"%s\" \t(%lu of %lu completed)\n", t_ipaddr_str, t_login_ptr, t_login_ptr, sent, todo); + } else + printf("New pair: host: \"%s\"\t login \"%s\" - pass \"%s\" \t(%lu of %lu completed)\n", t_ipaddr_str, t_login_ptr, t_pass_ptr, sent, todo); + } + + memset(&sb, 0, sizeof(sb)); + length = strlen(t_login_ptr) + 1; + strcpy(sb, t_login_ptr); + if (b < try_password_same_as_login + try_null_password) { + if (try_null_password && b == 0) { + length += 1; + } + if (try_password_same_as_login && ((b == 0 && try_null_password == 0) || (b == 1 && try_null_password))) { + strcpy(sb + length, t_login_ptr); + length += strlen(t_login_ptr) + 1; } - } else i++; - } - if (i >= tasks || killed >= tasks) { - printf("All childrens are dead.\n"); - exit(-1); - } + } else { + while (((try_password_same_as_login && strcmp(t_pass_ptr, t_login_ptr) == 0) + || (try_null_password && strlen(t_pass_ptr) == 0)) && b < countpass) { + if (verbose) + printf("Detected double with -e n|s option, skipping double password try. %s <-> %s\n", t_login_ptr, t_pass_ptr); + t_pass_ptr += strlen(t_pass_ptr) + 1; + b++; + sent++; + } + if (b == countpass) { + strcpy(sb + length, "THChydra"); + length += 9; + b = countpass - 1; + if (sent > todo) + sent = todo; + } else { + strcpy(sb + length, t_pass_ptr); + length += strlen(t_pass_ptr) + 1; + } + } + if (verbose) + printf("New pair: login \"%s\" - pass \"%s\" \t(%lu of %lu completed)\n", sb, sb + strlen(sb) + 1, sent, todo); + write(socketpairs[c][0], sb, length); + if (debug) printf("Pair sent to process %d\n", pids[c]); + } else { + if (debug) printf("Process %d reported it quit\n",pids[c]); + socketpairs[c][0] = -1; + pids[c] = 0; + i++; + (void) wait3(NULL, WNOHANG, NULL); + } + } + } else i++; + } + if (i >= tasks || killed >= tasks) { + printf("All childrens are dead.\n"); + fprintf(stderr, "Server (%s) scan complete\n", t_ipaddr_str); + write(addr_socketpairs[sID][0], "Q", 1); + goto wait_addr; + } } + } + if (b < countpass && b >= try_password_same_as_login + try_null_password) { + while(*t_pass_ptr != '\0') t_pass_ptr++; + t_pass_ptr++; + } } - if (b < countpass && b >= try_password_same_as_login + try_null_password) { - while(*pass_ptr != '\0') pass_ptr++; - pass_ptr++; - } - } - if (a < countlogin) { - while(*login_ptr != '\0') login_ptr++; - login_ptr++; - } - if (colonfile == NULL) { - pass_ptr = pass_ptr_save; - } else { - if ((char *) pass_ptr != (char *) &HYDRA_EXIT) { - while(*login_ptr != '\0') login_ptr++; - login_ptr++; + if (a < countlogin) { + while(*t_login_ptr != '\0') t_login_ptr++; + t_login_ptr++; } - pass_ptr = login_ptr; - while(*pass_ptr != '\0' && *pass_ptr != ':') pass_ptr++; - if (*pass_ptr == ':') { - *pass_ptr = '\0'; - pass_ptr++; + if (colonfile == NULL) { + t_pass_ptr = t_pass_ptr_save; } else { - if (strlen(login_ptr) > 0) fprintf(stderr, "Invalid line in colonfile: %s\n", login_ptr); - pass_ptr = HYDRA_EXIT; + if ((char *) t_pass_ptr != (char *) &HYDRA_EXIT) { + while(*t_login_ptr != '\0') t_login_ptr++; + t_login_ptr++; + } + t_pass_ptr = t_login_ptr; + while(*t_pass_ptr != '\0' && *t_pass_ptr != ':') t_pass_ptr++; + if (*t_pass_ptr == ':') { + *t_pass_ptr = '\0'; + t_pass_ptr++; + } else { + if (strlen(t_login_ptr) > 0) fprintf(stderr, "Invalid line in colonfile: %s\n", t_login_ptr); + t_pass_ptr = HYDRA_EXIT; + } } - } - } + } - i = 0; - j = 0; - (void) wait3(NULL, WNOHANG, NULL); - if (verbose) printf("Waiting for children to finnish their jobs ...\n"); - while(i < tasks && j < 5) { - i = 0; - for(c = 0; c < tasks; c++) { - if (socketpairs[c][0] >= 0) { + i = 0; + j = 0; + (void) wait3(NULL, WNOHANG, NULL); + if (verbose) printf("Waiting for children to finnish their jobs ...\n"); + while(i < tasks && j < 5) { + i = 0; + for(c = 0; c < tasks; c++) { + if (socketpairs[c][0] >= 0) { if (read(socketpairs[c][0], &rc, 1) > 0 || j == 4) { - i++; - (void) write(socketpairs[c][0], HYDRA_EXIT, sizeof(HYDRA_EXIT)); - socketpairs[c][0] = -1; + i++; + (void) write(socketpairs[c][0], HYDRA_EXIT, sizeof(HYDRA_EXIT)); + socketpairs[c][0] = -1; } - } else i++; - } - if (i < tasks) { - j++; - sleep(1); + } else i++; + } + if (i < tasks) { + j++; + sleep(1); + } + } + + i = 0; + j = 1; + while (j > 0 && killed < tasks && i <= (WAITTIME + tasks + 6)) { + j = 0; + (void) wait3(NULL, WNOHANG, NULL); + for(c = 0; c < tasks; c++) { + if (pids[c] > 0) + if (kill(pids[c], 0) >= 0) + j++; + } + sleep(1); + i++; + if (debug) printf("tasks: %d still alive: %d killed: %d time: %d of %d\n", tasks, j, killed, i, WAITTIME + tasks + 6); + } } - } - i = 0; - j = 1; - while (j > 0 && killed < tasks && i <= (WAITTIME + tasks + 6)) { - j = 0; - (void) wait3(NULL, WNOHANG, NULL); - for(c = 0; c < tasks; c++) { - if (pids[c] > 0) - if (kill(pids[c], 0) >= 0) - j++; - } - sleep(1); - i++; - if (debug) printf("tasks: %d still alive: %d killed: %d time: %d of %d\n", tasks, j, killed, i, WAITTIME + tasks + 6); - } + for(i = 0; i < tasks; i++) + if (pids[i] > 0) + kill(pids[i], SIGTERM); + + fprintf(stderr, "Server (%s) scan complete\n", t_ipaddr_str); + write(addr_socketpairs[sID][0], "Q", 1); + goto wait_addr; + } + } + } // loop while waiting for an address + } // IP scanners fork + + close(addr_socketpairs[sID][0]); + if (addr_pids[sID] > 0) { + write(addr_socketpairs[sID][1], "N", 1); + fcntl(addr_socketpairs[sID][0], F_SETFL, O_NONBLOCK); + fcntl(addr_socketpairs[sID][1], F_SETFL, O_NONBLOCK); + } else { + perror("Fork for children failed"); + addr_socketpairs[sID][0] = -1; } + } - for(i = 0; i < tasks; i++) - if (pids[i] > 0) - kill(pids[i], SIGTERM); + /* feed the children with ip address data - be a good mom */ + int a = 0, scans = 0, done = 0; + char rc; + while (done < countinfile) { + for (a=0; a < servers; a++) { + if (read(addr_socketpairs[a][1], &rc, 1) > 0) { + read(addr_socketpairs[a][1], &rc, 1); + if (rc == 'N') { + scans++; + + /* resolve target */ + if (inet_pton(AF_INET, ipaddr_ptr, &in) <= 0) { + if ((target = gethostbyname(ipaddr_ptr)) != NULL) + memcpy(&ip, target->h_addr, 4); + } else { + memcpy(&ip, &in.s_addr, 4); + } + + if ((target = gethostbyname(ipaddr_ptr)) == NULL) { + done++; + fprintf(stderr, "Error: invalid server address: %s\n", ipaddr_ptr); + write(addr_socketpairs[a][1], "N", 1); + } else { + write(addr_socketpairs[a][1], "Y", 1); + write(addr_socketpairs[a][1], &ip, sizeof(ip)); + } + + if (scans < countinfile) { + while (*ipaddr_ptr != '\0') ipaddr_ptr++; + ipaddr_ptr++; + } + } else if (rc == 'Q') { + done++; + /* scan finished. should proc start another? */ + if (scans < countinfile) + write(addr_socketpairs[a][1], "N", 1); + else { + write(addr_socketpairs[a][1], "Q", 1); + addr_pids[a] = 0; + } + } + } + } + } - /* yeah we did it */ - printf("%s finished.\n", PROGRAM); + /* yeah we did it */ + printf("%s finished.\n", PROGRAM); - fclose(ofp); + fclose(ofp); - return 0; + return 0; } #ifndef NESSUS_PLUGIN int main(int argc, char * argv[]) { - return hydra_main(-1, NULL, argc, argv); + return hydra_main(-1, NULL, argc, argv); } #endif diff -uN hydra-2.4/hydra-cisco.c hydra-2.4-m0j0/hydra-cisco.c --- hydra-2.4/hydra-cisco.c 2002-03-24 06:10:06.000000000 -0600 +++ hydra-2.4-m0j0/hydra-cisco.c 2003-10-14 14:28:56.000000000 -0500 @@ -3,121 +3,120 @@ extern char *HYDRA_EXIT; char *buf; -int start_cisco(int s, int port, unsigned char options,char *miscptr,FILE *fp) { - char *empty = ""; - char *pass, buffer[300]; - +int start_cisco(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { + char *empty = ""; + char *pass, buffer[300]; + + if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; + + // maybe \r\n or \r\000 needed instead of a single \n ? + sprintf(buffer, "%.250s\r\n", pass); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + buf = hydra_receive_line(s); + if (strstr(buf, "assw") != NULL) { + hydra_completed_pair(); + free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 3; if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; - -// maybe \r\n or \r\000 needed instead of a single \n ? sprintf(buffer, "%.250s\r\n", pass); if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; + return 1; } buf = hydra_receive_line(s); if (strstr(buf, "assw") != NULL) { - hydra_completed_pair(); - free(buf); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 3; - if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; - sprintf(buffer, "%.250s\r\n", pass); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - buf = hydra_receive_line(s); - if (strstr(buf, "assw") != NULL) { - hydra_completed_pair(); - free(buf); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 3; - if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; - sprintf(buffer, "%.250s\r\n", pass); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - buf = hydra_receive_line(s); - } - - } - - if (strstr(buf, "assw") != NULL || strstr(buf, "ad ") != NULL || strstr(buf, "attempt") != NULL || strstr(buf, "fail") != NULL) { - free(buf); - hydra_completed_pair(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 3; + hydra_completed_pair(); + free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 3; + if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; + sprintf(buffer, "%.250s\r\n", pass); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; + } + buf = hydra_receive_line(s); } + } - hydra_report_found(port, "cisco", fp); - hydra_completed_pair_found(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 3; + if (strstr(buf, "assw") != NULL || strstr(buf, "ad ") != NULL || strstr(buf, "attempt") != NULL || strstr(buf, "fail") != NULL) { free(buf); + hydra_completed_pair(); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 3; return 1; + } + + hydra_report_found_host(port, ip, "cisco", fp); + hydra_completed_pair_found(); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 3; + free(buf); + return 1; } void service_cisco(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port) { - int run = 1, failc = 0, retry = 1, next_run, sock = -1; - int myport = PORT_TELNET, mysslport = PORT_TELNET_SSL; + int run = 1, failc = 0, retry = 1, next_run, sock = -1; + int myport = PORT_TELNET, mysslport = PORT_TELNET_SSL; - hydra_register_socket(sp); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return; - while(1) { - next_run = 0; - switch(run) { - case 1: /* connect and service init function */ - { - unsigned char *buf2 = malloc(256); - int f = 0; - 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(); - } - do { - if (f != 0) free(buf2); else f = 1; - if ((buf2 = hydra_receive_line(sock)) == NULL) { - if (failc < retry) { - next_run = 1; - failc++; - fprintf(stderr, "Error: Child with pid %d was disconnected - retrying (%d of %d retries)\n", (int)getpid(), failc, retry); - sleep(3); - break; - } else { - fprintf(stderr, "Error: Child with pid %d was disconnected - exiting\n", (int)getpid()); - hydra_child_exit(); - } - } - } while ( strstr(buf2, "assw") == NULL); - free(buf2); - if (next_run != 0) break; - failc = 0; - next_run = 2; - break; - } - case 2: /* run the cracking function */ - next_run = start_cisco(sock, port, options, miscptr, fp); - break; - case 3: /* clean exit */ - if (sock >= 0) sock = hydra_disconnect(sock); - hydra_child_exit(); - return; - default: fprintf(stderr,"Caught unknown return code, exiting!\n"); - hydra_child_exit(); - exit(-1); + hydra_register_socket(sp); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return; + while(1) { + next_run = 0; + switch(run) { + case 1: /* connect and service init function */ + { + unsigned char *buf2 = malloc(256); + int f = 0; + 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(); } - run = next_run; + do { + if (f != 0) free(buf2); else f = 1; + if ((buf2 = hydra_receive_line(sock)) == NULL) { + if (failc < retry) { + next_run = 1; + failc++; + fprintf(stderr, "Error: Child with pid %d was disconnected - retrying (%d of %d retries)\n", (int)getpid(), failc, retry); + sleep(3); + break; + } else { + fprintf(stderr, "Error: Child with pid %d was disconnected - exiting\n", (int)getpid()); + hydra_child_exit(); + } + } + } while ( strstr(buf2, "assw") == NULL); + free(buf2); + if (next_run != 0) break; + failc = 0; + next_run = 2; + break; + } + case 2: /* run the cracking function */ + next_run = start_cisco(sock, ip, port, options, miscptr, fp); + break; + case 3: /* clean exit */ + if (sock >= 0) sock = hydra_disconnect(sock); + hydra_child_exit(); + return; + default: fprintf(stderr,"Caught unknown return code, exiting!\n"); + hydra_child_exit(); + exit(-1); } + run = next_run; + } } diff -uN hydra-2.4/hydra-cisco-enable.c hydra-2.4-m0j0/hydra-cisco-enable.c --- hydra-2.4/hydra-cisco-enable.c 2003-05-09 07:25:23.000000000 -0500 +++ hydra-2.4-m0j0/hydra-cisco-enable.c 2003-10-14 14:29:48.000000000 -0500 @@ -3,7 +3,7 @@ extern char *HYDRA_EXIT; char *buf; -int start_cisco_enable(int s,int port,unsigned char options,char *miscptr,FILE *fp) { +int start_cisco_enable(int s,unsigned long int ip,int port,unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *pass, buffer[300]; @@ -49,7 +49,7 @@ return 1; } - hydra_report_found(port, "cisco-enable", fp); + hydra_report_found_host(port, ip, "cisco-enable", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -133,7 +133,7 @@ break; } case 2: /* run the cracking function */ - next_run = start_cisco_enable(sock, port, options, miscptr, fp); + next_run = start_cisco_enable(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-ftp.c hydra-2.4-m0j0/hydra-ftp.c --- hydra-2.4/hydra-ftp.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-ftp.c 2003-10-14 14:31:46.000000000 -0500 @@ -3,7 +3,7 @@ extern char *HYDRA_EXIT; char *buf; -int start_ftp(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_ftp(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = "\"\""; char *login, *pass, buffer[300]; int i = 1; @@ -35,7 +35,7 @@ if (buf == NULL) return 1; if (buf[0] == '2') { - hydra_report_found(port, "ftp", fp); + hydra_report_found_host(port, ip, "ftp", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -95,7 +95,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_ftp(sock,port, options, miscptr, fp); + next_run = start_ftp(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-http.c hydra-2.4-m0j0/hydra-http.c --- hydra-2.4/hydra-http.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-http.c 2003-10-14 14:31:32.000000000 -0500 @@ -49,7 +49,7 @@ strcpy(buf, bof); } -int start_http(int s, int port, unsigned char options,char *miscptr,FILE *fp) { +int start_http(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login, *pass, buffer[300], buffer2[110]; char *header = ""; // XXX TODO: @@ -82,7 +82,7 @@ ptr = ((char*)index(buf, ' ')) + 1; if (*ptr == '2') { - hydra_report_found(port, "www", fp); + hydra_report_found_host(port, ip, "www", fp); hydra_completed_pair_found(); } else { if (*ptr != '4') @@ -129,7 +129,7 @@ break; } case 2: /* run the cracking function */ - next_run = start_http(sock, port, options, miscptr, fp); + next_run = start_http(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-icq.c hydra-2.4-m0j0/hydra-icq.c --- hydra-2.4/hydra-icq.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-icq.c 2003-10-14 14:32:25.000000000 -0500 @@ -130,7 +130,7 @@ return (hydra_send(s, buf, 10, 0)); } -int start_icq(int sock, int port, FILE *output, char *miscptr, FILE *fp) { +int start_icq(int sock, unsigned long int ip, int port, FILE *output, char *miscptr, FILE *fp) { unsigned char buf[1024]; char *login, *pass; char *empty=""; @@ -159,7 +159,7 @@ } if(buf[2] == 0x5a && buf[3] == 0x00) { - hydra_report_found(port, "icq", output); + hydra_report_found_host(port, ip, "icq", output); hydra_completed_pair_found(); icq_ack(sock, login); icq_login_1(sock, login); @@ -212,7 +212,7 @@ next_run = 2; break; case 2: - next_run = start_icq(sock, port, fp, miscptr, fp); + next_run = start_icq(sock, ip, port, fp, miscptr, fp); break; case 3: if(sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-imap.c hydra-2.4-m0j0/hydra-imap.c --- hydra-2.4/hydra-imap.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-imap.c 2003-10-14 14:33:49.000000000 -0500 @@ -5,7 +5,7 @@ char *buf; int counter; -int start_imap(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_imap(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login, *pass, buffer[300]; @@ -32,7 +32,7 @@ } free(buf); - hydra_report_found(port, "imap", fp); + hydra_report_found_host(port, ip, "imap", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -55,11 +55,11 @@ if ((options & OPTION_SSL) == 0) { if (port != 0) myport = port; sock = hydra_connect_tcp(ip, myport); - port = myport; + port = myport; } else { if (port != 0) mysslport = port; sock = hydra_connect_ssl(ip, mysslport); - port = mysslport; + port = mysslport; } if (sock < 0) { fprintf(stderr, "Error: Child with pid %d terminating, can not connect\n", (int)getpid()); @@ -76,7 +76,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_imap(sock, port, options, miscptr, fp); + next_run = start_imap(sock, ip, port, options, miscptr, fp); counter++; break; case 3: /* clean exit */ diff -uN hydra-2.4/hydra-ldap.c hydra-2.4-m0j0/hydra-ldap.c --- hydra-2.4/hydra-ldap.c 2003-05-09 07:25:23.000000000 -0500 +++ hydra-2.4-m0j0/hydra-ldap.c 2003-10-14 14:39:18.000000000 -0500 @@ -20,7 +20,7 @@ char *buf; int counter; -int start_ldap(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_ldap(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login = "", *pass, buffer[512]; int length; @@ -55,7 +55,7 @@ // success is: 0a 01 00 - failure is: 0a 01 31 if ((buf[0] != 0 && buf[9] == 0) || (buf[0] != 32 && buf[9] == 32)) { - hydra_report_found(port, "ldap", fp); + hydra_report_found_host(port, ip, "ldap", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -105,7 +105,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_ldap(sock, port, options, miscptr, fp); + next_run = start_ldap(sock, ip, port, options, miscptr, fp); counter++; break; case 3: /* clean exit */ diff -uN hydra-2.4/hydra-mod.c hydra-2.4-m0j0/hydra-mod.c --- hydra-2.4/hydra-mod.c 2003-08-14 10:39:53.000000000 -0500 +++ hydra-2.4-m0j0/hydra-mod.c 2003-10-14 15:08:33.000000000 -0500 @@ -15,6 +15,7 @@ int fail = 0; int alarm_went_off = 0; int use_ssl = 0; +char ipaddr_str[INET_ADDRSTRLEN]; #ifdef OPENSSL SSL *ssl = NULL; @@ -211,6 +212,11 @@ fprintf(fp, "[%d][%s] login: %s password: %s\n",port, svc, hydra_get_next_login(),hydra_get_next_password()); } +void hydra_report_found_host(int port, unsigned int ip, char * svc, FILE *fp) { + inet_ntop(AF_INET, &ip, ipaddr_str, sizeof(ipaddr_str)); + fprintf(fp, "[%d][%s] host: %s login: %s password: %s\n",port, svc, ipaddr_str, hydra_get_next_login(),hydra_get_next_password()); +} + int hydra_connect_ssl(unsigned long int host, int port) { #ifdef OPENSSL return (internal__hydra_connect_ssl(host, port, SOCK_STREAM, 6)); diff -uN hydra-2.4/hydra-mod.h hydra-2.4-m0j0/hydra-mod.h --- hydra-2.4/hydra-mod.h 2002-03-24 05:46:11.000000000 -0600 +++ hydra-2.4-m0j0/hydra-mod.h 2003-10-14 13:59:07.000000000 -0500 @@ -15,6 +15,7 @@ extern void hydra_completed_pair(); extern void hydra_completed_pair_found(); extern void hydra_report_found(int port, char * svc, FILE *fp); +extern void hydra_report_found_host(int port, unsigned int ip, char * svc, FILE *fp); extern int hydra_connect_ssl(unsigned long int host, int port); extern int hydra_connect_tcp(unsigned long int host, int port); extern int hydra_connect_udp(unsigned long int host, int port); diff -uN hydra-2.4/hydra-mysql.c hydra-2.4-m0j0/hydra-mysql.c --- hydra-2.4/hydra-mysql.c 2003-08-20 04:34:21.000000000 -0500 +++ hydra-2.4-m0j0/hydra-mysql.c 2003-10-14 14:41:01.000000000 -0500 @@ -137,7 +137,7 @@ return 0; } -int start_mysql(int sock, int port, unsigned char options, char* miscptr, FILE *fp) +int start_mysql(int sock, unsigned long int ip, int port, unsigned char options, char* miscptr, FILE *fp) { char *response = NULL, *login = NULL, *pass = NULL; unsigned long response_len; @@ -178,7 +178,7 @@ if(!res) { hydra_mysql_send_com_quit(sock); sock = hydra_disconnect(sock); - hydra_report_found(port, "mysql", fp); + hydra_report_found_host(port, ip, "mysql", fp); hydra_completed_pair_found(); free(response); if(memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) @@ -223,7 +223,7 @@ next_run = 2; break; case 2 : /* run the cracking function */ - next_run = start_mysql(sock, port, options, miscptr, fp); + next_run = start_mysql(sock, ip, port, options, miscptr, fp); break; case 3 : /* clean exit */ if (sock >= 0) { diff -uN hydra-2.4/hydra-nntp.c hydra-2.4-m0j0/hydra-nntp.c --- hydra-2.4/hydra-nntp.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-nntp.c 2003-10-14 14:41:42.000000000 -0500 @@ -3,7 +3,7 @@ extern char *HYDRA_EXIT; char *buf; -int start_nntp(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_nntp(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = "\"\""; char *login, *pass, buffer[300]; int i = 1; @@ -35,7 +35,7 @@ if (buf == NULL) return 1; if (buf[0] == '2') { - hydra_report_found(port, "nntp", fp); + hydra_report_found_host(port, ip, "nntp", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -95,7 +95,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_nntp(sock, port, options, miscptr, fp); + next_run = start_nntp(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-pcnfs.c hydra-2.4-m0j0/hydra-pcnfs.c --- hydra-2.4/hydra-pcnfs.c 2003-08-20 04:43:23.000000000 -0500 +++ hydra-2.4-m0j0/hydra-pcnfs.c 2003-10-14 14:42:30.000000000 -0500 @@ -33,7 +33,7 @@ // Lets start ... -int start_pcnfs(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_pcnfs(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login, *pass, buffer[LEN_HDR_RPC+LEN_AUTH_UNIX+LEN_HDR_PCN_AUTH]; char *ptr, *pkt = buffer; @@ -112,7 +112,7 @@ } if (buf[27] == 32 && buf[28] == 32 && buf[29] == 32 ) { - hydra_report_found(port, "pcnfs", fp); + hydra_report_found_host(port, ip, "pcnfs", fp); hydra_completed_pair_found(); free(buf); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) @@ -160,7 +160,7 @@ break; } case 2: /* run the cracking function */ - next_run = start_pcnfs(sock, port, options, miscptr, fp); + next_run = start_pcnfs(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-pop3.c hydra-2.4-m0j0/hydra-pop3.c --- hydra-2.4/hydra-pop3.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-pop3.c 2003-10-14 14:43:07.000000000 -0500 @@ -4,7 +4,7 @@ char *buf; -int start_pop3(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_pop3(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = "\"\""; char *login, *pass, buffer[300]; @@ -34,7 +34,7 @@ } if ((buf = hydra_receive_line(s)) == NULL) return(1); if (buf[0] == '+') { - hydra_report_found(port, "pop3", fp); + hydra_report_found_host(port, ip, "pop3", fp); hydra_completed_pair_found(); free(buf); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) @@ -85,7 +85,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_pop3(sock, port, options, miscptr, fp); + next_run = start_pop3(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-rexec.c hydra-2.4-m0j0/hydra-rexec.c --- hydra-2.4/hydra-rexec.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-rexec.c 2003-10-14 14:43:48.000000000 -0500 @@ -5,7 +5,7 @@ extern char *HYDRA_EXIT; char *buf; -int start_rexec(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_rexec(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login, *pass, buffer[300] = "", buffer2[100], *bptr = buffer2; int ret; @@ -31,7 +31,7 @@ ret = hydra_recv(s, buffer, sizeof(buffer)); if (ret > 0 && buffer[0] == 0) { - hydra_report_found(port, "rexec", fp); + hydra_report_found_host(port, ip, "rexec", fp); hydra_completed_pair_found(); } else hydra_completed_pair(); @@ -72,7 +72,7 @@ break; } case 2: /* run the cracking function */ - next_run = start_rexec(sock, port, options, miscptr, fp); + next_run = start_rexec(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-smb.c hydra-2.4-m0j0/hydra-smb.c --- hydra-2.4/hydra-smb.c 2003-05-09 07:25:23.000000000 -0500 +++ hydra-2.4-m0j0/hydra-smb.c 2003-10-14 14:45:38.000000000 -0500 @@ -85,8 +85,7 @@ return -1; /* failed */ } -int -smb_login(int s, char *login, char *password) { +int smb_login(int s, char *login, char *password) { int len = strlen(login) + strlen(password) + 57; int bcc = 2 + strlen(login) + strlen(password); int len_hi = len / 256, len_low = len % 256; @@ -132,7 +131,7 @@ return -1; } -int start_smb(int s, int port, unsigned char options, char *miscptr, FILE *fp) { +int start_smb(int s, unsigned long int ip, int port, unsigned char options, char *miscptr, FILE *fp) { char *empty = ""; char *login, *pass; @@ -140,7 +139,7 @@ if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; if(smb_login(s, login, pass) == 0) { - hydra_report_found(port, "smb", fp); + hydra_report_found_host(port, ip, "smb", fp); hydra_completed_pair_found(); free(buf); hydra_disconnect(s); @@ -191,7 +190,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_smb(sock, port, options, miscptr, fp); + next_run = start_smb(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-smbnt.c hydra-2.4-m0j0/hydra-smbnt.c --- hydra-2.4/hydra-smbnt.c 1969-12-31 18:00:00.000000000 -0600 +++ hydra-2.4-m0j0/hydra-smbnt.c 2003-10-14 14:24:28.000000000 -0500 @@ -0,0 +1,379 @@ +#include "hydra-mod.h" +#include "md4.h" +#include + +/* + SMB NTLM Password/HASH Checking Hydra Module + Copyright (C) m0j0.j0j0 + m0j0.j0j0 / m0j0@foofus.net + 09/30/2003 + + Based on code from: SMB Auditing Tool + [Copyright (C) Patrik Karlsson 2001] + + This code allows Hydra to directly test NTLM hashes against + a Windows host via '-m HASH'. This may be useful for an + auditor who has aquired a sam._ or pwdump file and would + like to quickly determine which are valid entries. This + module can also be used to test SMB passwords against devices + that do not allow clear text LanMan passwords. + + See http://www.foofus.net/m0j0/passhash.html for further + examples. + + Greets: Foofus, Phenfen & Fizzgig +*/ + +extern char *HYDRA_EXIT; +char challenge[8]; + +static u_char Get7Bits(u_char *input, int startBit) { + register unsigned int word; + + word = (unsigned)input[startBit / 8] << 8; + word |= (unsigned)input[startBit / 8 + 1]; + + word >>= 15 - (startBit % 8 + 7); + + return word & 0xFE; +} + +// Make the key +static void MakeKey(u_char *key, u_char *des_key) { + des_key[0] = Get7Bits(key, 0); + des_key[1] = Get7Bits(key, 7); + des_key[2] = Get7Bits(key, 14); + des_key[3] = Get7Bits(key, 21); + des_key[4] = Get7Bits(key, 28); + des_key[5] = Get7Bits(key, 35); + des_key[6] = Get7Bits(key, 42); + des_key[7] = Get7Bits(key, 49); + + des_set_odd_parity((des_cblock *)des_key); +} + +// Do the DesEncryption +void DesEncrypt(u_char *clear, u_char *key, u_char *cipher) { + des_cblock des_key; + des_key_schedule key_schedule; + + MakeKey(key, des_key); + des_set_key(&des_key, key_schedule); + des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); +} + +/* + HashNTLM + Function: Create a NTLM hash from the challenge + Variables: + ntlmhash = the hash created from this function + pass = users password + challenge = the challenge recieved from the server +*/ +void HashNTLM(u_char **ntlmhash, u_char *pass, u_char *challenge, char *miscptr) { + MD4_CTX md4Context; + u_char hash[16]; // MD4_SIGNATURE_SIZE = 16 + u_char unicodePassword[256 * 2]; // MAX_NT_PASSWORD = 256 + u_char p21[21]; + u_char ntlm_response[24]; + int i=0,j=0; + int mdlen = strlen(pass) * 2 * 8; + u_char *p; + + /* Use NTLM Hash instead of password */ + if ((miscptr != NULL) && (strcmp(miscptr, "HASH") == 0)) { + // 1000:D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: + p = pass; + while ((*p != '\0') && (i < 2)) { + if (*p == ':') i++; + p++; + } + + if (*p == '\0') { + fprintf(stderr, "Error reading PWDUMP file.\n"); + exit(1); + } + + char HexChar; + int HexValue; + for (i=0; i<16; i++) { + HexValue = 0x0; + for (j=0; j<2; j++) { + HexChar = (char)p[2*i+j]; + + if (HexChar > 0x39) + HexChar = HexChar | 0x20; /* convert upper case to lower */ + + if (!(((HexChar >= 0x30) && (HexChar <= 0x39))|| /* 0 - 9 */ + ((HexChar >= 0x61) && (HexChar <= 0x66)))) { /* a - f */ + //fprintf(stderr, "Error invalid char (%c) for hash.\n", HexChar); + //exit(1); + HexChar = 0x30; + } + + HexChar -= 0x30; + if (HexChar > 0x09) /* HexChar is "a" - "f" */ + HexChar -= 0x27; + + HexValue = (HexValue << 4) | (char)HexChar; + } + hash[i] = (u_char)HexValue; + } + } else { + /* Initialize the Unicode version of the secret (== password). */ + /* This implicitly supports 8-bit ISO8859/1 characters. */ + bzero(unicodePassword, sizeof(unicodePassword)); + for (i = 0; i < strlen(pass); i++) + unicodePassword[i * 2] = (u_char)pass[i]; + + MD4Init(&md4Context); + MD4Update(&md4Context, unicodePassword, mdlen); + MD4Final(hash, &md4Context); /* Tell MD4 we're done */ + } + + memset(p21, '\0', 21); + memcpy(p21, hash, 16); + + DesEncrypt(challenge, p21 + 0, ntlm_response + 0); + DesEncrypt(challenge, p21 + 7, ntlm_response + 8); + DesEncrypt(challenge, p21 + 14, ntlm_response + 16); + + memcpy(*ntlmhash, ntlm_response, 24); +} + +/* + NBS Session Request + Function: Request a new session from the server + Returns: TRUE on success else FALSE. +*/ +int NBSSessionRequest(int s) { + char nb_name[32]; // netbiosname + char nb_local[32]; // netbios localredirector + char rqbuf[7] = {0x81, 0x00, 0x00, 0x48, 0x20, 0x00, 0x20}; + char *buf; + u_char rbuf[400]; + + // convert computer name to netbios name + memset(nb_name, 0, 32); + memset(nb_local, 0, 32); + memcpy(nb_name, "CKFDENECFDEFFCFGEFFCCACACACACACA", 32); // *SMBSERVER + memcpy(nb_local, "EIFJEEFCEBCACACACACACACACACACACA", 32); // HYDRA + + buf = (char *) malloc(100); + memset(buf, 0, 100); + memcpy(buf, rqbuf, 5); + memcpy(buf+5, nb_name, 32); + memcpy(buf+37, rqbuf+5, 2); + memcpy(buf+39, nb_local, 32); + memcpy(buf+71, rqbuf+5, 1); + + hydra_send(s, buf, 72, 0); + free(buf); + + memset(rbuf, 0, 400); + hydra_recv(s, rbuf, sizeof(rbuf)); + + if (rbuf[0] == 0x82) + return 0; /* success */ + else + return -1; /* failed */ +} + + +/* + SMBNegProt + Function: Negotiate protocol with server ... + Actually a pseudo negotiation since the whole + program counts on NTLM support :) + + The challenge is retrieved from the answer + No error checking is performed i.e cross your fingers.... +*/ +int SMBNegProt(int s) { + char buf[168] = {0x00, 0x00, 0x00, 0xa4, 0xff, 0x53, 0x4d, 0x42, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7d, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x81, 0x00, 0x02, + 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, + 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, + 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, + 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, + 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, + 0x4b, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x33, 0x00, + 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, + 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, + 0x52, 0x4b, 0x53, 0x20, 0x33, 0x2e, 0x30, 0x00, + 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, + 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, + 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53, + 0x61, 0x6d, 0x62, 0x61, 0x00, 0x02, 0x4e, 0x54, + 0x20, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x20, + 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4e, 0x54, 0x20, + 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00}; + + char rbuf[400]; + memset(rbuf, 0, 400); + + hydra_send(s, buf, 168, 0); + hydra_recv(s, rbuf, sizeof(rbuf)); + + // retrieve the challenge + memcpy(challenge, rbuf+73, sizeof(challenge)); + + return 2; +} + + +/* + SMBSessionSetup + Function: Send username + response to the challenge from + the server. + Currently we're sendin ZEROES for the LMHASH since + NT4/2000 doesn't seem to look at this if we got a + valid NTLM hash. + Returns: TRUE on success else FALSE. +*/ +int SMBSessionSetup(int s, char *user, char *pass, char *miscptr) { + char b[137] = {0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, + 0x42, 0x73, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x7d, 0x00, 0x00, 0x01, 0x00, 0x0d, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x3c, 0x7d, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x48, 0x00, 0xdf, 0x82, 0xb9, 0x2f, 0xda, 0xdb, + 0x43, 0x47, 0x09, 0xdb, 0x7f, 0xfc, 0xb0, 0xa8, + 0xf0, 0x46, 0xe2, 0xfe, 0x64, 0x6d, 0x67, 0x58, + 0xe0, 0xf9, 0xca, 0x9f, 0x5e, 0xdb, 0xe0, 0x15, + 0x80, 0xf8, 0x54, 0xe3, 0x6e, 0xe9, 0xf8, 0x88, + 0x80, 0x19, 0xb6, 0xf9, 0xae, 0xb7, 0xa6, 0x62, + 0x14, 0xfc, 0x54, 0x45, 0x53, 0x54, 0x00, 0x4d, + 0x59, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x00, 0x55, + 0x6e, 0x69, 0x78, 0x00, 0x53, 0x61, 0x6d, 0x62, + 0x61, 0x00}; + + u_char buf[512]; + u_char *NTLMhash; + u_char LMhash[24]; + u_char workgroup[16]; + u_char rbuf[400]; + int userlen; + + NTLMhash = (u_char *) malloc(24); + + memset(NTLMhash, 0, 24); + memset(LMhash, 0, 24); + memset(workgroup, 0, 16); + memset(rbuf, 0, 400); + + HashNTLM(&NTLMhash, pass, challenge, miscptr); + + memset(buf, 0, 512); + memcpy(buf, b, 89); + memcpy(buf+65, LMhash, 24); + memcpy(buf+89, NTLMhash, 24); + + userlen = strlen(user); + + memcpy(buf+113, user, userlen); + memset(buf+(113+userlen), 0, 1); + memcpy(buf+(114+userlen), workgroup, strlen(workgroup)); + memcpy(buf+(114+userlen+strlen(workgroup)), b+125, 12); + + // set the header length + buf[3] = ( userlen + strlen(workgroup) + 0x7A ) % 256; + buf[2] = ( userlen + strlen(workgroup) + 0x7A ) / 256; + + // set data length + buf[63] = 0x1F + strlen(workgroup) + userlen; + + hydra_send(s, buf, 126+userlen+strlen(workgroup), 0); + + hydra_recv(s, rbuf, sizeof(rbuf)); + return rbuf[9]; +} + +int start_smbnt(int s, unsigned long int ip, int port, unsigned char options, char *miscptr, FILE *fp) { + char *empty = ""; + char *login, *pass; + + if (strlen(login = hydra_get_next_login()) == 0) login = empty; + if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; + + int SMBerr = SMBSessionSetup(s, login, pass, miscptr); + + if ( 0x00 == SMBerr ) { // success + hydra_report_found_host(port, ip, "smb", fp); + hydra_completed_pair_found(); + } + else if ( 0x24 == SMBerr ) { // change password on next login [success] + hydra_report_found_host(port, ip, "smb (must change password)", fp); + hydra_completed_pair_found(); + } + else if ( 0x72 == SMBerr ) { // account disabled + hydra_report_found_host(port, ip, "smb (account disabled)", fp); + hydra_completed_pair(); + } + else if ( 0x34 == SMBerr ) { // account locked out + fprintf(stderr, "[%d][smb] Account: %s is locked out\n", port, login); + hydra_completed_pair(); + } + else { // failed + hydra_completed_pair(); + } + + hydra_disconnect(s); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 3; + return 1; +} + +void service_smbnt(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port) { + int run = 1, next_run, sock = -1; + int myport = PORT_SMB, mysslport = PORT_SMB_SSL; + + hydra_register_socket(sp); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return; + for(;;) { + switch(run) { + case 1: /* connect and service init function */ + if (sock >= 0) + sock = hydra_disconnect(sock); + usleep(300000); + 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(); + } + if ( NBSSessionRequest(sock) < 0 ) { + fprintf(stderr, "Session Setup Failed: "); + fprintf(stderr, "(Is the server service running?)\n"); + exit(-1); + } + next_run = SMBNegProt(sock); + break; + case 2: /* run the cracking function */ + next_run = start_smbnt(sock, ip, port, options, miscptr, fp); + break; + case 3: /* clean exit */ + if (sock >= 0) sock = hydra_disconnect(sock); + hydra_child_exit(); + return; + default: fprintf(stderr,"Caught unknown return code (%d), exiting!\n", run); + hydra_child_exit(); + exit(-1); + } + run = next_run; + } +} diff -uN hydra-2.4/hydra-socks5.c hydra-2.4-m0j0/hydra-socks5.c --- hydra-2.4/hydra-socks5.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-socks5.c 2003-10-14 14:45:27.000000000 -0500 @@ -4,7 +4,7 @@ unsigned char *buf; -int start_socks5(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_socks5(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login, *pass, buffer[300]; @@ -30,7 +30,7 @@ if ((buf = hydra_receive_line(s)) == NULL) return(1); if (buf[1] != 255) { - hydra_report_found(port, "socks5", fp); + hydra_report_found_host(port, ip, "socks5", fp); hydra_completed_pair(); free(buf); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) @@ -63,11 +63,11 @@ if ((options & OPTION_SSL) == 0) { if (port != 0) myport = port; sock = hydra_connect_tcp(ip, myport); - port = myport; + port = myport; } else { if (port != 0) mysslport = port; sock = hydra_connect_ssl(ip, mysslport); - port = mysslport; + port = mysslport; } if (sock < 0) { fprintf(stderr, "Error: Child with pid %d terminating, can not connect\n", (int)getpid()); @@ -76,7 +76,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_socks5(sock, port, options, miscptr, fp); + next_run = start_socks5(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-telnet.c hydra-2.4-m0j0/hydra-telnet.c --- hydra-2.4/hydra-telnet.c 2002-03-24 05:53:07.000000000 -0600 +++ hydra-2.4-m0j0/hydra-telnet.c 2003-10-14 14:48:55.000000000 -0500 @@ -7,7 +7,7 @@ // added extra null byte sending via "+ 1" below ... should work! -int start_telnet(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_telnet(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *login, *pass, buffer[300]; int i = 0; @@ -33,7 +33,7 @@ if ((buf = hydra_receive_line(s)) == NULL) return 1; if (index(buf, '/') != NULL || index(buf, '>') != NULL || index(buf, '%') != NULL || index(buf, '$') != NULL || index(buf, '#') != NULL || index(buf, '%') != NULL) { - hydra_report_found(port, "telnet", fp); + hydra_report_found_host(port, ip, "telnet", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -67,7 +67,7 @@ while ((buf = hydra_receive_line(s)) != NULL && make_to_lower(buf) && (strstr(buf, "login:") == NULL || strstr(buf, "last login:") != NULL) && strstr(buf, "sername:") == NULL) { if (index(buf, '/') != NULL || index(buf, '>') != NULL || index(buf, '%') != NULL || index(buf, '$') != NULL || index(buf, '#') != NULL || index(buf, '%') != NULL) { - hydra_report_found(port, "telnet", fp); + hydra_report_found_host(port, ip, "telnet", fp); hydra_completed_pair_found(); free(buf); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) @@ -154,7 +154,7 @@ next_run = 2; break; case 2: /* run the cracking function */ - next_run = start_telnet(sock, port, options, miscptr, fp); + next_run = start_telnet(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/hydra-vnc.c hydra-2.4-m0j0/hydra-vnc.c --- hydra-2.4/hydra-vnc.c 2003-08-20 04:36:35.000000000 -0500 +++ hydra-2.4-m0j0/hydra-vnc.c 2003-10-14 14:48:18.000000000 -0500 @@ -39,7 +39,7 @@ } } -int start_vnc(int s,int port, unsigned char options,char *miscptr,FILE *fp) { +int start_vnc(int s, unsigned long int ip, int port, unsigned char options,char *miscptr,FILE *fp) { char *empty = ""; char *pass; @@ -57,7 +57,7 @@ if ((buf = hydra_receive_line(s)) == NULL) return(1); switch (buf[3]) { - case 0: hydra_report_found(port, "vnc", fp); + case 0: hydra_report_found_host(port, ip, "vnc", fp); hydra_completed_pair_found(); free(buf); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) @@ -96,11 +96,11 @@ if ((options & OPTION_SSL) == 0) { if (port != 0) myport = port; sock = hydra_connect_tcp(ip, myport); - port = myport; + port = myport; } else { if (port != 0) mysslport = port; sock = hydra_connect_ssl(ip, mysslport); - port = mysslport; + port = mysslport; } if (sock < 0) { fprintf(stderr, "Error: Child with pid %d terminating, can not connect\n", (int)getpid()); @@ -142,7 +142,7 @@ free(buf); break; case 2: /* run the cracking function */ - next_run = start_vnc(sock, port, options, miscptr, fp); + next_run = start_vnc(sock, ip, port, options, miscptr, fp); break; case 3: /* clean exit */ if (sock >= 0) sock = hydra_disconnect(sock); diff -uN hydra-2.4/ips.txt hydra-2.4-m0j0/ips.txt --- hydra-2.4/ips.txt 1969-12-31 18:00:00.000000000 -0600 +++ hydra-2.4-m0j0/ips.txt 2003-10-14 15:38:19.000000000 -0500 @@ -0,0 +1,2 @@ +mike +jack diff -uN hydra-2.4/Makefile.am hydra-2.4-m0j0/Makefile.am --- hydra-2.4/Makefile.am 2003-08-20 04:34:21.000000000 -0500 +++ hydra-2.4-m0j0/Makefile.am 2003-10-01 10:11:28.000000000 -0500 @@ -4,26 +4,26 @@ CC = gcc OPTS = -O2 -I. -Wall -LIBS = +LIBS = DIR = /bin SRC = hydra-vnc.c hydra-pcnfs.c hydra-rexec.c hydra-nntp.c hydra-socks5.c \ hydra-telnet.c hydra-cisco.c hydra-http.c hydra-ftp.c hydra-imap.c \ hydra-pop3.c hydra-smb.c hydra-icq.c hydra-cisco-enable.c hydra-ldap.c \ - hydra-mysql.c d3des.c hydra-mod.c hydra.c + hydra-mysql.c hydra-smbnt.c d3des.c md4.c hydra-mod.c hydra.c OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \ hydra-telnet.o hydra-cisco.o hydra-http.o hydra-ftp.o hydra-imap.o \ hydra-pop3.o hydra-smb.o hydra-icq.o hydra-cisco-enable.o hydra-ldap.o \ - hydra-mysql.o d3des.o hydra-mod.o hydra.o + hydra-mysql.o hydra-smbnt.o d3des.o md4.o hydra-mod.o hydra.o BIN = hydra EXTRA_DIST = README CHANGES TODO INSTALL LICENSE.GNU LICENCE.HYDRA \ - hydra-mod.h hydra.h d3des.h + hydra-mod.h hydra.h d3des.h md4.h all: hydra hydra: $(OBJ) - $(CC) $(OPTS) $(LIBS) -o $(BIN) $(OBJ) $(LIB) $(XLIBS) $(XLIBPATHS) + $(CC) $(OPTS) $(LIBS) -o $(BIN) $(OBJ) $(LIB) $(XLIBS) $(XLIBPATHS) $(LIBDES) @echo @echo If men could get pregnant, abortion would be a sacrament @echo diff -uN hydra-2.4/md4.c hydra-2.4-m0j0/md4.c --- hydra-2.4/md4.c 1969-12-31 18:00:00.000000000 -0600 +++ hydra-2.4-m0j0/md4.c 2003-09-29 14:30:22.000000000 -0500 @@ -0,0 +1,297 @@ +/* +** ******************************************************************** +** md4.c -- Implementation of MD4 Message Digest Algorithm ** +** Updated: 2/16/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +/* +** To use MD4: +** -- Include md4.h in your program +** -- Declare an MDstruct MD to hold the state of the digest +** computation. +** -- Initialize MD using MDbegin(&MD) +** -- For each full block (64 bytes) X you wish to process, call +** MD4Update(&MD,X,512) +** (512 is the number of bits in a full block.) +** -- For the last block (less than 64 bytes) you wish to process, +** MD4Update(&MD,X,n) +** where n is the number of bits in the partial block. A partial +** block terminates the computation, so every MD computation +** should terminate by processing a partial block, even if it +** has n = 0. +** -- The message digest is available in MD.buffer[0] ... +** MD.buffer[3]. (Least-significant byte of each word +** should be output first.) +** -- You can print out the digest using MDprint(&MD) +*/ + +/* Implementation notes: +** This implementation assumes that ints are 32-bit quantities. +*/ + +#define TRUE 1 +#define FALSE 0 + +/* Compile-time includes +*/ +#include +#include "md4.h" + +/* Compile-time declarations of MD4 "magic constants". +*/ +#define I0 0x67452301 /* Initial values for MD buffer */ +#define I1 0xefcdab89 +#define I2 0x98badcfe +#define I3 0x10325476 +#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ +#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ +/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 +** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. +** Table 2, page 660. +*/ + +#define fs1 3 /* round 1 shift amounts */ +#define fs2 7 +#define fs3 11 +#define fs4 19 +#define gs1 3 /* round 2 shift amounts */ +#define gs2 5 +#define gs3 9 +#define gs4 13 +#define hs1 3 /* round 3 shift amounts */ +#define hs2 9 +#define hs3 11 +#define hs4 15 + +/* Compile-time macro declarations for MD4. +** Note: The "rot" operator uses the variable "tmp". +** It assumes tmp is declared as unsigned int, so that the >> +** operator will shift in zeros rather than extending the sign bit. +*/ +#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) +#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) +#define h(X,Y,Z) (X^Y^Z) +#define rot(X,S) (tmp=X,(tmp<>(32-S))) +#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) +#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) +#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) + +/* MD4print(MDp) +** Print message digest buffer MDp as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte of +** buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +** This is a user-callable routine. +*/ +void +MD4Print(MDp) +MD4_CTX *MDp; +{ + int i,j; + for (i=0;i<4;i++) + for (j=0;j<32;j=j+8) + printf("%02x",(MDp->buffer[i]>>j) & 0xFF); +} + +/* MD4Init(MDp) +** Initialize message digest buffer MDp. +** This is a user-callable routine. +*/ +void +MD4Init(MDp) +MD4_CTX *MDp; +{ + int i; + MDp->buffer[0] = I0; + MDp->buffer[1] = I1; + MDp->buffer[2] = I2; + MDp->buffer[3] = I3; + for (i=0;i<8;i++) MDp->count[i] = 0; + MDp->done = 0; +} + +/* MDblock(MDp,X) +** Update message digest buffer MDp->buffer using 16-word data block X. +** Assumes all 16 words of X are full of data. +** Does not update MDp->count. +** This routine is not user-callable. +*/ +static void +MDblock(MDp,Xb) +MD4_CTX *MDp; +unsigned char *Xb; +{ + register unsigned int tmp, A, B, C, D; + unsigned int X[16]; + int i; + + for (i = 0; i < 16; ++i) { + X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); + Xb += 4; + } + + A = MDp->buffer[0]; + B = MDp->buffer[1]; + C = MDp->buffer[2]; + D = MDp->buffer[3]; + /* Update the message digest buffer */ + ff(A , B , C , D , 0 , fs1); /* Round 1 */ + ff(D , A , B , C , 1 , fs2); + ff(C , D , A , B , 2 , fs3); + ff(B , C , D , A , 3 , fs4); + ff(A , B , C , D , 4 , fs1); + ff(D , A , B , C , 5 , fs2); + ff(C , D , A , B , 6 , fs3); + ff(B , C , D , A , 7 , fs4); + ff(A , B , C , D , 8 , fs1); + ff(D , A , B , C , 9 , fs2); + ff(C , D , A , B , 10 , fs3); + ff(B , C , D , A , 11 , fs4); + ff(A , B , C , D , 12 , fs1); + ff(D , A , B , C , 13 , fs2); + ff(C , D , A , B , 14 , fs3); + ff(B , C , D , A , 15 , fs4); + gg(A , B , C , D , 0 , gs1); /* Round 2 */ + gg(D , A , B , C , 4 , gs2); + gg(C , D , A , B , 8 , gs3); + gg(B , C , D , A , 12 , gs4); + gg(A , B , C , D , 1 , gs1); + gg(D , A , B , C , 5 , gs2); + gg(C , D , A , B , 9 , gs3); + gg(B , C , D , A , 13 , gs4); + gg(A , B , C , D , 2 , gs1); + gg(D , A , B , C , 6 , gs2); + gg(C , D , A , B , 10 , gs3); + gg(B , C , D , A , 14 , gs4); + gg(A , B , C , D , 3 , gs1); + gg(D , A , B , C , 7 , gs2); + gg(C , D , A , B , 11 , gs3); + gg(B , C , D , A , 15 , gs4); + hh(A , B , C , D , 0 , hs1); /* Round 3 */ + hh(D , A , B , C , 8 , hs2); + hh(C , D , A , B , 4 , hs3); + hh(B , C , D , A , 12 , hs4); + hh(A , B , C , D , 2 , hs1); + hh(D , A , B , C , 10 , hs2); + hh(C , D , A , B , 6 , hs3); + hh(B , C , D , A , 14 , hs4); + hh(A , B , C , D , 1 , hs1); + hh(D , A , B , C , 9 , hs2); + hh(C , D , A , B , 5 , hs3); + hh(B , C , D , A , 13 , hs4); + hh(A , B , C , D , 3 , hs1); + hh(D , A , B , C , 11 , hs2); + hh(C , D , A , B , 7 , hs3); + hh(B , C , D , A , 15 , hs4); + MDp->buffer[0] += A; + MDp->buffer[1] += B; + MDp->buffer[2] += C; + MDp->buffer[3] += D; +} + +/* MD4Update(MDp,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use. +** (if not a multiple of 8, uses high bits of last byte.) +** Update MDp using the number of bits of X given by count. +** This is the basic input routine for an MD4 user. +** The routine completes the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. A call with count 0 will be ignored if the +** MD has already been terminated (done != 0), so an extra call with +** count 0 can be given as a "courtesy close" to force termination +** if desired. +*/ +void +MD4Update(MDp,X,count) +MD4_CTX *MDp; +unsigned char *X; +unsigned int count; +{ + unsigned int i, tmp, bit, byte, mask; + unsigned char XX[64]; + unsigned char *p; + + /* return with no error if this is a courtesy close with count + ** zero and MDp->done is true. + */ + if (count == 0 && MDp->done) return; + /* check to see if MD is already done and report error */ + if (MDp->done) + { printf("\nError: MD4Update MD already done."); return; } + + /* Add count to MDp->count */ + tmp = count; + p = MDp->count; + while (tmp) + { tmp += *p; + *p++ = tmp; + tmp = tmp >> 8; + } + + /* Process data */ + if (count == 512) + { /* Full block of data to handle */ + MDblock(MDp,X); + } + else if (count > 512) /* Check for count too large */ + { + printf("\nError: MD4Update called with illegal count value %d.", + count); + return; + } + else /* partial block -- must be last block so finish up */ + { + /* Find out how many bytes and residual bits there are */ + byte = count >> 3; + bit = count & 7; + /* Copy X into XX since we need to modify it */ + for (i=0;i<=byte;i++) XX[i] = X[i]; + for (i=byte+1;i<64;i++) XX[i] = 0; + /* Add padding '1' bit and low-order zeros in last byte */ + mask = 1 << (7 - bit); + XX[byte] = (XX[byte] | mask) & ~( mask - 1); + /* If room for bit count, finish up with this block */ + if (byte <= 55) + { + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + else /* need to do two blocks to finish up */ + { + MDblock(MDp,XX); + for (i=0;i<56;i++) XX[i] = 0; + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + /* Set flag saying we're done with MD computation */ + MDp->done = 1; + } +} + +/* +** Finish up MD4 computation and return message digest. +*/ +void +MD4Final(buf, MD) +unsigned char *buf; +MD4_CTX *MD; +{ + int i, j; + unsigned int w; + + MD4Update(MD, NULL, 0); + for (i = 0; i < 4; ++i) { + w = MD->buffer[i]; + for (j = 0; j < 4; ++j) { + *buf++ = w; + w >>= 8; + } + } +} + +/* +** End of md4.c +****************************(cut)***********************************/ diff -uN hydra-2.4/md4.h hydra-2.4-m0j0/md4.h --- hydra-2.4/md4.h 1969-12-31 18:00:00.000000000 -0600 +++ hydra-2.4-m0j0/md4.h 2003-09-29 14:32:08.000000000 -0500 @@ -0,0 +1,64 @@ + +/* +** ******************************************************************** +** md4.h -- Header file for implementation of ** +** MD4 Message Digest Algorithm ** +** Updated: 2/13/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + + +/* MDstruct is the data structure for a message digest computation. +*/ +typedef struct { + unsigned int buffer[4]; /* Holds 4-word result of MD computation */ + unsigned char count[8]; /* Number of bits processed so far */ + unsigned int done; /* Nonzero means MD computation finished */ +} MD4_CTX; + +/* MD4Init(MD4_CTX *) +** Initialize the MD4_CTX prepatory to doing a message digest +** computation. +*/ +extern void MD4Init __P((MD4_CTX *MD)); + +/* MD4Update(MD,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use (an unsigned int). +** Updates MD using the first "count" bits of X. +** The array pointed to by X is not modified. +** If count is not a multiple of 8, MD4Update uses high bits of +** last byte. +** This is the basic input routine for a user. +** The routine terminates the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. Zero is OK for a count. +*/ +extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); + +/* MD4Print(MD) +** Prints message digest buffer MD as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte +** of buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +*/ +extern void MD4Print __P((MD4_CTX *)); + +/* MD4Final(buf, MD) +** Returns message digest from MD and terminates the message +** digest computation. +*/ +extern void MD4Final __P((unsigned char *, MD4_CTX *)); + +/* +** End of md4.h +****************************(cut)***********************************/ Common subdirectories: hydra-2.4/old and hydra-2.4-m0j0/old