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
* 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
* 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 for SSL connection to support TLSv1.2 etc.
* 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?

View file

@ -4,7 +4,10 @@
OPTS=-I. -O3
# -Wall -g -pedantic
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 \
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-sid.c hydra-http-proxy.c hydra-http-form.c hydra-irc.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 \
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 \
@ -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-http-proxy.o hydra-http-form.o hydra-irc.o hydra-redis.o \
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
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
install: strip
-mkdir -p $(PREFIX)$(DIR)
cp -f hydra-wizard.sh $(BINS) $(PREFIX)$(DIR) && cd $(PREFIX)$(DIR) && 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
-sed -e "s|^INSTALLDIR=.*|INSTALLDIR="$(PREFIX)"|" dpl4hydra.sh > $(PREFIX)/bin/dpl4hydra.sh
-chmod 755 $(PREFIX)/bin/dpl4hydra.sh
-mkdir -p $(PREFIX)/etc/
-cp -f *.csv $(PREFIX)/etc/
-mkdir -p $(PREFIX)/man/man1
-cp -f hydra.1 xhydra.1 pw-inspector.1 $(PREFIX)/man/man1
-mkdir -p $(DESTDIR)$(PREFIX)$(BINDIR)
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 $(DESTDIR)$(PREFIX)$(BINDIR) && cd $(DESTDIR)$(PREFIX)$(BINDIR) && chmod 755 xhydra || echo OK > /dev/null
-sed -e "s|^INSTALLDIR=.*|INSTALLDIR="$(PREFIX)"|" dpl4hydra.sh | sed -e "s|^LOCATION=.*|LOCATION="$(DATADIR)"|" > $(DESTDIR)$(PREFIX)$(BINDIR)/dpl4hydra.sh
-chmod 755 $(DESTDIR)$(PREFIX)$(BINDIR)/dpl4hydra.sh
-mkdir -p $(DESTDIR)$(PREFIX)$(DATADIR)
-cp -f *.csv $(DESTDIR)$(PREFIX)$(DATADIR)
-mkdir -p $(DESTDIR)$(PREFIX)$(MANDIR)
-cp -f hydra.1 xhydra.1 pw-inspector.1 $(DESTDIR)$(PREFIX)$(MANDIR)
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

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
XLIBPATHS="-L/usr/lib -L/usr/local/lib -L/lib"
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 "$SSLNEW" ]; then
XDEFINES="$XDEFINES -DLIBOPENSSL"
@ -1016,7 +1024,7 @@ if [ -n "$RSA" ]; then
XDEFINES="$XDEFINES -DNO_RSA_LEGACY"
fi
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
OLDPATH="$i"
else
@ -1024,11 +1032,29 @@ for i in $SSL_PATH $CRYPTO_PATH $SSH_PATH $NSL_PATH $SOCKET_PATH $RESOLV_PATH $S
OLDPATH="$i"
fi
done
if [ -n "$SSL_IPATH" ]; then
XIPATHS="-I$SSL_IPATH"
if [ -n "$CURSES_IPATH" ]; then
XIPATHS="$XIPATHS -I$CURSES_IPATH"
fi
if [ -n "$CURSES_PATH" ]; then
XLIBS="$XLIBS -lcurses"
if [ -n "$FIREBIRD_IPATH" ]; then
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
if [ -n "$SAPR3_IPATH" ]; then
XIPATHS="$XIPATHS -I$SAPR3_IPATH"
@ -1045,20 +1071,15 @@ fi
if [ -n "$SVN_IPATH" ]; then
XIPATHS="$XIPATHS -I$SVN_IPATH"
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
XIPATHS="$XIPATHS -I$AFP_IPATH"
fi
if [ -n "$ORACLE_IPATH" ]; then
XIPATHS="$XIPATHS -I$ORACLE_IPATH"
fi
if [ -n "$CURSES_PATH" ]; then
XLIBS="$XLIBS -lcurses"
fi
if [ -n "$SSL_PATH" ]; then
XLIBS="$XLIBS -lssl"
fi
@ -1122,7 +1143,7 @@ if [ "X" = "X$PREFIX" ]; then
PREFIX="/usr/local"
fi
if [ "X" = "X$XHYDRA_SUPPORT" ]; then
if [ "X" = "X$XHYDRA_SUPPORT" -o "Xdisable" = "X$XHYDRA_SUPPORT" ]; then
XHYDRA_SUPPORT=""
else
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"
/* HTTP Header Types */
#define HEADER_TYPE_USERHEADER 'h'
#define HEADER_TYPE_USERHEADER_REPL 'H'
#define HEADER_TYPE_DEFAULT 'D'
#define HEADER_TYPE_USERHEADER 'h'
#define HEADER_TYPE_USERHEADER_REPL 'H'
#define HEADER_TYPE_DEFAULT 'D'
#define HEADER_TYPE_DEFAULT_REPL 'd'
extern char *HYDRA_EXIT;
char *buf;
@ -67,6 +68,13 @@ typedef struct header_node {
struct header_node *next;
} 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 getcookie = 1;
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;
}
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:
* +----------+ +--------+ +--------+ +--------+
@ -129,7 +249,9 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type)
if (new_header && new_value) {
if ((type == HEADER_TYPE_USERHEADER) ||
(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:
* 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
*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
// Replace the default header's value with this new 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) {
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)
strcpy(cur_ptr->value, newvalue);
else {
hydra_report(stderr, "[ERROR] Out of memory.");
hydra_report(stderr, "[ERROR] Out of memory (hddrep).");
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) {
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)
strcpy(cur_ptr->value, new_value);
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);
}
}
}
}
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;
while (next_ptr) {
while (next_ptr != NULL) {
free(cur_ptr->header);
free(cur_ptr->value);
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 *login, *pass, clogin[256], cpass[256];
char header[8096], *upd3variables;
char *cookie_header = NULL;
char *http_request;
int found = !success_cond, i, j;
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;
i = analyze_server_response(s); // ignore result
if (strlen(cookie) > 0)
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT);
process_cookies(&ptr_cookie, cookie);
hydra_reconnect(s, ip, port, options);
}
// 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);
if (!header_exists(&ptr_head, "Content-Type", 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);
http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1;
} 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);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1;
@ -508,7 +641,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 1;
i = analyze_server_response(s); // ignore result
if (strlen(cookie) > 0)
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT);
process_cookies(&ptr_cookie, cookie);
hydra_reconnect(s, ip, port, options);
}
// 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);
if (!header_exists(&ptr_head, "Content-Type", 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);
http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1;
} 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);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
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)
return 1;
i = analyze_server_response(s); // ignore result
if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) {
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT);
if (strlen(cookie) > 0) {
//printf("[DEBUG] Got cookie: %s\n", cookie);
process_cookies(&ptr_cookie, cookie);
normal_request = stringify_headers(&ptr_head);
}
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);
if (!header_exists(&ptr_head, "Content-Type", 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);
http_request = prepare_http_request("POST", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1;
} 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);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
return 1;
@ -579,8 +733,8 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
return 4;
}
if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT);
if (strlen(cookie) > 0)
process_cookies(&ptr_cookie, cookie);
//if page was redirected, follow the location header
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;
found = analyze_server_response(s);
if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT);
if (strlen(cookie) > 0)
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;
}
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 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;
}
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;
case 3: /* clean exit */
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) {
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)
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 {
hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n");
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) {
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)
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 {
hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n");
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 */
} else if ((ptr2 = index(webtarget, '/')) != NULL) {
if (freemischttpform == 0) {
freemischttpform = 1;
miscptr = malloc(strlen(ptr2) + 1);
strcpy(miscptr, ptr2);
*ptr2 = 0;
if ((miscptr = malloc(strlen(ptr2) + 1)) != NULL) {
freemischttpform = 1;
strcpy(miscptr, ptr2);
*ptr2 = 0;
}
}
} else
webtarget = NULL;
@ -963,7 +1120,7 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
break;
}
// 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;
case 'H':
// 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;
}
// 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;
// no default
}

View file

@ -189,7 +189,9 @@ int start_http(int s, char *ip, int port, unsigned char options, char *miscptr,
if (debug)
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)) {
hydra_report_found_host(port, ip, "www", fp);
hydra_completed_pair_found();
@ -199,7 +201,7 @@ int start_http(int s, char *ip, int port, unsigned char options, char *miscptr,
}
} else {
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
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);
memset(buffer, 0, sizeof(buffer));
sasl_plain(buffer, login, pass);
sprintf(buffer, "%.250s\r\n", buffer);
memset(buffer2, 0, sizeof(buffer2));
sasl_plain(buffer2, login, pass);
sprintf(buffer, "%.250s\r\n", buffer2);
break;
#ifdef LIBOPENSSL

View file

@ -47,6 +47,7 @@ int __first_connect = 1;
char ipstring[64];
unsigned int colored_output = 1;
char quiet = 0;
int old_ssl = 0;
#ifdef LIBOPENSSL
SSL *ssl = NULL;
@ -468,13 +469,23 @@ int internal__hydra_connect_to_ssl(int socket) {
if (sslContext == NULL) {
/* context: ssl2 + ssl3 is allowed, whatever the server demands */
// 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));
if (old_ssl) {
if ((sslContext = SSL_CTX_new(SSLv23_client_method())) == NULL) {
if (verbose) {
err = ERR_get_error();
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 */
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 *newstr = NULL;
if (string == NULL)
return NULL;
if (substr == NULL || replacement == NULL)
return strdup(string);
tok = strstr(string, substr);
if (tok == NULL)
return strdup(string);
newstr = malloc(strlen(string) - strlen(substr) + strlen(replacement) + 1);
newstr = malloc(strlen(string) - strlen(substr) + strlen(replacement) + 2);
if (newstr == NULL)
return NULL;
memset(newstr, 0, strlen(string) - strlen(substr) + strlen(replacement) + 2);
memcpy(newstr, string, tok - string);
memcpy(newstr + (tok - string), replacement, strlen(replacement));
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;
}

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);
}
/*
* 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) {
// called before the childrens are forked off, so this is the function
// which should be filled if initial connections and service setup has to be
// performed once only.
//
// fill if needed.
//
// return codes:
// 0 all OK
// -1 error, hydra will exit, so print a good error message here
// 0 - when the server is redis and it requires password
// 1 - when the server is not redis or when the server do not require password
int sock = -1;
int myport = PORT_REDIS, mysslport = PORT_REDIS_SSL;
char buffer[] = "\x2a\x31\x0d\x0a\x24\x34\x0d\x0a\x70\x69\x6e\x67\x0d\x0a";
hydra_register_socket(sp);
if (sock >= 0)
sock = hydra_disconnect(sock);
if ((options & OPTION_SSL) == 0) {
if (port != 0)
myport = port;
sock = hydra_connect_tcp(ip, myport);
port = myport;
} else {
if (port != 0)
mysslport = port;
sock = hydra_connect_ssl(ip, mysslport);
port = mysslport;
}
if (verbose)
printf("[VERBOSE] Initial redis password authentication test and response test ...\n");
if (sock < 0) {
hydra_report(stderr, "[ERROR] Can not connect to port %d on the target\n", myport);
hydra_child_exit(1);
}
// generating ping request as redis-cli
if (debug)
printf("[DEBUG] buffer = %s\n", buffer);
// [debug mode]: buffer is:
// *1
// $4
// ping
if (hydra_send(sock, buffer, strlen(buffer), 0) < 0) {
return 1;
}
buf = hydra_receive_line(sock);
if (debug)
printf("[DEBUG] buf = %s\n", buf);
// authentication test
if (strstr(buf, "+PONG") != NULL) { // the server do not require password
hydra_report(stderr, "[!] The server do not require password.\n");
free(buf);
return 1;
}
// server response test
if (strstr(buf, "-NOAUTH Authentication required") == NULL) {
hydra_report(stderr, "[ERROR] The server is not redis, exit.\n");
free(buf);
return 1;
}
if (verbose)
printf("[VERBOSE] The redis server requires password.\n");
free(buf);
sock = hydra_disconnect(sock);
return 0;
}

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 */
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);
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 */
if ((strstr(buf, CHALLENGE_STR) != NULL) || (strstr(buf, CHALLENGE_STR2) != NULL)) {
char *ptr = strstr(buf, CHALLENGE_STR);
if (!ptr)
ptr = strstr(buf, CHALLENGE_STR2);
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
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)
hydra_child_exit(1);
if (strstr(buf, "<stream:stream") == NULL) {
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 (verbose || debug)
hydra_report(stderr, "[ERROR] Not an xmpp protocol or service shutdown: %s\n", buf);
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;
}
}
free(buf);
hydra_child_exit(1);
}
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);
} while (xmpp_auth_mechanism == AUTH_ERROR);
if ((miscptr != NULL) && (strlen(miscptr) > 0)) {
int i;

254
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_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_rtsp(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE
#ifdef HAVE_MATH_H
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);
@ -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_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_rtsp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE
// ADD NEW SERVICES HERE
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 MAXLINESIZE ( ( MAXBUF / 2 ) - 4 )
@ -170,6 +173,7 @@ extern char *hydra_address2string(char *address);
extern int colored_output;
extern char quiet;
extern int do_retry;
extern int old_ssl;
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_pass[MAXTASKS * 2 + 2];
char *skiplogin[SKIPLOGIN];
// char *bfg_ptr[MAXTASKS];
// char *bfg_ptr[MAXTASKS];
} hydra_target;
typedef struct {
@ -310,7 +314,7 @@ void help(int ext) {
#ifdef HAVE_MATH_H
" [-x MIN:MAX:CHARSET]"
#endif
" [-SuvVd46] "
" [-SOuvVd46] "
//"[server service [OPT]]|"
"[service://server[:PORT][/OPT]]\n");
printf("\nOptions:\n");
@ -346,7 +350,9 @@ void help(int ext) {
if (ext)
printf(" -v / -V / -d verbose mode / show login+pass for each attempt / debug mode \n");
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");
if (ext == 0)
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.redo = 1;
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,
hh.current_login_ptr, hh.current_pass_ptr);
printf("[DEBUG] we will redo the following combination: target %s child %d login \"%s\" pass \"%s\"\n", hydra_targets[hh.target_no]->target,
j, hh.current_login_ptr, hh.current_pass_ptr);
}
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]))) */ )
@ -760,7 +766,8 @@ void hydra_restore_read() {
int i, j, orig_debug = debug;
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) {
fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE);
perror("");
@ -776,7 +783,8 @@ void hydra_restore_read() {
}
fck = (int) fread(&bf_options, sizeof(bf_options), 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) {
bf_options.crs = NULL;
} else {
@ -784,7 +792,8 @@ void hydra_restore_read() {
memcpy(bf_options.crs, mynull, sizeof(mynull));
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);
hydra_brains.ofp = stdout;
@ -792,7 +801,8 @@ void hydra_restore_read() {
hydra_options.restore = 1;
verbose = hydra_options.verbose;
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) {
debug = 1;
hydra_options.debug = 1;
@ -807,35 +817,42 @@ void hydra_restore_read() {
sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n')
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) {
hydra_options.outfile_ptr = malloc(strlen(out) + 1);
strcpy(hydra_options.outfile_ptr, out);
} else
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);
if (out[0] != 0 && out[strlen(out) - 1] == '\n')
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)
hydra_options.miscptr = NULL;
else {
hydra_options.miscptr = malloc(strlen(out) + 1);
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);
if (out[0] != 0 && out[strlen(out) - 1] == '\n')
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);
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);
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
pass_ptr = malloc(hydra_brains.sizepass);
fck = (int) fread(pass_ptr, hydra_brains.sizepass, 1, f);
@ -843,7 +860,8 @@ void hydra_restore_read() {
hydra_options.colonfile = empty_login; // dummy
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));
for (j = 0; j < hydra_brains.targets; j++) {
@ -867,6 +885,7 @@ void hydra_restore_read() {
strcpy(hydra_targets[j]->pass_ptr, out);
}
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++) {
sck = fgets(out, sizeof(out), f);
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]->failed = 0;
}
if (debug) printf("[DEBUG] reading restore file: Step 11 complete\n");
hydra_heads = malloc((hydra_options.max_use + 2) * sizeof(int) + 8);
if (debug)
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++) {
hydra_heads[j] = malloc(sizeof(hydra_head));
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;
sck = fgets(out, sizeof(out), f);
if (hydra_heads[j]->redo) {
if (debug) printf("[DEBUG] head %d redo\n", j);
if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0;
hydra_heads[j]->current_login_ptr = malloc(strlen(out) + 1);
@ -911,7 +932,8 @@ void hydra_restore_read() {
if (hydra_heads[j]->redo) {
if (out[0] != 0 && out[strlen(out) - 1] == '\n')
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) {
hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1);
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;
}
}
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);
if (out[0] != 0 && out[strlen(out) - 1] == '\n')
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);
exit(-1);
} else {
// if (tmp[0] == ':') {
// *ptr = 0;
// ptr++;
// }
// if (tmp[len - 1] == ':' && len > 1) {
// len++;
// tmp[len - 1] = 0;
// }
// if (tmp[0] == ':') {
// *ptr = 0;
// ptr++;
// }
// if (tmp[len - 1] == ':' && len > 1) {
// len++;
// tmp[len - 1] = 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);
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);
// 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 < 4)
@ -1234,7 +1260,7 @@ int hydra_spawn_head(int head_no, int target_no) {
free(pass_ptr);
if (hydra_options.colonfile != NULL && hydra_options.colonfile != empty_login)
free(csv_ptr);
// we must keep servers_ptr for cmdlinetarget to work
// we must keep servers_ptr for cmdlinetarget to work
if (debug)
printf("[DEBUG] head_no %d has pid %d\n", head_no, getpid());
@ -1243,8 +1269,11 @@ int hydra_spawn_head(int head_no, int target_no) {
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)
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);
}
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);
if (strcmp(hydra_options.service, "redis") == 0)
@ -1372,7 +1401,10 @@ int hydra_spawn_head(int head_no, int target_no) {
#endif
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);
// 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
exit(-1);
@ -1467,7 +1499,8 @@ int hydra_lookup_port(char *service) {
{"rdp", PORT_RDP, PORT_RDP_SSL},
{"asterisk", PORT_ASTERISK, PORT_ASTERISK_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}
};
@ -1488,7 +1521,8 @@ int hydra_lookup_port(char *service) {
// killit = 1 : kill(pid); fail = 1 : redo, fail = 2/3 : disable
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)
return;
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) {
free(hydra_heads[head_no]->current_pass_ptr);
hydra_heads[head_no]->current_pass_ptr = empty_login;
// hydra_bfg_remove(head_no);
// hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = NULL;
// hydra_bfg_remove(head_no);
// hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = 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) {
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)
j = 248;
else if (j == 0)
return empty_login;
for (i = 0; i < j; i++)
hydra_heads[head_no]->reverse[i] = login[j - (i + 1)];
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;
}
@ -1911,7 +1980,7 @@ int hydra_send_next_pair(int target_no, int head_no) {
}
}
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 {
if (hydra_targets[target_no]->skipcnt > 0) {
snpj = 0;
@ -2186,7 +2255,7 @@ int main(int argc, char *argv[]) {
help(1);
if (argc < 2)
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) {
case 'h':
help(1);
@ -2194,6 +2263,9 @@ int main(int argc, char *argv[]) {
case 'q':
quiet = 1;
break;
case 'O':
old_ssl = 1;
break;
case 'u':
hydra_options.loop_mode = 1;
break;
@ -2261,7 +2333,7 @@ int main(int argc, char *argv[]) {
break;
case 'o':
hydra_options.outfile_ptr = optarg;
// colored_output = 0;
// colored_output = 0;
break;
case 'M':
hydra_options.infile_ptr = optarg;
@ -2382,7 +2454,7 @@ int main(int argc, char *argv[]) {
hydra_options.service = argv[optind];
if (optind + 2 == argc)
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
char *targetdef = strdup(argv[optind]);
char *service_pos, *target_pos, *port_pos = NULL, *param_pos = NULL;
@ -2433,7 +2505,7 @@ int main(int argc, char *argv[]) {
*--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)
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 {
@ -2790,7 +2862,9 @@ int main(int argc, char *argv[]) {
if (hydra_options.miscptr == NULL)
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 (hydra_options.tasks > 8) {
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;
}
if (strcmp(hydra_options.service, "cisco-enable") == 0) {
i = 2;
if (hydra_options.login == NULL) {
//hydra_options.login = empty_login;
if (hydra_options.login != NULL || hydra_options.loginfile != NULL)
i = 1; // login will be the initial Username: login, or line Password:
}
if (hydra_options.miscptr == NULL) {
else
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");
}
if (hydra_options.tasks > 4)
fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco enable services.\n");
}
@ -2950,6 +3022,7 @@ int main(int argc, char *argv[]) {
}
// ADD NEW SERVICES HERE
if (i == 0) {
fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service);
exit(-1);
@ -3022,6 +3095,9 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", 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.loginfile != NULL) {
@ -3124,8 +3200,8 @@ int main(int argc, char *argv[]) {
bail("Could not allocate enough memory for colon file data");
memset(csv_ptr, 0, hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8);
fill_mem(csv_ptr, cfp, 1);
//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");
//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_brains.countpass = 1;
pass_ptr = login_ptr = csv_ptr;
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);
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);
if (hydra_targets == NULL)
bail("Could not allocate enough memory for target data");
@ -3384,7 +3460,7 @@ int main(int argc, char *argv[]) {
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)
hydra_options.max_use = hydra_brains.targets * hydra_options.tasks;
if (hydra_options.max_use > MAXTASKS)
@ -3400,9 +3476,9 @@ int main(int argc, char *argv[]) {
hydra_options.tasks = MAXTASKS;
}
}
// hydra_options.max_use = hydra_brains.targets * hydra_options.tasks;
// if (hydra_options.max_use > MAXTASKS)
// hydra_options.max_use = MAXTASKS;
// hydra_options.max_use = hydra_brains.targets * hydra_options.tasks;
// if (hydra_options.max_use > MAXTASKS)
// hydra_options.max_use = MAXTASKS;
math2 = (hydra_brains.todo / hydra_options.tasks);
if (hydra_brains.todo % hydra_options.tasks)
math2++;
@ -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",
(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_brains.ofp = fopen(hydra_options.outfile_ptr, "a+")) == NULL) {
@ -3542,7 +3618,7 @@ int main(int argc, char *argv[]) {
// here we call the init function of the relevant service module
// should we do the init centrally or should each child do that?
// 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++)
hydra_service_init(i);
@ -3568,7 +3644,8 @@ int main(int argc, char *argv[]) {
tmp_time = time(NULL);
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) {
case -1:
// disabled head, ignored
@ -3584,7 +3661,8 @@ int main(int argc, char *argv[]) {
if (debug)
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 (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);
} else
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 (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)
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
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) {
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
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 {
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)
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
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) {
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
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_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)
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
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) {
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
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_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++)
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)
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
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;
}
// fall through
@ -3766,7 +3857,7 @@ int main(int argc, char *argv[]) {
for (j = 0; j < hydra_options.max_use; j++)
if (hydra_heads[j]->active >= 0)
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
(long unsigned int) ((elapsed_status - starttime) / 3600), // hours
(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);
}
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++)
if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0)
hydra_kill_head(i, 1, 3);

View file

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

187
sasl.c
View file

@ -1,10 +1,8 @@
#include "sasl.h"
/*
print_hex is used for debug
it displays the string buf hexa values of size len
*/
int print_hex(unsigned char *buf, int len) {
int i;
@ -19,23 +17,18 @@ int print_hex(unsigned char *buf, int len) {
n++;
}
printf("\n");
return (0);
}
/*
RFC 4013: SASLprep: Stringprep Profile for User Names and Passwords
code based on gsasl_saslprep from GSASL project
*/
int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
#if LIBIDN
int rc;
rc = stringprep_profile(in, out, "SASLprep", (flags & SASL_ALLOW_UNASSIGNED) ? STRINGPREP_NO_UNASSIGNED : 0);
if (rc != STRINGPREP_OK) {
*out = NULL;
return -1;
@ -47,7 +40,6 @@ int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
return -1;
}
#endif
#else
size_t i, inlen = strlen(in);
@ -68,36 +60,27 @@ int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
return 0;
}
/*
RFC 4616: The PLAIN Simple Authentication and Security Layer (SASL) Mechanism
sasl_plain computes the plain authentication from strings login and password
and stored the value in variable result
the first parameter result must be able to hold at least 255 bytes!
*/
void sasl_plain(char *result, char *login, char *pass) {
char *preplogin;
char *preppasswd;
int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
if (rc) {
result = NULL;
return;
}
rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) {
free(preplogin);
result = NULL;
return;
}
if (2 * strlen(preplogin) + 3 + strlen(preppasswd) < 180) {
strcpy(result, preplogin);
strcpy(result + strlen(preplogin) + 1, preplogin);
@ -111,17 +94,12 @@ void sasl_plain(char *result, char *login, char *pass) {
#ifdef LIBOPENSSL
/*
RFC 2195: IMAP/POP AUTHorize Extension for Simple Challenge/Response
sasl_cram_md5 computes the cram-md5 authentication from password string
and the challenge sent by the server, and stored the value in variable
result
the parameter result must be able to hold at least 100 bytes!
*/
void sasl_cram_md5(char *result, char *pass, char *challenge) {
char ipad[64];
char opad[64];
@ -134,16 +112,13 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
result = NULL;
return;
}
rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) {
result = NULL;
return;
}
memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad));
if (strlen(preppasswd) >= 64) {
MD5_Init(&md5c);
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(opad, preppasswd); // safe
}
for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36;
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, challenge, strlen(challenge));
MD5_Final(md5_raw, &md5c);
MD5_Init(&md5c);
MD5_Update(&md5c, opad, 64);
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
and the challenge sent by the server, and stored the value in variable
result
the parameter result must be able to hold at least 100 bytes!
*/
void sasl_cram_sha1(char *result, char *pass, char *challenge) {
char ipad[64];
@ -196,16 +166,13 @@ void sasl_cram_sha1(char *result, char *pass, char *challenge) {
result = NULL;
return;
}
rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) {
result = NULL;
return;
}
memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad));
if (strlen(preppasswd) >= 64) {
SHA1_Init(&shac);
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(opad, preppasswd); // safe
}
for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36;
opad[i] ^= 0x5c;
}
SHA1_Init(&shac);
SHA1_Update(&shac, ipad, 64);
SHA1_Update(&shac, challenge, strlen(challenge));
SHA1_Final(sha1_raw, &shac);
SHA1_Init(&shac);
SHA1_Update(&shac, opad, 64);
SHA1_Update(&shac, sha1_raw, SHA_DIGEST_LENGTH);
SHA1_Final(sha1_raw, &shac);
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
sprintf(result, "%02x", sha1_raw[i]);
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
and the challenge sent by the server, and stored the value in variable
result
the parameter result must be able to hold at least 100 bytes!
*/
void sasl_cram_sha256(char *result, char *pass, char *challenge) {
char ipad[64];
@ -260,16 +220,13 @@ void sasl_cram_sha256(char *result, char *pass, char *challenge) {
result = NULL;
return;
}
memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad));
rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) {
result = NULL;
return;
}
if (strlen(preppasswd) >= 64) {
SHA256_Init(&sha256c);
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(opad, preppasswd); // safe
}
for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36;
opad[i] ^= 0x5c;
}
SHA256_Init(&sha256c);
SHA256_Update(&sha256c, ipad, 64);
SHA256_Update(&sha256c, challenge, strlen(challenge));
SHA256_Final(sha256_raw, &sha256c);
SHA256_Init(&sha256c);
SHA256_Update(&sha256c, opad, 64);
SHA256_Update(&sha256c, sha256_raw, SHA256_DIGEST_LENGTH);
SHA256_Final(sha256_raw, &sha256c);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf(result, "%02x", sha256_raw[i]);
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
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) {
char *pbuffer = NULL;
@ -320,27 +270,23 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
MD5_CTX md5c;
char *preplogin;
char *preppasswd;
int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
memset(realm, 0, sizeof(realm));
if (rc) {
result = NULL;
return;
}
rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) {
free(preplogin);
result = NULL;
return;
}
//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
//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="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
//warning some not well configured xmpp server is sending no realm
//DEBUG S: nonce="3448160828",qop="auth",charset=utf-8,algorithm=md5-sess
pbuffer = buffer;
do {
currentpos++;
@ -361,17 +307,15 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
}
pbuffer++;
} while ((pbuffer[0] != '\0') && (pbuffer[0] > 31) && (ind < array_size));
//save the latest one
//save the latest one
if (ind < array_size) {
array[ind] = malloc(currentpos + 1);
strncpy(array[ind], buffer + lastpos, currentpos);
array[ind][currentpos] = '\0';
ind++;
}
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] == ' ')) {
char *tmp = strdup(array[i]);
@ -380,9 +324,9 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(tmp);
}
if (strstr(array[i], "nonce=") != NULL) {
//check if it contains double-quote
//check if it contains double-quote
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;
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], "\"") != 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;
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) {
/*
The value "auth" indicates authentication; the value "auth-int" indicates
authentication with integrity protection; the value "auth-conf"
indicates authentication with integrity protection and encryption.
*/
/*
The value "auth" indicates authentication; the value "auth-int" indicates
authentication with integrity protection; the value "auth-conf"
indicates authentication with integrity protection and encryption.
*/
auth_find = 1;
if ((strstr(array[i], "\"auth\"") == NULL) && (strstr(array[i], "\"auth,") == NULL) && (strstr(array[i], ",auth\"") == NULL)) {
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], "\"") != 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;
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]);
array[i] = NULL;
}
if (!strlen(algo)) {
//assuming by default algo is MD5
//assuming by default algo is MD5
memset(algo, 0, sizeof(algo));
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))
snprintf(realm, sizeof(realm), "%s", miscptr);
//compute ha1
//support for algo = MD5
//compute ha1
//support for algo = MD5
snprintf(buffer, 500, "%s:%s:%s", preplogin, realm, preppasswd);
MD5_Init(&md5c);
MD5_Update(&md5c, buffer, strlen(buffer));
MD5_Final(response, &md5c);
//for MD5-sess
//for MD5-sess
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)) {
memset(buffer3, 0, sizeof(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));
sprintf(buffer + sizeof(response), ":%s:%s", nonce, "hydra");
}
MD5_Init(&md5c);
MD5_Update(&md5c, buffer, strlen(buffer));
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]);
pbuffer += 2;
}
//compute ha2
//proxy case
//compute ha2
//proxy case
if (strstr(type, "proxy") != NULL)
sprintf(buffer, "%s:%s", "HEAD", miscptr);
else
//http case
//http case
if ((strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL))
sprintf(buffer, "%s:%s", type, miscptr);
else
//sip case
//sip case
if (strstr(type, "sip") != NULL)
sprintf(buffer, "REGISTER:%s:%s", type, miscptr);
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);
MD5_Init(&md5c);
MD5_Update(&md5c, buffer, strlen(buffer));
MD5_Final(response, &md5c);
pbuffer = buffer2;
for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(pbuffer, "%02x", response[i]);
pbuffer += 2;
}
//compute response
//compute response
if (!auth_find)
snprintf(buffer, 500, "%s:%s", nonce, buffer2);
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, buffer, strlen(buffer));
MD5_Final(response, &md5c);
pbuffer = buffer;
for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(pbuffer, "%02x", response[i]);
pbuffer += 2;
}
//create the auth response
//create the auth response
if (strstr(type, "proxy") != NULL) {
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",
@ -584,19 +523,23 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
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);
} else {
if (use_proxy == 1 && proxy_authentication != NULL)
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\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, proxy_authentication, header);
else {
if (use_proxy == 1)
if (strstr(type, "rtsp") != NULL) {
snprintf(result, 500, "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s://%s:%i\", response=\"%s\"\r\n", preplogin, realm, nonce, type, webtarget, port, buffer);
} else {
if (use_proxy == 1 && proxy_authentication != NULL)
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",
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);
"%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, proxy_authentication, header);
else {
if (use_proxy == 1)
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",
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);
}
/*
RFC 5802: Salted Challenge Response Authentication Mechanism
Note: SCRAM is a client-first SASL mechanism
I want to thx Simon Josefsson for his public server test,
and my girlfriend that let me work on that 2 whole nights ;)
clientfirstmessagebare must be at least 500 bytes in size!
*/
void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage) {
int saltlen = 0;
@ -632,7 +570,6 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
char ClientProof[SHA_DIGEST_LENGTH];
unsigned char clientproof_b64[50];
char *preppasswd;
int rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) {
@ -640,11 +577,10 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
return;
}
/*client-final-message */
/*client-final-message */
if (debug)
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) {
hydra_report(stderr, "Error: Can't understand server message\n");
free(preppasswd);
@ -654,10 +590,9 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
strncpy(buffer, serverfirstmessage, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
nonce = strtok(buffer, ",");
//continue to search from the previous successful call
//continue to search from the previous successful call
salt = strtok(NULL, ",");
ic = strtok(NULL, ",");
iter = atoi(ic + 2);
if (iter == 0) {
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;
return;
}
if ((nonce != NULL) && (strlen(nonce) > 2))
snprintf(clientfinalmessagewithoutproof, sizeof(clientfinalmessagewithoutproof), "c=biws,%s", nonce);
else {
@ -674,9 +608,8 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
result = NULL;
return;
}
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);
else {
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;
}
/* SaltedPassword := Hi(Normalize(password), salt, i) */
/* SaltedPassword := Hi(Normalize(password), salt, i) */
saltlen = from64tobits((char *) salt, buffer);
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");
free(preppasswd);
@ -695,21 +627,20 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
return;
}
/* ClientKey := HMAC(SaltedPassword, "Client Key") */
/* ClientKey := HMAC(SaltedPassword, "Client Key") */
#define CLIENT_KEY "Client Key"
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);
/* ClientSignature := HMAC(StoredKey, AuthMessage) */
/* ClientSignature := HMAC(StoredKey, AuthMessage) */
snprintf(AuthMessage, 500, "%s,%s,%s", clientfirstmessagebare, serverfirstmessage, clientfinalmessagewithoutproof);
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);
to64frombits(clientproof_b64, (const unsigned char *) ClientProof, 20);
snprintf(result, 500, "%s,p=%s", clientfinalmessagewithoutproof, clientproof_b64);
if (debug)
hydra_report(stderr, "DEBUG C: %s\n", result);