diff --git a/CHANGES b/CHANGES index efc0558..43cbe38 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,7 @@ Changelog for hydra Release 8.2-pre * Added new -O option to hydra to support SSL servers that do not suport TLS * Added xhydra gtk patche by Petar Kaleychev to support modules that do not use usernames +* Added patch to redis for initial service checking by Petar Kaleychev - thanks a lot! * Better library finding in ./configure for SVN + support for Darwin Homebrew (and further enhanced) * Fixed http-form module crash that only occurs on *BSD/OSX systems. Thanks to zdk for reporting! * Fixed for SSL connection to support TLSv1.2 etc. diff --git a/hydra-redis.c b/hydra-redis.c index 87fb432..b38d3e7 100644 --- a/hydra-redis.c +++ b/hydra-redis.c @@ -88,16 +88,79 @@ void service_redis(char *ip, int sp, unsigned char options, char *miscptr, FILE service_redis_core(ip, sp, options, miscptr, fp, port, 0); } +/* +* Initial password authentication test and response test for the redis server, +* added by Petar Kaleychev +* The service_redis_init function is generating ping request as redis-cli (command line interface). +* You can use redis-cli to connect with Redis. After start of the redis-server in another terminal the following: +* % ./redis-cli +* redis> ping +* when the server do not require password, leads to: +* PONG +* when the server requires password, leads to: +* (error) NOAUTH Authentication required. +* That is used for initial password authentication and redis server response tests in service_redis_init +*/ int service_redis_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { // called before the childrens are forked off, so this is the function // which should be filled if initial connections and service setup has to be // performed once only. - // - // fill if needed. - // // return codes: - // 0 all OK - // -1 error, hydra will exit, so print a good error message here + // 0 - when the server is redis and it requires password + // 1 - when the server is not redis or when the server do not require password + int sock = -1; + int myport = PORT_REDIS, mysslport = PORT_REDIS_SSL; + char buffer[] = "\x2a\x31\x0d\x0a\x24\x34\x0d\x0a\x70\x69\x6e\x67\x0d\x0a"; + + hydra_register_socket(sp); + if (sock >= 0) + sock = hydra_disconnect(sock); + 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 (verbose) + printf("[VERBOSE] Initial redis password authentication test and response test ...\n"); + if (sock < 0) { + hydra_report(stderr, "[ERROR] Can not connect to port %d on the target\n", myport); + hydra_child_exit(1); + } + // generating ping request as redis-cli + if (debug) + printf("[DEBUG] buffer = %s\n", buffer); + // [debug mode]: buffer is: + // *1 + // $4 + // ping + if (hydra_send(sock, buffer, strlen(buffer), 0) < 0) { + return 1; + } + buf = hydra_receive_line(sock); + if (debug) + printf("[DEBUG] buf = %s\n", buf); + // authentication test + if (strstr(buf, "+PONG") != NULL) { // the server do not require password + hydra_report(stderr, "[!] The server do not require password.\n"); + free(buf); + return 1; + } + // server response test + if (strstr(buf, "-NOAUTH Authentication required") == NULL) { + hydra_report(stderr, "[ERROR] The server is not redis, exit.\n"); + free(buf); + return 1; + } + if (verbose) + printf("[VERBOSE] The redis server requires password.\n"); + free(buf); + sock = hydra_disconnect(sock); return 0; }