Compare commits

...

76 commits
v9.5 ... master

Author SHA1 Message Date
van Hauser
96b42617d7
Merge pull request #1021 from lhywk/fix/null-check-start_redis
Some checks failed
release / Build the docker image (push) Has been cancelled
Fix Add NULL check to prevent NULL pointer dereference in start_redis( )
2025-07-03 09:56:21 +02:00
lhywk
cbd08d5702 Add NULL check after hydra_receive_line() in start_redis() 2025-07-03 05:07:27 +00:00
van Hauser
8e6ccbba8e
Merge pull request #1020 from xh4vm/master
Some checks failed
release / Build the docker image (push) Has been cancelled
POP3 CAPA response fix
2025-06-29 17:00:04 +02:00
xh4vm
5ddee91edc feat: pop3 capa fix 2025-06-29 19:22:31 +05:00
van Hauser
e762093915
Merge pull request #1019 from oss-belobog/fix-leak
Fix several memory leaks
2025-06-11 10:41:14 +02:00
oss-belobog
f80dc5aa02 fix several memory leaks 2025-06-04 00:54:30 +08:00
van Hauser
b763262c4a
Merge pull request #1007 from motypi/use-library-for-mssql
Use library for mssql
2025-04-04 14:19:04 +02:00
van Hauser
5dbcfdc362
Merge pull request #1009 from iskanred/master
Fix typo in README: lenght
2025-04-04 14:18:17 +02:00
iskanred
21262626e0 Fix typo in README: lenght 2025-04-01 04:59:28 +03:00
motypi
1af1682414 delete tds7 function and print warning 2025-03-24 10:25:04 +01:00
motypi
b5eb38e48f mixed TDS7 into old function 2025-03-24 09:05:03 +01:00
motypi
5f706c7071 freetds install in README 2025-03-19 20:35:29 +01:00
motypi
bc48f7625b added dbclose() and dbexit() in mssql module 2025-03-19 20:17:39 +01:00
motypi
369374b166 revert Makefile 2025-03-19 12:14:50 +01:00
motypi
17c6228f7b generated Makefile 2025-03-19 08:01:10 +01:00
motypi
3635dff5ff handle libraries accommodate old version of TDS 2025-03-19 07:41:46 +01:00
van Hauser
c57df67aeb
Merge pull request #1005 from xh4vm/http-misc-targets
feat: added paths for brute force and additional settings
2025-03-18 16:05:37 +01:00
motypi
3c233fdbc0 Used freetds to use TDSv7. First working version. 2025-03-18 16:05:08 +01:00
xh4vm
b81105f6af fix: hydra-http-form documentation 2025-03-18 17:35:41 +05:00
xh4vm
aae8baae83 fix: hydra-http documentation 2025-03-18 17:32:56 +05:00
xh4vm
ba45db1496 feat: added documentation 2025-03-14 19:28:04 +05:00
xh4vm
ad286790ca feat: integration with http[s]-* 2025-03-13 12:26:57 +05:00
van Hauser
9bf9f8ba76
Merge pull request #1003 from motypi/add-distributed-computing
Add distributed computing
2025-03-12 10:52:40 +01:00
motypi
b8ea180d85 unique segment filename 2025-03-12 10:38:25 +01:00
motypi
74b37e24c8 unique segment filename 2025-03-12 10:37:01 +01:00
xh4vm
79f7d52ba2 feat: added paths for brute force and additional settings for all targets from the file 2025-03-12 13:07:12 +05:00
van Hauser
7bf582699d
Merge pull request #1004 from xh4vm/postgres-custom-port
feat: added the ability to brute force a custom port
2025-03-11 18:06:53 +01:00
xh4vm
4fad67d307 feat: added the ability to brute force a custom port 2025-03-11 18:42:09 +05:00
motypi
5eea263707 remove segment files at exit 2025-03-11 14:10:52 +01:00
motypi
8faf1984d8 removed debug messages 2025-03-10 23:02:55 +01:00
motypi
f632c7231e added help for -D option 2025-03-10 22:41:50 +01:00
motypi
2c50bb8e6d added wordlist (password,login,colonfile) segmentation on the fly using cmd option -D 2025-03-10 13:58:09 +01:00
motypi
a8f80debed added variables and applied skipping function 2025-03-04 10:34:23 +01:00
motypi
3cc53fe778 created skip_password function 2025-03-03 13:00:37 +01:00
van Hauser
6aaeee97a3
Merge pull request #914 from tothi/fix-smb-pw-expiry
fix smb password expired vs account expired confusion
2025-02-18 09:20:09 +01:00
van Hauser
4fb430b18e
Merge pull request #947 from Proto1337/master
Bump Debian version in Dockerfile to Bookworm
2025-02-18 09:19:16 +01:00
van Hauser
e4367b2f13
Merge pull request #970 from ccc-aaa/master
Fix compile errors when compiling against freerdp3
2025-02-18 09:18:43 +01:00
van Hauser
b19b39c575
Merge pull request #1001 from motypi/add-http-multipart-format
Add http multipart format
2025-02-10 16:09:52 +01:00
motypi
db099fcdac cleaning code 2025-02-10 14:57:07 +01:00
motypi
ba9a3ba8de add help for multipart mode, remove junk files 2025-02-10 10:37:17 +01:00
motypi
65c897da68 multipart feature finished 2025-02-07 14:27:04 +01:00
Imane Khouani
80a11bb1e0 no comments 2025-02-06 17:54:26 +01:00
Imane Khouani
6cca92477e no comments 2025-02-06 17:48:39 +01:00
Imane Khouani
5e01d0d4e5 build multipart function completed 2025-02-06 17:38:59 +01:00
Imane Khouani
373da88a7e build multipart function completed 2025-02-06 17:21:47 +01:00
motypi
57216f5ce6 added multipart_mode flag, build function incomplete 2025-02-06 16:26:53 +01:00
motypi
71c846d14f started on the build_multipart_body function 2025-02-06 14:11:48 +01:00
motypi
0b7d3c4bbf integrated multipart in start_http_form, created multipart flag 2025-02-05 23:18:42 +01:00
a12092
7545077a16 Unify settings access between freerdp 2 and 3
use `instance->context->settings` in both versions.
2024-08-13 14:19:14 +08:00
a12092
eb7ab3907b Adapt with freerdp changes
FreeRDP/FreeRDP#7738
use fields under rdpContext instead of freerdp

FreeRDP/FreeRDP@5f8100
removes reference to MaxTimeInCheckLoop since FreeRDP has dropped this
field after migrating away from blocking poll loop.
2024-08-13 13:40:20 +08:00
Umut Yilmaz
eaf17e9d5d
Bump Dockerfile Base Image
* Debian Buster -> Debian Bookworm
2024-05-07 21:53:13 +02:00
vanhauser-thc
03cdc31f98 update oracle url 2024-04-01 14:18:47 +02:00
tothi
82fd1a3ca0
Update hydra-smb.c
fixed logging (if found -> hydra_report to stdout with Information instead of Error)
2024-02-29 02:52:00 +01:00
vanhauser-thc
8c4165a83b show form 401 option 2023-12-07 15:54:02 +01:00
vanhauser-thc
438e4fa537 fix 2023-12-05 09:36:16 +01:00
van Hauser
02e0c8ce3e
Merge pull request #912 from Hatsumi-FR/fix/redefinition-of-tmp
Fix "make" error
2023-12-05 09:32:17 +01:00
van Hauser
fb090d4bf9
Merge pull request #915 from tothi/add-ssh-legacy-ciphers
add legacy SSH ciphers support
2023-12-05 09:31:46 +01:00
TÓTH István
9269d54ca4 add legacy SSH ciphers support 2023-12-05 01:19:55 +01:00
TÓTH István
48c1e20985 fix smb password expired vs account expired confusion 2023-12-05 01:13:11 +01:00
Hatsumi-FR
15b1f93903 Fix "make" error
Variable 'tmp' was moved to a higher scope in the parse_options function of hydra-http-form.c. This change was necessary to prevent duplicate declarations in the different switch case blocks. This PR fix "make" error : error: redefinition of ‘tmp’
2023-12-03 14:11:19 +01:00
van Hauser
e950212789
Merge pull request #898 from andraxin/patch-1
Update hydra-http-form.c
2023-11-29 16:11:23 +01:00
andraxin
1dce42a0cc
Update hydra-http-form.c
Fix handling web forms that may return 401.
2023-09-29 00:06:49 +02:00
vanhauser-thc
16b424af4d support -W for modules that use libarries 2023-08-13 13:07:10 +02:00
van Hauser
b4a2b0b4ef
Merge pull request #882 from danielvandenberg95/master-1
Allow HTTP-POST with F=403
2023-08-13 10:47:00 +00:00
Daniël van den Berg
d2363dc99e
Allow HTTP-POST with F=403
I had a site which returns 200OK, but a json containing 403. Get results in "invalid api call". Allow using F= with post.
2023-08-10 16:25:37 +02:00
vanhauser-thc
568ef74e0d nits 2023-07-21 10:44:38 +02:00
van Hauser
93abd60fc9
Merge pull request #869 from R-Rothrock/master
Fixed #868 on vanhauser-thc/thc-hydra
2023-07-12 15:43:10 +02:00
Roan Rothrock
fb964fc113 Fixed #868 on vanhauser-thc/thc-hydra 2023-07-11 10:15:24 -05:00
van Hauser
e5c9eb6ab7
Merge pull request #867 from CoenTempelaars/issue-863
fix replacement of user/pass placeholders in http header
2023-07-08 09:58:05 +02:00
Coen Tempelaars
310068c9ca fix replacement of user/pass placeholders in http header 2023-07-08 09:43:38 +02:00
vanhauser-thc
8a2df9b8f2 9.6dev 2023-06-30 17:21:44 +02:00
van Hauser
b8feed0e5d
Merge pull request #861 from bearxy123/master
fix memory leaks for hydra-http-form.c
2023-06-30 18:16:41 +03:00
xiongyi
bb0fc93539 fix memory leaks for hydra-http-form.c
Signed-off-by: xiongyi <xiongyi@uniontech.com>
2023-06-27 17:45:38 +08:00
van Hauser
888da899f9
Merge pull request #860 from neo-one0873/patch-1
fix: array proxy_string_port may out of bound
2023-06-27 09:40:29 +03:00
neo-one0873
58256c8b4f
fix: array proxy_string_port may out of bound
when proxy_count=64, array proxy_string_port , proxy_string_ip, etc. may out of bound.
2023-06-27 10:41:16 +08:00
vanhauser-thc
28f073fd79 fix pw-inspector 2023-06-24 12:03:03 +02:00
32 changed files with 597 additions and 176 deletions

View file

@ -2,6 +2,8 @@ Changelog for hydra
-------------------
Release 9.5
* many modules did not support -W (all those that used a library for the
connection). All (or most?) should be fixed now.
* http-form:
- The help for http-form was wrong. the condition variable must always be
the *last* parameter, not the third

View file

@ -1,4 +1,4 @@
FROM debian:buster-slim
FROM debian:bookworm-slim
ARG HYDRA_VERSION="github"

View file

@ -24,5 +24,5 @@ https://wiki.termux.com/wiki/Graphical_Environment
For the Oracle login module, install the basic and SDK packages:
http://www.oracle.com/technetwork/database/features/instant-client/index.html
https://www.oracle.com/database/technologies/instant-client/downloads.html

View file

@ -4,7 +4,7 @@
WARN_CLANG=-Wformat-nonliteral -Wstrncat-size -Wformat-security -Wsign-conversion -Wconversion -Wfloat-conversion -Wshorten-64-to-32 -Wuninitialized -Wmissing-variable-declarations -Wmissing-declarations
WARN_GCC=-Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-truncation=2 -Wnull-dereference -Wstrict-overflow=2 -Wstringop-overflow=4 -Walloca-larger-than=4096 -Wtype-limits -Wconversion -Wtrampolines -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -fno-common -Wcast-align
CFLAGS ?= -g
OPTS=-I. -O3 $(CFLAGS) -fcommon
OPTS=-I. -O3 $(CFLAGS) -fcommon -Wno-deprecated-declarations
CPPFLAGS += -D_GNU_SOURCE
# -Wall -g -pedantic
LIBS=-lm

4
README
View file

@ -96,7 +96,7 @@ for a few optional modules (note that some might not be available on your distri
apt-get install libssl-dev libssh-dev libidn11-dev libpcre3-dev \
libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev \
firebird-dev libmemcached-dev libgpg-error-dev \
libgcrypt11-dev libgcrypt20-dev
libgcrypt11-dev libgcrypt20-dev freetds-dev
```
This enables all optional modules and features with the exception of Oracle,
@ -267,7 +267,7 @@ Examples:
-x 1:3:a generate passwords from length 1 to 3 with all lowercase letters
-x 2:5:/ generate passwords from length 2 to 5 containing only slashes
-x 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers
-x '3:3:aA1&~#\\ "\'<{([-|_^@)]=}>$%*?./§,;:!`' -v generates lenght 3 passwords with all 95 characters, and verbose.
-x '3:3:aA1&~#\\ "\'<{([-|_^@)]=}>$%*?./§,;:!`' -v generates length 3 passwords with all 95 characters, and verbose.
```
Example:

37
configure vendored
View file

@ -185,6 +185,32 @@ else
echo " ... zlib not found, gzip support disabled"
fi
echo "Checking for sybdb (sybdb.h) ..."
for i in $INCDIRS; do
if [ -f "$i/sybdb.h" ]; then
HAVE_SYBDB="y"
fi
done
if [ -n "$HAVE_SYBDB" ]; then
echo " ... found"
else
echo " ... sybdb not found, MSSQL module will lack TDSv7 support"
fi
echo "Checking for sybfront (sybfront.h) ..."
for i in $INCDIRS; do
if [ -f "$i/sybfront.h" ]; then
HAVE_SYBFRONT="y"
fi
done
if [ -n "$HAVE_SYBFRONT" ]; then
echo " ... found"
else
echo " ... sybfront not found, MSSQL module will lack TDSv7 support"
fi
echo "Checking for openssl (libssl/libcrypto/ssl.h/sha.h) ..."
if [ "X" != "X$DEBUG" ]; then
echo DEBUG: SSL_LIB=$LIBDIRS `ls -d /*ssl /usr/*ssl /opt/*ssl /usr/local/*ssl /opt/local/*ssl /*ssl/lib /usr/*ssl/lib /opt/*ssl/lib /usr/local/*ssl/lib /opt/local/*ssl/lib 2> /dev/null`
@ -966,7 +992,7 @@ if [ -n "$ORACLE_PATH" -a -n "$ORACLE_IPATH" ]; then
fi
if [ "X" = "X$ORACLE_PATH" -o "X" = "X$ORACLE_IPATH" ]; then
echo " ... NOT found, module Oracle disabled"
echo "Get basic and sdk package from http://www.oracle.com/technetwork/database/features/instant-client/index.html"
echo "Get basic and sdk package from https://www.oracle.com/database/technologies/instant-client/downloads.html"
ORACLE_PATH=""
ORACLE_IPATH=""
fi
@ -1496,6 +1522,12 @@ fi
if [ -n "$RSA" ]; then
XDEFINES="$XDEFINES -DNO_RSA_LEGACY"
fi
if [ -n "$HAVE_SYBDB" ]; then
XDEFINES="$XDEFINES -DHAVE_SYBDB"
fi
if [ -n "$HAVE_SYBFRONT" ]; then
XDEFINES="$XDEFINES -DHAVE_SYBFRONT"
fi
if [ -n "$HAVE_ZLIB" ]; then
XDEFINES="$XDEFINES -DHAVE_ZLIB"
fi
@ -1627,6 +1659,9 @@ fi
if [ -n "$HAVE_ZLIB" ]; then
XLIBS="$XLIBS -lz"
fi
if [ -n "$HAVE_SYBDB" ]; then
XLIBS="$XLIBS -lsybdb"
fi
if [ -n "$CURSES_PATH" ]; then
XLIBS="$XLIBS -lcurses"
fi

View file

@ -22,6 +22,7 @@ void dummy_firebird() { printf("\n"); }
#define DEFAULT_DB "C:\\Program Files\\Firebird\\Firebird_1_5\\security.fdb"
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
int32_t start_firebird(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
@ -124,6 +125,8 @@ void service_firebird(char *ip, int32_t sp, unsigned char options, char *miscptr
*/
next_run = start_firebird(sock, ip, port, options, miscptr, fp);
if ((next_run == 1 || next_run == 2) && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3:

View file

@ -26,8 +26,10 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char
if (verbose)
printf("[INFO] user %s does not exist, skipping\n", login);
hydra_completed_pair_skip();
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) {
free(buf);
return 4;
}
free(buf);
return 1;
}
@ -35,8 +37,10 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char
if (buf[0] == '2') {
hydra_report_found_host(port, ip, "ftp", fp);
hydra_completed_pair_found();
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) {
free(buf);
return 4;
}
free(buf);
return 1;
}
@ -61,8 +65,10 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char
if (buf[0] == '2') {
hydra_report_found_host(port, ip, "ftp", fp);
hydra_completed_pair_found();
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) {
free(buf);
return 4;
}
free(buf);
return 1;
}

201
hydra-http-form.c Normal file → Executable file
View file

@ -66,6 +66,8 @@ int32_t success_cond = 0;
int32_t getcookie = 1;
int32_t auth_flag = 0;
int32_t code_302_is_success = 0;
int32_t code_401_is_failure = 0;
int32_t multipart_mode = 0;
char cookie[4096] = "", cmiscptr[1024];
@ -314,10 +316,15 @@ 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) + 1);
if (cur_ptr->value)
strcpy(cur_ptr->value, newvalue);
else {
size_t oldlen = strlen(oldvalue);
size_t newlen = strlen(newvalue);
if (oldlen != newlen)
cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(cur_ptr->value) - oldlen + newlen + 1);
if (cur_ptr->value) {
char *p = strstr(cur_ptr->value, oldvalue);
memmove(p + newlen, p + oldlen, strlen(p + oldlen) + 1);
memcpy(p, newvalue, newlen);
} else {
hydra_report(stderr, "[ERROR] Out of memory (hddrep).\n");
hydra_child_exit(0);
}
@ -384,7 +391,7 @@ char *stringify_headers(ptr_header_node *ptr_head) {
}
int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
char *ptr, *ptr2;
char *ptr, *ptr2, *tmp;
if (miscptr == NULL)
return 1;
@ -432,9 +439,26 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
sprintf(cookieurl, "%.1000s", hydra_strrep(miscptr + 2, "\\:", ":"));
miscptr = ptr;
break;
case '1':
code_401_is_failure = 1;
tmp = strchr(miscptr, ':');
if (tmp)
miscptr = tmp + 1;
else
miscptr += strlen(miscptr);
break;
case '2':
code_302_is_success = 1;
char *tmp = strchr(miscptr, ':');
tmp = strchr(miscptr, ':');
if (tmp)
miscptr = tmp + 1;
else
miscptr += strlen(miscptr);
break;
case 'm': // fall through
case 'M':
multipart_mode = 1;
tmp = strchr(miscptr, ':');
if (tmp)
miscptr = tmp + 1;
else
@ -518,6 +542,97 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
return 1;
}
char *build_multipart_body(char *multipart_boundary) {
if (!variables)
return NULL;
char *body = NULL;
size_t body_size = 0;
// Duplicate "variables" for tokenizing
char *vars_dup = strdup(variables);
if (!vars_dup)
return NULL;
// Tokenize the string using '&' as a delimiter
char *pair = strtok(vars_dup, "&");
while (pair != NULL) {
// Find the '=' separator in each pair
char *equal_sign = strchr(pair, '=');
if (!equal_sign) {
pair = strtok(NULL, "&");
continue;
}
*equal_sign = '\0';
char *key = pair;
char *value = equal_sign + 1;
// Build the multipart section for the field
int section_len = snprintf(NULL, 0,
"--%s\r\n"
"Content-Disposition: form-data; name=\"%s\"\r\n"
"\r\n"
"%s\r\n",
multipart_boundary, key, value);
char *section = malloc(section_len + 1);
if (!section) {
free(body);
free(vars_dup);
return NULL;
}
snprintf(section, section_len + 1,
"--%s\r\n"
"Content-Disposition: form-data; name=\"%s\"\r\n"
"\r\n"
"%s\r\n",
multipart_boundary, key, value);
// Reallocate the body buffer to add this section
size_t new_body_size = body_size + section_len;
char *new_body = realloc(body, new_body_size + 1); // +1 for null terminator
if (!new_body) {
free(section);
free(body);
free(vars_dup);
return NULL;
}
body = new_body;
if (body_size == 0)
strcpy(body, section);
else
strcat(body, section);
body_size = new_body_size;
free(section);
pair = strtok(NULL, "&");
}
free(vars_dup);
// Append the closing boundary: --<boundary>--\r\n
int closing_len = snprintf(NULL, 0, "--%s--\r\n", multipart_boundary);
char *closing = malloc(closing_len + 1);
if (!closing) {
free(body);
return NULL;
}
snprintf(closing, closing_len + 1, "--%s--\r\n", multipart_boundary);
size_t final_size = body_size + closing_len;
char *final_body = realloc(body, final_size + 1);
if (!final_body) {
free(closing);
free(body);
return NULL;
}
body = final_body;
strcat(body, closing);
free(closing);
return body;
}
char *prepare_http_request(char *type, char *path, char *params, char *headers) {
uint32_t reqlen = 0;
char *http_request = NULL;
@ -726,7 +841,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
char *http_request = NULL;
int32_t found = !success_cond, i, j;
char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH];
char content_type[256];
memset(header, 0, sizeof(header));
cookie[0] = 0; // reset cookies from potential previous attempt
@ -746,11 +861,24 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
clogin[sizeof(clogin) - 1] = 0;
strncpy(cpass, html_encode(pass), sizeof(cpass) - 1);
cpass[sizeof(cpass) - 1] = 0;
upd3variables = hydra_strrep(variables, "^USER^", clogin);
if (multipart_mode) {
snprintf(content_type, sizeof(content_type), "multipart/form-data; boundary=----THC-HydraBoundaryz2Z2z");
char *multipart_body = build_multipart_body("----THC-HydraBoundaryz2Z2z");
upd3variables = multipart_body;
}else{
snprintf(content_type, sizeof(content_type), "application/x-www-form-urlencoded");
upd3variables = variables;
}
upd3variables = hydra_strrep(upd3variables, "^USER^", clogin);
upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass);
upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login);
upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass);
// Replace the user/pass placeholders in the user-supplied headers
hdrrep(&ptr_head, "^USER^", clogin);
hdrrep(&ptr_head, "^PASS^", cpass);
@ -782,7 +910,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
else
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);
add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT);
if (cookie_header != NULL)
free(cookie_header);
cookie_header = stringify_cookies(ptr_cookie);
@ -796,8 +924,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL)
free(http_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) {
free(cookie_header);
return 1;
}
} else {
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0");
@ -814,9 +944,11 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL)
free(http_request);
http_request = prepare_http_request("GET", 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) {
free(cookie_header);
return 1;
}
}
} else {
if (use_proxy == 1) {
// proxy without authentication
@ -844,7 +976,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
else
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);
add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT);
if (cookie_header != NULL)
free(cookie_header);
cookie_header = stringify_cookies(ptr_cookie);
@ -858,8 +990,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL)
free(http_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) {
free(cookie_header);
return 1;
}
} else {
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0");
@ -876,9 +1010,11 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL)
free(http_request);
http_request = prepare_http_request("GET", 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) {
free(cookie_header);
return 1;
}
}
} else {
// direct web server, no proxy
normal_request = NULL;
@ -907,7 +1043,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
else
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);
add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT);
if (cookie_header != NULL)
free(cookie_header);
cookie_header = stringify_cookies(ptr_cookie);
@ -921,8 +1057,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL)
free(http_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) {
free(cookie_header);
return 1;
}
} else {
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0");
@ -939,11 +1077,13 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL)
free(http_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) {
free(cookie_header);
return 1;
}
}
}
}
if (debug)
hydra_report_debug(stdout, "HTTP request sent:\n%s\n", http_request);
@ -954,13 +1094,18 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
found = success_cond;
}
if (auth_flag) { // we received a 401 error - user is using wrong module
if (auth_flag) { // we received a 401 error - user may be using wrong module
if (code_401_is_failure) { // apparently they don't think so -- treat 401 as failure
hydra_completed_pair();
return 1;
} else {
hydra_report(stderr,
"[ERROR] the target is using HTTP auth, not a web form, received HTTP "
"error code 401. Use module \"http%s-get\" instead.\n",
"[ERROR] received HTTP error code 401. The target may be using HTTP auth, "
"not a web form. Use module \"http%s-get\" instead, or set \"1=\".\n",
(options & OPTION_SSL) > 0 ? "s" : "");
return 2;
}
}
if (strlen(cookie) > 0)
process_cookies(&ptr_cookie, cookie);
@ -1105,8 +1250,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
hydra_reconnect(s, ip, port, options, hostname);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) {
free(cookie_header);
return 1;
}
found = analyze_server_response(s);
if (strlen(cookie) > 0)
@ -1443,8 +1590,10 @@ void usage_http_form(const char *service) {
" the sent/received data!\n"
" Note that using invalid login condition checks can result in false positives!\n"
"\nThe following parameters are optional and are put between the form parameters\n"
" and the condition string; seperate them too with colons:\n"
"and the condition string; seperate them too with colons:\n"
" 1= 401 error response is interpreted as user/pass wrong\n"
" 2= 302 page forward return codes identify a successful attempt\n"
" M= attack forms that use multipart format\n"
" (c|C)=/page/uri to define a different page to gather initial "
"cookies from\n"
" (g|G)= skip pre-requests - only use this when no pre-cookies are required\n"
@ -1475,6 +1624,12 @@ void usage_http_form(const char *service) {
" \"/exchweb/bin/auth/:F=failed"
"owaauth.dll:destination=http%%3A%%2F%%2F<target>%%2Fexchange&flags=0&"
"username=<domain>%%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:"
"C=/exchweb\":reason=\n",
"C=/exchweb\":reason=\n"
"To attack multiple targets, you can use the -M option with a file "
"containing the targets and their parameters.\n"
"Example file content:\n"
" localhost:8443/login:type=login&login=^USER^&password=^PASS^:h=test\\: header:F=401\n"
" localhost:9443/login2:type=login&login=^USER^&password=^PASS^:h=test\\: header:F=302\n"
" ...\n\n",
service);
}

10
hydra-http.c Normal file → Executable file
View file

@ -451,7 +451,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis
start--;
memset(start, '\0', condition_len);
if (debug)
hydra_report(stderr, "Modificated options:%s\n", miscptr);
hydra_report(stderr, "Modified options:%s\n", miscptr);
} else {
if (debug)
hydra_report(stderr, "Condition not found\n");
@ -474,6 +474,12 @@ void usage_http(const char *service) {
" combination is invalid. Note: this must be the last option "
"supplied.\n"
"For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: "
"sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n",
"sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n"
"To attack multiple targets, you can use the -M option with a file "
"containing the targets and their parameters.\n"
"Example file content:\n"
" localhost:5000/protected:A=BASIC\n"
" localhost:5002/protected_path:A=NTLM\n"
" ...\n\n",
service);
}

View file

@ -13,6 +13,7 @@ void dummy_mcached() { printf("\n"); }
extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec);
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
int mcached_send_com_quit(int32_t sock) {
@ -117,6 +118,8 @@ void service_mcached(char *ip, int32_t sp, unsigned char options, char *miscptr,
switch (run) {
case 1:
next_run = start_mcached(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 2:
hydra_child_exit(0);

View file

@ -14,6 +14,7 @@ void dummy_mongodb() { printf("\n"); }
extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec);
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
char *buf;
@ -136,6 +137,8 @@ void service_mongodb(char *ip, int32_t sp, unsigned char options, char *miscptr,
switch (run) {
case 1:
next_run = start_mongodb(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 2:
hydra_child_exit(0);

View file

@ -1,10 +1,14 @@
#include "hydra-mod.h"
#define MSLEN 30
extern char *HYDRA_EXIT;
char *buf;
#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB)
#include <sybdb.h>
#include <sybfront.h>
#endif
#define MSLEN 30
unsigned char p_hdr[] = "\x02\x00\x02\x00\x00\x00\x02\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
@ -56,6 +60,7 @@ unsigned char p_lng[] = "\x02\x01\x00\x47\x00\x00\x02\x00\x00\x00\x00"
int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = "";
char *login, *pass, buffer[1024];
char *ipaddr_str = hydra_address2string(ip);
char ms_login[MSLEN + 1];
char ms_pass[MSLEN + 1];
unsigned char len_login, len_pass;
@ -65,6 +70,42 @@ int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, ch
login = empty;
if (strlen(pass = hydra_get_next_password()) == 0)
pass = empty;
#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB)
if ((strlen(login) > MSLEN) || (strlen(pass) > MSLEN)){
DBPROCESS *dbproc;
LOGINREC *attempt;
attempt = dblogin();
DBSETLUSER(attempt, login);
DBSETLPWD(attempt, pass);
// Connect without specifying a database
dbproc = dbopen(attempt, ipaddr_str);
if (dbproc != NULL) {
dbclose(dbproc);
dbexit();
hydra_report_found_host(port, ip, "mssql", fp);
hydra_completed_pair_found();
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 2;
return 1;
}
hydra_completed_pair();
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 2;
return 1;
}
#else
if ((strlen(login) > MSLEN) || (strlen(pass) > MSLEN)){
fprintf(stderr,"[WARNING] To crack credentials longer than 30 characters, install freetds and recompile\n");
}
#endif
if (strlen(login) > MSLEN)
login[MSLEN - 1] = 0;
if (strlen(pass) > MSLEN)
@ -119,6 +160,10 @@ void service_mssql(char *ip, int32_t sp, unsigned char options, char *miscptr, F
int32_t run = 1, next_run = 1, sock = -1;
int32_t myport = PORT_MSSQL, mysslport = PORT_MSSQL_SSL;
#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB)
dbinit();
#endif
hydra_register_socket(sp);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return;

View file

@ -35,6 +35,7 @@ char *hydra_scramble(char *to, const char *message, const char *password);
extern int32_t internal__hydra_recv(int32_t socket, char *buf, int32_t length);
extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec);
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
char mysqlsalt[9];
@ -332,6 +333,8 @@ void service_mysql(char *ip, int32_t sp, unsigned char options, char *miscptr, F
break;
case 2: /* run the cracking function */
next_run = start_mysql(sock, ip, port, options, miscptr, fp);
if ((next_run == 1 || next_run == 2) && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3: /* clean exit */
if (sock >= 0) {

View file

@ -19,6 +19,7 @@ void dummy_oracle_listener() { printf("\n"); }
#include <openssl/des.h>
#define HASHSIZE 17
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
char *buf;
unsigned char *hash;
@ -304,6 +305,8 @@ void service_oracle_listener(char *ip, int32_t sp, unsigned char options, char *
}
/* run the cracking function */
next_run = start_oracle_listener(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3: /* clean exit */
if (sock >= 0)

View file

@ -16,6 +16,7 @@ void dummy_oracle_sid() { printf("\n"); }
#include <openssl/des.h>
#define HASHSIZE 16
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
char *buf;
unsigned char *hash;
@ -113,6 +114,8 @@ void service_oracle_sid(char *ip, int32_t sp, unsigned char options, char *miscp
}
/* run the cracking function */
next_run = start_oracle_sid(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3: /* clean exit */
if (sock >= 0)

View file

@ -21,6 +21,7 @@ void dummy_oracle() { printf("\n"); }
#include <stdbool.h>
#include <sys/types.h>
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
OCIEnv *o_environment;
@ -165,6 +166,8 @@ void service_oracle(char *ip, int32_t sp, unsigned char options, char *miscptr,
break;
case 2:
next_run = start_oracle(sock, ip, port, options, miscptr, fp);
if ((next_run == 1 || next_run == 2) && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3: /* clean exit */
if (sock >= 0)

View file

@ -109,7 +109,7 @@ char *pop3_read_server_capacity(int32_t sock) {
buf[strlen(buf) - 1] = 0;
if (buf[strlen(buf) - 1] == '\r')
buf[strlen(buf) - 1] = 0;
if (*(ptr) == '.' || *(ptr) == '-')
if (buf[strlen(buf) - 1] == '.' || *(ptr) == '.' || *(ptr) == '-')
resp = 1;
}
}

View file

@ -16,6 +16,7 @@ void dummy_postgres() { printf("\n"); }
#define DEFAULT_DB "template1"
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
int32_t start_postgres(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
@ -40,7 +41,7 @@ int32_t start_postgres(int32_t s, char *ip, int32_t port, unsigned char options,
* Building the connection string
*/
snprintf(connection_string, sizeof(connection_string), "host = '%s' dbname = '%s' user = '%s' password = '%s' ", hydra_address2string(ip), database, login, pass);
snprintf(connection_string, sizeof(connection_string), "host = '%s' port = '%d' dbname = '%s' user = '%s' password = '%s' ", hydra_address2string(ip), port, database, login, pass);
if (verbose)
hydra_report(stderr, "connection string: %s\n", connection_string);
@ -99,6 +100,8 @@ void service_postgres(char *ip, int32_t sp, unsigned char options, char *miscptr
* Here we start the password cracking process
*/
next_run = start_postgres(sock, ip, port, options, miscptr, fp);
if ((next_run == 2 || next_run == 1) && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3:
if (sock >= 0)

View file

@ -16,24 +16,30 @@ void dummy_rdp() { printf("\n"); }
#else
#include <freerdp/freerdp.h>
#include <freerdp/version.h>
freerdp *instance = 0;
BOOL rdp_connect(char *server, int32_t port, char *domain, char *login, char *password) {
int32_t err = 0;
instance->settings->Username = login;
instance->settings->Password = password;
instance->settings->IgnoreCertificate = TRUE;
rdpSettings* settings = instance->context->settings;
settings->Username = login;
settings->Password = password;
settings->IgnoreCertificate = TRUE;
if (password[0] == 0)
instance->settings->AuthenticationOnly = FALSE;
settings->AuthenticationOnly = FALSE;
else
instance->settings->AuthenticationOnly = TRUE;
instance->settings->ServerHostname = server;
instance->settings->ServerPort = port;
instance->settings->Domain = domain;
instance->settings->MaxTimeInCheckLoop = 100;
settings->AuthenticationOnly = TRUE;
settings->ServerHostname = server;
settings->ServerPort = port;
settings->Domain = domain;
#if FREERDP_VERSION_MAJOR == 2
settings->MaxTimeInCheckLoop = 100;
#endif
// freerdp timeout format is microseconds -> default:15000
instance->settings->TcpConnectTimeout = hydra_options.waittime * 1000;
instance->settings->TlsSecLevel = 0;
settings->TcpConnectTimeout = hydra_options.waittime * 1000;
settings->TlsSecLevel = 0;
freerdp_connect(instance);
err = freerdp_get_last_error(instance->context);
return err;
@ -125,6 +131,8 @@ void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL
else
sleep(hydra_options.conwait);
next_run = start_rdp(ip, myport, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 2: /* clean exit */
freerdp_disconnect(instance);

View file

@ -24,6 +24,11 @@ int32_t start_redis(int32_t s, char *ip, int32_t port, unsigned char options, ch
return 1;
}
buf = hydra_receive_line(s);
if (buf == NULL) {
hydra_report(stderr, "[ERROR] Failed to receive response from Redis server.\n");
return 3;
}
if (buf[0] == '+') {
hydra_report_found_host(port, ip, "redis", fp);
hydra_completed_pair_found();

View file

@ -6,7 +6,9 @@
//
//
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "hydra-mod.h"
#include "sasl.h"

View file

@ -14,6 +14,7 @@ const int32_t *__ctype_b;
extern void flood(); /* for -lm */
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
RFC_ERROR_INFO_EX error_info;
@ -99,6 +100,8 @@ void service_sapr3(char *ip, int32_t sp, unsigned char options, char *miscptr, F
switch (run) {
case 1: /* connect and service init function */
next_run = start_sapr3(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 2:
hydra_child_exit(0);

View file

@ -1280,8 +1280,8 @@ int32_t start_smb(int32_t s, char *ip, int32_t port, unsigned char options, char
} else if (SMBerr == 0x000193) { /* Valid password, account expired */
hydra_report(stdout, "[%d][smb] Host: %s Account: %s Valid password, account expired\n", port, ipaddr_str, login);
hydra_report_found_host(port, ip, "smb", fp);
hydra_completed_pair_found();
} else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, account expired */
hydra_completed_pair_skip();
} else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, password expired */
hydra_report(stdout,
"[%d][smb] Host: %s Account: %s Valid password, password "
"expired and must be changed on next logon\n",
@ -1304,14 +1304,13 @@ int32_t start_smb(int32_t s, char *ip, int32_t port, unsigned char options, char
hydra_report(stderr, "[INFO] LM dialect may be disabled, try LMV2 instead\n");
hydra_completed_pair_skip();
} else if (SMBerr == 0x000024) { /* change password on next login [success] */
hydra_report(stdout, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login);
hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login);
hydra_completed_pair_found();
} else if (SMBerr == 0x00006D) { /* STATUS_LOGON_FAILURE */
hydra_completed_pair();
} else if (SMBerr == 0x000071) { /* password expired */
if (verbose)
fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: PASSWORD EXPIRED\n", port, ipaddr_str, login);
hydra_completed_pair_skip();
hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: PASSWORD EXPIRED\n", port, ipaddr_str, login);
hydra_completed_pair_found();
} else if ((SMBerr == 0x000072) || (SMBerr == 0xBF0002)) { /* account disabled */ /* BF0002 on w2k */
if (verbose)
fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_DISABLED\n", port, ipaddr_str, login);

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <string.h>
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
typedef struct creds {
@ -173,10 +174,15 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) {
}
void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
static int first_run = 0;
hydra_register_socket(sp);
while (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT))) {
char *login, *pass;
if (first_run && hydra_options.conwait)
sleep(hydra_options.conwait);
login = hydra_get_next_login();
pass = hydra_get_next_password();
@ -191,6 +197,8 @@ void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
} else {
hydra_completed_pair();
}
first_run = 1;
}
EXIT_NORMAL;
}

View file

@ -47,6 +47,9 @@ int32_t start_ssh(int32_t s, char *ip, int32_t port, unsigned char options, char
ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &hydra_options.waittime);
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none");
// might be better to add the legacy (first two for KEX and HOST) to the default instead of specifying the full list
ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256");
ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256");
if (ssh_connect(session) != 0) {
// if the connection was drop, exit and let hydra main handle it
if (verbose)
@ -119,6 +122,8 @@ void service_ssh(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL
switch (run) {
case 1: /* connect and service init function */
next_run = start_ssh(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 2:
ssh_disconnect(session);
@ -190,6 +195,9 @@ int32_t service_ssh_init(char *ip, int32_t sp, unsigned char options, char *misc
ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &hydra_options.waittime);
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none");
// might be better to add the legacy (first two for KEX and HOST) to the default instead of specifying the full list
ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256");
ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256");
if (ssh_connect(session) != 0) {
fprintf(stderr, "[ERROR] could not connect to ssh://%s:%d - %s\n", hydra_address2string_beautiful(ip), port, ssh_get_error(session));
return 2;

View file

@ -16,6 +16,7 @@ void dummy_sshkey() { printf("\n"); }
#if LIBSSH_VERSION_MAJOR >= 0 && LIBSSH_VERSION_MINOR >= 4
extern ssh_session session;
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
extern int32_t new_session;
@ -117,6 +118,8 @@ void service_sshkey(char *ip, int32_t sp, unsigned char options, char *miscptr,
switch (run) {
case 1: /* connect and service init function */
next_run = start_sshkey(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 2:
ssh_disconnect(session);

View file

@ -4,7 +4,9 @@
#ifdef LIBSVN
/* needed on openSUSE */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#if !defined PATH_MAX && defined HAVE_SYS_PARAM_H
#include <sys/param.h>
@ -30,6 +32,7 @@ void dummy_svn() { printf("\n"); }
extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec);
extern hydra_option hydra_options;
extern char *HYDRA_EXIT;
#define DEFAULT_BRANCH "trunk"
@ -195,6 +198,8 @@ void service_svn(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL
break;
case 2:
next_run = start_svn(sock, ip, port, options, miscptr, fp);
if ((next_run == 1 || next_run == 2) && hydra_options.conwait)
sleep(hydra_options.conwait);
break;
case 3:
if (sock >= 0)

137
hydra.c
View file

@ -228,7 +228,7 @@ char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cobaltstrike cvs fire
#define RESTOREFILE "./hydra.restore"
#define PROGRAM "Hydra"
#define VERSION "v9.5"
#define VERSION "v9.6dev"
#define AUTHOR "van Hauser/THC"
#define EMAIL "<vh@thc.org>"
#define AUTHOR2 "David Maciejak"
@ -267,6 +267,7 @@ typedef struct {
typedef struct {
char *target;
char *miscptr;
char ip[36];
char *login_ptr;
char *pass_ptr;
@ -343,6 +344,11 @@ int32_t prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed
int32_t child_head_no = -1, child_socket;
int32_t total_redo_count = 0;
// requred for distributed attack capability
uint32_t num_segments = 0;
uint32_t my_segment = 0;
char junk_file[50];
// moved for restore feature
int32_t process_restore = 0, dont_unlink;
char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL;
@ -388,7 +394,7 @@ static const struct {
{"http-get-form", service_http_form_init, service_http_get_form, usage_http_form},
{"http-head", service_http_init, service_http_head, NULL},
{"http-form", service_http_form_init, NULL, usage_http_form},
{"http-post", NULL, service_http_post, usage_http},
{"http-post", service_http_init, service_http_post, usage_http},
{"http-post-form", service_http_form_init, service_http_post_form, usage_http_form},
SERVICE3("http-proxy", http_proxy),
SERVICE3("http-proxy-urlenum", http_proxy_urlenum),
@ -519,6 +525,8 @@ void help(int32_t ext) {
"instead of -L/-P options\n"
" -M FILE list of servers to attack, one entry per "
"line, ':' to specify port\n");
PRINT_NORMAL(ext, " -D XofY Divide wordlist into Y segments and use the "
"Xth segment.\n");
PRINT_EXTEND(ext, " -o FILE write found login/password pairs to FILE instead of stdout\n"
" -b FORMAT specify the format for the -o FILE: text(default), json, "
"jsonv1\n"
@ -1174,13 +1182,12 @@ void hydra_service_init(int32_t target_no) {
int32_t x = 99;
int32_t i;
hydra_target *t = hydra_targets[target_no];
char *miscptr = hydra_options.miscptr;
FILE *ofp = hydra_brains.ofp;
for (i = 0; x == 99 && i < sizeof(services) / sizeof(services[0]); i++) {
if (strcmp(hydra_options.service, services[i].name) == 0) {
if (services[i].init) {
x = services[i].init(t->ip, -1, options, miscptr, ofp, t->port, t->target);
x = services[i].init(t->ip, -1, options, t->miscptr, ofp, t->port, t->target);
break;
}
}
@ -1264,13 +1271,13 @@ int32_t hydra_spawn_head(int32_t head_no, int32_t target_no) {
hydra_target *t = hydra_targets[target_no];
int32_t sp = hydra_heads[head_no]->sp[1];
char *miscptr = hydra_options.miscptr;
// char *miscptr = hydra_options.miscptr;
FILE *ofp = hydra_brains.ofp;
hydra_target *head_target = hydra_targets[hydra_heads[head_no]->target_no];
for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) {
if (strcmp(hydra_options.service, services[i].name) == 0) {
if (services[i].exec) {
services[i].exec(t->ip, sp, options, miscptr, ofp, t->port, head_target->target);
services[i].exec(t->ip, sp, options, t->miscptr, ofp, t->port, head_target->target);
// just in case a module returns (which it shouldnt) we let it exit
// here
exit(-1);
@ -1591,6 +1598,73 @@ char *hydra_reverse_login(int32_t head_no, char *login) {
return hydra_heads[head_no]->reverse;
}
void delete_junk_files(){
remove(junk_file);
}
FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){
if(my_segment > num_segments){
fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile);
return NULL;
}
FILE *output_file;
char line[500];
char output_file_name[50];
uint32_t line_number = 0;
double total_lines = countlines(file,0);
if(num_segments > total_lines){
fprintf(stderr, "[ERROR] in option -D XofY, Y must not be greater than the total number of lines in the file to be divided: %s\n", hydra_options.passfile);
return NULL;
}
double segment_size_double = total_lines / num_segments;
// round up segment_size_float to integer
uint64_t segment_size = (uint64_t)segment_size_double;
if(segment_size < segment_size_double)
segment_size++;
uint64_t segment_start = segment_size * (my_segment - 1) + 1;
uint64_t segment_end = segment_size * my_segment;
srand(time(NULL));
int filetag = rand();
sprintf(output_file_name, "segment_%d_%d.txt",filetag, my_segment);
output_file = fopen(output_file_name, "w");
if(!output_file){
fprintf(stderr, "[ERROR] Segment file empty: %s\n", hydra_options.passfile);
return NULL;
}
strcpy(junk_file, output_file_name);
atexit(delete_junk_files);
while(fgets(line, sizeof line, file) != NULL && line_number < segment_end){
line_number++;
if(line_number >= segment_start && line_number <= segment_end)
fprintf(output_file, "%s", line);
}
rewind(file);
fclose(output_file);
output_file = fopen(output_file_name, "r");
return output_file;
}
int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) {
// variables moved to save stack
snpdone = 0;
@ -2045,7 +2119,7 @@ void process_proxy_line(int32_t type, char *string) {
string[strlen(string) - 1] = 0;
if (string[strlen(string) - 1] == '\r')
string[strlen(string) - 1] = 0;
if (proxy_count > MAX_PROXY_COUNT) {
if (proxy_count >= MAX_PROXY_COUNT) {
fprintf(stderr, "[WARNING] maximum amount of proxies loaded, ignoring this entry: %s\n", string);
return;
}
@ -2171,13 +2245,13 @@ void process_proxy_line(int32_t type, char *string) {
int main(int argc, char *argv[]) {
char *proxy_string = NULL, *device = NULL, *memcheck;
char *outfile_format_tmp;
FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp;
FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp, *filecloser=NULL;
size_t countinfile = 1, sizeinfile = 0;
uint64_t math2;
int32_t i = 0, j = 0, k, error = 0, modusage = 0, ignore_restore = 0, do_switch;
int32_t head_no = 0, target_no = 0, exit_condition = 0, readres;
time_t starttime, elapsed_status, elapsed_restore, status_print = 59, tmp_time;
char *tmpptr, *tmpptr2;
char *tmpptr, *tmpptr2, *tmpptr3;
char rc, buf[MAXBUF];
time_t last_attempt = 0;
fd_set fdreadheads;
@ -2307,6 +2381,7 @@ int main(int argc, char *argv[]) {
hydra_options.loginfile = NULL;
hydra_options.pass = NULL;
hydra_options.passfile = NULL;
hydra_options.distributed = NULL;
hydra_options.tasks = TASKS;
hydra_options.max_use = MAXTASKS;
hydra_options.outfile_format = FORMAT_PLAIN_TEXT;
@ -2320,8 +2395,18 @@ int main(int argc, char *argv[]) {
help(1);
if (argc < 2)
help(0);
while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) {
while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:D:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) {
switch (i) {
case 'D':
hydra_options.distributed = optarg;
if (sscanf(hydra_options.distributed, "%dof%d", &my_segment, &num_segments) != 2) {
fprintf(stderr, "Invalid format. Expected format -D XofY where X and Y are integers.\n");
exit(EXIT_FAILURE);
}
else{
fprintf(stdout, "Option \'D\': successfully set X to %d and Y to %d\n", my_segment, num_segments);
}
break;
case 'h':
help(1);
break;
@ -3201,6 +3286,7 @@ int main(int argc, char *argv[]) {
bail("Compiled without SSL support, module not available");
#endif
}
if (hydra_options.infile_ptr == NULL) {
if (hydra_options.miscptr == NULL) {
fprintf(stderr, "[WARNING] You must supply the web page as an "
"additional option or via -m, default path set to /\n");
@ -3276,6 +3362,7 @@ int main(int argc, char *argv[]) {
}
}
}
}
if (strcmp(hydra_options.service, "xmpp") == 0)
i = 1;
@ -3402,6 +3489,13 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile);
exit(-1);
}
else if (hydra_options.passfile == NULL){
if(my_segment && num_segments){
filecloser = lfp;
lfp = hydra_divide_file(lfp, my_segment, num_segments);
fclose(filecloser);
}
}
hydra_brains.countlogin = countlines(lfp, 0);
hydra_brains.sizelogin = size_of_data;
if (hydra_brains.countlogin == 0) {
@ -3434,6 +3528,11 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile);
exit(-1);
}
else if(my_segment && num_segments){
filecloser = pfp;
pfp = hydra_divide_file(pfp, my_segment, num_segments);
fclose(filecloser);
}
hydra_brains.countpass = countlines(pfp, 0);
hydra_brains.sizepass = size_of_data;
if (hydra_brains.countpass == 0) {
@ -3488,6 +3587,11 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile);
exit(-1);
}
else if(my_segment && num_segments){
filecloser = cfp;
cfp = hydra_divide_file(cfp, my_segment, num_segments);
fclose(filecloser);
}
hydra_brains.countlogin = countlines(cfp, 1);
hydra_brains.sizelogin = size_of_data;
if (hydra_brains.countlogin == 0) {
@ -3591,6 +3695,7 @@ int main(int argc, char *argv[]) {
}
} else
hydra_targets[i]->target = tmpptr;
if ((tmpptr2 = strchr(tmpptr, ':')) != NULL) {
*tmpptr2++ = 0;
tmpptr = tmpptr2;
@ -3600,6 +3705,13 @@ int main(int argc, char *argv[]) {
}
if (hydra_targets[i]->port == 0)
hydra_targets[i]->port = hydra_options.port;
if ((tmpptr3 = strchr(tmpptr, '/')) != NULL) {
hydra_targets[i]->miscptr = tmpptr3;
}
else
hydra_targets[i]->miscptr = "/";
while (*tmpptr != 0)
tmpptr++;
tmpptr++;
@ -3622,6 +3734,7 @@ int main(int argc, char *argv[]) {
memset(hydra_targets[0], 0, sizeof(hydra_target));
hydra_targets[0]->target = servers_ptr = hydra_options.server;
hydra_targets[0]->port = hydra_options.port;
hydra_targets[0]->miscptr = hydra_options.miscptr;
sizeservers = strlen(hydra_options.server) + 1;
} else {
/* CIDR notation on command line, e.g. 192.168.0.0/24 */
@ -3666,6 +3779,7 @@ int main(int argc, char *argv[]) {
memcpy(&target.sin_addr.s_addr, (char *)&addr_cur2, 4);
hydra_targets[i]->target = strdup(inet_ntoa((struct in_addr)target.sin_addr));
hydra_targets[i]->port = hydra_options.port;
hydra_targets[i]->miscptr = hydra_options.miscptr;
addr_cur++;
i++;
}
@ -3681,6 +3795,7 @@ int main(int argc, char *argv[]) {
memset(hydra_targets[0], 0, sizeof(hydra_target));
hydra_targets[0]->target = servers_ptr = hydra_options.server;
hydra_targets[0]->port = hydra_options.port;
hydra_targets[0]->miscptr = hydra_options.miscptr;
sizeservers = strlen(hydra_options.server) + 1;
}
for (i = 0; i < hydra_brains.targets; i++) {
@ -4113,7 +4228,7 @@ int main(int argc, char *argv[]) {
} 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);
} 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 misc: %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_targets[hydra_heads[head_no]->target_no]->miscptr, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
}
if (hydra_options.outfile_format == FORMAT_JSONV1 && hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) {
fprintf(hydra_brains.ofp,

View file

@ -194,6 +194,7 @@ typedef struct {
int32_t cidr;
int32_t time_next_attempt;
output_format_t outfile_format;
char *distributed; // Use distributed computing by splitting user files on the fly
char *login;
char *loginfile;
char *pass;

View file

@ -50,7 +50,7 @@ int main(int argc, char *argv[]) {
int32_t sets = 0, countsets = 0, minlen = 0, maxlen = MAXLENGTH, count = 0;
int32_t set_low = 0, set_up = 0, set_no = 0, set_print = 0, set_other = 0;
FILE *in = stdin, *out = stdout;
char buf[MAXLENGTH + 1];
unsigned char buf[MAXLENGTH + 1];
prg = argv[0];
if (argc < 2)
@ -124,9 +124,9 @@ int main(int argc, char *argv[]) {
if (countsets == 0)
countsets = sets;
while (fgets(buf, sizeof(buf), in) != NULL) {
i = -1;
if (buf[0] == 0)
while (fgets((void *)buf, sizeof(buf), in) != NULL) {
int is_low = 0, is_up = 0, is_no = 0, is_print = 0, is_other = 0;
if (!buf[0])
continue;
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
@ -134,40 +134,31 @@ int main(int argc, char *argv[]) {
buf[strlen(buf) - 1] = 0;
if (strlen(buf) >= minlen && strlen(buf) <= maxlen) {
i = 0;
if (countsets > 0) {
if (set_low)
if (strpbrk(buf, "abcdefghijklmnopqrstuvwxyz") != NULL)
i++;
if (set_up)
if (strpbrk(buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") != NULL)
i++;
if (set_no)
if (strpbrk(buf, "0123456789") != NULL)
i++;
if (set_print) {
j = 0;
for (k = 0; k < strlen(buf); k++)
if (isprint((int32_t)buf[k]) != 0 && isalnum((int32_t)buf[k]) == 0)
j = 1;
if (j)
i++;
}
if (set_other) {
for (i = 0; i < strlen(buf) && j; i++) {
j = 0;
for (k = 0; k < strlen(buf); k++)
if (isprint((int32_t)buf[k]) == 0 && isalnum((int32_t)buf[k]) == 0)
if (set_low && islower(buf[i])) {
j = 1;
if (j)
i++;
is_low = 1;
} else if (set_up && isupper(buf[i])) {
j = 1;
is_up = 1;
} else if (set_no && isdigit(buf[i])) {
j = 1;
is_no = 1;
} else if (set_print && isprint(buf[i]) && !isalnum(buf[i])) {
j = 1;
is_print = 1;
} else if (set_other && !isprint(buf[i])) {
j = 1;
is_other = 1;
}
}
if (i >= countsets) {
if (j && countsets <= is_low + is_up + is_no + is_print + is_other) {
fprintf(out, "%s\n", buf);
count++;
}
}
/* fprintf(stderr, "[DEBUG] i: %d minlen: %d maxlen: %d len: %d\n", i,
* minlen, maxlen, strlen(buf)); */
}
fclose(in);
fclose(out);