Update from original repository

This commit is contained in:
Renato Alencar 2015-06-25 18:19:11 -03:00
parent bfaa4c83a7
commit 78c4fd11d7
15 changed files with 4425 additions and 4146 deletions

View file

@ -2,11 +2,17 @@ Changelog for hydra
------------------- -------------------
Release 8.2-pre Release 8.2-pre
* Added RTSP module, thanks to jjavi89 for supplying!
* 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 xhydra gtk patche by Petar Kaleychev to support modules that do not use usernames
* Better library finding in ./configure for SVN + support for Darwin Homebrew * 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 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. * Fixed for SSL connection to support TLSv1.2 etc.
* Support for different RSA keylengths, thanks to fann95 for the patch * Support for different RSA keylengths, thanks to fann95 for the patch
* Fixed a bug where the cisco-enable module was not working with the password-only logon mode
* Fixed an out of memory bug in http-form
* Fixed imap PLAIN method
* ... your patch? * ... your patch?

View file

@ -4,7 +4,10 @@
OPTS=-I. -O3 OPTS=-I. -O3
# -Wall -g -pedantic # -Wall -g -pedantic
LIBS=-lm LIBS=-lm
DIR=/bin BINDIR = /bin
MANDIR ?= /man/man1
DATADIR ?= /etc
DESTDIR ?=
SRC = hydra-vnc.c hydra-pcnfs.c hydra-rexec.c hydra-nntp.c hydra-socks5.c \ 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-telnet.c hydra-cisco.c hydra-http.c hydra-ftp.c hydra-imap.c \
@ -16,7 +19,7 @@ SRC = hydra-vnc.c hydra-pcnfs.c hydra-rexec.c hydra-nntp.c hydra-socks5.c \
hydra-oracle.c hydra-vmauthd.c hydra-asterisk.c hydra-firebird.c hydra-afp.c hydra-ncp.c \ hydra-oracle.c hydra-vmauthd.c hydra-asterisk.c hydra-firebird.c hydra-afp.c hydra-ncp.c \
hydra-oracle-sid.c hydra-http-proxy.c hydra-http-form.c hydra-irc.c \ hydra-oracle-sid.c hydra-http-proxy.c hydra-http-form.c hydra-irc.c \
hydra-rdp.c hydra-s7-300.c hydra-redis.c \ hydra-rdp.c hydra-s7-300.c hydra-redis.c \
crc32.c d3des.c bfg.c ntlm.c sasl.c hmacmd5.c hydra-mod.c crc32.c d3des.c bfg.c ntlm.c sasl.c hmacmd5.c hydra-mod.c hydra-rtsp.c
OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \ 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-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-pop3.o hydra-smb.o hydra-icq.o hydra-cisco-enable.o hydra-ldap.o \
@ -27,7 +30,7 @@ OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \
hydra-oracle-sid.o hydra-oracle.o hydra-vmauthd.o hydra-asterisk.o hydra-firebird.o hydra-afp.o hydra-ncp.o \ hydra-oracle-sid.o hydra-oracle.o hydra-vmauthd.o hydra-asterisk.o hydra-firebird.o hydra-afp.o hydra-ncp.o \
hydra-http-proxy.o hydra-http-form.o hydra-irc.o hydra-redis.o \ hydra-http-proxy.o hydra-http-form.o hydra-irc.o hydra-redis.o \
hydra-rdp.o hydra-s7-300.c \ hydra-rdp.o hydra-s7-300.c \
crc32.o d3des.o bfg.o ntlm.o sasl.o hmacmd5.o hydra-mod.o crc32.o d3des.o bfg.o ntlm.o sasl.o hmacmd5.o hydra-mod.o hydra-rtsp.o
BINS = hydra pw-inspector BINS = hydra pw-inspector
EXTRA_DIST = README README.arm README.palm CHANGES TODO INSTALL LICENSE \ EXTRA_DIST = README README.arm README.palm CHANGES TODO INSTALL LICENSE \
@ -57,15 +60,15 @@ strip: all
-echo OK > /dev/null && test -x xhydra && strip xhydra || echo OK > /dev/null -echo OK > /dev/null && test -x xhydra && strip xhydra || echo OK > /dev/null
install: strip install: strip
-mkdir -p $(PREFIX)$(DIR) -mkdir -p $(DESTDIR)$(PREFIX)$(BINDIR)
cp -f hydra-wizard.sh $(BINS) $(PREFIX)$(DIR) && cd $(PREFIX)$(DIR) && chmod 755 hydra-wizard.sh $(BINS) cp -f hydra-wizard.sh $(BINS) $(DESTDIR)$(PREFIX)$(BINDIR) && cd $(DESTDIR)$(PREFIX)$(BINDIR) && chmod 755 hydra-wizard.sh $(BINS)
-echo OK > /dev/null && test -x xhydra && cp xhydra $(PREFIX)$(DIR) && cd $(PREFIX)$(DIR) && chmod 755 xhydra || echo OK > /dev/null -echo OK > /dev/null && test -x xhydra && cp xhydra $(DESTDIR)$(PREFIX)$(BINDIR) && cd $(DESTDIR)$(PREFIX)$(BINDIR) && chmod 755 xhydra || echo OK > /dev/null
-sed -e "s|^INSTALLDIR=.*|INSTALLDIR="$(PREFIX)"|" dpl4hydra.sh > $(PREFIX)/bin/dpl4hydra.sh -sed -e "s|^INSTALLDIR=.*|INSTALLDIR="$(PREFIX)"|" dpl4hydra.sh | sed -e "s|^LOCATION=.*|LOCATION="$(DATADIR)"|" > $(DESTDIR)$(PREFIX)$(BINDIR)/dpl4hydra.sh
-chmod 755 $(PREFIX)/bin/dpl4hydra.sh -chmod 755 $(DESTDIR)$(PREFIX)$(BINDIR)/dpl4hydra.sh
-mkdir -p $(PREFIX)/etc/ -mkdir -p $(DESTDIR)$(PREFIX)$(DATADIR)
-cp -f *.csv $(PREFIX)/etc/ -cp -f *.csv $(DESTDIR)$(PREFIX)$(DATADIR)
-mkdir -p $(PREFIX)/man/man1 -mkdir -p $(DESTDIR)$(PREFIX)$(MANDIR)
-cp -f hydra.1 xhydra.1 pw-inspector.1 $(PREFIX)/man/man1 -cp -f hydra.1 xhydra.1 pw-inspector.1 $(DESTDIR)$(PREFIX)$(MANDIR)
clean: clean:
rm -rf xhydra pw-inspector hydra *.o core *.core *.stackdump *~ Makefile.in Makefile dev_rfc hydra.restore arm/*.ipk arm/ipkg/usr/bin/* hydra-gtk/src/*.o hydra-gtk/src/xhydra hydra-gtk/stamp-h hydra-gtk/config.status hydra-gtk/errors hydra-gtk/config.log hydra-gtk/src/.deps hydra-gtk/src/Makefile hydra-gtk/Makefile rm -rf xhydra pw-inspector hydra *.o core *.core *.stackdump *~ Makefile.in Makefile dev_rfc hydra.restore arm/*.ipk arm/ipkg/usr/bin/* hydra-gtk/src/*.o hydra-gtk/src/xhydra hydra-gtk/stamp-h hydra-gtk/config.status hydra-gtk/errors hydra-gtk/config.log hydra-gtk/src/.deps hydra-gtk/src/Makefile hydra-gtk/Makefile

49
configure vendored
View file

@ -968,6 +968,14 @@ XIPATHS=""
if [ -n "$FIREBIRD_PATH" -o -n "$PCRE_PATH" -o -n "$IDN_PATH" -o -n "$SSL_PATH" -o -n "$CRYPTO_PATH" -o -n "$NSL_PATH" -o -n "$SOCKET_PATH" -o -n "$RESOLV_PATH" -o -n "$SAPR3_PATH" -o -n "$SSH_PATH" -o -n "$POSTGRES_PATH" -o -n "$SVN_PATH" -o -n "$NCP_PATH" -o -n "$CURSES_PATH" -o -n "$ORACLE_PATH" -o -n "$AFP_PATH" -o -n "$MYSQL_PATH" ]; then if [ -n "$FIREBIRD_PATH" -o -n "$PCRE_PATH" -o -n "$IDN_PATH" -o -n "$SSL_PATH" -o -n "$CRYPTO_PATH" -o -n "$NSL_PATH" -o -n "$SOCKET_PATH" -o -n "$RESOLV_PATH" -o -n "$SAPR3_PATH" -o -n "$SSH_PATH" -o -n "$POSTGRES_PATH" -o -n "$SVN_PATH" -o -n "$NCP_PATH" -o -n "$CURSES_PATH" -o -n "$ORACLE_PATH" -o -n "$AFP_PATH" -o -n "$MYSQL_PATH" ]; then
XLIBPATHS="-L/usr/lib -L/usr/local/lib -L/lib" XLIBPATHS="-L/usr/lib -L/usr/local/lib -L/lib"
fi fi
if [ -n "$MYSQL_IPATH" ]; then
XIPATHS="$XIPATHS -I$MYSQL_IPATH"
if [ -n "$MYSQLINSUBDIR" ]; then
XDEFINES="$XDEFINES -DHAVE_MYSQL_MYSQL_H"
else
XDEFINES="$XDEFINES -DHAVE_MYSQL_H"
fi
fi
if [ -n "$SSL_PATH" ]; then if [ -n "$SSL_PATH" ]; then
if [ -n "$SSLNEW" ]; then if [ -n "$SSLNEW" ]; then
XDEFINES="$XDEFINES -DLIBOPENSSL" XDEFINES="$XDEFINES -DLIBOPENSSL"
@ -1016,7 +1024,7 @@ if [ -n "$RSA" ]; then
XDEFINES="$XDEFINES -DNO_RSA_LEGACY" XDEFINES="$XDEFINES -DNO_RSA_LEGACY"
fi fi
OLDPATH="" OLDPATH=""
for i in $SSL_PATH $CRYPTO_PATH $SSH_PATH $NSL_PATH $SOCKET_PATH $RESOLV_PATH $SAPR3_PATH $POSTGRES_PATH $SVN_PATH $NCP_PATH $CURSES_PATH $ORACLE_PATH $AFP_PATH $MYSQL_PATH; do for i in $SSL_PATH $FIREBIRD_PATH $WORACLE_LIB_PATH $PCRE_PATH $IDN_PATH $CRYPTO_PATH $SSH_PATH $NSL_PATH $SOCKET_PATH $RESOLV_PATH $SAPR3_PATH $POSTGRES_PATH $SVN_PATH $NCP_PATH $CURSES_PATH $ORACLE_PATH $AFP_PATH $MYSQL_PATH; do
if [ "$OLDPATH" = "$i" ]; then if [ "$OLDPATH" = "$i" ]; then
OLDPATH="$i" OLDPATH="$i"
else else
@ -1024,11 +1032,29 @@ for i in $SSL_PATH $CRYPTO_PATH $SSH_PATH $NSL_PATH $SOCKET_PATH $RESOLV_PATH $S
OLDPATH="$i" OLDPATH="$i"
fi fi
done done
if [ -n "$SSL_IPATH" ]; then if [ -n "$CURSES_IPATH" ]; then
XIPATHS="-I$SSL_IPATH" XIPATHS="$XIPATHS -I$CURSES_IPATH"
fi fi
if [ -n "$CURSES_PATH" ]; then if [ -n "$FIREBIRD_IPATH" ]; then
XLIBS="$XLIBS -lcurses" XIPATHS="$XIPATHS -I$FIREBIRD_IPATH"
fi
if [ -n "$IDN_IPATH" ]; then
XIPATHS="$XIPATHS -I$IDN_IPATH"
fi
if [ -n "$NCP_IPATH" ]; then
XIPATHS="$XIPATHS -I$NCP_IPATH"
fi
if [ -n "$PCRE_IPATH" ]; then
XIPATHS="$XIPATHS -I$PCRE_IPATH"
fi
if [ -n "$POSTGRES_IPATH" ]; then
XIPATHS="$XIPATHS -I$POSTGRES_IPATH"
fi
if [ -n "$PR29_IPATH" ]; then
XIPATHS="$XIPATHS -I$PR29_IPATH"
fi
if [ -n "$SSL_IPATH" ]; then
XIPATHS="$XIPATHS -I$SSL_IPATH"
fi fi
if [ -n "$SAPR3_IPATH" ]; then if [ -n "$SAPR3_IPATH" ]; then
XIPATHS="$XIPATHS -I$SAPR3_IPATH" XIPATHS="$XIPATHS -I$SAPR3_IPATH"
@ -1045,20 +1071,15 @@ fi
if [ -n "$SVN_IPATH" ]; then if [ -n "$SVN_IPATH" ]; then
XIPATHS="$XIPATHS -I$SVN_IPATH" XIPATHS="$XIPATHS -I$SVN_IPATH"
fi fi
if [ -n "$MYSQL_IPATH" ]; then
XIPATHS="$XIPATHS -I$MYSQL_IPATH"
if [ -n "$MYSQLINSUBDIR" ]; then
XDEFINES="$XDEFINES -DHAVE_MYSQL_MYSQL_H"
else
XDEFINES="$XDEFINES -DHAVE_MYSQL_H"
fi
fi
if [ -n "$AFP_IPATH" ]; then if [ -n "$AFP_IPATH" ]; then
XIPATHS="$XIPATHS -I$AFP_IPATH" XIPATHS="$XIPATHS -I$AFP_IPATH"
fi fi
if [ -n "$ORACLE_IPATH" ]; then if [ -n "$ORACLE_IPATH" ]; then
XIPATHS="$XIPATHS -I$ORACLE_IPATH" XIPATHS="$XIPATHS -I$ORACLE_IPATH"
fi fi
if [ -n "$CURSES_PATH" ]; then
XLIBS="$XLIBS -lcurses"
fi
if [ -n "$SSL_PATH" ]; then if [ -n "$SSL_PATH" ]; then
XLIBS="$XLIBS -lssl" XLIBS="$XLIBS -lssl"
fi fi
@ -1122,7 +1143,7 @@ if [ "X" = "X$PREFIX" ]; then
PREFIX="/usr/local" PREFIX="/usr/local"
fi fi
if [ "X" = "X$XHYDRA_SUPPORT" ]; then if [ "X" = "X$XHYDRA_SUPPORT" -o "Xdisable" = "X$XHYDRA_SUPPORT" ]; then
XHYDRA_SUPPORT="" XHYDRA_SUPPORT=""
else else
XHYDRA_SUPPORT="xhydra" XHYDRA_SUPPORT="xhydra"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -52,9 +52,10 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da
#include "hydra-mod.h" #include "hydra-mod.h"
/* HTTP Header Types */ /* HTTP Header Types */
#define HEADER_TYPE_USERHEADER 'h' #define HEADER_TYPE_USERHEADER 'h'
#define HEADER_TYPE_USERHEADER_REPL 'H' #define HEADER_TYPE_USERHEADER_REPL 'H'
#define HEADER_TYPE_DEFAULT 'D' #define HEADER_TYPE_DEFAULT 'D'
#define HEADER_TYPE_DEFAULT_REPL 'd'
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
char *buf; char *buf;
@ -67,6 +68,13 @@ typedef struct header_node {
struct header_node *next; struct header_node *next;
} t_header_node, *ptr_header_node; } t_header_node, *ptr_header_node;
typedef struct cookie_node {
char *name;
char *value;
struct cookie_node *prev;
struct cookie_node *next;
} t_cookie_node, *ptr_cookie_node;
int success_cond = 0; int success_cond = 0;
int getcookie = 1; int getcookie = 1;
int auth_flag = 0; int auth_flag = 0;
@ -106,6 +114,118 @@ ptr_header_node header_exists(ptr_header_node * ptr_head, char *header_name, cha
return found_header; return found_header;
} }
int append_cookie(char *name, char *value, ptr_cookie_node *last_cookie)
{
ptr_cookie_node new_ptr = (ptr_cookie_node) malloc(sizeof(t_cookie_node));
if (!new_ptr)
return 0;
new_ptr->name = name;
new_ptr->value = value;
new_ptr->next = NULL;
new_ptr->prev = NULL;
if (*last_cookie == NULL)
*last_cookie = new_ptr;
else
(*last_cookie)->next = new_ptr;
return 1;
}
char * stringify_cookies(ptr_cookie_node ptr_cookie)
{
ptr_cookie_node cur_ptr = NULL;
unsigned int length = 1;
char *cookie_hdr = (char *) malloc(length);
if (cookie_hdr) {
memset(cookie_hdr, 0, length);
for (cur_ptr = ptr_cookie; cur_ptr; cur_ptr = cur_ptr->next) {
length += 2 + strlen(cur_ptr->name) + strlen(cur_ptr->value);
cookie_hdr = (char *) realloc(cookie_hdr, length);
if (cookie_hdr) {
strcat(cookie_hdr, cur_ptr->name);
strcat(cookie_hdr, "=");
strcat(cookie_hdr, cur_ptr->value);
if (cur_ptr->next)
strcat(cookie_hdr, ";");
} else
goto bail;
}
goto success;
}
bail:
if (cookie_hdr) {
free(cookie_hdr);
cookie_hdr = NULL;
}
success:
return cookie_hdr;
}
/*
* Cookie list layout:
* +----------+ +--------+ +------+
* | ptr_head | --> | next | --> | NULL |
* +----------+ | header | +------+
* | value |
* +--------+
* Returns 1 if success, or 0 otherwise.
*/
int add_or_update_cookie(ptr_cookie_node * ptr_cookie, char * cookie_expr)
{
ptr_cookie_node cur_ptr = NULL, new_ptr = NULL;
char * cookie = strdup(cookie_expr);
char * cookie_name = NULL,
* cookie_value = strstr(cookie_expr, "=");
if (cookie_value) {
cookie_name = strndup(cookie_expr, cookie_value - cookie_expr);
cookie_value = strdup(cookie_value + 1);
// we've got the cookie's name and value, now it's time to insert or update the list
if (*ptr_cookie == NULL) {
// no cookies
append_cookie(cookie_name, cookie_value, ptr_cookie);
} else {
for (cur_ptr = *ptr_cookie; cur_ptr; cur_ptr = cur_ptr->next) {
if (strcmp(cur_ptr->name, cookie_name) == 0) {
free(cur_ptr->value);
cur_ptr->value = cookie_value;
break;
}
if (cur_ptr->next == NULL) {
append_cookie(cookie_name, cookie_value, &cur_ptr);
break;
}
}
}
} else
return 0;
return 1;
}
int process_cookies(ptr_cookie_node * ptr_cookie, char * cookie_expr)
{
char *tok = NULL;
char *expr = strdup(cookie_expr);
int res = 0;
if (strstr(cookie_expr, ";")) {
tok = strtok(expr, ";");
while (tok) {
res = add_or_update_cookie(ptr_cookie, tok);
if (!res)
return res;
tok = strtok(NULL, ";");
}
return res;
} else {
return add_or_update_cookie(ptr_cookie, expr);
}
}
/* /*
* List layout: * List layout:
* +----------+ +--------+ +--------+ +--------+ * +----------+ +--------+ +--------+ +--------+
@ -129,7 +249,9 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type)
if (new_header && new_value) { if (new_header && new_value) {
if ((type == HEADER_TYPE_USERHEADER) || if ((type == HEADER_TYPE_USERHEADER) ||
(type == HEADER_TYPE_DEFAULT && !header_exists(ptr_head, new_header, HEADER_TYPE_USERHEADER_REPL)) || (type == HEADER_TYPE_DEFAULT && !header_exists(ptr_head, new_header, HEADER_TYPE_USERHEADER_REPL)) ||
(type == HEADER_TYPE_USERHEADER_REPL && !header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))) { (type == HEADER_TYPE_USERHEADER_REPL && !header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT)) ||
(type == HEADER_TYPE_DEFAULT_REPL && !header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))
) {
/* /*
* We are in one of the following scenarios: * We are in one of the following scenarios:
* 1. A default header with no user-supplied headers that replace it. * 1. A default header with no user-supplied headers that replace it.
@ -153,7 +275,7 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type)
// head is NULL, so the list is empty // head is NULL, so the list is empty
*ptr_head = new_ptr; *ptr_head = new_ptr;
} }
} else if (type == HEADER_TYPE_USERHEADER_REPL && (existing_hdr = header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))) { } else if ((type == HEADER_TYPE_DEFAULT_REPL || type == HEADER_TYPE_USERHEADER_REPL) && (existing_hdr = header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT)) != NULL) {
// It's a user-supplied header that must replace a default one // It's a user-supplied header that must replace a default one
// Replace the default header's value with this new value // Replace the default header's value with this new value
free(existing_hdr->value); free(existing_hdr->value);
@ -177,11 +299,11 @@ void hdrrep(ptr_header_node * ptr_head, char *oldvalue, char *newvalue) {
for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) { for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) {
if ((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)) { if ((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)) {
cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(newvalue)); cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(newvalue) + 1);
if (cur_ptr->value) if (cur_ptr->value)
strcpy(cur_ptr->value, newvalue); strcpy(cur_ptr->value, newvalue);
else { else {
hydra_report(stderr, "[ERROR] Out of memory."); hydra_report(stderr, "[ERROR] Out of memory (hddrep).");
hydra_child_exit(0); hydra_child_exit(0);
} }
} }
@ -196,21 +318,21 @@ void hdrrepv(ptr_header_node * ptr_head, char *hdrname, char *new_value) {
for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) { for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) {
if ((cur_ptr->type == HEADER_TYPE_DEFAULT) && strcmp(cur_ptr->header, hdrname) == 0) { if ((cur_ptr->type == HEADER_TYPE_DEFAULT) && strcmp(cur_ptr->header, hdrname) == 0) {
cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(new_value)); cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(new_value) + 1);
if (cur_ptr->value) if (cur_ptr->value)
strcpy(cur_ptr->value, new_value); strcpy(cur_ptr->value, new_value);
else { else {
hydra_report(stderr, "[ERROR] Out of memory"); hydra_report(stderr, "[ERROR] Out of memory (hdrrepv %d)", strlen(new_value) + 1);
hydra_child_exit(0); hydra_child_exit(0);
} }
} }
} }
} }
void cleanup(ptr_header_node * ptr_head) { void cleanup(ptr_header_node *ptr_head) {
ptr_header_node cur_ptr = *ptr_head, next_ptr = cur_ptr; ptr_header_node cur_ptr = *ptr_head, next_ptr = cur_ptr;
while (next_ptr) { while (next_ptr != NULL) {
free(cur_ptr->header); free(cur_ptr->header);
free(cur_ptr->value); free(cur_ptr->value);
next_ptr = cur_ptr->next; next_ptr = cur_ptr->next;
@ -435,10 +557,11 @@ void hydra_reconnect(int s, char *ip, int port, unsigned char options) {
} }
} }
int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type, ptr_header_node ptr_head) { int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type, ptr_header_node ptr_head, ptr_cookie_node ptr_cookie) {
char *empty = ""; char *empty = "";
char *login, *pass, clogin[256], cpass[256]; char *login, *pass, clogin[256], cpass[256];
char header[8096], *upd3variables; char header[8096], *upd3variables;
char *cookie_header = NULL;
char *http_request; char *http_request;
int found = !success_cond, i, j; int found = !success_cond, i, j;
char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH];
@ -472,7 +595,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 1; return 1;
i = analyze_server_response(s); // ignore result i = analyze_server_response(s); // ignore result
if (strlen(cookie) > 0) if (strlen(cookie) > 0)
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); process_cookies(&ptr_cookie, cookie);
hydra_reconnect(s, ip, port, options); hydra_reconnect(s, ip, port, options);
} }
// now prepare for the "real" request // now prepare for the "real" request
@ -486,12 +609,22 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT);
if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT);
cookie_header = stringify_cookies(ptr_cookie);
if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT);
else
hdrrepv(&ptr_head, "Cookie", cookie_header);
normal_request = stringify_headers(&ptr_head); normal_request = stringify_headers(&ptr_head);
http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
} else { } else {
normal_request = stringify_headers(&ptr_head); cookie_header = stringify_cookies(ptr_cookie);
if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT);
else
hdrrepv(&ptr_head, "Cookie", cookie_header);
normal_request = stringify_headers(&ptr_head);
http_request = prepare_http_request("GET", url, upd3variables, normal_request); http_request = prepare_http_request("GET", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
@ -508,7 +641,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 1; return 1;
i = analyze_server_response(s); // ignore result i = analyze_server_response(s); // ignore result
if (strlen(cookie) > 0) if (strlen(cookie) > 0)
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); process_cookies(&ptr_cookie, cookie);
hydra_reconnect(s, ip, port, options); hydra_reconnect(s, ip, port, options);
} }
// now prepare for the "real" request // now prepare for the "real" request
@ -522,12 +655,22 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT);
if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT);
cookie_header = stringify_cookies(ptr_cookie);
if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT);
else
hdrrepv(&ptr_head, "Cookie", cookie_header);
normal_request = stringify_headers(&ptr_head); normal_request = stringify_headers(&ptr_head);
http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
} else { } else {
normal_request = stringify_headers(&ptr_head); cookie_header = stringify_cookies(ptr_cookie);
if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT);
else
hdrrepv(&ptr_head, "Cookie", cookie_header);
normal_request = stringify_headers(&ptr_head);
http_request = prepare_http_request("GET", url, upd3variables, normal_request); http_request = prepare_http_request("GET", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
@ -540,8 +683,9 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
i = analyze_server_response(s); // ignore result i = analyze_server_response(s); // ignore result
if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) { if (strlen(cookie) > 0) {
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); //printf("[DEBUG] Got cookie: %s\n", cookie);
process_cookies(&ptr_cookie, cookie);
normal_request = stringify_headers(&ptr_head); normal_request = stringify_headers(&ptr_head);
} }
hydra_reconnect(s, ip, port, options); hydra_reconnect(s, ip, port, options);
@ -555,12 +699,22 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT);
if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT);
cookie_header = stringify_cookies(ptr_cookie);
if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT);
else
hdrrepv(&ptr_head, "Cookie", cookie_header);
normal_request = stringify_headers(&ptr_head); normal_request = stringify_headers(&ptr_head);
http_request = prepare_http_request("POST", url, upd3variables, normal_request); http_request = prepare_http_request("POST", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
} else { } else {
normal_request = stringify_headers(&ptr_head); cookie_header = stringify_cookies(ptr_cookie);
if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT);
else
hdrrepv(&ptr_head, "Cookie", cookie_header);
normal_request = stringify_headers(&ptr_head);
http_request = prepare_http_request("GET", url, upd3variables, normal_request); http_request = prepare_http_request("GET", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1; return 1;
@ -579,8 +733,8 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 4; return 4;
} }
if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) if (strlen(cookie) > 0)
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); process_cookies(&ptr_cookie, cookie);
//if page was redirected, follow the location header //if page was redirected, follow the location header
redirected_cpt = MAX_REDIRECT; redirected_cpt = MAX_REDIRECT;
@ -694,8 +848,8 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 1; return 1;
found = analyze_server_response(s); found = analyze_server_response(s);
if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) if (strlen(cookie) > 0)
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); process_cookies(ptr_cookie, cookie);
} }
} }
@ -710,7 +864,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 1; return 1;
} }
void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port, char *type, ptr_header_node * ptr_head) { void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port, char *type, ptr_header_node * ptr_head, ptr_cookie_node * ptr_cookie) {
int run = 1, next_run = 1, sock = -1; int run = 1, next_run = 1, sock = -1;
int myport = PORT_HTTP, mysslport = PORT_HTTP_SSL; int myport = PORT_HTTP, mysslport = PORT_HTTP_SSL;
@ -760,7 +914,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F
break; break;
} }
case 2: /* run the cracking function */ case 2: /* run the cracking function */
next_run = start_http_form(sock, ip, port, options, miscptr, fp, type, *ptr_head); next_run = start_http_form(sock, ip, port, options, miscptr, fp, type, *ptr_head, *ptr_cookie);
break; break;
case 3: /* clean exit */ case 3: /* clean exit */
if (sock >= 0) if (sock >= 0)
@ -792,10 +946,11 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F
} }
void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) {
ptr_header_node ptr_head = initialize(ip, options, miscptr); ptr_cookie_node ptr_cookie = NULL;
ptr_header_node ptr_head = initialize(ip, options, miscptr);
if (ptr_head) if (ptr_head)
service_http_form(ip, sp, options, miscptr, fp, port, "GET", &ptr_head); service_http_form(ip, sp, options, miscptr, fp, port, "GET", &ptr_head, &ptr_cookie);
else { else {
hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n"); hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n");
hydra_child_exit(1); hydra_child_exit(1);
@ -803,10 +958,11 @@ void service_http_get_form(char *ip, int sp, unsigned char options, char *miscpt
} }
void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) {
ptr_header_node ptr_head = initialize(ip, options, miscptr); ptr_cookie_node ptr_cookie = NULL;
ptr_header_node ptr_head = initialize(ip, options, miscptr);
if (ptr_head) if (ptr_head)
service_http_form(ip, sp, options, miscptr, fp, port, "POST", &ptr_head); service_http_form(ip, sp, options, miscptr, fp, port, "POST", &ptr_head, &ptr_cookie);
else { else {
hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n"); hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n");
hydra_child_exit(1); hydra_child_exit(1);
@ -843,10 +999,11 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
miscptr = slash; /* to make things easier to user */ miscptr = slash; /* to make things easier to user */
} else if ((ptr2 = index(webtarget, '/')) != NULL) { } else if ((ptr2 = index(webtarget, '/')) != NULL) {
if (freemischttpform == 0) { if (freemischttpform == 0) {
freemischttpform = 1; if ((miscptr = malloc(strlen(ptr2) + 1)) != NULL) {
miscptr = malloc(strlen(ptr2) + 1); freemischttpform = 1;
strcpy(miscptr, ptr2); strcpy(miscptr, ptr2);
*ptr2 = 0; *ptr2 = 0;
}
} }
} else } else
webtarget = NULL; webtarget = NULL;
@ -963,7 +1120,7 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
break; break;
} }
// Error: abort execution // Error: abort execution
hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); hydra_report(stderr, "[ERROR] Out of memory for HTTP headers (h).");
return NULL; return NULL;
case 'H': case 'H':
// add a new header, or replace an existing one's value // add a new header, or replace an existing one's value
@ -992,7 +1149,7 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
break; break;
} }
// Error: abort execution // Error: abort execution
hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); hydra_report(stderr, "[ERROR] Out of memory for HTTP headers (H).");
return NULL; return NULL;
// no default // no default
} }

View file

@ -189,7 +189,9 @@ int start_http(int s, char *ip, int port, unsigned char options, char *miscptr,
if (debug) if (debug)
hydra_report(stderr, "S:%s\n", http_buf); hydra_report(stderr, "S:%s\n", http_buf);
ptr = ((char *) index(http_buf, ' ')) + 1; ptr = ((char *) index(http_buf, ' '));
if (ptr != NULL)
ptr++;
if (ptr != NULL && (*ptr == '2' || *ptr == '3' || strncmp(ptr, "403", 3) == 0 || strncmp(ptr, "404", 3) == 0)) { if (ptr != NULL && (*ptr == '2' || *ptr == '3' || strncmp(ptr, "403", 3) == 0 || strncmp(ptr, "404", 3) == 0)) {
hydra_report_found_host(port, ip, "www", fp); hydra_report_found_host(port, ip, "www", fp);
hydra_completed_pair_found(); hydra_completed_pair_found();
@ -199,7 +201,7 @@ int start_http(int s, char *ip, int port, unsigned char options, char *miscptr,
} }
} else { } else {
if (ptr != NULL && *ptr != '4') if (ptr != NULL && *ptr != '4')
fprintf(stderr, "[WARNING] Unusual return code: %c for %s:%s\n", (char) *(index(http_buf, ' ') + 1), login, pass); fprintf(stderr, "[WARNING] Unusual return code: %.3s for %s:%s\n", (char) *ptr, login, pass);
//the first authentication type failed, check the type from server header //the first authentication type failed, check the type from server header
if ((hydra_strcasestr(http_buf, "WWW-Authenticate: Basic") == NULL) && (http_auth_mechanism == AUTH_BASIC)) { if ((hydra_strcasestr(http_buf, "WWW-Authenticate: Basic") == NULL) && (http_auth_mechanism == AUTH_BASIC)) {

View file

@ -102,9 +102,9 @@ int start_imap(int s, char *ip, int port, unsigned char options, char *miscptr,
} }
free(buf); free(buf);
memset(buffer, 0, sizeof(buffer)); memset(buffer2, 0, sizeof(buffer2));
sasl_plain(buffer, login, pass); sasl_plain(buffer2, login, pass);
sprintf(buffer, "%.250s\r\n", buffer); sprintf(buffer, "%.250s\r\n", buffer2);
break; break;
#ifdef LIBOPENSSL #ifdef LIBOPENSSL

View file

@ -47,6 +47,7 @@ int __first_connect = 1;
char ipstring[64]; char ipstring[64];
unsigned int colored_output = 1; unsigned int colored_output = 1;
char quiet = 0; char quiet = 0;
int old_ssl = 0;
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
SSL *ssl = NULL; SSL *ssl = NULL;
@ -468,13 +469,23 @@ int internal__hydra_connect_to_ssl(int socket) {
if (sslContext == NULL) { if (sslContext == NULL) {
/* context: ssl2 + ssl3 is allowed, whatever the server demands */ /* context: ssl2 + ssl3 is allowed, whatever the server demands */
// if ((sslContext = SSL_CTX_new(SSLv23_client_method())) == NULL) { if (old_ssl) {
if ((sslContext = SSL_CTX_new(TLSv1_2_client_method())) == NULL) { if ((sslContext = SSL_CTX_new(SSLv23_client_method())) == NULL) {
if (verbose) { if (verbose) {
err = ERR_get_error(); err = ERR_get_error();
fprintf(stderr, "[ERROR] SSL allocating context: %s\n", ERR_error_string(err, NULL)); fprintf(stderr, "[ERROR] SSL allocating context: %s\n", ERR_error_string(err, NULL));
}
return -1;
}
} else {
// if ((sslContext = SSL_CTX_new(SSLv23_client_method())) == NULL) {
if ((sslContext = SSL_CTX_new(TLSv1_2_client_method())) == NULL) {
if (verbose) {
err = ERR_get_error();
fprintf(stderr, "[ERROR] SSL allocating context: %s\n", ERR_error_string(err, NULL));
}
return -1;
} }
return -1;
} }
/* set the compatbility mode */ /* set the compatbility mode */
SSL_CTX_set_options(sslContext, SSL_OP_ALL); SSL_CTX_set_options(sslContext, SSL_OP_ALL);
@ -1198,16 +1209,20 @@ char *hydra_string_replace(const char *string, const char *substr, const char *r
char *tok = NULL; char *tok = NULL;
char *newstr = NULL; char *newstr = NULL;
if (string == NULL)
return NULL;
if (substr == NULL || replacement == NULL)
return strdup(string);
tok = strstr(string, substr); tok = strstr(string, substr);
if (tok == NULL) if (tok == NULL)
return strdup(string); return strdup(string);
newstr = malloc(strlen(string) - strlen(substr) + strlen(replacement) + 1); newstr = malloc(strlen(string) - strlen(substr) + strlen(replacement) + 2);
if (newstr == NULL) if (newstr == NULL)
return NULL; return NULL;
memset(newstr, 0, strlen(string) - strlen(substr) + strlen(replacement) + 2);
memcpy(newstr, string, tok - string); memcpy(newstr, string, tok - string);
memcpy(newstr + (tok - string), replacement, strlen(replacement)); memcpy(newstr + (tok - string), replacement, strlen(replacement));
memcpy(newstr + (tok - string) + strlen(replacement), tok + strlen(substr), strlen(string) - strlen(substr) - (tok - string)); memcpy(newstr + (tok - string) + strlen(replacement), tok + strlen(substr), strlen(string) - strlen(substr) - (tok - string));
memset(newstr + strlen(string) - strlen(substr) + strlen(replacement), 0, 1);
return newstr; return newstr;
} }

View file

@ -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); 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 <petar.kaleychev@gmail.com>
* 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) { 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 // 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 // which should be filled if initial connections and service setup has to be
// performed once only. // performed once only.
//
// fill if needed.
//
// return codes: // return codes:
// 0 all OK // 0 - when the server is redis and it requires password
// -1 error, hydra will exit, so print a good error message here // 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; return 0;
} }

View file

@ -180,7 +180,7 @@ int start_smtp(int s, char *ip, int port, unsigned char options, char *miscptr,
/* 504 5.7.4 Unrecognized authentication type */ /* 504 5.7.4 Unrecognized authentication type */
if (strstr(buf, "334") == NULL) { if (strstr(buf, "334") == NULL) {
hydra_report(stderr, "[ERROR] SMTP LOGIN AUTH, either this auth is disabled\nor server is not using auth: %s\n", buf); hydra_report(stderr, "[ERROR] SMTP LOGIN AUTH, either this auth is disabled or server is not using auth: %s\n", buf);
free(buf); free(buf);
return 3; return 3;
} }

View file

@ -96,6 +96,7 @@ int start_xmpp(int s, char *ip, int port, unsigned char options, char *miscptr,
/* server now would ask for the password */ /* server now would ask for the password */
if ((strstr(buf, CHALLENGE_STR) != NULL) || (strstr(buf, CHALLENGE_STR2) != NULL)) { if ((strstr(buf, CHALLENGE_STR) != NULL) || (strstr(buf, CHALLENGE_STR2) != NULL)) {
char *ptr = strstr(buf, CHALLENGE_STR); char *ptr = strstr(buf, CHALLENGE_STR);
if (!ptr) if (!ptr)
ptr = strstr(buf, CHALLENGE_STR2); ptr = strstr(buf, CHALLENGE_STR2);
char *ptr_end = strstr(ptr, CHALLENGE_END_STR); char *ptr_end = strstr(ptr, CHALLENGE_END_STR);
@ -334,56 +335,54 @@ void service_xmpp(char *target, char *ip, int sp, unsigned char options, char *m
} }
//some server is longer to answer //some server is longer to answer
usleep(300000); usleep(300000);
buf = hydra_receive_line(sock); do {
if ((buf = hydra_receive_line(sock)) == NULL) {
/* no auth method identified */
hydra_report(stderr, "[ERROR] no authentication methods can be identified %s\n", buf);
free(buf);
hydra_child_exit(1);
}
if (buf == NULL) if (strstr(buf, "<stream:stream") == NULL) {
hydra_child_exit(1); if (verbose || debug)
hydra_report(stderr, "[ERROR] Not an xmpp protocol or service shutdown: %s\n", buf);
free(buf);
hydra_child_exit(1);
}
if (strstr(buf, "<stream:stream") == NULL) { if (strstr(buf, "<stream:error")) {
if (verbose || debug) if (strstr(buf, "<host-unknown"))
hydra_report(stderr, "[ERROR] Not an xmpp protocol or service shutdown: %s\n", buf); hydra_report(stderr, "[ERROR] %s host unknown, you have to specify a fqdn xmpp server, the domain name will be used in the jabber init request : %s\n", domain, buf);
else
hydra_report(stderr, "[ERROR] xmpp protocol : %s\n", buf);
free(buf);
hydra_child_exit(1);
}
/* try to identify which features is supported */
if (strstr(buf, ":xmpp-tls") != NULL) {
tls = 1;
}
if (strstr(buf, ":xmpp-sasl") != NULL) {
if (strstr(buf, "<mechanism>SCRAM-SHA-1</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_SCRAMSHA1;
}
if (strstr(buf, "<mechanism>CRAM-MD5</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_CRAMMD5;
}
if (strstr(buf, "<mechanism>DIGEST-MD5</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_DIGESTMD5;
}
if (strstr(buf, "<mechanism>PLAIN</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_PLAIN;
}
if (strstr(buf, "<mechanism>LOGIN</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_LOGIN;
}
}
free(buf); free(buf);
hydra_child_exit(1); } while (xmpp_auth_mechanism == AUTH_ERROR);
}
if (strstr(buf, "<stream:error")) {
if (strstr(buf, "<host-unknown"))
hydra_report(stderr, "[ERROR] %s host unknown, you have to specify a fqdn xmpp server, the domain name will be used in the jabber init request : %s\n", domain, buf);
else
hydra_report(stderr, "[ERROR] xmpp protocol : %s\n", buf);
free(buf);
hydra_child_exit(1);
}
/* try to identify which features is supported */
if (strstr(buf, ":xmpp-tls") != NULL) {
tls = 1;
}
if (strstr(buf, ":xmpp-sasl") != NULL) {
if (strstr(buf, "<mechanism>SCRAM-SHA-1</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_SCRAMSHA1;
}
if (strstr(buf, "<mechanism>CRAM-MD5</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_CRAMMD5;
}
if (strstr(buf, "<mechanism>DIGEST-MD5</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_DIGESTMD5;
}
if (strstr(buf, "<mechanism>PLAIN</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_PLAIN;
}
if (strstr(buf, "<mechanism>LOGIN</mechanism>") != NULL) {
xmpp_auth_mechanism = AUTH_LOGIN;
}
}
if (xmpp_auth_mechanism == AUTH_ERROR) {
/* no auth method identified */
hydra_report(stderr, "[ERROR] no authentication methods can be identified %s\n", buf);
free(buf);
hydra_child_exit(1);
}
free(buf);
if ((miscptr != NULL) && (strlen(miscptr) > 0)) { if ((miscptr != NULL) && (strlen(miscptr) > 0)) {
int i; int i;

306
hydra.c
View file

@ -48,9 +48,11 @@ extern void service_xmpp(char *target, char *ip, int sp, unsigned char options,
extern void service_irc(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_irc(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern void service_http_proxy_urlenum(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_http_proxy_urlenum(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern void service_s7_300(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_s7_300(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern void service_rtsp(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
#ifdef HAVE_MATH_H #ifdef HAVE_MATH_H
extern void service_mysql(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_mysql(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_mysql_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_mysql_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
@ -134,13 +136,14 @@ extern int service_vmauthd_init(char *ip, int sp, unsigned char options, char *m
extern int service_vnc_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_vnc_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_xmpp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_xmpp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_s7_300_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_s7_300_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_rtsp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
char *SERVICES = char *SERVICES =
"asterisk afp cisco cisco-enable cvs firebird ftp ftps http[s]-{head|get} http[s]-{get|post}-form http-proxy http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3[-{cram|digest}md5][s] mssql mysql ncp nntp oracle oracle-listener oracle-sid pcanywhere pcnfs pop3[s] postgres rdp redis rexec rlogin rsh s7-300 sapr3 sip smb smtp[s] smtp-enum snmp socks5 ssh sshkey svn teamspeak telnet[s] vmauthd vnc xmpp"; "asterisk afp cisco cisco-enable cvs firebird ftp ftps http[s]-{head|get} http[s]-{get|post}-form http-proxy http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3[-{cram|digest}md5][s] mssql mysql ncp nntp oracle oracle-listener oracle-sid pcanywhere pcnfs pop3[s] postgres rdp redis rexec rlogin rsh rtsp s7-300 sapr3 sip smb smtp[s] smtp-enum snmp socks5 ssh sshkey svn teamspeak telnet[s] vmauthd vnc xmpp";
#define MAXBUF 520 #define MAXBUF 520
#define MAXLINESIZE ( ( MAXBUF / 2 ) - 4 ) #define MAXLINESIZE ( ( MAXBUF / 2 ) - 4 )
@ -170,6 +173,7 @@ extern char *hydra_address2string(char *address);
extern int colored_output; extern int colored_output;
extern char quiet; extern char quiet;
extern int do_retry; extern int do_retry;
extern int old_ssl;
void hydra_kill_head(int head_no, int killit, int fail); void hydra_kill_head(int head_no, int killit, int fail);
@ -207,7 +211,7 @@ typedef struct {
char *redo_login[MAXTASKS * 2 + 2]; char *redo_login[MAXTASKS * 2 + 2];
char *redo_pass[MAXTASKS * 2 + 2]; char *redo_pass[MAXTASKS * 2 + 2];
char *skiplogin[SKIPLOGIN]; char *skiplogin[SKIPLOGIN];
// char *bfg_ptr[MAXTASKS]; // char *bfg_ptr[MAXTASKS];
} hydra_target; } hydra_target;
typedef struct { typedef struct {
@ -231,8 +235,8 @@ typedef struct {
int loop_mode; // valid modes: 0 = password, 1 = user int loop_mode; // valid modes: 0 = password, 1 = user
int ssl; int ssl;
int restore; int restore;
int debug; // is external - for restore int debug; // is external - for restore
int verbose; // is external - for restore int verbose; // is external - for restore
int showAttempt; int showAttempt;
int tasks; int tasks;
int try_null_password; int try_null_password;
@ -248,9 +252,9 @@ typedef struct {
char *outfile_ptr; char *outfile_ptr;
char *infile_ptr; char *infile_ptr;
char *colonfile; char *colonfile;
int waittime; // is external - for restore int waittime; // is external - for restore
int conwait; // is external - for restore int conwait; // is external - for restore
unsigned int port; // is external - for restore unsigned int port; // is external - for restore
char *miscptr; char *miscptr;
char *server; char *server;
char *service; char *service;
@ -263,7 +267,7 @@ typedef struct {
int port_ssl; int port_ssl;
} hydra_portlist; } hydra_portlist;
// external vars // external vars
extern char HYDRA_EXIT[5]; extern char HYDRA_EXIT[5];
#if !defined(ANDROID) && !defined(__BIONIC__) #if !defined(ANDROID) && !defined(__BIONIC__)
@ -282,7 +286,7 @@ extern char *proxy_authentication;
extern char *cmdlinetarget; extern char *cmdlinetarget;
extern char *fe80; extern char *fe80;
// required global vars // required global vars
char *prg; char *prg;
size_t size_of_data = -1; size_t size_of_data = -1;
hydra_head **hydra_heads = NULL; hydra_head **hydra_heads = NULL;
@ -293,7 +297,7 @@ char *sck = NULL;
int prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed = 0; int prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed = 0;
int child_head_no = -1, child_socket; int child_head_no = -1, child_socket;
// moved for restore feature // moved for restore feature
int process_restore = 0, dont_unlink; int process_restore = 0, dont_unlink;
char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL; char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL;
size_t countservers = 1, sizeservers = 0; size_t countservers = 1, sizeservers = 0;
@ -310,7 +314,7 @@ void help(int ext) {
#ifdef HAVE_MATH_H #ifdef HAVE_MATH_H
" [-x MIN:MAX:CHARSET]" " [-x MIN:MAX:CHARSET]"
#endif #endif
" [-SuvVd46] " " [-SOuvVd46] "
//"[server service [OPT]]|" //"[server service [OPT]]|"
"[service://server[:PORT][/OPT]]\n"); "[service://server[:PORT][/OPT]]\n");
printf("\nOptions:\n"); printf("\nOptions:\n");
@ -346,7 +350,9 @@ void help(int ext) {
if (ext) if (ext)
printf(" -v / -V / -d verbose mode / show login+pass for each attempt / debug mode \n"); printf(" -v / -V / -d verbose mode / show login+pass for each attempt / debug mode \n");
if (ext) if (ext)
printf(" -q do not print messages about connection erros\n"); printf(" -O use old SSL v2 and v3\n");
if (ext)
printf(" -q do not print messages about connection errors\n");
printf(" -U service module usage details\n"); printf(" -U service module usage details\n");
if (ext == 0) if (ext == 0)
printf(" -h more command line options (COMPLETE HELP)\n"); printf(" -h more command line options (COMPLETE HELP)\n");
@ -735,8 +741,8 @@ void hydra_restore_write(int print_msg) {
|| (hh.current_pass_ptr != NULL && hh.current_pass_ptr != empty_login)) { || (hh.current_pass_ptr != NULL && hh.current_pass_ptr != empty_login)) {
hh.redo = 1; hh.redo = 1;
if (print_msg && debug) if (print_msg && debug)
printf("[DEBUG] we will redo the following combination: target %s login \"%s\" pass \"%s\"\n", hydra_targets[hh.target_no]->target, printf("[DEBUG] we will redo the following combination: target %s child %d login \"%s\" pass \"%s\"\n", hydra_targets[hh.target_no]->target,
hh.current_login_ptr, hh.current_pass_ptr); j, hh.current_login_ptr, hh.current_pass_ptr);
} }
fck = fwrite((char *) &hh, sizeof(hydra_head), 1, f); fck = fwrite((char *) &hh, sizeof(hydra_head), 1, f);
if (hh.redo /* && (hydra_options.bfg == 0 || (hh.current_pass_ptr == hydra_targets[hh.target_no]->bfg_ptr[j] && isprint((char) hh.current_pass_ptr[0]))) */ ) if (hh.redo /* && (hydra_options.bfg == 0 || (hh.current_pass_ptr == hydra_targets[hh.target_no]->bfg_ptr[j] && isprint((char) hh.current_pass_ptr[0]))) */ )
@ -760,7 +766,8 @@ void hydra_restore_read() {
int i, j, orig_debug = debug; int i, j, orig_debug = debug;
char out[1024]; char out[1024];
if (debug) printf("[DEBUG] reading restore file %s\n", RESTOREFILE); if (debug)
printf("[DEBUG] reading restore file %s\n", RESTOREFILE);
if ((f = fopen(RESTOREFILE, "r")) == NULL) { if ((f = fopen(RESTOREFILE, "r")) == NULL) {
fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE); fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE);
perror(""); perror("");
@ -776,7 +783,8 @@ void hydra_restore_read() {
} }
fck = (int) fread(&bf_options, sizeof(bf_options), 1, f); fck = (int) fread(&bf_options, sizeof(bf_options), 1, f);
fck = (int) fread(mynull, sizeof(mynull), 1, f); fck = (int) fread(mynull, sizeof(mynull), 1, f);
if (debug) printf("[DEBUG] reading restore file: Step 1 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 1 complete\n");
if (mynull[0] + mynull[1] + mynull[2] + mynull[3] == 0) { if (mynull[0] + mynull[1] + mynull[2] + mynull[3] == 0) {
bf_options.crs = NULL; bf_options.crs = NULL;
} else { } else {
@ -784,7 +792,8 @@ void hydra_restore_read() {
memcpy(bf_options.crs, mynull, sizeof(mynull)); memcpy(bf_options.crs, mynull, sizeof(mynull));
fck = fread(bf_options.crs + sizeof(mynull), BF_CHARSMAX - sizeof(mynull), 1, f); fck = fread(bf_options.crs + sizeof(mynull), BF_CHARSMAX - sizeof(mynull), 1, f);
} }
if (debug) printf("[DEBUG] reading restore file: Step 2 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 2 complete\n");
fck = (int) fread(&hydra_brains, sizeof(hydra_brain), 1, f); fck = (int) fread(&hydra_brains, sizeof(hydra_brain), 1, f);
hydra_brains.ofp = stdout; hydra_brains.ofp = stdout;
@ -792,7 +801,8 @@ void hydra_restore_read() {
hydra_options.restore = 1; hydra_options.restore = 1;
verbose = hydra_options.verbose; verbose = hydra_options.verbose;
debug = hydra_options.debug; debug = hydra_options.debug;
if (debug || orig_debug) printf("[DEBUG] run_debug %d, orig_debug %d\n", debug, orig_debug); if (debug || orig_debug)
printf("[DEBUG] run_debug %d, orig_debug %d\n", debug, orig_debug);
if (orig_debug) { if (orig_debug) {
debug = 1; debug = 1;
hydra_options.debug = 1; hydra_options.debug = 1;
@ -807,43 +817,51 @@ void hydra_restore_read() {
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] reading restore file: Step 3 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 3 complete\n");
if (strlen(out) > 0) { if (strlen(out) > 0) {
hydra_options.outfile_ptr = malloc(strlen(out) + 1); hydra_options.outfile_ptr = malloc(strlen(out) + 1);
strcpy(hydra_options.outfile_ptr, out); strcpy(hydra_options.outfile_ptr, out);
} else } else
hydra_options.outfile_ptr = NULL; hydra_options.outfile_ptr = NULL;
if (debug) printf("[DEBUG] reading restore file: Step 4 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 4 complete\n");
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] reading restore file: Step 5 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 5 complete\n");
if (strlen(out) == 0) if (strlen(out) == 0)
hydra_options.miscptr = NULL; hydra_options.miscptr = NULL;
else { else {
hydra_options.miscptr = malloc(strlen(out) + 1); hydra_options.miscptr = malloc(strlen(out) + 1);
strcpy(hydra_options.miscptr, out); strcpy(hydra_options.miscptr, out);
} }
if (debug) printf("[DEBUG] reading restore file: Step 6 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 6 complete\n");
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] reading restore file: Step 7 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 7 complete\n");
hydra_options.service = malloc(strlen(out) + 1); hydra_options.service = malloc(strlen(out) + 1);
strcpy(hydra_options.service, out); strcpy(hydra_options.service, out);
if (debug) printf("[DEBUG] reading restore file: Step 8 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 8 complete\n");
login_ptr = malloc(hydra_brains.sizelogin); login_ptr = malloc(hydra_brains.sizelogin);
fck = (int) fread(login_ptr, hydra_brains.sizelogin, 1, f); fck = (int) fread(login_ptr, hydra_brains.sizelogin, 1, f);
if (debug) printf("[DEBUG] reading restore file: Step 9 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 9 complete\n");
if ((hydra_options.mode & 64) != 64) { // NOT colonfile mode if ((hydra_options.mode & 64) != 64) { // NOT colonfile mode
pass_ptr = malloc(hydra_brains.sizepass); pass_ptr = malloc(hydra_brains.sizepass);
fck = (int) fread(pass_ptr, hydra_brains.sizepass, 1, f); fck = (int) fread(pass_ptr, hydra_brains.sizepass, 1, f);
} else { // colonfile mode } else { // colonfile mode
hydra_options.colonfile = empty_login; // dummy hydra_options.colonfile = empty_login; // dummy
pass_ptr = csv_ptr = login_ptr; pass_ptr = csv_ptr = login_ptr;
} }
if (debug) printf("[DEBUG] reading restore file: Step 10 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 10 complete\n");
hydra_targets = malloc((hydra_brains.targets + 3) * sizeof(hydra_targets)); hydra_targets = malloc((hydra_brains.targets + 3) * sizeof(hydra_targets));
for (j = 0; j < hydra_brains.targets; j++) { for (j = 0; j < hydra_brains.targets; j++) {
@ -867,6 +885,7 @@ void hydra_restore_read() {
strcpy(hydra_targets[j]->pass_ptr, out); strcpy(hydra_targets[j]->pass_ptr, out);
} }
if (hydra_targets[j]->redo > 0) if (hydra_targets[j]->redo > 0)
if (debug) printf("[DEBUG] target %d redo %d\n", j, hydra_targets[j]->redo);
for (i = 0; i < hydra_targets[j]->redo; i++) { for (i = 0; i < hydra_targets[j]->redo; i++) {
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
@ -893,8 +912,9 @@ void hydra_restore_read() {
hydra_targets[j]->use_count = 0; hydra_targets[j]->use_count = 0;
hydra_targets[j]->failed = 0; hydra_targets[j]->failed = 0;
} }
if (debug) printf("[DEBUG] reading restore file: Step 11 complete\n"); if (debug)
hydra_heads = malloc((hydra_options.max_use + 2) * sizeof(int) + 8); printf("[DEBUG] reading restore file: Step 11 complete\n");
hydra_heads = malloc((hydra_options.max_use + 2) * sizeof(int) + 16);
for (j = 0; j < hydra_options.max_use; j++) { for (j = 0; j < hydra_options.max_use; j++) {
hydra_heads[j] = malloc(sizeof(hydra_head)); hydra_heads[j] = malloc(sizeof(hydra_head));
fck = (int) fread(hydra_heads[j], sizeof(hydra_head), 1, f); fck = (int) fread(hydra_heads[j], sizeof(hydra_head), 1, f);
@ -902,6 +922,7 @@ void hydra_restore_read() {
hydra_heads[j]->sp[1] = -1; hydra_heads[j]->sp[1] = -1;
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (hydra_heads[j]->redo) { if (hydra_heads[j]->redo) {
if (debug) printf("[DEBUG] head %d redo\n", j);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
hydra_heads[j]->current_login_ptr = malloc(strlen(out) + 1); hydra_heads[j]->current_login_ptr = malloc(strlen(out) + 1);
@ -911,7 +932,8 @@ void hydra_restore_read() {
if (hydra_heads[j]->redo) { if (hydra_heads[j]->redo) {
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] TEMP head %d: out[0] == %d, hydra_heads[j]->current_login_ptr[0] == %d\n", j, out[0], hydra_heads[j]->current_login_ptr[0]); if (debug)
printf("[DEBUG] TEMP head %d: pass == %s, login == %s\n", j, out, hydra_heads[j]->current_login_ptr);
if (out[0] != 0 || hydra_heads[j]->current_login_ptr[0] != 0) { if (out[0] != 0 || hydra_heads[j]->current_login_ptr[0] != 0) {
hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1); hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1);
strcpy(hydra_heads[j]->current_pass_ptr, out); strcpy(hydra_heads[j]->current_pass_ptr, out);
@ -926,7 +948,8 @@ if (debug) printf("[DEBUG] TEMP head %d: out[0] == %d, hydra_heads[j]->current_l
hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login; hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login;
} }
} }
if (debug) printf("[DEBUG] reading restore file: Step 12 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 12 complete\n");
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
@ -1027,14 +1050,14 @@ void fill_mem(char *ptr, FILE * fp, int colonmode) {
fprintf(stderr, "[ERROR] invalid line in colon file (-C), missing colon in line: %s\n", tmp); fprintf(stderr, "[ERROR] invalid line in colon file (-C), missing colon in line: %s\n", tmp);
exit(-1); exit(-1);
} else { } else {
// if (tmp[0] == ':') { // if (tmp[0] == ':') {
// *ptr = 0; // *ptr = 0;
// ptr++; // ptr++;
// } // }
// if (tmp[len - 1] == ':' && len > 1) { // if (tmp[len - 1] == ':' && len > 1) {
// len++; // len++;
// tmp[len - 1] = 0; // tmp[len - 1] = 0;
// } // }
*ptr2 = 0; *ptr2 = 0;
} }
} }
@ -1177,7 +1200,10 @@ void hydra_service_init(int target_no) {
x = service_xmpp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); x = service_xmpp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
if (strcmp(hydra_options.service, "s7-300") == 0) if (strcmp(hydra_options.service, "s7-300") == 0)
x = service_s7_300_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); x = service_s7_300_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE if (strcmp(hydra_options.service, "rtsp") == 0)
x = service_rtsp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE
if (x != 0 && x != 99) { if (x != 0 && x != 99) {
if (x > 0 && x < 4) if (x > 0 && x < 4)
@ -1207,8 +1233,8 @@ int hydra_spawn_head(int head_no, int target_no) {
if (socketpair(PF_UNIX, SOCK_STREAM, 0, hydra_heads[head_no]->sp) == 0) { if (socketpair(PF_UNIX, SOCK_STREAM, 0, hydra_heads[head_no]->sp) == 0) {
child_head_no = head_no; child_head_no = head_no;
if ((hydra_heads[head_no]->pid = fork()) == 0) { // THIS IS THE CHILD if ((hydra_heads[head_no]->pid = fork()) == 0) { // THIS IS THE CHILD
// set new signals for child // set new signals for child
process_restore = 0; process_restore = 0;
child_socket = hydra_heads[head_no]->sp[1]; child_socket = hydra_heads[head_no]->sp[1];
signal(SIGCHLD, killed_childs); signal(SIGCHLD, killed_childs);
@ -1220,7 +1246,7 @@ int hydra_spawn_head(int head_no, int target_no) {
signal(SIGHUP, exit); signal(SIGHUP, exit);
signal(SIGINT, exit); signal(SIGINT, exit);
signal(SIGPIPE, exit); signal(SIGPIPE, exit);
// free structures to make memory available // free structures to make memory available
cmdlinetarget = hydra_targets[target_no]->target; cmdlinetarget = hydra_targets[target_no]->target;
for (i = 0; i < hydra_options.max_use; i++) for (i = 0; i < hydra_options.max_use; i++)
if (i != head_no) if (i != head_no)
@ -1234,17 +1260,20 @@ int hydra_spawn_head(int head_no, int target_no) {
free(pass_ptr); free(pass_ptr);
if (hydra_options.colonfile != NULL && hydra_options.colonfile != empty_login) if (hydra_options.colonfile != NULL && hydra_options.colonfile != empty_login)
free(csv_ptr); free(csv_ptr);
// we must keep servers_ptr for cmdlinetarget to work // we must keep servers_ptr for cmdlinetarget to work
if (debug) if (debug)
printf("[DEBUG] head_no %d has pid %d\n", head_no, getpid()); printf("[DEBUG] head_no %d has pid %d\n", head_no, getpid());
// now call crack module // now call crack module
if (strcmp(hydra_options.service, "asterisk") == 0) if (strcmp(hydra_options.service, "asterisk") == 0)
service_asterisk(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); service_asterisk(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
if (strcmp(hydra_options.service, "telnet") == 0) if (strcmp(hydra_options.service, "telnet") == 0)
service_telnet(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); service_telnet(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
if (strcmp(hydra_options.service, "ftp") == 0) if (strcmp(hydra_options.service, "ftp") == 0) {
service_ftp(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); service_ftp(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
}
if (strcmp(hydra_options.service, "ftps") == 0) if (strcmp(hydra_options.service, "ftps") == 0)
service_ftps(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); service_ftps(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
if (strcmp(hydra_options.service, "redis") == 0) if (strcmp(hydra_options.service, "redis") == 0)
@ -1372,14 +1401,17 @@ int hydra_spawn_head(int head_no, int target_no) {
#endif #endif
if (strcmp(hydra_options.service, "s7-300") == 0) if (strcmp(hydra_options.service, "s7-300") == 0)
service_s7_300(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); service_s7_300(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE if (strcmp(hydra_options.service, "rtsp") == 0)
service_rtsp(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE
// just in case a module returns (which it shouldnt) we let it exit here
// just in case a module returns (which it shouldnt) we let it exit here
exit(-1); exit(-1);
} else { } else {
child_head_no = -1; child_head_no = -1;
if (hydra_heads[head_no]->pid > 0) { if (hydra_heads[head_no]->pid > 0) {
fck = write(hydra_heads[head_no]->sp[1], "n", 1); // yes, a small "n" - this way we can distinguish later if the client successfully tested a pair and is requesting a new one or the mother did that fck = write(hydra_heads[head_no]->sp[1], "n", 1); // yes, a small "n" - this way we can distinguish later if the client successfully tested a pair and is requesting a new one or the mother did that
(void) fcntl(hydra_heads[head_no]->sp[0], F_SETFL, O_NONBLOCK); (void) fcntl(hydra_heads[head_no]->sp[0], F_SETFL, O_NONBLOCK);
if (hydra_heads[head_no]->redo != 1) if (hydra_heads[head_no]->redo != 1)
hydra_heads[head_no]->target_no = target_no; hydra_heads[head_no]->target_no = target_no;
@ -1467,7 +1499,8 @@ int hydra_lookup_port(char *service) {
{"rdp", PORT_RDP, PORT_RDP_SSL}, {"rdp", PORT_RDP, PORT_RDP_SSL},
{"asterisk", PORT_ASTERISK, PORT_ASTERISK_SSL}, {"asterisk", PORT_ASTERISK, PORT_ASTERISK_SSL},
{"s7-300", PORT_S7_300, PORT_S7_300_SSL}, {"s7-300", PORT_S7_300, PORT_S7_300_SSL},
// ADD NEW SERVICES HERE - add new port numbers to hydra.h {"rtsp", PORT_RTSP, PORT_RTSP_SSL},
// ADD NEW SERVICES HERE - add new port numbers to hydra.h
{"", PORT_NOPORT, PORT_NOPORT} {"", PORT_NOPORT, PORT_NOPORT}
}; };
@ -1488,7 +1521,8 @@ int hydra_lookup_port(char *service) {
// killit = 1 : kill(pid); fail = 1 : redo, fail = 2/3 : disable // killit = 1 : kill(pid); fail = 1 : redo, fail = 2/3 : disable
void hydra_kill_head(int head_no, int killit, int fail) { void hydra_kill_head(int head_no, int killit, int fail) {
if (debug) printf("[DEBUG] head_no %d, kill %d, fail %d\n", head_no, killit, fail); if (debug)
printf("[DEBUG] head_no %d, kill %d, fail %d\n", head_no, killit, fail);
if (head_no < 0) if (head_no < 0)
return; return;
if (hydra_heads[head_no]->active > 0) { if (hydra_heads[head_no]->active > 0) {
@ -1524,8 +1558,8 @@ void hydra_kill_head(int head_no, int killit, int fail) {
&& strlen(hydra_heads[head_no]->current_pass_ptr) > 0 && hydra_heads[head_no]->current_pass_ptr != hydra_heads[head_no]->current_login_ptr) { && strlen(hydra_heads[head_no]->current_pass_ptr) > 0 && hydra_heads[head_no]->current_pass_ptr != hydra_heads[head_no]->current_login_ptr) {
free(hydra_heads[head_no]->current_pass_ptr); free(hydra_heads[head_no]->current_pass_ptr);
hydra_heads[head_no]->current_pass_ptr = empty_login; hydra_heads[head_no]->current_pass_ptr = empty_login;
// hydra_bfg_remove(head_no); // hydra_bfg_remove(head_no);
// hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = NULL; // hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = NULL;
} }
(void) wait3(NULL, WNOHANG, NULL); (void) wait3(NULL, WNOHANG, NULL);
} }
@ -1622,16 +1656,51 @@ void hydra_increase_fail_count(int target_no, int head_no) {
} }
char *hydra_reverse_login(int head_no, char *login) { char *hydra_reverse_login(int head_no, char *login) {
int i, j = strlen(login); int i, j;
char *start, *pos;
unsigned char keep;
if (login == NULL || (j = strlen(login)) < 1)
return empty_login;
if (j > 248) if (j > 248)
j = 248; j = 248;
else if (j == 0)
return empty_login;
for (i = 0; i < j; i++) for (i = 0; i < j; i++)
hydra_heads[head_no]->reverse[i] = login[j - (i + 1)]; hydra_heads[head_no]->reverse[i] = login[j - (i + 1)];
hydra_heads[head_no]->reverse[j] = 0; hydra_heads[head_no]->reverse[j] = 0;
// UTF stuff now
start = hydra_heads[head_no]->reverse;
pos = start + j;
while(start < --pos) {
switch( (*pos & 0xF0) >> 4 ) {
case 0xF: /* U+010000-U+10FFFF: four bytes. */
keep = *pos;
*pos = *(pos-3);
*(pos-3) = keep;
keep = *(pos-1);
*(pos-1) = *(pos-2);
*(pos-2) = keep;
pos -= 3;
break;
case 0xE: /* U+000800-U+00FFFF: three bytes. */
keep = *pos;
*pos = *(pos-2);
*(pos-2) = keep;
pos -= 2;
break;
case 0xC: /* fall-through */
case 0xD: /* U+000080-U+0007FF: two bytes. */
keep = *pos;
*pos = *(pos-1);
*(pos-1) = keep;
pos--;
break;
}
}
return hydra_heads[head_no]->reverse; return hydra_heads[head_no]->reverse;
} }
@ -1911,7 +1980,7 @@ int hydra_send_next_pair(int target_no, int head_no) {
} }
} }
if (hydra_brains.targets > hydra_brains.finished) if (hydra_brains.targets > hydra_brains.finished)
hydra_kill_head(head_no, 1, 0); // otherwise done in main while loop hydra_kill_head(head_no, 1, 0); // otherwise done in main while loop
} else { } else {
if (hydra_targets[target_no]->skipcnt > 0) { if (hydra_targets[target_no]->skipcnt > 0) {
snpj = 0; snpj = 0;
@ -2159,7 +2228,7 @@ int main(int argc, char *argv[]) {
(void) setvbuf(stdout, NULL, _IONBF, 0); (void) setvbuf(stdout, NULL, _IONBF, 0);
(void) setvbuf(stderr, NULL, _IONBF, 0); (void) setvbuf(stderr, NULL, _IONBF, 0);
// set defaults // set defaults
memset(&hydra_options, 0, sizeof(hydra_options)); memset(&hydra_options, 0, sizeof(hydra_options));
memset(&hydra_brains, 0, sizeof(hydra_brains)); memset(&hydra_brains, 0, sizeof(hydra_brains));
prg = argv[0]; prg = argv[0];
@ -2186,7 +2255,7 @@ int main(int argc, char *argv[]) {
help(1); help(1);
if (argc < 2) if (argc < 2)
help(0); help(0);
while ((i = getopt(argc, argv, "hq64Rde:vVl:fFg:L:p:P:o:M:C:t:T:m:w:W:s:SUux:")) >= 0) { while ((i = getopt(argc, argv, "hq64Rde:vVl:fFg:L:p:OP:o:M:C:t:T:m:w:W:s:SUux:")) >= 0) {
switch (i) { switch (i) {
case 'h': case 'h':
help(1); help(1);
@ -2194,6 +2263,9 @@ int main(int argc, char *argv[]) {
case 'q': case 'q':
quiet = 1; quiet = 1;
break; break;
case 'O':
old_ssl = 1;
break;
case 'u': case 'u':
hydra_options.loop_mode = 1; hydra_options.loop_mode = 1;
break; break;
@ -2261,7 +2333,7 @@ int main(int argc, char *argv[]) {
break; break;
case 'o': case 'o':
hydra_options.outfile_ptr = optarg; hydra_options.outfile_ptr = optarg;
// colored_output = 0; // colored_output = 0;
break; break;
case 'M': case 'M':
hydra_options.infile_ptr = optarg; hydra_options.infile_ptr = optarg;
@ -2359,7 +2431,7 @@ int main(int argc, char *argv[]) {
bail("You can only use -P OR -p, not both\n"); bail("You can only use -P OR -p, not both\n");
if (hydra_options.restore) { if (hydra_options.restore) {
hydra_restore_read(); hydra_restore_read();
// stuff we have to copy from the non-restore part // stuff we have to copy from the non-restore part
if (strncmp(hydra_options.service, "http-", 5) == 0) { if (strncmp(hydra_options.service, "http-", 5) == 0) {
if (getenv("HYDRA_PROXY_HTTP") && getenv("HYDRA_PROXY")) if (getenv("HYDRA_PROXY_HTTP") && getenv("HYDRA_PROXY"))
bail("Found HYDRA_PROXY_HTTP *and* HYDRA_PROXY environment variables - you can use only ONE for the service http-head/http-get!"); bail("Found HYDRA_PROXY_HTTP *and* HYDRA_PROXY environment variables - you can use only ONE for the service http-head/http-get!");
@ -2368,7 +2440,7 @@ int main(int argc, char *argv[]) {
use_proxy = 1; use_proxy = 1;
} }
} }
} else { // normal mode, aka non-restore mode } else { // normal mode, aka non-restore mode
if (hydra_options.colonfile) if (hydra_options.colonfile)
hydra_options.loop_mode = 0; // just to be sure hydra_options.loop_mode = 0; // just to be sure
if (hydra_options.infile_ptr != NULL) { if (hydra_options.infile_ptr != NULL) {
@ -2382,8 +2454,8 @@ int main(int argc, char *argv[]) {
hydra_options.service = argv[optind]; hydra_options.service = argv[optind];
if (optind + 2 == argc) if (optind + 2 == argc)
hydra_options.miscptr = argv[optind + 1]; hydra_options.miscptr = argv[optind + 1];
} else if (optind + 2 != argc && optind + 3 != argc) { } else if (optind + 2 != argc && optind + 3 != argc && optind < argc) {
// check if targetdef follow syntax <service-name>://<target>[:<port-number>][/<parameters>] or it's a syntax error // check if targetdef follow syntax <service-name>://<target>[:<port-number>][/<parameters>] or it's a syntax error
char *targetdef = strdup(argv[optind]); char *targetdef = strdup(argv[optind]);
char *service_pos, *target_pos, *port_pos = NULL, *param_pos = NULL; char *service_pos, *target_pos, *port_pos = NULL, *param_pos = NULL;
@ -2433,7 +2505,7 @@ int main(int argc, char *argv[]) {
*--param_pos = '/'; *--param_pos = '/';
hydra_options.miscptr = param_pos; hydra_options.miscptr = param_pos;
} }
//printf("target: %s service: %s port: %s opt: %s\n", target_pos, hydra_options.service, port_pos, param_pos); //printf("target: %s service: %s port: %s opt: %s\n", target_pos, hydra_options.service, port_pos, param_pos);
if (debug) if (debug)
printf("[DEBUG] opt:%d argc:%d mod:%s tgt:%s port:%d misc:%s\n", optind, argc, hydra_options.service, hydra_options.server, hydra_options.port, hydra_options.miscptr); printf("[DEBUG] opt:%d argc:%d mod:%s tgt:%s port:%d misc:%s\n", optind, argc, hydra_options.service, hydra_options.server, hydra_options.port, hydra_options.miscptr);
} else { } else {
@ -2790,7 +2862,9 @@ int main(int argc, char *argv[]) {
if (hydra_options.miscptr == NULL) if (hydra_options.miscptr == NULL)
bail("-m option is required to specify the DN\n"); bail("-m option is required to specify the DN\n");
} }
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
if (strcmp(hydra_options.service, "rtsp") == 0)
i = 1;
if (strcmp(hydra_options.service, "s7-300") == 0) { if (strcmp(hydra_options.service, "s7-300") == 0) {
if (hydra_options.tasks > 8) { if (hydra_options.tasks > 8) {
fprintf(stderr, "[INFO] Reduced number of tasks to 8 (the PLC does not like more connections)\n"); fprintf(stderr, "[INFO] Reduced number of tasks to 8 (the PLC does not like more connections)\n");
@ -2799,14 +2873,12 @@ int main(int argc, char *argv[]) {
i = 2; i = 2;
} }
if (strcmp(hydra_options.service, "cisco-enable") == 0) { if (strcmp(hydra_options.service, "cisco-enable") == 0) {
i = 2; if (hydra_options.login != NULL || hydra_options.loginfile != NULL)
if (hydra_options.login == NULL) {
//hydra_options.login = empty_login;
i = 1; // login will be the initial Username: login, or line Password: i = 1; // login will be the initial Username: login, or line Password:
} else
if (hydra_options.miscptr == NULL) { i = 2;
if (hydra_options.miscptr == NULL)
fprintf(stderr, "[WARNING] You did not supply the initial support to the Cisco via -l, assuming direct console access\n"); fprintf(stderr, "[WARNING] You did not supply the initial support to the Cisco via -l, assuming direct console access\n");
}
if (hydra_options.tasks > 4) if (hydra_options.tasks > 4)
fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco enable services.\n"); fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco enable services.\n");
} }
@ -2948,7 +3020,8 @@ int main(int argc, char *argv[]) {
// hydra_options.conwait = conwait = 1; // hydra_options.conwait = conwait = 1;
i = 1; i = 1;
} }
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
if (i == 0) { if (i == 0) {
fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service); fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service);
@ -3008,7 +3081,7 @@ int main(int argc, char *argv[]) {
bail("The -x (password bruteforce generation option) doesn't work with -p/P, -C or -e!\n"); bail("The -x (password bruteforce generation option) doesn't work with -p/P, -C or -e!\n");
if (hydra_options.try_password_reverse_login == 0 && hydra_options.try_password_same_as_login == 0 && hydra_options.try_null_password == 0 if (hydra_options.try_password_reverse_login == 0 && hydra_options.try_password_same_as_login == 0 && hydra_options.try_null_password == 0
&& (i != 3 && (hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.colonfile == NULL)) && hydra_options.bfg == 0) { && (i != 3 && (hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.colonfile == NULL)) && hydra_options.bfg == 0) {
// test if the service is smtp-enum as it could be used either with a login+pass or only a login // test if the service is smtp-enum as it could be used either with a login+pass or only a login
if (strstr(hydra_options.service, "smtp-enum") != NULL) if (strstr(hydra_options.service, "smtp-enum") != NULL)
hydra_options.pass = empty_login; hydra_options.pass = empty_login;
else else
@ -3022,6 +3095,9 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", MAXTASKS); fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", MAXTASKS);
hydra_options.max_use = MAXTASKS; hydra_options.max_use = MAXTASKS;
} }
// script kiddie patch
if (hydra_options.server != NULL && (hydra_strcasestr(hydra_options.server, "gmail.") != NULL || hydra_strcasestr(hydra_options.server, "googlemail.") != NULL))
fprintf(stderr, "[WARNING] Google Mail has bruteforce detection and sends false positives. You are not doing anything illegal right?!\n");
if (hydra_options.colonfile == NULL) { if (hydra_options.colonfile == NULL) {
if (hydra_options.loginfile != NULL) { if (hydra_options.loginfile != NULL) {
@ -3124,8 +3200,8 @@ int main(int argc, char *argv[]) {
bail("Could not allocate enough memory for colon file data"); bail("Could not allocate enough memory for colon file data");
memset(csv_ptr, 0, hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8); memset(csv_ptr, 0, hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8);
fill_mem(csv_ptr, cfp, 1); fill_mem(csv_ptr, cfp, 1);
//printf("count: %d, size: %d\n", hydra_brains.countlogin, hydra_brains.sizelogin); //printf("count: %d, size: %d\n", hydra_brains.countlogin, hydra_brains.sizelogin);
//hydra_dump_data(csv_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, "colon data"); //hydra_dump_data(csv_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, "colon data");
hydra_brains.countpass = 1; hydra_brains.countpass = 1;
pass_ptr = login_ptr = csv_ptr; pass_ptr = login_ptr = csv_ptr;
while (*pass_ptr != 0) while (*pass_ptr != 0)
@ -3155,7 +3231,7 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for targets is empty: %s", hydra_options.infile_ptr); fprintf(stderr, "[ERROR] File for targets is empty: %s", hydra_options.infile_ptr);
exit(-1); exit(-1);
} }
// if (countinfile > 60) fprintf(stderr, "[WARNING] the -M option is not working correctly at the moment for target lists > 60!\n"); // if (countinfile > 60) fprintf(stderr, "[WARNING] the -M option is not working correctly at the moment for target lists > 60!\n");
hydra_targets = malloc(sizeof(hydra_targets) * (countservers + 2) + 8); hydra_targets = malloc(sizeof(hydra_targets) * (countservers + 2) + 8);
if (hydra_targets == NULL) if (hydra_targets == NULL)
bail("Could not allocate enough memory for target data"); bail("Could not allocate enough memory for target data");
@ -3272,7 +3348,7 @@ int main(int argc, char *argv[]) {
hydra_targets[i]->pass_state = 3; hydra_targets[i]->pass_state = 3;
} }
} }
} // END OF restore == 0 } // END OF restore == 0
if (getenv("HYDRA_PROXY") && use_proxy == 0) { if (getenv("HYDRA_PROXY") && use_proxy == 0) {
printf("[INFO] Using Connect Proxy: %s\n", getenv("HYDRA_PROXY")); printf("[INFO] Using Connect Proxy: %s\n", getenv("HYDRA_PROXY"));
@ -3384,7 +3460,7 @@ int main(int argc, char *argv[]) {
hydra_options.tasks = hydra_brains.todo; hydra_options.tasks = hydra_brains.todo;
} }
} }
if (hydra_options.max_use == MAXTASKS) { // only if it was not set via -T if (hydra_options.max_use == MAXTASKS) { // only if it was not set via -T
if (hydra_options.max_use < hydra_brains.targets * hydra_options.tasks) if (hydra_options.max_use < hydra_brains.targets * hydra_options.tasks)
hydra_options.max_use = hydra_brains.targets * hydra_options.tasks; hydra_options.max_use = hydra_brains.targets * hydra_options.tasks;
if (hydra_options.max_use > MAXTASKS) if (hydra_options.max_use > MAXTASKS)
@ -3400,14 +3476,14 @@ int main(int argc, char *argv[]) {
hydra_options.tasks = MAXTASKS; hydra_options.tasks = MAXTASKS;
} }
} }
// hydra_options.max_use = hydra_brains.targets * hydra_options.tasks; // hydra_options.max_use = hydra_brains.targets * hydra_options.tasks;
// if (hydra_options.max_use > MAXTASKS) // if (hydra_options.max_use > MAXTASKS)
// hydra_options.max_use = MAXTASKS; // hydra_options.max_use = MAXTASKS;
math2 = (hydra_brains.todo / hydra_options.tasks); math2 = (hydra_brains.todo / hydra_options.tasks);
if (hydra_brains.todo % hydra_options.tasks) if (hydra_brains.todo % hydra_options.tasks)
math2++; math2++;
math2 = (math2 * hydra_brains.targets) / hydra_options.max_use; math2 = (math2 * hydra_brains.targets) / hydra_options.max_use;
// set options (bits!) // set options (bits!)
options = 0; options = 0;
if (hydra_options.ssl) if (hydra_options.ssl)
options = options | OPTION_SSL; options = options | OPTION_SSL;
@ -3420,7 +3496,7 @@ int main(int argc, char *argv[]) {
hydra_brains.targets, hydra_brains.targets == 1 ? "" : "s", hydra_options.max_use, hydra_brains.todo, hydra_brains.todo == 1 ? "y" : "ies", hydra_brains.targets, hydra_brains.targets == 1 ? "" : "s", hydra_options.max_use, hydra_brains.todo, hydra_brains.todo == 1 ? "y" : "ies",
(unsigned long int) hydra_brains.countlogin, (unsigned long int) hydra_brains.countpass, math2, math2 == 1 ? "y" : "ies"); (unsigned long int) hydra_brains.countlogin, (unsigned long int) hydra_brains.countpass, math2, math2 == 1 ? "y" : "ies");
printf("[DATA] attacking service %s on port %d%s\n", hydra_options.service, port, hydra_options.ssl == 1 ? " with SSL" : ""); printf("[DATA] attacking service %s on port %d%s\n", hydra_options.service, port, hydra_options.ssl == 1 ? " with SSL" : "");
if (hydra_options.outfile_ptr != NULL) { if (hydra_options.outfile_ptr != NULL) {
if ((hydra_brains.ofp = fopen(hydra_options.outfile_ptr, "a+")) == NULL) { if ((hydra_brains.ofp = fopen(hydra_options.outfile_ptr, "a+")) == NULL) {
@ -3433,8 +3509,8 @@ int main(int argc, char *argv[]) {
fprintf(hydra_brains.ofp, " %s", argv[i]); fprintf(hydra_brains.ofp, " %s", argv[i]);
fprintf(hydra_brains.ofp, ")\n"); fprintf(hydra_brains.ofp, ")\n");
} }
// we have to flush all writeable buffered file pointers before forking // we have to flush all writeable buffered file pointers before forking
// set appropriate signals for mother // set appropriate signals for mother
signal(SIGCHLD, killed_childs); signal(SIGCHLD, killed_childs);
if (debug == 0) if (debug == 0)
signal(SIGTERM, kill_children); signal(SIGTERM, kill_children);
@ -3542,7 +3618,7 @@ int main(int argc, char *argv[]) {
// here we call the init function of the relevant service module // here we call the init function of the relevant service module
// should we do the init centrally or should each child do that? // should we do the init centrally or should each child do that?
// that depends largely on the number of targets and maximum tasks // that depends largely on the number of targets and maximum tasks
// if (hydra_brains.targets == 1 || (hydra_brains.targets < 4 && hydra_options.tasks / hydra_brains.targets > 4 && hydra_brains.todo > 15)) // if (hydra_brains.targets == 1 || (hydra_brains.targets < 4 && hydra_options.tasks / hydra_brains.targets > 4 && hydra_brains.todo > 15))
for (i = 0; i < hydra_brains.targets; i++) for (i = 0; i < hydra_brains.targets; i++)
hydra_service_init(i); hydra_service_init(i);
@ -3568,7 +3644,8 @@ int main(int argc, char *argv[]) {
tmp_time = time(NULL); tmp_time = time(NULL);
for (head_no = 0; head_no < hydra_options.max_use; head_no++) { for (head_no = 0; head_no < hydra_options.max_use; head_no++) {
if (debug && hydra_heads[head_no]->active != -1) printf("[DEBUG] head_no[%d] to target_no %d active %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->active); if (debug && hydra_heads[head_no]->active != -1)
printf("[DEBUG] head_no[%d] to target_no %d active %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->active);
switch (hydra_heads[head_no]->active) { switch (hydra_heads[head_no]->active) {
case -1: case -1:
// disabled head, ignored // disabled head, ignored
@ -3584,7 +3661,8 @@ int main(int argc, char *argv[]) {
if (debug) if (debug)
printf("[DEBUG] child %d got target %d selected\n", head_no, hydra_heads[head_no]->target_no); printf("[DEBUG] child %d got target %d selected\n", head_no, hydra_heads[head_no]->target_no);
if (hydra_heads[head_no]->target_no < 0) { if (hydra_heads[head_no]->target_no < 0) {
if (debug) printf("[DEBUG] hydra_select_target() reports no more targets left\n"); if (debug)
printf("[DEBUG] hydra_select_target() reports no more targets left\n");
hydra_kill_head(head_no, 0, 3); hydra_kill_head(head_no, 0, 3);
} else } else
hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); // target_no is ignored if head->redo == 1 hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); // target_no is ignored if head->redo == 1
@ -3624,34 +3702,47 @@ int main(int argc, char *argv[]) {
if (colored_output) { if (colored_output) {
if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) {
if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0)
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target);
else else
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port,
hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr);
} else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port,
hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n",
hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target,
hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
} else { } else {
if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) {
if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0)
printf("[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target); printf("[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target);
else else
printf("[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr); printf("[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr);
} else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
printf("[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); printf("[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
} }
if (hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { if (hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) {
if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) {
if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0)
fprintf(hydra_brains.ofp, "[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target); fprintf(hydra_brains.ofp, "[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target);
else else
fprintf(hydra_brains.ofp, "[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr); fprintf(hydra_brains.ofp, "[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr);
} else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
} }
if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found
if (hydra_targets[hydra_heads[head_no]->target_no]->done == 0) { if (hydra_targets[hydra_heads[head_no]->target_no]->done == 0) {
@ -3669,10 +3760,10 @@ int main(int argc, char *argv[]) {
for (j = 0; j < hydra_options.max_use; j++) for (j = 0; j < hydra_options.max_use; j++)
if (hydra_heads[j]->active >= 0 && (hydra_heads[j]->target_no == target_no || hydra_options.exit_found == 2)) { if (hydra_heads[j]->active >= 0 && (hydra_heads[j]->target_no == target_no || hydra_options.exit_found == 2)) {
if (hydra_brains.targets > hydra_brains.finished && hydra_options.exit_found < 2) if (hydra_brains.targets > hydra_brains.finished && hydra_options.exit_found < 2)
hydra_kill_head(j, 1, 0); // kill all heads working on the target hydra_kill_head(j, 1, 0); // kill all heads working on the target
else else
hydra_kill_head(j, 1, 2); // kill all heads working on the target hydra_kill_head(j, 1, 2); // kill all heads working on the target
} }
continue; continue;
} }
// fall through // fall through
@ -3766,7 +3857,7 @@ int main(int argc, char *argv[]) {
for (j = 0; j < hydra_options.max_use; j++) for (j = 0; j < hydra_options.max_use; j++)
if (hydra_heads[j]->active >= 0) if (hydra_heads[j]->active >= 0)
k++; k++;
printf("[STATUS] %.2f tries/min, %lu tries in %02lu:%02luh, %lu to do in %02lu:%02luh, %d active\n", (1.0 * hydra_brains.sent) / (((elapsed_status - starttime) * 1.0) / 60), // tries/min printf("[STATUS] %.2f tries/min, %lu tries in %02lu:%02luh, %lu to do in %02lu:%02luh, %d active\n", (1.0 * hydra_brains.sent) / (((elapsed_status - starttime) * 1.0) / 60), // tries/min
hydra_brains.sent, // tries hydra_brains.sent, // tries
(long unsigned int) ((elapsed_status - starttime) / 3600), // hours (long unsigned int) ((elapsed_status - starttime) / 3600), // hours
(long unsigned int) (((elapsed_status - starttime) % 3600) / 60), // minutes (long unsigned int) (((elapsed_status - starttime) % 3600) / 60), // minutes
@ -3810,7 +3901,8 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] illegal target result value (%d=>%d)\n", i, hydra_targets[i]->done); fprintf(stderr, "[ERROR] illegal target result value (%d=>%d)\n", i, hydra_targets[i]->done);
} }
if (debug) printf("[DEBUG] killing all remaining childs now that might be stuck\n"); if (debug)
printf("[DEBUG] killing all remaining childs now that might be stuck\n");
for (i = 0; i < hydra_options.max_use; i++) for (i = 0; i < hydra_options.max_use; i++)
if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0) if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0)
hydra_kill_head(i, 1, 3); hydra_kill_head(i, 1, 3);

View file

@ -118,6 +118,8 @@
#define PORT_S7_300_SSL 102 #define PORT_S7_300_SSL 102
#define PORT_REDIS 6379 #define PORT_REDIS 6379
#define PORT_REDIS_SSL 6379 #define PORT_REDIS_SSL 6379
#define PORT_RTSP 554
#define PORT_RTSP_SSL 554
#define False 0 #define False 0
#define True 1 #define True 1

189
sasl.c
View file

@ -1,10 +1,8 @@
#include "sasl.h" #include "sasl.h"
/* /*
print_hex is used for debug print_hex is used for debug
it displays the string buf hexa values of size len it displays the string buf hexa values of size len
*/ */
int print_hex(unsigned char *buf, int len) { int print_hex(unsigned char *buf, int len) {
int i; int i;
@ -19,23 +17,18 @@ int print_hex(unsigned char *buf, int len) {
n++; n++;
} }
printf("\n"); printf("\n");
return (0); return (0);
} }
/* /*
RFC 4013: SASLprep: Stringprep Profile for User Names and Passwords RFC 4013: SASLprep: Stringprep Profile for User Names and Passwords
code based on gsasl_saslprep from GSASL project code based on gsasl_saslprep from GSASL project
*/ */
int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) { int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
#if LIBIDN #if LIBIDN
int rc; int rc;
rc = stringprep_profile(in, out, "SASLprep", (flags & SASL_ALLOW_UNASSIGNED) ? STRINGPREP_NO_UNASSIGNED : 0); rc = stringprep_profile(in, out, "SASLprep", (flags & SASL_ALLOW_UNASSIGNED) ? STRINGPREP_NO_UNASSIGNED : 0);
if (rc != STRINGPREP_OK) { if (rc != STRINGPREP_OK) {
*out = NULL; *out = NULL;
return -1; return -1;
@ -47,7 +40,6 @@ int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
return -1; return -1;
} }
#endif #endif
#else #else
size_t i, inlen = strlen(in); size_t i, inlen = strlen(in);
@ -68,36 +60,27 @@ int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
return 0; return 0;
} }
/* /*
RFC 4616: The PLAIN Simple Authentication and Security Layer (SASL) Mechanism RFC 4616: The PLAIN Simple Authentication and Security Layer (SASL) Mechanism
sasl_plain computes the plain authentication from strings login and password sasl_plain computes the plain authentication from strings login and password
and stored the value in variable result and stored the value in variable result
the first parameter result must be able to hold at least 255 bytes! the first parameter result must be able to hold at least 255 bytes!
*/ */
void sasl_plain(char *result, char *login, char *pass) { void sasl_plain(char *result, char *login, char *pass) {
char *preplogin; char *preplogin;
char *preppasswd; char *preppasswd;
int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin); int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
free(preplogin); free(preplogin);
result = NULL; result = NULL;
return; return;
} }
if (2 * strlen(preplogin) + 3 + strlen(preppasswd) < 180) { if (2 * strlen(preplogin) + 3 + strlen(preppasswd) < 180) {
strcpy(result, preplogin); strcpy(result, preplogin);
strcpy(result + strlen(preplogin) + 1, preplogin); strcpy(result + strlen(preplogin) + 1, preplogin);
@ -111,17 +94,12 @@ void sasl_plain(char *result, char *login, char *pass) {
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
/* /*
RFC 2195: IMAP/POP AUTHorize Extension for Simple Challenge/Response RFC 2195: IMAP/POP AUTHorize Extension for Simple Challenge/Response
sasl_cram_md5 computes the cram-md5 authentication from password string sasl_cram_md5 computes the cram-md5 authentication from password string
and the challenge sent by the server, and stored the value in variable and the challenge sent by the server, and stored the value in variable
result result
the parameter result must be able to hold at least 100 bytes! the parameter result must be able to hold at least 100 bytes!
*/ */
void sasl_cram_md5(char *result, char *pass, char *challenge) { void sasl_cram_md5(char *result, char *pass, char *challenge) {
char ipad[64]; char ipad[64];
char opad[64]; char opad[64];
@ -134,16 +112,13 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
result = NULL; result = NULL;
return; return;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad)); memset(opad, 0, sizeof(opad));
if (strlen(preppasswd) >= 64) { if (strlen(preppasswd) >= 64) {
MD5_Init(&md5c); MD5_Init(&md5c);
MD5_Update(&md5c, preppasswd, strlen(preppasswd)); MD5_Update(&md5c, preppasswd, strlen(preppasswd));
@ -154,7 +129,6 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
strcpy(ipad, preppasswd); // safe strcpy(ipad, preppasswd); // safe
strcpy(opad, preppasswd); // safe strcpy(opad, preppasswd); // safe
} }
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36; ipad[i] ^= 0x36;
opad[i] ^= 0x5c; opad[i] ^= 0x5c;
@ -163,7 +137,6 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
MD5_Update(&md5c, ipad, 64); MD5_Update(&md5c, ipad, 64);
MD5_Update(&md5c, challenge, strlen(challenge)); MD5_Update(&md5c, challenge, strlen(challenge));
MD5_Final(md5_raw, &md5c); MD5_Final(md5_raw, &md5c);
MD5_Init(&md5c); MD5_Init(&md5c);
MD5_Update(&md5c, opad, 64); MD5_Update(&md5c, opad, 64);
MD5_Update(&md5c, md5_raw, MD5_DIGEST_LENGTH); MD5_Update(&md5c, md5_raw, MD5_DIGEST_LENGTH);
@ -176,13 +149,10 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
} }
/* /*
sasl_cram_sha1 computes the cram-sha1 authentication from password string sasl_cram_sha1 computes the cram-sha1 authentication from password string
and the challenge sent by the server, and stored the value in variable and the challenge sent by the server, and stored the value in variable
result result
the parameter result must be able to hold at least 100 bytes! the parameter result must be able to hold at least 100 bytes!
*/ */
void sasl_cram_sha1(char *result, char *pass, char *challenge) { void sasl_cram_sha1(char *result, char *pass, char *challenge) {
char ipad[64]; char ipad[64];
@ -196,16 +166,13 @@ void sasl_cram_sha1(char *result, char *pass, char *challenge) {
result = NULL; result = NULL;
return; return;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad)); memset(opad, 0, sizeof(opad));
if (strlen(preppasswd) >= 64) { if (strlen(preppasswd) >= 64) {
SHA1_Init(&shac); SHA1_Init(&shac);
SHA1_Update(&shac, preppasswd, strlen(preppasswd)); SHA1_Update(&shac, preppasswd, strlen(preppasswd));
@ -216,22 +183,18 @@ void sasl_cram_sha1(char *result, char *pass, char *challenge) {
strcpy(ipad, preppasswd); // safe strcpy(ipad, preppasswd); // safe
strcpy(opad, preppasswd); // safe strcpy(opad, preppasswd); // safe
} }
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36; ipad[i] ^= 0x36;
opad[i] ^= 0x5c; opad[i] ^= 0x5c;
} }
SHA1_Init(&shac); SHA1_Init(&shac);
SHA1_Update(&shac, ipad, 64); SHA1_Update(&shac, ipad, 64);
SHA1_Update(&shac, challenge, strlen(challenge)); SHA1_Update(&shac, challenge, strlen(challenge));
SHA1_Final(sha1_raw, &shac); SHA1_Final(sha1_raw, &shac);
SHA1_Init(&shac); SHA1_Init(&shac);
SHA1_Update(&shac, opad, 64); SHA1_Update(&shac, opad, 64);
SHA1_Update(&shac, sha1_raw, SHA_DIGEST_LENGTH); SHA1_Update(&shac, sha1_raw, SHA_DIGEST_LENGTH);
SHA1_Final(sha1_raw, &shac); SHA1_Final(sha1_raw, &shac);
for (i = 0; i < SHA_DIGEST_LENGTH; i++) { for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
sprintf(result, "%02x", sha1_raw[i]); sprintf(result, "%02x", sha1_raw[i]);
result += 2; result += 2;
@ -240,13 +203,10 @@ void sasl_cram_sha1(char *result, char *pass, char *challenge) {
} }
/* /*
sasl_cram_sha256 computes the cram-sha256 authentication from password string sasl_cram_sha256 computes the cram-sha256 authentication from password string
and the challenge sent by the server, and stored the value in variable and the challenge sent by the server, and stored the value in variable
result result
the parameter result must be able to hold at least 100 bytes! the parameter result must be able to hold at least 100 bytes!
*/ */
void sasl_cram_sha256(char *result, char *pass, char *challenge) { void sasl_cram_sha256(char *result, char *pass, char *challenge) {
char ipad[64]; char ipad[64];
@ -260,16 +220,13 @@ void sasl_cram_sha256(char *result, char *pass, char *challenge) {
result = NULL; result = NULL;
return; return;
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad)); memset(opad, 0, sizeof(opad));
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
} }
if (strlen(preppasswd) >= 64) { if (strlen(preppasswd) >= 64) {
SHA256_Init(&sha256c); SHA256_Init(&sha256c);
SHA256_Update(&sha256c, preppasswd, strlen(preppasswd)); SHA256_Update(&sha256c, preppasswd, strlen(preppasswd));
@ -280,22 +237,18 @@ void sasl_cram_sha256(char *result, char *pass, char *challenge) {
strcpy(ipad, preppasswd); // safe strcpy(ipad, preppasswd); // safe
strcpy(opad, preppasswd); // safe strcpy(opad, preppasswd); // safe
} }
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36; ipad[i] ^= 0x36;
opad[i] ^= 0x5c; opad[i] ^= 0x5c;
} }
SHA256_Init(&sha256c); SHA256_Init(&sha256c);
SHA256_Update(&sha256c, ipad, 64); SHA256_Update(&sha256c, ipad, 64);
SHA256_Update(&sha256c, challenge, strlen(challenge)); SHA256_Update(&sha256c, challenge, strlen(challenge));
SHA256_Final(sha256_raw, &sha256c); SHA256_Final(sha256_raw, &sha256c);
SHA256_Init(&sha256c); SHA256_Init(&sha256c);
SHA256_Update(&sha256c, opad, 64); SHA256_Update(&sha256c, opad, 64);
SHA256_Update(&sha256c, sha256_raw, SHA256_DIGEST_LENGTH); SHA256_Update(&sha256c, sha256_raw, SHA256_DIGEST_LENGTH);
SHA256_Final(sha256_raw, &sha256c); SHA256_Final(sha256_raw, &sha256c);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf(result, "%02x", sha256_raw[i]); sprintf(result, "%02x", sha256_raw[i]);
result += 2; result += 2;
@ -304,11 +257,8 @@ void sasl_cram_sha256(char *result, char *pass, char *challenge) {
} }
/* /*
RFC 2831: Using Digest Authentication as a SASL Mechanism RFC 2831: Using Digest Authentication as a SASL Mechanism
the parameter result must be able to hold at least 500 bytes!! the parameter result must be able to hold at least 500 bytes!!
*/ */
void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *miscptr, char *type, char *webtarget, int webport, char *header) { void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *miscptr, char *type, char *webtarget, int webport, char *header) {
char *pbuffer = NULL; char *pbuffer = NULL;
@ -320,27 +270,23 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
MD5_CTX md5c; MD5_CTX md5c;
char *preplogin; char *preplogin;
char *preppasswd; char *preppasswd;
int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin); int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
memset(realm, 0, sizeof(realm)); memset(realm, 0, sizeof(realm));
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
free(preplogin); free(preplogin);
result = NULL; result = NULL;
return; return;
} }
//DEBUG S: nonce="HB3HGAk+hxKpijy/ichq7Wob3Zo17LPM9rr4kMX7xRM=",realm="tida",qop="auth",maxbuf=4096,charset=utf-8,algorithm=md5-sess //DEBUG S: nonce="HB3HGAk+hxKpijy/ichq7Wob3Zo17LPM9rr4kMX7xRM=",realm="tida",qop="auth",maxbuf=4096,charset=utf-8,algorithm=md5-sess
//DEBUG S: nonce="1Mr6c8WjOd/x5r8GUnGeQIRNUtOVtItu3kQOGAmsZfM=",realm="test.com",qop="auth,auth-int,auth-conf",cipher="rc4-40,rc4-56,rc4,des,3des",maxbuf=4096,charset=utf-8,algorithm=md5-sess //DEBUG S: nonce="1Mr6c8WjOd/x5r8GUnGeQIRNUtOVtItu3kQOGAmsZfM=",realm="test.com",qop="auth,auth-int,auth-conf",cipher="rc4-40,rc4-56,rc4,des,3des",maxbuf=4096,charset=utf-8,algorithm=md5-sess
//warning some not well configured xmpp server is sending no realm //warning some not well configured xmpp server is sending no realm
//DEBUG S: nonce="3448160828",qop="auth",charset=utf-8,algorithm=md5-sess //DEBUG S: nonce="3448160828",qop="auth",charset=utf-8,algorithm=md5-sess
pbuffer = buffer; pbuffer = buffer;
do { do {
currentpos++; currentpos++;
@ -361,17 +307,15 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
} }
pbuffer++; pbuffer++;
} while ((pbuffer[0] != '\0') && (pbuffer[0] > 31) && (ind < array_size)); } while ((pbuffer[0] != '\0') && (pbuffer[0] > 31) && (ind < array_size));
//save the latest one
//save the latest one
if (ind < array_size) { if (ind < array_size) {
array[ind] = malloc(currentpos + 1); array[ind] = malloc(currentpos + 1);
strncpy(array[ind], buffer + lastpos, currentpos); strncpy(array[ind], buffer + lastpos, currentpos);
array[ind][currentpos] = '\0'; array[ind][currentpos] = '\0';
ind++; ind++;
} }
for (i = 0; i < ind; i++) { for (i = 0; i < ind; i++) {
//removing space chars between comma separated value if any //removing space chars between comma separated value if any
while ((array[i] != NULL) && (array[i][0] == ' ')) { while ((array[i] != NULL) && (array[i][0] == ' ')) {
char *tmp = strdup(array[i]); char *tmp = strdup(array[i]);
@ -380,9 +324,9 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(tmp); free(tmp);
} }
if (strstr(array[i], "nonce=") != NULL) { if (strstr(array[i], "nonce=") != NULL) {
//check if it contains double-quote //check if it contains double-quote
if (strstr(array[i], "\"") != NULL) { if (strstr(array[i], "\"") != NULL) {
//assume last char is also a double-quote //assume last char is also a double-quote
int nonce_string_len = strlen(array[i]) - strlen("nonce=\"") - 1; int nonce_string_len = strlen(array[i]) - strlen("nonce=\"") - 1;
if ((nonce_string_len > 0) && (nonce_string_len <= sizeof(nonce) - 1)) { if ((nonce_string_len > 0) && (nonce_string_len <= sizeof(nonce) - 1)) {
@ -405,7 +349,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
} }
if (strstr(array[i], "realm=") != NULL) { if (strstr(array[i], "realm=") != NULL) {
if (strstr(array[i], "\"") != NULL) { if (strstr(array[i], "\"") != NULL) {
//assume last char is also a double-quote //assume last char is also a double-quote
int realm_string_len = strlen(array[i]) - strlen("realm=\"") - 1; int realm_string_len = strlen(array[i]) - strlen("realm=\"") - 1;
if ((realm_string_len > 0) && (realm_string_len <= sizeof(realm) - 1)) { if ((realm_string_len > 0) && (realm_string_len <= sizeof(realm) - 1)) {
@ -427,11 +371,12 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
} }
} }
if (strstr(array[i], "qop=") != NULL) { if (strstr(array[i], "qop=") != NULL) {
/*
The value "auth" indicates authentication; the value "auth-int" indicates /*
authentication with integrity protection; the value "auth-conf" The value "auth" indicates authentication; the value "auth-int" indicates
indicates authentication with integrity protection and encryption. authentication with integrity protection; the value "auth-conf"
*/ indicates authentication with integrity protection and encryption.
*/
auth_find = 1; auth_find = 1;
if ((strstr(array[i], "\"auth\"") == NULL) && (strstr(array[i], "\"auth,") == NULL) && (strstr(array[i], ",auth\"") == NULL)) { if ((strstr(array[i], "\"auth\"") == NULL) && (strstr(array[i], "\"auth,") == NULL) && (strstr(array[i], ",auth\"") == NULL)) {
int j; int j;
@ -446,7 +391,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
} }
if (strstr(array[i], "algorithm=") != NULL) { if (strstr(array[i], "algorithm=") != NULL) {
if (strstr(array[i], "\"") != NULL) { if (strstr(array[i], "\"") != NULL) {
//assume last char is also a double-quote //assume last char is also a double-quote
int algo_string_len = strlen(array[i]) - strlen("algorithm=\"") - 1; int algo_string_len = strlen(array[i]) - strlen("algorithm=\"") - 1;
if ((algo_string_len > 0) && (algo_string_len <= sizeof(algo) - 1)) { if ((algo_string_len > 0) && (algo_string_len <= sizeof(algo) - 1)) {
@ -480,29 +425,25 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(array[i]); free(array[i]);
array[i] = NULL; array[i] = NULL;
} }
if (!strlen(algo)) { if (!strlen(algo)) {
//assuming by default algo is MD5 //assuming by default algo is MD5
memset(algo, 0, sizeof(algo)); memset(algo, 0, sizeof(algo));
strcpy(algo, "MD5"); strcpy(algo, "MD5");
} }
//xmpp case, some xmpp server is not sending the realm so we have to set it up //xmpp case, some xmpp server is not sending the realm so we have to set it up
if ((strlen(realm) == 0) && (strstr(type, "xmpp") != NULL)) if ((strlen(realm) == 0) && (strstr(type, "xmpp") != NULL))
snprintf(realm, sizeof(realm), "%s", miscptr); snprintf(realm, sizeof(realm), "%s", miscptr);
//compute ha1
//compute ha1 //support for algo = MD5
//support for algo = MD5
snprintf(buffer, 500, "%s:%s:%s", preplogin, realm, preppasswd); snprintf(buffer, 500, "%s:%s:%s", preplogin, realm, preppasswd);
MD5_Init(&md5c); MD5_Init(&md5c);
MD5_Update(&md5c, buffer, strlen(buffer)); MD5_Update(&md5c, buffer, strlen(buffer));
MD5_Final(response, &md5c); MD5_Final(response, &md5c);
//for MD5-sess
//for MD5-sess
if (strstr(algo, "5-sess") != NULL) { if (strstr(algo, "5-sess") != NULL) {
buffer[0] = 0; //memset(buffer, 0, sizeof(buffer)); => buffer is char*! buffer[0] = 0; //memset(buffer, 0, sizeof(buffer)); => buffer is char*!
/* per RFC 2617 Errata ID 1649 */ /* per RFC 2617 Errata ID 1649 */
if ((strstr(type, "proxy") != NULL) || (strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL)) { if ((strstr(type, "proxy") != NULL) || (strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL)) {
memset(buffer3, 0, sizeof(buffer3)); memset(buffer3, 0, sizeof(buffer3));
pbuffer = buffer3; pbuffer = buffer3;
@ -515,7 +456,6 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
memcpy(buffer, response, sizeof(response)); memcpy(buffer, response, sizeof(response));
sprintf(buffer + sizeof(response), ":%s:%s", nonce, "hydra"); sprintf(buffer + sizeof(response), ":%s:%s", nonce, "hydra");
} }
MD5_Init(&md5c); MD5_Init(&md5c);
MD5_Update(&md5c, buffer, strlen(buffer)); MD5_Update(&md5c, buffer, strlen(buffer));
MD5_Final(response, &md5c); MD5_Final(response, &md5c);
@ -526,34 +466,35 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
sprintf(pbuffer, "%02x", response[i]); sprintf(pbuffer, "%02x", response[i]);
pbuffer += 2; pbuffer += 2;
} }
//compute ha2
//compute ha2 //proxy case
//proxy case
if (strstr(type, "proxy") != NULL) if (strstr(type, "proxy") != NULL)
sprintf(buffer, "%s:%s", "HEAD", miscptr); sprintf(buffer, "%s:%s", "HEAD", miscptr);
else else
//http case //http case
if ((strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL)) if ((strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL))
sprintf(buffer, "%s:%s", type, miscptr); sprintf(buffer, "%s:%s", type, miscptr);
else else
//sip case //sip case
if (strstr(type, "sip") != NULL) if (strstr(type, "sip") != NULL)
sprintf(buffer, "REGISTER:%s:%s", type, miscptr); sprintf(buffer, "REGISTER:%s:%s", type, miscptr);
else else
//others //others
if (strstr(type, "rtsp") != NULL)
sprintf(buffer, "DESCRIBE:%s://%s:%i", type, webtarget, port);
else
//others
sprintf(buffer, "AUTHENTICATE:%s/%s", type, realm); sprintf(buffer, "AUTHENTICATE:%s/%s", type, realm);
MD5_Init(&md5c); MD5_Init(&md5c);
MD5_Update(&md5c, buffer, strlen(buffer)); MD5_Update(&md5c, buffer, strlen(buffer));
MD5_Final(response, &md5c); MD5_Final(response, &md5c);
pbuffer = buffer2; pbuffer = buffer2;
for (i = 0; i < MD5_DIGEST_LENGTH; i++) { for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(pbuffer, "%02x", response[i]); sprintf(pbuffer, "%02x", response[i]);
pbuffer += 2; pbuffer += 2;
} }
//compute response
//compute response
if (!auth_find) if (!auth_find)
snprintf(buffer, 500, "%s:%s", nonce, buffer2); snprintf(buffer, 500, "%s:%s", nonce, buffer2);
else else
@ -563,14 +504,12 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
MD5_Update(&md5c, ":", 1); MD5_Update(&md5c, ":", 1);
MD5_Update(&md5c, buffer, strlen(buffer)); MD5_Update(&md5c, buffer, strlen(buffer));
MD5_Final(response, &md5c); MD5_Final(response, &md5c);
pbuffer = buffer; pbuffer = buffer;
for (i = 0; i < MD5_DIGEST_LENGTH; i++) { for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(pbuffer, "%02x", response[i]); sprintf(pbuffer, "%02x", response[i]);
pbuffer += 2; pbuffer += 2;
} }
//create the auth response
//create the auth response
if (strstr(type, "proxy") != NULL) { if (strstr(type, "proxy") != NULL) {
snprintf(result, 500, snprintf(result, 500,
"HEAD %s HTTP/1.0\r\n%sProxy-Authorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n", "HEAD %s HTTP/1.0\r\n%sProxy-Authorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n",
@ -584,19 +523,23 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
if (strstr(type, "sip") != NULL) { if (strstr(type, "sip") != NULL) {
snprintf(result, 500, "username=\"%s\",realm=\"%s\",nonce=\"%s\",uri=\"%s:%s\",response=%s", preplogin, realm, nonce, type, realm, buffer); snprintf(result, 500, "username=\"%s\",realm=\"%s\",nonce=\"%s\",uri=\"%s:%s\",response=%s", preplogin, realm, nonce, type, realm, buffer);
} else { } else {
if (use_proxy == 1 && proxy_authentication != NULL) if (strstr(type, "rtsp") != NULL) {
snprintf(result, 500, snprintf(result, 500, "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s://%s:%i\", response=\"%s\"\r\n", preplogin, realm, nonce, type, webtarget, port, buffer);
"%s http://%s:%d%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n", } else {
type, webtarget, webport, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, proxy_authentication, header); if (use_proxy == 1 && proxy_authentication != NULL)
else {
if (use_proxy == 1)
snprintf(result, 500, snprintf(result, 500,
"%s http://%s:%d%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n", "%s http://%s:%d%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n",
type, webtarget, webport, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, header); type, webtarget, webport, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, proxy_authentication, header);
else else {
snprintf(result, 500, if (use_proxy == 1)
"%s %s HTTP/1.0\r\nHost: %s\r\nAuthorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n", snprintf(result, 500,
type, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, header); "%s http://%s:%d%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n",
type, webtarget, webport, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, header);
else
snprintf(result, 500,
"%s %s HTTP/1.0\r\nHost: %s\r\nAuthorization: Digest username=\"%s\", realm=\"%s\", response=\"%s\", nonce=\"%s\", cnonce=\"hydra\", nc=00000001, algorithm=%s, qop=auth, uri=\"%s\"\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\nConnection: keep-alive\r\n%s\r\n",
type, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, header);
}
} }
} }
} }
@ -605,17 +548,12 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(preppasswd); free(preppasswd);
} }
/* /*
RFC 5802: Salted Challenge Response Authentication Mechanism RFC 5802: Salted Challenge Response Authentication Mechanism
Note: SCRAM is a client-first SASL mechanism Note: SCRAM is a client-first SASL mechanism
I want to thx Simon Josefsson for his public server test, I want to thx Simon Josefsson for his public server test,
and my girlfriend that let me work on that 2 whole nights ;) and my girlfriend that let me work on that 2 whole nights ;)
clientfirstmessagebare must be at least 500 bytes in size! clientfirstmessagebare must be at least 500 bytes in size!
*/ */
void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage) { void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage) {
int saltlen = 0; int saltlen = 0;
@ -632,7 +570,6 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
char ClientProof[SHA_DIGEST_LENGTH]; char ClientProof[SHA_DIGEST_LENGTH];
unsigned char clientproof_b64[50]; unsigned char clientproof_b64[50];
char *preppasswd; char *preppasswd;
int rc = sasl_saslprep(pass, 0, &preppasswd); int rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
@ -640,11 +577,10 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
return; return;
} }
/*client-final-message */ /*client-final-message */
if (debug) if (debug)
hydra_report(stderr, "DEBUG S: %s\n", serverfirstmessage); hydra_report(stderr, "DEBUG S: %s\n", serverfirstmessage);
//r=hydra28Bo7kduPpAZLzhRQiLxc8Y9tiwgw+yP,s=ldDgevctH+Kg7b8RnnA3qA==,i=4096
//r=hydra28Bo7kduPpAZLzhRQiLxc8Y9tiwgw+yP,s=ldDgevctH+Kg7b8RnnA3qA==,i=4096
if (strstr(serverfirstmessage, "r=") == NULL) { if (strstr(serverfirstmessage, "r=") == NULL) {
hydra_report(stderr, "Error: Can't understand server message\n"); hydra_report(stderr, "Error: Can't understand server message\n");
free(preppasswd); free(preppasswd);
@ -654,10 +590,9 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
strncpy(buffer, serverfirstmessage, sizeof(buffer) - 1); strncpy(buffer, serverfirstmessage, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0'; buffer[sizeof(buffer) - 1] = '\0';
nonce = strtok(buffer, ","); nonce = strtok(buffer, ",");
//continue to search from the previous successful call //continue to search from the previous successful call
salt = strtok(NULL, ","); salt = strtok(NULL, ",");
ic = strtok(NULL, ","); ic = strtok(NULL, ",");
iter = atoi(ic + 2); iter = atoi(ic + 2);
if (iter == 0) { if (iter == 0) {
hydra_report(stderr, "Error: Can't understand server response\n"); hydra_report(stderr, "Error: Can't understand server response\n");
@ -665,7 +600,6 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
result = NULL; result = NULL;
return; return;
} }
if ((nonce != NULL) && (strlen(nonce) > 2)) if ((nonce != NULL) && (strlen(nonce) > 2))
snprintf(clientfinalmessagewithoutproof, sizeof(clientfinalmessagewithoutproof), "c=biws,%s", nonce); snprintf(clientfinalmessagewithoutproof, sizeof(clientfinalmessagewithoutproof), "c=biws,%s", nonce);
else { else {
@ -674,9 +608,8 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
result = NULL; result = NULL;
return; return;
} }
if ((salt != NULL) && (strlen(salt) > 2) && (strlen(salt) <= sizeof(buffer))) if ((salt != NULL) && (strlen(salt) > 2) && (strlen(salt) <= sizeof(buffer)))
//s=ghgIAfLl1+yUy/Xl1WD5Tw== remove the header s= //s=ghgIAfLl1+yUy/Xl1WD5Tw== remove the header s=
strcpy(buffer, salt + 2); strcpy(buffer, salt + 2);
else { else {
hydra_report(stderr, "Error: Could not identify server salt value\n"); hydra_report(stderr, "Error: Could not identify server salt value\n");
@ -685,9 +618,8 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
return; return;
} }
/* SaltedPassword := Hi(Normalize(password), salt, i) */ /* SaltedPassword := Hi(Normalize(password), salt, i) */
saltlen = from64tobits((char *) salt, buffer); saltlen = from64tobits((char *) salt, buffer);
if (PKCS5_PBKDF2_HMAC_SHA1(preppasswd, strlen(preppasswd), (unsigned char *) salt, saltlen, iter, SHA_DIGEST_LENGTH, SaltedPassword) != 1) { if (PKCS5_PBKDF2_HMAC_SHA1(preppasswd, strlen(preppasswd), (unsigned char *) salt, saltlen, iter, SHA_DIGEST_LENGTH, SaltedPassword) != 1) {
hydra_report(stderr, "Error: Failed to generate PBKDF2\n"); hydra_report(stderr, "Error: Failed to generate PBKDF2\n");
free(preppasswd); free(preppasswd);
@ -695,21 +627,20 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
return; return;
} }
/* ClientKey := HMAC(SaltedPassword, "Client Key") */ /* ClientKey := HMAC(SaltedPassword, "Client Key") */
#define CLIENT_KEY "Client Key" #define CLIENT_KEY "Client Key"
HMAC(EVP_sha1(), SaltedPassword, SHA_DIGEST_LENGTH, (const unsigned char *) CLIENT_KEY, strlen(CLIENT_KEY), ClientKey, &resultlen); HMAC(EVP_sha1(), SaltedPassword, SHA_DIGEST_LENGTH, (const unsigned char *) CLIENT_KEY, strlen(CLIENT_KEY), ClientKey, &resultlen);
/* StoredKey := H(ClientKey) */ /* StoredKey := H(ClientKey) */
SHA1((const unsigned char *) ClientKey, SHA_DIGEST_LENGTH, StoredKey); SHA1((const unsigned char *) ClientKey, SHA_DIGEST_LENGTH, StoredKey);
/* ClientSignature := HMAC(StoredKey, AuthMessage) */ /* ClientSignature := HMAC(StoredKey, AuthMessage) */
snprintf(AuthMessage, 500, "%s,%s,%s", clientfirstmessagebare, serverfirstmessage, clientfinalmessagewithoutproof); snprintf(AuthMessage, 500, "%s,%s,%s", clientfirstmessagebare, serverfirstmessage, clientfinalmessagewithoutproof);
HMAC(EVP_sha1(), StoredKey, SHA_DIGEST_LENGTH, (const unsigned char *) AuthMessage, strlen(AuthMessage), ClientSignature, &resultlen); HMAC(EVP_sha1(), StoredKey, SHA_DIGEST_LENGTH, (const unsigned char *) AuthMessage, strlen(AuthMessage), ClientSignature, &resultlen);
/* ClientProof := ClientKey XOR ClientSignature */ /* ClientProof := ClientKey XOR ClientSignature */
xor(ClientProof, (char *) ClientKey, (char *) ClientSignature, 20); xor(ClientProof, (char *) ClientKey, (char *) ClientSignature, 20);
to64frombits(clientproof_b64, (const unsigned char *) ClientProof, 20); to64frombits(clientproof_b64, (const unsigned char *) ClientProof, 20);
snprintf(result, 500, "%s,p=%s", clientfinalmessagewithoutproof, clientproof_b64); snprintf(result, 500, "%s,p=%s", clientfinalmessagewithoutproof, clientproof_b64);
if (debug) if (debug)
hydra_report(stderr, "DEBUG C: %s\n", result); hydra_report(stderr, "DEBUG C: %s\n", result);