Compare commits

..

No commits in common. "master" and "v9.3" have entirely different histories.

42 changed files with 378 additions and 973 deletions

View file

@ -1,38 +0,0 @@
name: release
on:
push:
branches: [master, main]
tags-ignore: ['**']
paths-ignore: [README, TODO, PROBLEMS]
pull_request:
paths-ignore: [README, TODO, PROBLEMS]
jobs:
docker-image:
name: Build the docker image
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: gacts/github-slug@v1 # Action page: <https://github.com/gacts/github-slug>
id: slug
- uses: docker/build-push-action@v3 # Action page: <https://github.com/docker/build-push-action>
with:
context: .
file: Dockerfile
push: true
platforms: linux/amd64, linux/arm64
# ,linux/arm/v6, linux/arm/v7
tags: vanhauser/hydra:latest

21
CHANGES
View file

@ -1,27 +1,6 @@
Changelog for hydra 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
- Proxy support was not working correctly
* smb2: fix for updated libsmb2 which resulted in correct guessing attempts
not being detected
* smtp: break early if the server does not allow authentication
* rdp: detect more return codes that say a user is disabled etc.
Release 9.4
* Switched from pcre/pcre3 to pcre2 as pcre/pcre3 will be dropped from Debian
* Small fix for weird RTSP servers
* Added "2=" optional parameter to http-post-form module to tell hydra that
a "302" HTTP return code means success
* replaced wait3 with waitpid for better compatability
Release 9.3 Release 9.3
* support Xcode compilation * support Xcode compilation
* new module: cobaltstrike by ultimaiiii, thank you! * new module: cobaltstrike by ultimaiiii, thank you!

View file

@ -1,77 +0,0 @@
FROM debian:bookworm-slim
ARG HYDRA_VERSION="github"
LABEL \
org.opencontainers.image.url="https://github.com/vanhauser-thc/thc-hydra" \
org.opencontainers.image.source="https://github.com/vanhauser-thc/thc-hydra" \
org.opencontainers.image.version="$HYDRA_VERSION" \
org.opencontainers.image.vendor="vanhauser-thc" \
org.opencontainers.image.title="hydra" \
org.opencontainers.image.licenses="GNU AFFERO GENERAL PUBLIC LICENSE"
COPY . /src
RUN set -x \
&& apt-get update \
&& apt-get -y install \
#libmysqlclient-dev \
default-libmysqlclient-dev \
libgpg-error-dev \
#libmemcached-dev \
#libgcrypt11-dev \
libgcrypt-dev \
#libgcrypt20-dev \
#libgtk2.0-dev \
libpcre3-dev \
#firebird-dev \
libidn11-dev \
libssh-dev \
#libsvn-dev \
libssl-dev \
#libpq-dev \
make \
curl \
gcc \
1>/dev/null \
# The next line fixes the curl "SSL certificate problem: unable to get local issuer certificate" for linux/arm
&& c_rehash
# Get hydra sources and compile
RUN cd /src \
&& make clean \
&& ./configure \
&& make \
&& make install
# Make clean
RUN apt-get purge -y make gcc \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /src
# Verify hydra installation
RUN hydra -h || error_code=$? \
&& if [ ! "${error_code}" -eq 255 ]; then echo "Wrong exit code for 'hydra help' command"; exit 1; fi \
# Unprivileged user creation
&& echo 'hydra:x:10001:10001::/tmp:/sbin/nologin' > /etc/passwd \
&& echo 'hydra:x:10001:' > /etc/group
ARG INCLUDE_SECLISTS="true"
RUN set -x \
&& if [ "${INCLUDE_SECLISTS}" = "true" ]; then \
mkdir /tmp/seclists \
&& curl -SL "https://api.github.com/repos/danielmiessler/SecLists/tarball" -o /tmp/seclists/src.tar.gz \
&& tar xzf /tmp/seclists/src.tar.gz -C /tmp/seclists \
&& mv /tmp/seclists/*SecLists*/Passwords /opt/passwords \
&& mv /tmp/seclists/*SecLists*/Usernames /opt/usernames \
&& chmod -R u+r /opt/passwords /opt/usernames \
&& rm -Rf /tmp/seclists \
&& ls -la /opt/passwords /opt/usernames \
;fi
# Use an unprivileged user
USER 10001:10001
ENTRYPOINT ["hydra"]

View file

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

32
LICENSE
View file

@ -1,7 +1,12 @@
[see the end of the file for the special exception for linking with OpenSSL
- debian people need this]
GNU AFFERO GENERAL PUBLIC LICENSE GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007 Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -633,8 +638,8 @@ the "copyright" line and a pointer to where the full notice is found.
Copyright (C) <year> <name of author> Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU Affero General Public License as published by
by the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
@ -643,7 +648,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -658,4 +663,21 @@ specific requirements.
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>. <http://www.gnu.org/licenses/>.
Special Exception
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU Affero General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.

View file

@ -1,11 +1,10 @@
# #
# Makefile for Hydra - (c) 2001-2023 by van Hauser / THC <vh@thc.org> # Makefile for Hydra - (c) 2001-2022 by van Hauser / THC <vh@thc.org>
# #
WARN_CLANG=-Wformat-nonliteral -Wstrncat-size -Wformat-security -Wsign-conversion -Wconversion -Wfloat-conversion -Wshorten-64-to-32 -Wuninitialized -Wmissing-variable-declarations -Wmissing-declarations 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 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 CFLAGS ?= -g
OPTS=-I. -O3 $(CFLAGS) -fcommon -Wno-deprecated-declarations OPTS=-I. -O3 $(CFLAGS) -fcommon
CPPFLAGS += -D_GNU_SOURCE
# -Wall -g -pedantic # -Wall -g -pedantic
LIBS=-lm LIBS=-lm
DESTDIR ?= DESTDIR ?=

16
README
View file

@ -1,7 +1,7 @@
H Y D R A H Y D R A
(c) 2001-2023 by van Hauser / THC (c) 2001-2022 by van Hauser / THC
<vh@thc.org> https://github.com/vanhauser-thc/thc-hydra <vh@thc.org> https://github.com/vanhauser-thc/thc-hydra
many modules were written by David (dot) Maciejak @ gmail (dot) com many modules were written by David (dot) Maciejak @ gmail (dot) com
BFG code by Jan Dlabal <dlabaljan@gmail.com> BFG code by Jan Dlabal <dlabaljan@gmail.com>
@ -14,13 +14,6 @@
in these organizations do not care for laws and ethics anyways. in these organizations do not care for laws and ethics anyways.
You are not one of the "good" ones if you ignore this.) You are not one of the "good" ones if you ignore this.)
NOTE: no this is not meant to be a markdown doc! old school!
Hydra in the most current github state can be directly downloaded via docker:
```
docker pull vanhauser/hydra
```
INTRODUCTION INTRODUCTION
@ -68,10 +61,6 @@ repository is at Github:
Use the development version at your own risk. It contains new features and Use the development version at your own risk. It contains new features and
new bugs. Things might not work! new bugs. Things might not work!
Alternatively (and easier) to can pull it as a docker container:
```
docker pull vanhauser/hydra
```
HOW TO COMPILE HOW TO COMPILE
@ -96,7 +85,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 \ apt-get install libssl-dev libssh-dev libidn11-dev libpcre3-dev \
libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev \ libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev \
firebird-dev libmemcached-dev libgpg-error-dev \ firebird-dev libmemcached-dev libgpg-error-dev \
libgcrypt11-dev libgcrypt20-dev freetds-dev libgcrypt11-dev libgcrypt20-dev
``` ```
This enables all optional modules and features with the exception of Oracle, This enables all optional modules and features with the exception of Oracle,
@ -267,7 +256,6 @@ Examples:
-x 1:3:a generate passwords from length 1 to 3 with all lowercase letters -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 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 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers
-x '3:3:aA1&~#\\ "\'<{([-|_^@)]=}>$%*?./§,;:!`' -v generates length 3 passwords with all 95 characters, and verbose.
``` ```
Example: Example:

53
configure vendored
View file

@ -185,32 +185,6 @@ else
echo " ... zlib not found, gzip support disabled" echo " ... zlib not found, gzip support disabled"
fi 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) ..." echo "Checking for openssl (libssl/libcrypto/ssl.h/sha.h) ..."
if [ "X" != "X$DEBUG" ]; then 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` 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`
@ -406,21 +380,21 @@ if [ "X" = "X$CURSES_PATH" -o "X" = "X$CURSES_IPATH" ]; then
CURSES_IPATH="" CURSES_IPATH=""
fi fi
echo "Checking for pcre2 (libpcre/pcre.h) ..." echo "Checking for pcre (libpcre/pcre.h) ..."
for i in $LIBDIRS ; do for i in $LIBDIRS ; do
if [ "X" = "X$PCRE_PATH" ]; then if [ "X" = "X$PCRE_PATH" ]; then
if [ -f "$i/libpcre2-8.so" -o -f "$i/libpcre2-8.dylib" -o -f "$i/libpcre2-8.a" ]; then if [ -f "$i/libpcre.so" -o -f "$i/libpcre.dylib" -o -f "$i/libpcre.a" ]; then
PCRE_PATH="$i" PCRE_PATH="$i"
fi fi
fi fi
if [ "X" = "X$PCRE_PATH" ]; then if [ "X" = "X$PCRE_PATH" ]; then
TMP_LIB=`/bin/ls $i/libpcre2*.so* 2> /dev/null | grep libpcre.` TMP_LIB=`/bin/ls $i/libpcre.so* 2> /dev/null | grep libpcre.`
if [ -n "$TMP_LIB" ]; then if [ -n "$TMP_LIB" ]; then
PCRE_PATH="$i" PCRE_PATH="$i"
fi fi
fi fi
if [ "X" = "X$PCRE_PATH" ]; then if [ "X" = "X$PCRE_PATH" ]; then
TMP_LIB=`/bin/ls $i/libpcre2*.dll* 2> /dev/null | grep libpcre.` TMP_LIB=`/bin/ls $i/libpcre.dll* 2> /dev/null | grep libpcre.`
if [ -n "$TMP_LIB" ]; then if [ -n "$TMP_LIB" ]; then
PCRE_PATH="$i" PCRE_PATH="$i"
fi fi
@ -428,14 +402,14 @@ for i in $LIBDIRS ; do
done done
for i in $INCDIRS ; do for i in $INCDIRS ; do
if [ "X" != "X$PCRE_PATH" ]; then if [ "X" != "X$PCRE_PATH" ]; then
if [ -f "$i/pcre2.h" ]; then if [ -f "$i/pcre.h" ]; then
PCRE_IPATH="$i" PCRE_IPATH="$i"
fi fi
fi fi
done done
if [ "X" != "X$DEBUG" ]; then if [ "X" != "X$DEBUG" ]; then
echo DEBUG: PCRE_PATH=$PCRE_PATH/libpcre echo DEBUG: PCRE_PATH=$PCRE_PATH/libpcre
echo DEBUG: PCRE_IPATH=$PCRE_IPATH/pcre2.h echo DEBUG: PCRE_IPATH=$PCRE_IPATH/pcre.h
fi fi
if [ -n "$PCRE_PATH" -a -n "$PCRE_IPATH" ]; then if [ -n "$PCRE_PATH" -a -n "$PCRE_IPATH" ]; then
echo " ... found" echo " ... found"
@ -992,7 +966,7 @@ if [ -n "$ORACLE_PATH" -a -n "$ORACLE_IPATH" ]; then
fi fi
if [ "X" = "X$ORACLE_PATH" -o "X" = "X$ORACLE_IPATH" ]; then if [ "X" = "X$ORACLE_PATH" -o "X" = "X$ORACLE_IPATH" ]; then
echo " ... NOT found, module Oracle disabled" echo " ... NOT found, module Oracle disabled"
echo "Get basic and sdk package from https://www.oracle.com/database/technologies/instant-client/downloads.html" echo "Get basic and sdk package from http://www.oracle.com/technetwork/database/features/instant-client/index.html"
ORACLE_PATH="" ORACLE_PATH=""
ORACLE_IPATH="" ORACLE_IPATH=""
fi fi
@ -1382,7 +1356,7 @@ echo "Checking for Android specialities ..."
TMPC=comptest$$ TMPC=comptest$$
STRRCHR=" not" STRRCHR=" not"
echo '#include <stdio.h>' > $TMPC.c echo '#include <stdio.h>' > $TMPC.c
echo '#include <string.h>' >> $TMPC.c echo '#include <strings.h>' >> $TMPC.c
echo "int main() { char *x = strrchr(\"test\", 'e'); if (x == NULL) return 0; else return 1; }" >> $TMPC.c echo "int main() { char *x = strrchr(\"test\", 'e'); if (x == NULL) return 0; else return 1; }" >> $TMPC.c
$CC -o $TMPC $TMPC.c > /dev/null 2>&1 $CC -o $TMPC $TMPC.c > /dev/null 2>&1
test -x $TMPC && STRRCHR="" test -x $TMPC && STRRCHR=""
@ -1522,12 +1496,6 @@ fi
if [ -n "$RSA" ]; then if [ -n "$RSA" ]; then
XDEFINES="$XDEFINES -DNO_RSA_LEGACY" XDEFINES="$XDEFINES -DNO_RSA_LEGACY"
fi 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 if [ -n "$HAVE_ZLIB" ]; then
XDEFINES="$XDEFINES -DHAVE_ZLIB" XDEFINES="$XDEFINES -DHAVE_ZLIB"
fi fi
@ -1659,9 +1627,6 @@ fi
if [ -n "$HAVE_ZLIB" ]; then if [ -n "$HAVE_ZLIB" ]; then
XLIBS="$XLIBS -lz" XLIBS="$XLIBS -lz"
fi fi
if [ -n "$HAVE_SYBDB" ]; then
XLIBS="$XLIBS -lsybdb"
fi
if [ -n "$CURSES_PATH" ]; then if [ -n "$CURSES_PATH" ]; then
XLIBS="$XLIBS -lcurses" XLIBS="$XLIBS -lcurses"
fi fi
@ -1684,7 +1649,7 @@ if [ -n "$IDN_PATH" ]; then
XLIBS="$XLIBS -lidn" XLIBS="$XLIBS -lidn"
fi fi
if [ -n "$PCRE_PATH" ]; then if [ -n "$PCRE_PATH" ]; then
XLIBS="$XLIBS -lpcre2-8" XLIBS="$XLIBS -lpcre"
fi fi
if [ -n "$MYSQL_PATH" ]; then if [ -n "$MYSQL_PATH" ]; then
XLIBS="$XLIBS -lmysqlclient" XLIBS="$XLIBS -lmysqlclient"

View file

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

View file

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

8
hydra-gtk/configure vendored
View file

@ -2391,7 +2391,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
for ac_declaration in \ for ac_declaration in \
'#include <stdlib.h>' \ '' \
'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int) throw ();' \
@ -3192,7 +3192,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
for ac_declaration in \ for ac_declaration in \
'#include <stdlib.h>' \ '' \
'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int) throw ();' \
@ -3797,8 +3797,8 @@ main ()
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i)) if (XOR (islower (i), ISLOWER (i))
|| toupper (i) != TOUPPER (i)) || toupper (i) != TOUPPER (i))
return 2; exit(2);
return 0; exit (0);
} }
_ACEOF _ACEOF
rm -f conftest$ac_exeext rm -f conftest$ac_exeext

View file

@ -17,8 +17,6 @@
char *hydra_path1 = "./hydra"; char *hydra_path1 = "./hydra";
char *hydra_path2 = "/usr/local/bin/hydra"; char *hydra_path2 = "/usr/local/bin/hydra";
char *hydra_path3 = "/usr/bin/hydra"; char *hydra_path3 = "/usr/bin/hydra";
char *hydra_path4 = "/data/data/com.termux/files/usr/bin/hydra";
char *hydra_path5 = "/data/data/com.termux/files/usr/local/bin/hydra";
GtkWidget *wndMain; GtkWidget *wndMain;
char *HYDRA_BIN; char *HYDRA_BIN;
@ -55,10 +53,6 @@ int main(int argc, char *argv[]) {
HYDRA_BIN = hydra_path2; HYDRA_BIN = hydra_path2;
} else if (g_file_test(hydra_path3, G_FILE_TEST_IS_EXECUTABLE)) { } else if (g_file_test(hydra_path3, G_FILE_TEST_IS_EXECUTABLE)) {
HYDRA_BIN = hydra_path3; HYDRA_BIN = hydra_path3;
} else if (g_file_test(hydra_path4, G_FILE_TEST_IS_EXECUTABLE)) {
HYDRA_BIN = hydra_path4;
} else if (g_file_test(hydra_path5, G_FILE_TEST_IS_EXECUTABLE)) {
HYDRA_BIN = hydra_path5;
} else { } else {
g_error("Please tell me where hydra is, use --hydra-path\n"); g_error("Please tell me where hydra is, use --hydra-path\n");
return -1; return -1;

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

@ -20,23 +20,33 @@ Here's a couple of examples: -
./hydra -S -s 443 -l "<username>" -P pass.txt 10.221.64.2 https-get-form ./hydra -S -s 443 -l "<username>" -P pass.txt 10.221.64.2 https-get-form
"/irmlab1/vulnapp.php:username=^USER^&pass=^PASS^:incorrect" "/irmlab1/vulnapp.php:username=^USER^&pass=^PASS^:incorrect"
The option field (following the service field) takes ":" separated values: The option field (following the service field) takes three ":" separated
The first is the page on the server to GET or POST to. values and an optional fourth value, the first is the page on the server
The second is the POST/GET variables (taken from either the browser, or a proxy to GET or POST to, the second is the POST/GET variables (taken from either
such as ZAP) with the varying usernames and passwords in the "^USER^" and the browser, or a proxy such as PAROS) with the varying usernames and passwords
"^PASS^" placeholders. in the "^USER^" and "^PASS^" placeholders, the third is the string that it
The third + are optional parameters like C=, H= etc. (see below) checks for an *invalid* or *valid* login - any exception to this is counted
The final(!) parameter is the string that it checks for an *invalid* or *valid* as a success.
login
So please: So please:
* invalid condition login should be preceded by "F=" * invalid condition login should be preceded by "F="
* valid condition login should be preceded by "S=". * valid condition login should be preceded by "S=".
By default, if no header is found the condition is assume to be a fail (F=), By default, if no header is found the condition is assume to be a fail,
so checking for an *invalid* login string. so checking for *invalid* login.
The fourth optional value, can be a 'C' to define a different page to GET
initial cookies from.
If you specify the debug flag (-d) it will show you the response from the If you specify the verbose flag (-v) it will show you the response from the
HTTP server which is useful for checking the result of a failed login to HTTP server which is useful for checking the result of a failed login to
find something to pattern match against. This should be done together with -t 1. find something to pattern match against.
Module initially written by Phil Robinson, IRM Plc (releases@irmplc.com),
rewritten by David Maciejak
Fix and issue with strtok use and implement 1 step location follow if HTTP
3xx code is returned (david dot maciejak at gmail dot com)
Added fail or success condition, getting cookies, and allow 5 redirections by
david
*/ */
@ -65,9 +75,6 @@ typedef struct cookie_node {
int32_t success_cond = 0; int32_t success_cond = 0;
int32_t getcookie = 1; int32_t getcookie = 1;
int32_t auth_flag = 0; 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]; char cookie[4096] = "", cmiscptr[1024];
@ -252,7 +259,7 @@ int32_t add_header(ptr_header_node *ptr_head, char *header, char *value, char ty
ptr_header_node existing_hdr, new_ptr; ptr_header_node existing_hdr, new_ptr;
if (!header || !value || !strlen(header) || !strlen(value)) if (!header || !value || !strlen(header) || !strlen(value))
return 0; return;
// get to the last header // get to the last header
for (cur_ptr = *ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next) for (cur_ptr = *ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next)
@ -316,15 +323,10 @@ void hdrrep(ptr_header_node *ptr_head, char *oldvalue, char *newvalue) {
for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) { for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) {
if ((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)) { if ((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)) {
size_t oldlen = strlen(oldvalue); cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(newvalue) + 1);
size_t newlen = strlen(newvalue); if (cur_ptr->value)
if (oldlen != newlen) strcpy(cur_ptr->value, newvalue);
cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(cur_ptr->value) - oldlen + newlen + 1); else {
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_report(stderr, "[ERROR] Out of memory (hddrep).\n");
hydra_child_exit(0); hydra_child_exit(0);
} }
@ -391,7 +393,7 @@ char *stringify_headers(ptr_header_node *ptr_head) {
} }
int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
char *ptr, *ptr2, *tmp; char *ptr, *ptr2;
if (miscptr == NULL) if (miscptr == NULL)
return 1; return 1;
@ -401,7 +403,7 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
* Beware of the backslashes (\)! * Beware of the backslashes (\)!
*/ */
while (*miscptr != 0) { while (*miscptr != 0) {
if (strlen(miscptr) < 2 || miscptr[1] != '=') { if (strlen(miscptr) < 3 || miscptr[1] != '=') {
hydra_report(stderr, "[ERROR] optional parameters must have the format X=value: %s\n", miscptr); hydra_report(stderr, "[ERROR] optional parameters must have the format X=value: %s\n", miscptr);
return 0; return 0;
} }
@ -439,31 +441,6 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
sprintf(cookieurl, "%.1000s", hydra_strrep(miscptr + 2, "\\:", ":")); sprintf(cookieurl, "%.1000s", hydra_strrep(miscptr + 2, "\\:", ":"));
miscptr = ptr; miscptr = ptr;
break; 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;
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
miscptr += strlen(miscptr);
break;
case 'g': // fall through case 'g': // fall through
case 'G': case 'G':
ptr = miscptr + 2; ptr = miscptr + 2;
@ -542,97 +519,6 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
return 1; 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) { char *prepare_http_request(char *type, char *path, char *params, char *headers) {
uint32_t reqlen = 0; uint32_t reqlen = 0;
char *http_request = NULL; char *http_request = NULL;
@ -841,7 +727,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
char *http_request = NULL; char *http_request = NULL;
int32_t found = !success_cond, i, j; int32_t found = !success_cond, i, j;
char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH];
char content_type[256];
memset(header, 0, sizeof(header)); memset(header, 0, sizeof(header));
cookie[0] = 0; // reset cookies from potential previous attempt cookie[0] = 0; // reset cookies from potential previous attempt
@ -861,24 +747,11 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
clogin[sizeof(clogin) - 1] = 0; clogin[sizeof(clogin) - 1] = 0;
strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); strncpy(cpass, html_encode(pass), sizeof(cpass) - 1);
cpass[sizeof(cpass) - 1] = 0; 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, "^PASS^", cpass);
upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login); upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login);
upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass); upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass);
// Replace the user/pass placeholders in the user-supplied headers // Replace the user/pass placeholders in the user-supplied headers
hdrrep(&ptr_head, "^USER^", clogin); hdrrep(&ptr_head, "^USER^", clogin);
hdrrep(&ptr_head, "^PASS^", cpass); hdrrep(&ptr_head, "^PASS^", cpass);
@ -889,7 +762,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) { if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) {
if (getcookie) { if (getcookie) {
memset(proxy_string, 0, sizeof(proxy_string)); memset(proxy_string, 0, sizeof(proxy_string));
snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl);
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request);
@ -903,14 +776,14 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
// now prepare for the "real" request // now prepare for the "real" request
if (strcmp(type, "POST") == 0) { if (strcmp(type, "POST") == 0) {
memset(proxy_string, 0, sizeof(proxy_string)); memset(proxy_string, 0, sizeof(proxy_string));
snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url);
snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables));
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", content_length); hdrrepv(&ptr_head, "Content-Length", content_length);
else else
add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT);
if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT);
if (cookie_header != NULL) if (cookie_header != NULL)
free(cookie_header); free(cookie_header);
cookie_header = stringify_cookies(ptr_cookie); cookie_header = stringify_cookies(ptr_cookie);
@ -924,10 +797,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
free(cookie_header);
return 1; return 1;
}
} else { } else {
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0"); hdrrepv(&ptr_head, "Content-Length", "0");
@ -944,18 +815,16 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_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; return 1;
} }
}
} else { } else {
if (use_proxy == 1) { if (use_proxy == 1) {
// proxy without authentication // proxy without authentication
if (getcookie) { if (getcookie) {
// doing a GET to get cookies // doing a GET to get cookies
memset(proxy_string, 0, sizeof(proxy_string)); memset(proxy_string, 0, sizeof(proxy_string));
snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl);
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request);
@ -969,14 +838,14 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
// now prepare for the "real" request // now prepare for the "real" request
if (strcmp(type, "POST") == 0) { if (strcmp(type, "POST") == 0) {
memset(proxy_string, 0, sizeof(proxy_string)); memset(proxy_string, 0, sizeof(proxy_string));
snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url);
snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables));
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", content_length); hdrrepv(&ptr_head, "Content-Length", content_length);
else else
add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT);
if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT);
if (cookie_header != NULL) if (cookie_header != NULL)
free(cookie_header); free(cookie_header);
cookie_header = stringify_cookies(ptr_cookie); cookie_header = stringify_cookies(ptr_cookie);
@ -990,10 +859,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
free(cookie_header);
return 1; return 1;
}
} else { } else {
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0"); hdrrepv(&ptr_head, "Content-Length", "0");
@ -1010,11 +877,9 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_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; return 1;
} }
}
} else { } else {
// direct web server, no proxy // direct web server, no proxy
normal_request = NULL; normal_request = NULL;
@ -1043,7 +908,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
else else
add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT);
if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT))
add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT);
if (cookie_header != NULL) if (cookie_header != NULL)
free(cookie_header); free(cookie_header);
cookie_header = stringify_cookies(ptr_cookie); cookie_header = stringify_cookies(ptr_cookie);
@ -1057,10 +922,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("POST", url, upd3variables, normal_request); http_request = prepare_http_request("POST", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
free(cookie_header);
return 1; return 1;
}
} else { } else {
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0"); hdrrepv(&ptr_head, "Content-Length", "0");
@ -1077,34 +940,23 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (http_request != NULL) if (http_request != NULL)
free(http_request); free(http_request);
http_request = prepare_http_request("GET", url, upd3variables, normal_request); http_request = prepare_http_request("GET", url, upd3variables, normal_request);
if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { if (hydra_send(s, http_request, strlen(http_request), 0) < 0)
free(cookie_header);
return 1; return 1;
} }
} }
} }
}
if (debug) if (debug)
hydra_report_debug(stdout, "HTTP request sent:\n%s\n", http_request); hydra_report_debug(stdout, "HTTP request sent:\n%s\n", http_request);
found = analyze_server_response(s); found = analyze_server_response(s);
if (redirected_flag && code_302_is_success) { if (auth_flag) { // we received a 401 error - user is using wrong module
found = success_cond;
}
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, hydra_report(stderr,
"[ERROR] received HTTP error code 401. The target may be using HTTP auth, " "[ERROR] the target is using HTTP auth, not a web form, received HTTP "
"not a web form. Use module \"http%s-get\" instead, or set \"1=\".\n", "error code 401. Use module \"http%s-get\" instead.\n",
(options & OPTION_SSL) > 0 ? "s" : ""); (options & OPTION_SSL) > 0 ? "s" : "");
return 2; return 4;
}
} }
if (strlen(cookie) > 0) if (strlen(cookie) > 0)
@ -1115,10 +967,12 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
if (debug) if (debug)
printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff);
while (found == 0 && redirected_flag && !code_302_is_success && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) {
// we have to split the location // we have to split the location
char *startloc, *endloc; char *startloc, *endloc;
char str[2048], str2[2048], str3[2048], str4[2048]; char str[2048];
char str2[2048];
char str3[2048];
redirected_cpt--; redirected_cpt--;
redirected_flag = 0; redirected_flag = 0;
@ -1137,21 +991,19 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
startloc += strlen("://"); startloc += strlen("://");
if ((endloc = strchr(startloc, '\r')) != NULL) { if ((endloc = strchr(startloc, '\r')) != NULL) {
*endloc = 0; startloc[endloc - startloc] = 0;
} }
if ((endloc = strchr(startloc, '\n')) != NULL) { if ((endloc = strchr(startloc, '\n')) != NULL) {
*endloc = 0; startloc[endloc - startloc] = 0;
} }
strncpy(str, startloc, sizeof(str) - 1); strcpy(str, startloc);
str[sizeof(str) - 1] = 0;
endloc = strchr(str, '/'); endloc = strchr(str, '/');
if (endloc != NULL) { if (endloc != NULL) {
strncpy(str2, str, endloc - str); strncpy(str2, str, endloc - str);
str2[endloc - str] = 0; str2[endloc - str] = 0;
} else { } else
strcpy(str2, str); strncpy(str2, str, sizeof(str));
}
if (strlen(str) - strlen(str2) == 0) { if (strlen(str) - strlen(str2) == 0) {
strcpy(str3, "/"); strcpy(str3, "/");
@ -1160,8 +1012,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
str3[strlen(str) - strlen(str2)] = 0; str3[strlen(str) - strlen(str2)] = 0;
} }
} else { } else {
strncpy(str2, webtarget, sizeof(str2) - 1); strncpy(str2, webtarget, sizeof(str2));
str2[sizeof(str2) - 1] = 0;
if (redirected_url_buff[0] != '/') { if (redirected_url_buff[0] != '/') {
// it's a relative path, so we have to concatenate it // it's a relative path, so we have to concatenate it
// with the path from the first url given // with the path from the first url given
@ -1177,10 +1028,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
} else { } else {
sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff); sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff);
} }
} else { } else
strncpy(str3, redirected_url_buff, sizeof(str3) - 1); strncpy(str3, redirected_url_buff, sizeof(str3));
str3[sizeof(str3) - 1] = 0;
}
if (debug) if (debug)
hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url); hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url);
} }
@ -1192,13 +1041,12 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
str3[0] = '/'; str3[0] = '/';
} }
if (strrchr(str2, ':') == NULL && (port != 80 || port != 443)) { if (strrchr(url, ':') == NULL && port != 80) {
sprintf(str4, "%.2000s:%d", str2, port); sprintf(str2, "%.2040s:%d", str2, port);
strcpy(str2, str4);
} }
if (verbose) if (verbose)
hydra_report(stderr, "[VERBOSE] Page redirected to http[s]://%s%s\n", str2, str3); hydra_report(stderr, "[VERBOSE] Page redirected to http://%s%s\n", str2, str3);
if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT))
hdrrepv(&ptr_head, "Content-Length", "0"); hdrrepv(&ptr_head, "Content-Length", "0");
@ -1217,7 +1065,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
// proxy with authentication // proxy with authentication
hdrrepv(&ptr_head, "Host", str2); hdrrepv(&ptr_head, "Host", str2);
memset(proxy_string, 0, sizeof(proxy_string)); memset(proxy_string, 0, sizeof(proxy_string));
snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3);
if (normal_request != NULL) if (normal_request != NULL)
free(normal_request); free(normal_request);
normal_request = stringify_headers(&ptr_head); normal_request = stringify_headers(&ptr_head);
@ -1229,7 +1077,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
// proxy without authentication // proxy without authentication
hdrrepv(&ptr_head, "Host", str2); hdrrepv(&ptr_head, "Host", str2);
memset(proxy_string, 0, sizeof(proxy_string)); memset(proxy_string, 0, sizeof(proxy_string));
snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3);
if (normal_request != NULL) if (normal_request != NULL)
free(normal_request); free(normal_request);
normal_request = stringify_headers(&ptr_head); normal_request = stringify_headers(&ptr_head);
@ -1250,10 +1098,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
hydra_reconnect(s, ip, port, options, hostname); 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; return 1;
}
found = analyze_server_response(s); found = analyze_server_response(s);
if (strlen(cookie) > 0) if (strlen(cookie) > 0)
@ -1262,7 +1108,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options
} }
// if the last status is still 3xx, set it as a false // if the last status is still 3xx, set it as a false
if (found != -1 && found == success_cond && ((redirected_flag && code_302_is_success) || redirected_flag == 0 || success_cond == 1) && redirected_cpt >= 0) { if (found != -1 && found == success_cond && (redirected_flag == 0 || success_cond == 1) && redirected_cpt >= 0) {
hydra_report_found_host(port, ip, "www-form", fp); hydra_report_found_host(port, ip, "www-form", fp);
hydra_completed_pair_found(); hydra_completed_pair_found();
} else { } else {
@ -1427,7 +1273,8 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
ptr = ptr2 = NULL; ptr = ptr2 = NULL;
sprintf(bufferurl, "%.6096s", miscptr); sprintf(bufferurl, "%.6096s", miscptr);
ptr = url = bufferurl; url = bufferurl;
ptr = url;
while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\'))
ptr++; ptr++;
@ -1440,41 +1287,39 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
if (*ptr != 0) if (*ptr != 0)
*ptr++ = 0; *ptr++ = 0;
optional1 = cond = ptr; cond = ptr;
ptr2 = ptr + strlen(ptr); if ((ptr2 = strchr(ptr, ':')) != NULL) {
while (ptr2 > ptr && (*ptr2 != ':' || *(ptr2 - 1) == '\\'))
ptr2--;
if (*ptr2 == ':') {
*ptr2++ = 0; *ptr2++ = 0;
cond = ptr2; if (*ptr2)
} optional1 = ptr2;
else
if (optional1 == cond) optional1 = NULL;
} else
optional1 = NULL; optional1 = NULL;
if (strstr(url, "\\:") != NULL) { if (strstr(url, "\\:") != NULL) {
if ((ptr = malloc(strlen(url) + 1)) != NULL) { if ((ptr = malloc(strlen(url))) != NULL) {
strcpy(ptr, hydra_strrep(url, "\\:", ":")); strcpy(ptr, hydra_strrep(url, "\\:", ":"));
url = ptr; url = ptr;
} }
} }
if (strstr(variables, "\\:") != NULL) { if (strstr(variables, "\\:") != NULL) {
if ((ptr = malloc(strlen(variables) + 1)) != NULL) { if ((ptr = malloc(strlen(variables))) != NULL) {
strcpy(ptr, hydra_strrep(variables, "\\:", ":")); strcpy(ptr, hydra_strrep(variables, "\\:", ":"));
variables = ptr; variables = ptr;
} }
} }
if (strstr(cond, "\\:") != NULL) { if (strstr(cond, "\\:") != NULL) {
if ((ptr = malloc(strlen(cond) + 1)) != NULL) { if ((ptr = malloc(strlen(cond))) != NULL) {
strcpy(ptr, hydra_strrep(cond, "\\:", ":")); strcpy(ptr, hydra_strrep(cond, "\\:", ":"));
cond = ptr; cond = ptr;
} }
} }
// printf("ptr: %s ptr2: %s cond: %s url: %s variables: %s optional1: %s\n", ptr, ptr2, cond, url, variables, optional1 == NULL ? "null" : optional1); // printf("ptr: %s ptr2: %s cond: %s url: %s variables: %s optional1:
// %s\n", ptr, ptr2, cond, url, variables, optional1 == NULL ? "null" :
// optional1);
if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */) if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */)
hydra_child_exit(2); hydra_child_exit(2);
@ -1498,7 +1343,8 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
success_cond = 0; success_cond = 0;
} }
// printf("miscptr: %s, url=%s, variables=%s, ptr=%s, optional1: %s, cond: %s (%d)\n", miscptr, url, variables, ptr, optional1, cond, success_cond); // printf("miscptr: %s, url=%s, variables=%s, ptr=%s, optional1: %s, cond: %s
// (%d)\n", miscptr, url, variables, ptr, optional1, cond, success_cond);
/* /*
* Parse the user-supplied options. * Parse the user-supplied options.
@ -1571,29 +1417,27 @@ void usage_http_form(const char *service) {
"redirections in\n" "redirections in\n"
"a row. It always gathers a new cookie from the same URL without " "a row. It always gathers a new cookie from the same URL without "
"variables\n" "variables\n"
"The parameters requires at a minimum three \":\" separated values,\n" "The parameters take three \":\" separated values, plus optional "
"plus optional values.\n" "values.\n"
"(Note: if you need a colon in the option string as value, escape it " "(Note: if you need a colon in the option string as value, escape it "
"with \"\\:\", but do not escape a \"\\\" with \"\\\\\".)\n" "with \"\\:\", but do not escape a \"\\\" with \"\\\\\".)\n"
"\nSyntax: <url>:<form parameters>[:<optional>[:<optional>]:<condition string>\n" "\nSyntax: <url>:<form parameters>:<condition "
"\nFirst is the page on the server to GET or POST to (URL), e.g. \"/login\".\n" "string>[:<optional>[:<optional>]\n"
"Second is the POST/GET variables (taken from either the browser, proxy, etc.)\n" "First is the page on the server to GET or POST to (URL).\n"
" without the initial '?' character and the usernames and passwords being\n" "Second is the POST/GET variables (taken from either the browser, proxy, "
" replaced with \"^USER^\" (\"^USER64^\" for base64 encodings) and \"^PASS^\"\n" "etc.\n"
" (\"^PASS64^\" for base64 encodings).\n" " with url-encoded (resp. base64-encoded) usernames and passwords being "
"Third are optional parameters (see below)\n" "replaced in the\n"
"Last is the string that it checks for an *invalid* login (by default).\n" " \"^USER^\" (resp. \"^USER64^\") and \"^PASS^\" (resp. \"^PASS64^\") "
" Invalid condition login check can be preceded by \"F=\", successful condition\n" "placeholders (FORM PARAMETERS)\n"
"Third is the string that it checks for an *invalid* login (by default)\n"
" Invalid condition login check can be preceded by \"F=\", successful "
"condition\n"
" login check must be preceded by \"S=\".\n" " login check must be preceded by \"S=\".\n"
" This is where most people get it wrong! You have to check the webapp what a\n" " This is where most people get it wrong. You have to check the webapp "
" failed string looks like and put it in this parameter! Add the -d switch to see\n" "what a\n"
" the sent/received data!\n" " failed string looks like and put it in this parameter!\n"
" Note that using invalid login condition checks can result in false positives!\n" "The following parameters are optional:\n"
"\nThe following parameters are optional and are put between the form parameters\n"
"and the condition string; separate 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 " " (c|C)=/page/uri to define a different page to gather initial "
"cookies from\n" "cookies from\n"
" (g|G)= skip pre-requests - only use this when no pre-cookies are required\n" " (g|G)= skip pre-requests - only use this when no pre-cookies are required\n"
@ -1607,29 +1451,25 @@ void usage_http_form(const char *service) {
"exists, by the\n" "exists, by the\n"
" one supplied by the user, or add the header at the " " one supplied by the user, or add the header at the "
"end\n" "end\n"
"\nNote that if you are going to put colons (:) in your headers you should escape\n" "Note that if you are going to put colons (:) in your headers you should "
"them with a backslash (\\). All colons that are not option separators should be\n" "escape them with a backslash (\\).\n"
"escaped (see the examples above and below).\n" " All colons that are not option separators should be escaped (see the "
"You can specify a header without escaping the colons, but that way you will not\n" "examples above and below).\n"
"be able to put colons in the header value itself, as they will be interpreted by\n" " You can specify a header without escaping the colons, but that way you "
"hydra as option separators.\n" "will not be able to put colons\n"
" in the header value itself, as they will be interpreted by hydra as "
"option separators.\n"
"\nExamples:\n" "\nExamples:\n"
" \"/login.php:user=^USER^&pass=^PASS^:incorrect\"\n" " \"/login.php:user=^USER^&pass=^PASS^:incorrect\"\n"
" \"/" " \"/"
"login.php:user=^USER64^&pass=^PASS64^&colon=colon\\:escape:S=result=" "login.php:user=^USER64^&pass=^PASS64^&colon=colon\\:escape:S=authlog=.*"
"success\"\n" "success\"\n"
" \"/login.php:user=^USER^&pass=^PASS^&mid=123:authlog=.*failed\"\n" " \"/login.php:user=^USER^&pass=^PASS^&mid=123:authlog=.*failed\"\n"
" \"/:user=^USER&pass=^PASS^:H=Authorization\\: Basic " " \"/:user=^USER&pass=^PASS^:failed:H=Authorization\\: Basic "
"dT1w:H=Cookie\\: sessid=aaaa:h=X-User\\: ^USER^:H=User-Agent\\: wget\"\n" "dT1w:H=Cookie\\: sessid=aaaa:h=X-User\\: ^USER^:H=User-Agent\\: wget\"\n"
" \"/exchweb/bin/auth/:F=failed" " \"/exchweb/bin/auth/"
"owaauth.dll:destination=http%%3A%%2F%%2F<target>%%2Fexchange&flags=0&" "owaauth.dll:destination=http%%3A%%2F%%2F<target>%%2Fexchange&flags=0&"
"username=<domain>%%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:" "username=<domain>%%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:"
"C=/exchweb\":reason=\n" "reason=:C=/exchweb\"\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); service);
} }

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

@ -451,7 +451,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis
start--; start--;
memset(start, '\0', condition_len); memset(start, '\0', condition_len);
if (debug) if (debug)
hydra_report(stderr, "Modified options:%s\n", miscptr); hydra_report(stderr, "Modificated options:%s\n", miscptr);
} else { } else {
if (debug) if (debug)
hydra_report(stderr, "Condition not found\n"); hydra_report(stderr, "Condition not found\n");
@ -474,12 +474,6 @@ void usage_http(const char *service) {
" combination is invalid. Note: this must be the last option " " combination is invalid. Note: this must be the last option "
"supplied.\n" "supplied.\n"
"For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: " "For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: "
"sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n" "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\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); service);
} }

View file

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

View file

@ -7,8 +7,7 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif #endif
#ifdef HAVE_PCRE #ifdef HAVE_PCRE
#define PCRE2_CODE_UNIT_WIDTH 8 #include <pcre.h>
#include <pcre2.h>
#endif #endif
#define MAX_CONNECT_RETRY 1 #define MAX_CONNECT_RETRY 1
@ -662,10 +661,10 @@ char *hydra_get_next_pair() {
pair[sizeof(pair) - 1] = 0; pair[sizeof(pair) - 1] = 0;
__fck = read(intern_socket, pair, sizeof(pair) - 1); __fck = read(intern_socket, pair, sizeof(pair) - 1);
// if (debug) hydra_dump_data(pair, __fck, "CHILD READ PAIR"); // if (debug) hydra_dump_data(pair, __fck, "CHILD READ PAIR");
if (pair[0] == 0 || __fck <= 0) if (memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0)
return HYDRA_EMPTY;
if (__fck >= sizeof(HYDRA_EXIT) && memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0)
return HYDRA_EXIT; return HYDRA_EXIT;
if (pair[0] == 0)
return HYDRA_EMPTY;
} }
return pair; return pair;
} }
@ -1292,23 +1291,19 @@ void hydra_set_srcport(int32_t port) { src_port = port; }
#ifdef HAVE_PCRE #ifdef HAVE_PCRE
int32_t hydra_string_match(char *str, const char *regex) { int32_t hydra_string_match(char *str, const char *regex) {
pcre2_code *re = NULL; pcre *re = NULL;
int32_t error_code = 0; int32_t offset_error = 0;
PCRE2_SIZE error_offset; const char *error = NULL;
int32_t rc = 0; int32_t rc = 0;
re = pcre2_compile(regex, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS | PCRE2_DOTALL, &error_code, &error_offset, NULL); re = pcre_compile(regex, PCRE_CASELESS | PCRE_DOTALL, &error, &offset_error, NULL);
if (re == NULL) { if (re == NULL) {
fprintf(stderr, "[ERROR] PCRE compilation failed at offset %d: %d\n", error_offset, error_code); fprintf(stderr, "[ERROR] PCRE compilation failed at offset %d: %s\n", offset_error, error);
return 0; return 0;
} }
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL); rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, NULL, 0);
rc = pcre2_match(re, str, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); if (rc >= 0) {
pcre2_match_data_free(match_data);
pcre2_code_free(re);
if (rc >= 1) {
return 1; return 1;
} }
return 0; return 0;

View file

@ -14,7 +14,6 @@ void dummy_mongodb() { printf("\n"); }
extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec);
extern hydra_option hydra_options;
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
char *buf; char *buf;
@ -73,17 +72,10 @@ int32_t start_mongodb(int32_t s, char *ip, int32_t port, unsigned char options,
mongoc_log_set_handler(NULL, NULL); mongoc_log_set_handler(NULL, NULL);
bson_init(&q); bson_init(&q);
if (login[0] == '\0' && pass[0] == '\0') {
snprintf(uri, sizeof(uri), "mongodb://%s:%d/?authSource=%s", hydra_address2string(ip), port, miscptr);
} else {
snprintf(uri, sizeof(uri), "mongodb://%s:%s@%s:%d/?authSource=%s", login, pass, hydra_address2string(ip), port, miscptr); snprintf(uri, sizeof(uri), "mongodb://%s:%s@%s:%d/?authSource=%s", login, pass, hydra_address2string(ip), port, miscptr);
}
client = mongoc_client_new(uri); client = mongoc_client_new(uri);
if (!client) { if (!client)
hydra_completed_pair_skip();
return 3; return 3;
}
mongoc_client_set_appname(client, "hydra"); mongoc_client_set_appname(client, "hydra");
collection = mongoc_client_get_collection(client, miscptr, "test"); collection = mongoc_client_get_collection(client, miscptr, "test");
@ -98,11 +90,11 @@ int32_t start_mongodb(int32_t s, char *ip, int32_t port, unsigned char options,
mongoc_collection_destroy(collection); mongoc_collection_destroy(collection);
mongoc_client_destroy(client); mongoc_client_destroy(client);
mongoc_cleanup(); mongoc_cleanup();
hydra_completed_pair(); 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) {
return 3; return 3;
} }
return 1; return 2;
} }
} }
@ -137,8 +129,6 @@ void service_mongodb(char *ip, int32_t sp, unsigned char options, char *miscptr,
switch (run) { switch (run) {
case 1: case 1:
next_run = start_mongodb(sock, ip, port, options, miscptr, fp); next_run = start_mongodb(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break; break;
case 2: case 2:
hydra_child_exit(0); hydra_child_exit(0);

View file

@ -1,14 +1,10 @@
#include "hydra-mod.h" #include "hydra-mod.h"
extern char *HYDRA_EXIT;
char *buf;
#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB)
#include <sybdb.h>
#include <sybfront.h>
#endif
#define MSLEN 30 #define MSLEN 30
extern char *HYDRA_EXIT;
char *buf;
unsigned char p_hdr[] = "\x02\x00\x02\x00\x00\x00\x02\x00\x00\x00" 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"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
@ -60,7 +56,6 @@ 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) { int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = ""; char *empty = "";
char *login, *pass, buffer[1024]; char *login, *pass, buffer[1024];
char *ipaddr_str = hydra_address2string(ip);
char ms_login[MSLEN + 1]; char ms_login[MSLEN + 1];
char ms_pass[MSLEN + 1]; char ms_pass[MSLEN + 1];
unsigned char len_login, len_pass; unsigned char len_login, len_pass;
@ -70,42 +65,6 @@ int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, ch
login = empty; login = empty;
if (strlen(pass = hydra_get_next_password()) == 0) if (strlen(pass = hydra_get_next_password()) == 0)
pass = empty; 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) if (strlen(login) > MSLEN)
login[MSLEN - 1] = 0; login[MSLEN - 1] = 0;
if (strlen(pass) > MSLEN) if (strlen(pass) > MSLEN)
@ -160,10 +119,6 @@ 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 run = 1, next_run = 1, sock = -1;
int32_t myport = PORT_MSSQL, mysslport = PORT_MSSQL_SSL; int32_t myport = PORT_MSSQL, mysslport = PORT_MSSQL_SSL;
#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB)
dbinit();
#endif
hydra_register_socket(sp); hydra_register_socket(sp);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return; return;

View file

@ -35,7 +35,6 @@ 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 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 int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec);
extern hydra_option hydra_options;
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
char mysqlsalt[9]; char mysqlsalt[9];
@ -333,8 +332,6 @@ void service_mysql(char *ip, int32_t sp, unsigned char options, char *miscptr, F
break; break;
case 2: /* run the cracking function */ case 2: /* run the cracking function */
next_run = start_mysql(sock, ip, port, options, miscptr, fp); 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; break;
case 3: /* clean exit */ case 3: /* clean exit */
if (sock >= 0) { if (sock >= 0) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -366,7 +366,6 @@ void service_radmin2(char *ip, int32_t sp, unsigned char options, char *miscptr,
hydra_report(stderr, "Error: Child with pid %d terminating, protocol error\n", (int32_t)getpid()); hydra_report(stderr, "Error: Child with pid %d terminating, protocol error\n", (int32_t)getpid());
hydra_child_exit(2); hydra_child_exit(2);
} }
free(msg);
} }
#endif #endif
} }

View file

@ -9,37 +9,27 @@
#include "hydra-mod.h" #include "hydra-mod.h"
extern hydra_option hydra_options;
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
#ifndef LIBFREERDP #ifndef LIBFREERDP
void dummy_rdp() { printf("\n"); } void dummy_rdp() { printf("\n"); }
#else #else
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/version.h>
freerdp *instance = 0; freerdp *instance = 0;
BOOL rdp_connect(char *server, int32_t port, char *domain, char *login, char *password) { BOOL rdp_connect(char *server, int32_t port, char *domain, char *login, char *password) {
int32_t err = 0; int32_t err = 0;
rdpSettings* settings = instance->context->settings; instance->settings->Username = login;
instance->settings->Password = password;
settings->Username = login; instance->settings->IgnoreCertificate = TRUE;
settings->Password = password;
settings->IgnoreCertificate = TRUE;
if (password[0] == 0) if (password[0] == 0)
settings->AuthenticationOnly = FALSE; instance->settings->AuthenticationOnly = FALSE;
else else
settings->AuthenticationOnly = TRUE; instance->settings->AuthenticationOnly = TRUE;
settings->ServerHostname = server; instance->settings->ServerHostname = server;
settings->ServerPort = port; instance->settings->ServerPort = port;
settings->Domain = domain; instance->settings->Domain = domain;
instance->settings->MaxTimeInCheckLoop = 100;
#if FREERDP_VERSION_MAJOR == 2
settings->MaxTimeInCheckLoop = 100;
#endif
// freerdp timeout format is microseconds -> default:15000
settings->TcpConnectTimeout = hydra_options.waittime * 1000;
settings->TlsSecLevel = 0;
freerdp_connect(instance); freerdp_connect(instance);
err = freerdp_get_last_error(instance->context); err = freerdp_get_last_error(instance->context);
return err; return err;
@ -68,8 +58,7 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr,
} }
login_result = rdp_connect(server, port, domain, login, pass); login_result = rdp_connect(server, port, domain, login, pass);
if (debug) if (debug) hydra_report(stderr, "[DEBUG] rdp reported %08x\n", login_result);
hydra_report(stderr, "[DEBUG] rdp reported %08x\n", login_result);
switch (login_result) { switch (login_result) {
case 0: case 0:
// login success // login success
@ -82,10 +71,6 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr,
// login failure // login failure
hydra_completed_pair(); hydra_completed_pair();
break; break;
case 0x0002000f:
// login failure
hydra_completed_pair_skip();
break;
case 0x0002000d: case 0x0002000d:
hydra_report(stderr, hydra_report(stderr,
"[%d][rdp] account on %s might be valid but account not " "[%d][rdp] account on %s might be valid but account not "
@ -114,7 +99,6 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr,
void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
int32_t run = 1, next_run = 1; int32_t run = 1, next_run = 1;
int32_t myport = PORT_RDP; int32_t myport = PORT_RDP;
int32_t __first_rdp_connect = 1;
if (port != 0) if (port != 0)
myport = port; myport = port;
@ -126,13 +110,7 @@ void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL
next_run = 0; next_run = 0;
switch (run) { switch (run) {
case 1: /* run the cracking function */ case 1: /* run the cracking function */
if (__first_rdp_connect != 0)
__first_rdp_connect = 0;
else
sleep(hydra_options.conwait);
next_run = start_rdp(ip, myport, options, miscptr, fp); next_run = start_rdp(ip, myport, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break; break;
case 2: /* clean exit */ case 2: /* clean exit */
freerdp_disconnect(instance); freerdp_disconnect(instance);

View file

@ -24,11 +24,6 @@ int32_t start_redis(int32_t s, char *ip, int32_t port, unsigned char options, ch
return 1; return 1;
} }
buf = hydra_receive_line(s); 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] == '+') { if (buf[0] == '+') {
hydra_report_found_host(port, ip, "redis", fp); hydra_report_found_host(port, ip, "redis", fp);
hydra_completed_pair_found(); hydra_completed_pair_found();

View file

@ -6,10 +6,6 @@
// //
// //
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "hydra-mod.h" #include "hydra-mod.h"
#include "sasl.h" #include "sasl.h"
#include <stdio.h> #include <stdio.h>
@ -20,7 +16,7 @@ char packet[500];
char packet2[500]; char packet2[500];
int32_t is_Unauthorized(char *s) { int32_t is_Unauthorized(char *s) {
if (strcasestr(s, "401 Unauthorized") != NULL) { if (strstr(s, "401 Unauthorized") != NULL) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -28,7 +24,7 @@ int32_t is_Unauthorized(char *s) {
} }
int32_t is_NotFound(char *s) { int32_t is_NotFound(char *s) {
if (strcasestr(s, "404 Stream") != NULL || strcasestr(s, "404 Not") != NULL) { if (strstr(s, "404 Stream Not Found") != NULL) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -36,7 +32,7 @@ int32_t is_NotFound(char *s) {
} }
int32_t is_Authorized(char *s) { int32_t is_Authorized(char *s) {
if (strcasestr(s, "200 OK") != NULL) { if (strstr(s, "200 OK") != NULL) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -44,7 +40,7 @@ int32_t is_Authorized(char *s) {
} }
int32_t use_Basic_Auth(char *s) { int32_t use_Basic_Auth(char *s) {
if (strcasestr(s, "WWW-Authenticate: Basic") != NULL) { if (strstr(s, "WWW-Authenticate: Basic") != NULL) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -52,7 +48,7 @@ int32_t use_Basic_Auth(char *s) {
} }
int32_t use_Digest_Auth(char *s) { int32_t use_Digest_Auth(char *s) {
if (strcasestr(s, "WWW-Authenticate: Digest") != NULL) { if (strstr(s, "WWW-Authenticate: Digest") != NULL) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -108,6 +104,17 @@ int32_t start_rtsp(int32_t s, char *ip, int32_t port, unsigned char options, cha
} else { } else {
create_core_packet(1, ip, port); create_core_packet(1, ip, port);
if (use_Basic_Auth(lresp) == 1) {
free(lresp);
sprintf(buffer2, "%.249s:%.249s", login, pass);
hydra_tobase64((unsigned char *)buffer2, strlen(buffer2), sizeof(buffer2));
sprintf(buffer, "%.500sAuthorization: : Basic %.500s\r\n\r\n", packet2, buffer2);
if (debug) {
hydra_report(stderr, "C:%s\n", buffer);
}
} else {
if (use_Digest_Auth(lresp) == 1) { if (use_Digest_Auth(lresp) == 1) {
char aux[500] = "", dbuf[500] = "", *result = NULL; char aux[500] = "", dbuf[500] = "", *result = NULL;
char *pbuffer = hydra_strcasestr(lresp, "WWW-Authenticate: Digest "); char *pbuffer = hydra_strcasestr(lresp, "WWW-Authenticate: Digest ");
@ -122,23 +129,17 @@ int32_t start_rtsp(int32_t s, char *ip, int32_t port, unsigned char options, cha
"without OpenSSL/MD5 support\n"); "without OpenSSL/MD5 support\n");
return 3; return 3;
#endif #endif
if (result == NULL) { if (result == NULL) {
hydra_report(stderr, "[ERROR] digest generation failed\n"); hydra_report(stderr, "[ERROR] digest generation failed\n");
return 3; return 3;
} }
sprintf(buffer, "%.500sAuthorization: Digest %.500s\r\n\r\n", packet2, dbuf); sprintf(buffer, "%.500sAuthorization: Digest %.500s\r\n\r\n", packet2, dbuf);
if (debug)
if (debug) {
hydra_report(stderr, "C:%s\n", buffer); hydra_report(stderr, "C:%s\n", buffer);
} else if (use_Basic_Auth(lresp) == 1) { }
free(lresp); }
sprintf(buffer2, "%.249s:%.249s", login, pass);
hydra_tobase64((unsigned char *)buffer2, strlen(buffer2), sizeof(buffer2));
sprintf(buffer, "%.500sAuthorization: : Basic %.500s\r\n\r\n", packet2, buffer2);
if (debug)
hydra_report(stderr, "C:%s\n", buffer);
} else {
hydra_report(stderr, "[ERROR] unknown authentication protocol\n");
return 1;
} }
if (strlen(buffer) == 0) { if (strlen(buffer) == 0) {
@ -158,7 +159,7 @@ int32_t start_rtsp(int32_t s, char *ip, int32_t port, unsigned char options, cha
return 1; return 1;
} }
if (is_NotFound(lresp) || is_Authorized(lresp)) { if ((is_NotFound(lresp))) {
free(lresp); free(lresp);
hydra_completed_pair_found(); hydra_completed_pair_found();

View file

@ -14,7 +14,6 @@ const int32_t *__ctype_b;
extern void flood(); /* for -lm */ extern void flood(); /* for -lm */
extern hydra_option hydra_options;
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
RFC_ERROR_INFO_EX error_info; RFC_ERROR_INFO_EX error_info;
@ -100,8 +99,6 @@ void service_sapr3(char *ip, int32_t sp, unsigned char options, char *miscptr, F
switch (run) { switch (run) {
case 1: /* connect and service init function */ case 1: /* connect and service init function */
next_run = start_sapr3(sock, ip, port, options, miscptr, fp); next_run = start_sapr3(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break; break;
case 2: case 2:
hydra_child_exit(0); 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 */ } 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(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_report_found_host(port, ip, "smb", fp);
hydra_completed_pair_skip(); hydra_completed_pair_found();
} else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, password expired */ } else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, account expired */
hydra_report(stdout, hydra_report(stdout,
"[%d][smb] Host: %s Account: %s Valid password, password " "[%d][smb] Host: %s Account: %s Valid password, password "
"expired and must be changed on next logon\n", "expired and must be changed on next logon\n",
@ -1304,13 +1304,14 @@ 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_report(stderr, "[INFO] LM dialect may be disabled, try LMV2 instead\n");
hydra_completed_pair_skip(); hydra_completed_pair_skip();
} else if (SMBerr == 0x000024) { /* change password on next login [success] */ } else if (SMBerr == 0x000024) { /* change password on next login [success] */
hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login); hydra_report(stdout, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login);
hydra_completed_pair_found(); hydra_completed_pair_found();
} else if (SMBerr == 0x00006D) { /* STATUS_LOGON_FAILURE */ } else if (SMBerr == 0x00006D) { /* STATUS_LOGON_FAILURE */
hydra_completed_pair(); hydra_completed_pair();
} else if (SMBerr == 0x000071) { /* password expired */ } else if (SMBerr == 0x000071) { /* password expired */
hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: PASSWORD EXPIRED\n", port, ipaddr_str, login); if (verbose)
hydra_completed_pair_found(); fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: PASSWORD EXPIRED\n", port, ipaddr_str, login);
hydra_completed_pair_skip();
} else if ((SMBerr == 0x000072) || (SMBerr == 0xBF0002)) { /* account disabled */ /* BF0002 on w2k */ } else if ((SMBerr == 0x000072) || (SMBerr == 0xBF0002)) { /* account disabled */ /* BF0002 on w2k */
if (verbose) if (verbose)
fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_DISABLED\n", port, ipaddr_str, login); fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_DISABLED\n", port, ipaddr_str, login);

View file

@ -27,7 +27,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
extern hydra_option hydra_options;
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
typedef struct creds { typedef struct creds {
@ -127,11 +126,6 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) {
*/ */
switch (errno) { switch (errno) {
case 0:
// maybe false positive? unclear ... :( ... needs more testing
smbc_free_context(ctx, 1);
return true;
break;
case ENOENT: case ENOENT:
// Noticed this when connecting to older samba servers on linux // Noticed this when connecting to older samba servers on linux
// where any credentials are accepted. // where any credentials are accepted.
@ -174,15 +168,10 @@ 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) { 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); hydra_register_socket(sp);
while (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT))) { while (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT))) {
char *login, *pass; char *login, *pass;
if (first_run && hydra_options.conwait)
sleep(hydra_options.conwait);
login = hydra_get_next_login(); login = hydra_get_next_login();
pass = hydra_get_next_password(); pass = hydra_get_next_password();
@ -197,8 +186,6 @@ void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
} else { } else {
hydra_completed_pair(); hydra_completed_pair();
} }
first_run = 1;
} }
EXIT_NORMAL; EXIT_NORMAL;
} }

View file

@ -61,10 +61,6 @@ int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, cha
return 1; return 1;
if (strstr(buf, "334") == NULL) { if (strstr(buf, "334") == NULL) {
hydra_report(stderr, "[ERROR] SMTP PLAIN AUTH : %s\n", buf); hydra_report(stderr, "[ERROR] SMTP PLAIN AUTH : %s\n", buf);
if (strstr(buf, "503") != NULL) {
free(buf);
return 4;
}
free(buf); free(buf);
return 3; return 3;
} }
@ -442,12 +438,6 @@ void service_smtp(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
} }
hydra_child_exit(0); hydra_child_exit(0);
return; return;
case 4: /* error exit */
if (sock >= 0) {
sock = hydra_disconnect(sock);
}
hydra_child_exit(3);
return;
default: default:
hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n");
hydra_child_exit(0); hydra_child_exit(0);

View file

@ -47,9 +47,6 @@ 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_TIMEOUT, &hydra_options.waittime);
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "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 (ssh_connect(session) != 0) {
// if the connection was drop, exit and let hydra main handle it // if the connection was drop, exit and let hydra main handle it
if (verbose) if (verbose)
@ -122,8 +119,6 @@ void service_ssh(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL
switch (run) { switch (run) {
case 1: /* connect and service init function */ case 1: /* connect and service init function */
next_run = start_ssh(sock, ip, port, options, miscptr, fp); next_run = start_ssh(sock, ip, port, options, miscptr, fp);
if (next_run == 1 && hydra_options.conwait)
sleep(hydra_options.conwait);
break; break;
case 2: case 2:
ssh_disconnect(session); ssh_disconnect(session);
@ -195,9 +190,6 @@ 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_TIMEOUT, &hydra_options.waittime);
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "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 (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)); fprintf(stderr, "[ERROR] could not connect to ssh://%s:%d - %s\n", hydra_address2string_beautiful(ip), port, ssh_get_error(session));
return 2; return 2;

View file

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

View file

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

View file

@ -33,10 +33,10 @@ test -e "$pass" && passs="-P $pass"
test -e "$pass" || passs="-p $pass" test -e "$pass" || passs="-p $pass"
test -n "$port" && ports="-s $port" test -n "$port" && ports="-s $port"
test -n "$pw" && pws="-e $pw" test -n "$pw" && pws="-e $pw"
test -n "$opt" && { opts="-m $opt" ; dopts="-m '$opt'" ; } test -n "$opt" && opts="-m '$opt'"
echo The following command will be executed now: echo The following command will be executed now:
echo " hydra $users $passs -u $pws $ports $dopts $targets $service" echo " hydra $users $passs -u $pws $ports $opts $targets $service"
echo echo
read -p "Do you want to run the command now? [Y/n] " yn read -p "Do you want to run the command now? [Y/n] " yn
test "$yn" = "n" -o "$yn" = "N" && { echo Exiting. ; exit 0 ; } test "$yn" = "n" -o "$yn" = "N" && { echo Exiting. ; exit 0 ; }

View file

@ -1,4 +1,4 @@
.TH "HYDRA" "1" "01/01/2023" .TH "HYDRA" "1" "01/01/2022"
.SH NAME .SH NAME
hydra \- a very fast network logon cracker which supports many different services hydra \- a very fast network logon cracker which supports many different services
.SH SYNOPSIS .SH SYNOPSIS

158
hydra.c
View file

@ -1,5 +1,5 @@
/* /*
* hydra (c) 2001-2023 by van Hauser / THC <vh@thc.org> * hydra (c) 2001-2022 by van Hauser / THC <vh@thc.org>
* https://github.com/vanhauser-thc/thc-hydra * https://github.com/vanhauser-thc/thc-hydra
* *
* Parallized network login hacker. * Parallized network login hacker.
@ -228,7 +228,7 @@ char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cobaltstrike cvs fire
#define RESTOREFILE "./hydra.restore" #define RESTOREFILE "./hydra.restore"
#define PROGRAM "Hydra" #define PROGRAM "Hydra"
#define VERSION "v9.6dev" #define VERSION "v9.3"
#define AUTHOR "van Hauser/THC" #define AUTHOR "van Hauser/THC"
#define EMAIL "<vh@thc.org>" #define EMAIL "<vh@thc.org>"
#define AUTHOR2 "David Maciejak" #define AUTHOR2 "David Maciejak"
@ -267,7 +267,6 @@ typedef struct {
typedef struct { typedef struct {
char *target; char *target;
char *miscptr;
char ip[36]; char ip[36];
char *login_ptr; char *login_ptr;
char *pass_ptr; char *pass_ptr;
@ -344,11 +343,6 @@ 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 child_head_no = -1, child_socket;
int32_t total_redo_count = 0; 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 // moved for restore feature
int32_t process_restore = 0, dont_unlink; int32_t process_restore = 0, dont_unlink;
char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL; char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL;
@ -394,7 +388,7 @@ static const struct {
{"http-get-form", service_http_form_init, service_http_get_form, usage_http_form}, {"http-get-form", service_http_form_init, service_http_get_form, usage_http_form},
{"http-head", service_http_init, service_http_head, NULL}, {"http-head", service_http_init, service_http_head, NULL},
{"http-form", service_http_form_init, NULL, usage_http_form}, {"http-form", service_http_form_init, NULL, usage_http_form},
{"http-post", service_http_init, service_http_post, usage_http}, {"http-post", NULL, service_http_post, usage_http},
{"http-post-form", service_http_form_init, service_http_post_form, usage_http_form}, {"http-post-form", service_http_form_init, service_http_post_form, usage_http_form},
SERVICE3("http-proxy", http_proxy), SERVICE3("http-proxy", http_proxy),
SERVICE3("http-proxy-urlenum", http_proxy_urlenum), SERVICE3("http-proxy-urlenum", http_proxy_urlenum),
@ -525,8 +519,6 @@ void help(int32_t ext) {
"instead of -L/-P options\n" "instead of -L/-P options\n"
" -M FILE list of servers to attack, one entry per " " -M FILE list of servers to attack, one entry per "
"line, ':' to specify port\n"); "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" 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, " " -b FORMAT specify the format for the -o FILE: text(default), json, "
"jsonv1\n" "jsonv1\n"
@ -1034,7 +1026,7 @@ void killed_childs(int32_t signo) {
int32_t pid, i; int32_t pid, i;
killed++; killed++;
pid = waitpid(-1, NULL, WNOHANG); pid = wait3(NULL, WNOHANG, NULL);
for (i = 0; i < hydra_options.max_use; i++) { for (i = 0; i < hydra_options.max_use; i++) {
if (pid == hydra_heads[i]->pid) { if (pid == hydra_heads[i]->pid) {
hydra_heads[i]->pid = -1; hydra_heads[i]->pid = -1;
@ -1182,12 +1174,13 @@ void hydra_service_init(int32_t target_no) {
int32_t x = 99; int32_t x = 99;
int32_t i; int32_t i;
hydra_target *t = hydra_targets[target_no]; hydra_target *t = hydra_targets[target_no];
char *miscptr = hydra_options.miscptr;
FILE *ofp = hydra_brains.ofp; FILE *ofp = hydra_brains.ofp;
for (i = 0; x == 99 && i < sizeof(services) / sizeof(services[0]); i++) { for (i = 0; x == 99 && i < sizeof(services) / sizeof(services[0]); i++) {
if (strcmp(hydra_options.service, services[i].name) == 0) { if (strcmp(hydra_options.service, services[i].name) == 0) {
if (services[i].init) { if (services[i].init) {
x = services[i].init(t->ip, -1, options, t->miscptr, ofp, t->port, t->target); x = services[i].init(t->ip, -1, options, miscptr, ofp, t->port, t->target);
break; break;
} }
} }
@ -1271,13 +1264,13 @@ int32_t hydra_spawn_head(int32_t head_no, int32_t target_no) {
hydra_target *t = hydra_targets[target_no]; hydra_target *t = hydra_targets[target_no];
int32_t sp = hydra_heads[head_no]->sp[1]; int32_t sp = hydra_heads[head_no]->sp[1];
// char *miscptr = hydra_options.miscptr; char *miscptr = hydra_options.miscptr;
FILE *ofp = hydra_brains.ofp; FILE *ofp = hydra_brains.ofp;
hydra_target *head_target = hydra_targets[hydra_heads[head_no]->target_no]; hydra_target *head_target = hydra_targets[hydra_heads[head_no]->target_no];
for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) { for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) {
if (strcmp(hydra_options.service, services[i].name) == 0) { if (strcmp(hydra_options.service, services[i].name) == 0) {
if (services[i].exec) { if (services[i].exec) {
services[i].exec(t->ip, sp, options, t->miscptr, ofp, t->port, head_target->target); services[i].exec(t->ip, sp, options, miscptr, ofp, t->port, head_target->target);
// just in case a module returns (which it shouldnt) we let it exit // just in case a module returns (which it shouldnt) we let it exit
// here // here
exit(-1); exit(-1);
@ -1454,7 +1447,7 @@ void hydra_kill_head(int32_t head_no, int32_t killit, int32_t fail) {
// hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = // hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] =
// NULL; // NULL;
} }
(void)waitpid(-1, NULL, WNOHANG); (void)wait3(NULL, WNOHANG, NULL);
} }
void hydra_increase_fail_count(int32_t target_no, int32_t head_no) { void hydra_increase_fail_count(int32_t target_no, int32_t head_no) {
@ -1598,80 +1591,13 @@ char *hydra_reverse_login(int32_t head_no, char *login) {
return hydra_heads[head_no]->reverse; 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) { int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) {
// variables moved to save stack // variables moved to save stack
snpdone = 0; snpdone = 0;
snp_is_redo = 0; snp_is_redo = 0;
snpdont = 0; snpdont = 0;
loop_cnt++; loop_cnt++;
if (hydra_heads[head_no]->redo == 1 && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { if (hydra_heads[head_no]->redo && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) {
hydra_heads[head_no]->redo = 0; hydra_heads[head_no]->redo = 0;
snp_is_redo = 1; snp_is_redo = 1;
snpdone = 1; snpdone = 1;
@ -1703,7 +1629,7 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) {
return -1; return -1;
} }
if (hydra_heads[head_no]->redo == 1 && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { if (hydra_heads[head_no]->redo && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) {
hydra_heads[head_no]->redo = 0; hydra_heads[head_no]->redo = 0;
snp_is_redo = 1; snp_is_redo = 1;
snpdone = 1; snpdone = 1;
@ -1712,7 +1638,7 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) {
printf("[COMPLETED] target %s - login \"%s\" - pass \"%s\" - child %d - " printf("[COMPLETED] target %s - login \"%s\" - pass \"%s\" - child %d - "
"%" hPRIu64 " of %" hPRIu64 "\n", "%" hPRIu64 " of %" hPRIu64 "\n",
hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no, hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo); hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no, hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo);
// hydra_heads[head_no]->redo = 0; hydra_heads[head_no]->redo = 0;
if (hydra_targets[target_no]->redo_state > 0) { if (hydra_targets[target_no]->redo_state > 0) {
if (hydra_targets[target_no]->redo_state <= hydra_targets[target_no]->redo) { if (hydra_targets[target_no]->redo_state <= hydra_targets[target_no]->redo) {
hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo_state - 1]; hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo_state - 1];
@ -2119,7 +2045,7 @@ void process_proxy_line(int32_t type, char *string) {
string[strlen(string) - 1] = 0; string[strlen(string) - 1] = 0;
if (string[strlen(string) - 1] == '\r') if (string[strlen(string) - 1] == '\r')
string[strlen(string) - 1] = 0; 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); fprintf(stderr, "[WARNING] maximum amount of proxies loaded, ignoring this entry: %s\n", string);
return; return;
} }
@ -2245,13 +2171,13 @@ void process_proxy_line(int32_t type, char *string) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char *proxy_string = NULL, *device = NULL, *memcheck; char *proxy_string = NULL, *device = NULL, *memcheck;
char *outfile_format_tmp; char *outfile_format_tmp;
FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp, *filecloser=NULL; FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp;
size_t countinfile = 1, sizeinfile = 0; size_t countinfile = 1, sizeinfile = 0;
uint64_t math2; uint64_t math2;
int32_t i = 0, j = 0, k, error = 0, modusage = 0, ignore_restore = 0, do_switch; 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; int32_t head_no = 0, target_no = 0, exit_condition = 0, readres;
time_t starttime, elapsed_status, elapsed_restore, status_print = 59, tmp_time; time_t starttime, elapsed_status, elapsed_restore, status_print = 59, tmp_time;
char *tmpptr, *tmpptr2, *tmpptr3; char *tmpptr, *tmpptr2;
char rc, buf[MAXBUF]; char rc, buf[MAXBUF];
time_t last_attempt = 0; time_t last_attempt = 0;
fd_set fdreadheads; fd_set fdreadheads;
@ -2260,7 +2186,7 @@ int main(int argc, char *argv[]) {
struct sockaddr_in6 *ipv6 = NULL; struct sockaddr_in6 *ipv6 = NULL;
struct sockaddr_in *ipv4 = NULL; struct sockaddr_in *ipv4 = NULL;
printf("%s %s (c) 2023 by %s & %s - Please do not use in military or secret " printf("%s %s (c) 2022 by %s & %s - Please do not use in military or secret "
"service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).\n\n", "service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).\n\n",
PROGRAM, VERSION, AUTHOR, AUTHOR2); PROGRAM, VERSION, AUTHOR, AUTHOR2);
#ifndef LIBAFP #ifndef LIBAFP
@ -2381,7 +2307,6 @@ int main(int argc, char *argv[]) {
hydra_options.loginfile = NULL; hydra_options.loginfile = NULL;
hydra_options.pass = NULL; hydra_options.pass = NULL;
hydra_options.passfile = NULL; hydra_options.passfile = NULL;
hydra_options.distributed = NULL;
hydra_options.tasks = TASKS; hydra_options.tasks = TASKS;
hydra_options.max_use = MAXTASKS; hydra_options.max_use = MAXTASKS;
hydra_options.outfile_format = FORMAT_PLAIN_TEXT; hydra_options.outfile_format = FORMAT_PLAIN_TEXT;
@ -2395,18 +2320,8 @@ int main(int argc, char *argv[]) {
help(1); help(1);
if (argc < 2) if (argc < 2)
help(0); help(0);
while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:D: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:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) {
switch (i) { 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': case 'h':
help(1); help(1);
break; break;
@ -3286,7 +3201,6 @@ int main(int argc, char *argv[]) {
bail("Compiled without SSL support, module not available"); bail("Compiled without SSL support, module not available");
#endif #endif
} }
if (hydra_options.infile_ptr == NULL) {
if (hydra_options.miscptr == NULL) { if (hydra_options.miscptr == NULL) {
fprintf(stderr, "[WARNING] You must supply the web page as an " fprintf(stderr, "[WARNING] You must supply the web page as an "
"additional option or via -m, default path set to /\n"); "additional option or via -m, default path set to /\n");
@ -3362,7 +3276,6 @@ int main(int argc, char *argv[]) {
} }
} }
} }
}
if (strcmp(hydra_options.service, "xmpp") == 0) if (strcmp(hydra_options.service, "xmpp") == 0)
i = 1; i = 1;
@ -3408,7 +3321,8 @@ int main(int argc, char *argv[]) {
hydra_options.port = port; hydra_options.port = port;
} }
if (hydra_options.login == NULL && hydra_options.loginfile == NULL && hydra_options.colonfile == NULL) if (hydra_options.login == NULL && hydra_options.loginfile == NULL &&
hydra_options.colonfile == NULL)
hydra_options.exit_found = 1; hydra_options.exit_found = 1;
if (hydra_options.ssl == 0 && hydra_options.port == 443) if (hydra_options.ssl == 0 && hydra_options.port == 443)
@ -3489,13 +3403,6 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile); fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile);
exit(-1); 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.countlogin = countlines(lfp, 0);
hydra_brains.sizelogin = size_of_data; hydra_brains.sizelogin = size_of_data;
if (hydra_brains.countlogin == 0) { if (hydra_brains.countlogin == 0) {
@ -3528,11 +3435,6 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile); fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile);
exit(-1); 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.countpass = countlines(pfp, 0);
hydra_brains.sizepass = size_of_data; hydra_brains.sizepass = size_of_data;
if (hydra_brains.countpass == 0) { if (hydra_brains.countpass == 0) {
@ -3587,11 +3489,6 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile); fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile);
exit(-1); 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.countlogin = countlines(cfp, 1);
hydra_brains.sizelogin = size_of_data; hydra_brains.sizelogin = size_of_data;
if (hydra_brains.countlogin == 0) { if (hydra_brains.countlogin == 0) {
@ -3695,7 +3592,6 @@ int main(int argc, char *argv[]) {
} }
} else } else
hydra_targets[i]->target = tmpptr; hydra_targets[i]->target = tmpptr;
if ((tmpptr2 = strchr(tmpptr, ':')) != NULL) { if ((tmpptr2 = strchr(tmpptr, ':')) != NULL) {
*tmpptr2++ = 0; *tmpptr2++ = 0;
tmpptr = tmpptr2; tmpptr = tmpptr2;
@ -3705,13 +3601,6 @@ int main(int argc, char *argv[]) {
} }
if (hydra_targets[i]->port == 0) if (hydra_targets[i]->port == 0)
hydra_targets[i]->port = hydra_options.port; 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) while (*tmpptr != 0)
tmpptr++; tmpptr++;
tmpptr++; tmpptr++;
@ -3734,7 +3623,6 @@ int main(int argc, char *argv[]) {
memset(hydra_targets[0], 0, sizeof(hydra_target)); memset(hydra_targets[0], 0, sizeof(hydra_target));
hydra_targets[0]->target = servers_ptr = hydra_options.server; hydra_targets[0]->target = servers_ptr = hydra_options.server;
hydra_targets[0]->port = hydra_options.port; hydra_targets[0]->port = hydra_options.port;
hydra_targets[0]->miscptr = hydra_options.miscptr;
sizeservers = strlen(hydra_options.server) + 1; sizeservers = strlen(hydra_options.server) + 1;
} else { } else {
/* CIDR notation on command line, e.g. 192.168.0.0/24 */ /* CIDR notation on command line, e.g. 192.168.0.0/24 */
@ -3779,7 +3667,6 @@ int main(int argc, char *argv[]) {
memcpy(&target.sin_addr.s_addr, (char *)&addr_cur2, 4); 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]->target = strdup(inet_ntoa((struct in_addr)target.sin_addr));
hydra_targets[i]->port = hydra_options.port; hydra_targets[i]->port = hydra_options.port;
hydra_targets[i]->miscptr = hydra_options.miscptr;
addr_cur++; addr_cur++;
i++; i++;
} }
@ -3795,7 +3682,6 @@ int main(int argc, char *argv[]) {
memset(hydra_targets[0], 0, sizeof(hydra_target)); memset(hydra_targets[0], 0, sizeof(hydra_target));
hydra_targets[0]->target = servers_ptr = hydra_options.server; hydra_targets[0]->target = servers_ptr = hydra_options.server;
hydra_targets[0]->port = hydra_options.port; hydra_targets[0]->port = hydra_options.port;
hydra_targets[0]->miscptr = hydra_options.miscptr;
sizeservers = strlen(hydra_options.server) + 1; sizeservers = strlen(hydra_options.server) + 1;
} }
for (i = 0; i < hydra_brains.targets; i++) { for (i = 0; i < hydra_brains.targets; i++) {
@ -4228,7 +4114,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) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
printf("[%d][%s] host: %s 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); 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_format == FORMAT_JSONV1 && hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { if (hydra_options.outfile_format == FORMAT_JSONV1 && hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) {
fprintf(hydra_brains.ofp, fprintf(hydra_brains.ofp,
@ -4366,7 +4252,7 @@ int main(int argc, char *argv[]) {
// hydra_brains.sent); // hydra_brains.sent);
usleepn(USLEEP_LOOP); usleepn(USLEEP_LOOP);
(void)waitpid(-1, NULL, WNOHANG); (void)wait3(NULL, WNOHANG, NULL);
// write restore file and report status // write restore file and report status
if (process_restore == 1 && time(NULL) - elapsed_restore > 299) { if (process_restore == 1 && time(NULL) - elapsed_restore > 299) {
hydra_restore_write(0); hydra_restore_write(0);
@ -4469,7 +4355,7 @@ int main(int argc, char *argv[]) {
for (i = 0; i < hydra_options.max_use; i++) for (i = 0; i < hydra_options.max_use; i++)
if (hydra_heads[i]->active == HEAD_ACTIVE && hydra_heads[i]->pid > 0) if (hydra_heads[i]->active == HEAD_ACTIVE && hydra_heads[i]->pid > 0)
hydra_kill_head(i, 1, 3); hydra_kill_head(i, 1, 3);
(void)waitpid(-1, NULL, WNOHANG); (void)wait3(NULL, WNOHANG, NULL);
#define STRMAX (10 * 1024) #define STRMAX (10 * 1024)
char json_error[STRMAX + 2], tmp_str[STRMAX + 2]; char json_error[STRMAX + 2], tmp_str[STRMAX + 2];

View file

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

View file

@ -42,7 +42,7 @@ upcase characters (A,B,C,D, etc.)
numbers (1,2,3,4, etc.) numbers (1,2,3,4, etc.)
.TP .TP
.B \-p .B \-p
printable characters (which are not \-l/\-n/\-n, e.g. $,!,/,(,*, etc.) printable characters (which are not \-l/\-n/\-p, e.g. $,!,/,(,*, etc.)
.TP .TP
.B \ -s .B \ -s
special characters \- all others not withint the sets above special characters \- all others not withint the sets above

View file

@ -30,7 +30,7 @@ void help() {
printf(" -l lowcase characters (a,b,c,d, etc.)\n"); printf(" -l lowcase characters (a,b,c,d, etc.)\n");
printf(" -u upcase characters (A,B,C,D, etc.)\n"); printf(" -u upcase characters (A,B,C,D, etc.)\n");
printf(" -n numbers (1,2,3,4, etc.)\n"); printf(" -n numbers (1,2,3,4, etc.)\n");
printf(" -p printable characters (which are not -l/-u/-n, e.g. " printf(" -p printable characters (which are not -l/-n/-p, e.g. "
"$,!,/,(,*, etc.)\n"); "$,!,/,(,*, etc.)\n");
printf(" -s special characters - all others not within the sets " printf(" -s special characters - all others not within the sets "
"above\n"); "above\n");
@ -50,7 +50,7 @@ int main(int argc, char *argv[]) {
int32_t sets = 0, countsets = 0, minlen = 0, maxlen = MAXLENGTH, count = 0; 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; int32_t set_low = 0, set_up = 0, set_no = 0, set_print = 0, set_other = 0;
FILE *in = stdin, *out = stdout; FILE *in = stdin, *out = stdout;
unsigned char buf[MAXLENGTH + 1]; char buf[MAXLENGTH + 1];
prg = argv[0]; prg = argv[0];
if (argc < 2) if (argc < 2)
@ -124,9 +124,9 @@ int main(int argc, char *argv[]) {
if (countsets == 0) if (countsets == 0)
countsets = sets; countsets = sets;
while (fgets((void *)buf, sizeof(buf), in) != NULL) { while (fgets(buf, sizeof(buf), in) != NULL) {
int is_low = 0, is_up = 0, is_no = 0, is_print = 0, is_other = 0; i = -1;
if (!buf[0]) if (buf[0] == 0)
continue; continue;
if (buf[strlen(buf) - 1] == '\n') if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0; buf[strlen(buf) - 1] = 0;
@ -134,31 +134,40 @@ int main(int argc, char *argv[]) {
buf[strlen(buf) - 1] = 0; buf[strlen(buf) - 1] = 0;
if (strlen(buf) >= minlen && strlen(buf) <= maxlen) { if (strlen(buf) >= minlen && strlen(buf) <= maxlen) {
i = 0; i = 0;
j = 1; if (countsets > 0) {
for (i = 0; i < strlen(buf) && j; i++) { 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; j = 0;
if (set_low && islower(buf[i])) { for (k = 0; k < strlen(buf); k++)
if (isprint((int32_t)buf[k]) != 0 && isalnum((int32_t)buf[k]) == 0)
j = 1; j = 1;
is_low = 1; if (j)
} else if (set_up && isupper(buf[i])) { i++;
}
if (set_other) {
j = 0;
for (k = 0; k < strlen(buf); k++)
if (isprint((int32_t)buf[k]) == 0 && isalnum((int32_t)buf[k]) == 0)
j = 1; j = 1;
is_up = 1; if (j)
} else if (set_no && isdigit(buf[i])) { 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 (j && countsets <= is_low + is_up + is_no + is_print + is_other) { if (i >= countsets) {
fprintf(out, "%s\n", buf); fprintf(out, "%s\n", buf);
count++; count++;
} }
} }
/* fprintf(stderr, "[DEBUG] i: %d minlen: %d maxlen: %d len: %d\n", i,
* minlen, maxlen, strlen(buf)); */
} }
fclose(in); fclose(in);
fclose(out); fclose(out);