diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e7e79e7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,38 @@ +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: + id: slug + + - uses: docker/build-push-action@v3 # Action page: + with: + context: . + file: Dockerfile + push: true + platforms: linux/amd64, linux/arm64 +# ,linux/arm/v6, linux/arm/v7 + tags: vanhauser/hydra:latest + diff --git a/CHANGES b/CHANGES index e895e03..685f48d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,41 @@ 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 +* support Xcode compilation +* new module: cobaltstrike by ultimaiiii, thank you! +* fix for ssh to support -M or ip/range +* fix for rdp to detect empty passwords +* fix for http-form to no send empty headers +* fix for http on non-default ports when using with a proxy +* for vnc/cisco/... protocols that only check for a password, skip host + after the password is found +* fix to support IPv6 addresses in -M +* fix to test all entries in -C files, not exiting after the first found +* make disappearing targets faster to terminate on +* added "make uninstall" + Release 9.2 * fix for http-post-form optional parameters diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..3b450d3 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,20 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +authors: + - given-names: Marc + family-names: Heuse + name-particle: "van Hauser" + email: vh@thc.org + affiliation: The Hacker's Choice +title: "hydra" +version: 9.2 +type: software +date-released: 2021-03-15 +url: "https://github.com/vanhauser-thc/thc-hydra" +keywords: + - scanning + - passwords + - hacking + - pentesting + - securiy +license: AGPL-3.0-or-later diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9f16b02 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,77 @@ +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"] diff --git a/INSTALL b/INSTALL index 2258405..20f12fd 100644 --- a/INSTALL +++ b/INSTALL @@ -6,6 +6,23 @@ you run "./configure": Redhat/Fedora: yum install openssl-devel pcre-devel ncpfs-devel postgresql-devel libssh-devel subversion-devel libncurses-devel OpenSuSE: zypper install libopenssl-devel pcre-devel libidn-devel ncpfs-devel libssh-devel postgresql-devel subversion-devel libncurses-devel -For the Oracle login module, install the basic and SDK packages: - http://www.oracle.com/technetwork/database/features/instant-client/index.html + +For Termux/Android you need the following setup: + +Install the necessary dependencies + # pkg install -y x11-repo + # pkg install -y clang make openssl openssl-tool wget openssh coreutils gtk2 gtk3 +And then compiling hydra + # ./configure --prefix=$PREFIX + # make + # make install + + +To use xhydra, you will need to install a graphical output in termux, you can be guided from this article: + +https://wiki.termux.com/wiki/Graphical_Environment + + +For the Oracle login module, install the basic and SDK packages: + https://www.oracle.com/database/technologies/instant-client/downloads.html diff --git a/LICENSE b/LICENSE index 052a76b..0ad25db 100644 --- a/LICENSE +++ b/LICENSE @@ -1,12 +1,7 @@ -[see the end of the file for the special exception for linking with OpenSSL - - debian people need this] - - - GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -638,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 by - the Free Software Foundation, either version 3 of the License, or + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -648,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found. GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. @@ -663,21 +658,4 @@ specific requirements. 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. For more information on this, and how to apply and follow the GNU AGPL, see -. - - -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. - +. diff --git a/LICENSE.OPENSSL b/LICENSE_OPENSSL similarity index 100% rename from LICENSE.OPENSSL rename to LICENSE_OPENSSL diff --git a/Makefile b/Makefile index 372e67e..0fc0d2e 100644 --- a/Makefile +++ b/Makefile @@ -3,3 +3,6 @@ all: clean: cp -f Makefile.orig Makefile + +uninstall: + @echo Error: you must run "./configure" first diff --git a/Makefile.am b/Makefile.am index 1c915f1..f6d4bb0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,16 +1,19 @@ # -# Makefile for Hydra - (c) 2001-2020 by van Hauser / THC +# Makefile for Hydra - (c) 2001-2023 by van Hauser / THC # WARN_CLANG=-Wformat-nonliteral -Wstrncat-size -Wformat-security -Wsign-conversion -Wconversion -Wfloat-conversion -Wshorten-64-to-32 -Wuninitialized -Wmissing-variable-declarations -Wmissing-declarations WARN_GCC=-Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-truncation=2 -Wnull-dereference -Wstrict-overflow=2 -Wstringop-overflow=4 -Walloca-larger-than=4096 -Wtype-limits -Wconversion -Wtrampolines -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -fno-common -Wcast-align CFLAGS ?= -g -OPTS=-I. -O3 $(CFLAGS) -fcommon -Wl,--allow-multiple-definition +OPTS=-I. -O3 $(CFLAGS) -fcommon -Wno-deprecated-declarations +CPPFLAGS += -D_GNU_SOURCE # -Wall -g -pedantic LIBS=-lm DESTDIR ?= BINDIR = /bin MANDIR = /man/man1/ DATADIR = /etc +PIXDIR = /share/pixmaps +APPDIR = /share/applications SRC = hydra-vnc.c hydra-pcnfs.c hydra-rexec.c hydra-nntp.c hydra-socks5.c \ hydra-telnet.c hydra-cisco.c hydra-http.c hydra-ftp.c hydra-imap.c \ @@ -23,13 +26,13 @@ SRC = hydra-vnc.c hydra-pcnfs.c hydra-rexec.c hydra-nntp.c hydra-socks5.c \ hydra-asterisk.c hydra-firebird.c hydra-afp.c hydra-ncp.c hydra-rdp.c \ hydra-oracle-sid.c hydra-http-proxy.c hydra-http-form.c hydra-irc.c \ hydra-s7-300.c hydra-redis.c hydra-adam6500.c hydra-rtsp.c \ - hydra-rpcap.c hydra-radmin2.c \ + hydra-rpcap.c hydra-radmin2.c hydra-cobaltstrike.c \ hydra-time.c crc32.c d3des.c bfg.c ntlm.c sasl.c hmacmd5.c hydra-mod.c \ hydra-smb2.c OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \ hydra-telnet.o hydra-cisco.o hydra-http.o hydra-ftp.o hydra-imap.o \ hydra-pop3.o hydra-smb.o hydra-icq.o hydra-cisco-enable.o hydra-ldap.o \ - hydra-memcached.o hydra-mongodb.o hydra-mysql.o hydra-mssql.o hydra-xmpp.o \ + hydra-memcached.o hydra-mongodb.o hydra-mysql.o hydra-mssql.o hydra-cobaltstrike.o hydra-xmpp.o \ hydra-http-proxy-urlenum.o hydra-snmp.o hydra-cvs.o hydra-smtp.o \ hydra-smtp-enum.o hydra-sapr3.o hydra-ssh.o hydra-sshkey.o hydra-teamspeak.o \ hydra-postgres.o hydra-rsh.o hydra-rlogin.o hydra-oracle-listener.o \ @@ -65,7 +68,7 @@ pw-inspector: pw-inspector.c $(CC) $(OPTS) $(SEC) $(CFLAGS) $(CPPFLAGS) -c $< $(XDEFINES) $(XIPATHS) strip: all - strip $(BINS) + -strip $(BINS) -echo OK > /dev/null && test -x xhydra && strip xhydra || echo OK > /dev/null install: strip @@ -78,8 +81,18 @@ install: strip -cp -f *.csv $(DESTDIR)$(PREFIX)$(DATADIR) -mkdir -p $(DESTDIR)$(PREFIX)$(MANDIR) -cp -f hydra.1 xhydra.1 pw-inspector.1 $(DESTDIR)$(PREFIX)$(MANDIR) + -mkdir -p $(DESTDIR)$(PREFIX)$(PIXDIR) + -cp -f xhydra.png $(DESTDIR)$(PREFIX)$(PIXDIR)/ + -mkdir -p $(DESTDIR)$(PREFIX)$(APPDIR) + -desktop-file-install --dir $(DESTDIR)$(PREFIX)$(APPDIR) xhydra.desktop clean: rm -rf xhydra pw-inspector hydra *.o core *.core *.stackdump *~ Makefile.in Makefile dev_rfc hydra.restore arm/*.ipk arm/ipkg/usr/bin/* hydra-gtk/src/*.o hydra-gtk/src/xhydra hydra-gtk/stamp-h hydra-gtk/config.status hydra-gtk/errors hydra-gtk/config.log hydra-gtk/src/.deps hydra-gtk/src/Makefile hydra-gtk/Makefile cp -f Makefile.orig Makefile +uninstall: + -rm -f $(DESTDIR)$(PREFIX)$(BINDIR)/xhydra $(DESTDIR)$(PREFIX)$(BINDIR)/hydra $(DESTDIR)$(PREFIX)$(BINDIR)/pw-inspector $(DESTDIR)$(PREFIX)$(BINDIR)/hydra-wizard.sh $(DESTDIR)$(PREFIX)$(BINDIR)/dpl4hydra.sh + -rm -f $(DESTDIR)$(PREFIX)$(DATADIR)/dpl4hydra_full.csv $(DESTDIR)$(PREFIX)$(DATADIR)/dpl4hydra_local.csv + -rm -f $(DESTDIR)$(PREFIX)$(MANDIR)/hydra.1 $(DESTDIR)$(PREFIX)$(MANDIR)/xhydra.1 $(DESTDIR)$(PREFIX)$(MANDIR)/pw-inspector.1 + -rm -f $(DESTDIR)$(PREFIX)$(PIXDIR)/xhydra.png + -rm -f $(DESTDIR)$(PREFIX)$(APPDIR)/xhydra.desktop diff --git a/Makefile.orig b/Makefile.orig index 372e67e..0fc0d2e 100644 --- a/Makefile.orig +++ b/Makefile.orig @@ -3,3 +3,6 @@ all: clean: cp -f Makefile.orig Makefile + +uninstall: + @echo Error: you must run "./configure" first diff --git a/README.md b/README similarity index 96% rename from README.md rename to README index 322da43..ca95b03 100644 --- a/README.md +++ b/README @@ -1,7 +1,7 @@ H Y D R A - (c) 2001-2021 by van Hauser / THC + (c) 2001-2023 by van Hauser / THC https://github.com/vanhauser-thc/thc-hydra many modules were written by David (dot) Maciejak @ gmail (dot) com BFG code by Jan Dlabal @@ -14,6 +14,13 @@ in these organizations do not care for laws and ethics anyways. 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 @@ -61,6 +68,10 @@ repository is at Github: Use the development version at your own risk. It contains new features and new bugs. Things might not work! +Alternatively (and easier) to can pull it as a docker container: +``` +docker pull vanhauser/hydra +``` HOW TO COMPILE @@ -74,7 +85,7 @@ make install ``` If you want the ssh module, you have to setup libssh (not libssh2!) on your -system, get it from http://www.libssh.org, for ssh v1 support you also need +system, get it from https://www.libssh.org, for ssh v1 support you also need to add "-DWITH_SSH1=On" option in the cmake command line. IMPORTANT: If you compile on MacOS then you must do this - do not install libssh via brew! @@ -85,7 +96,7 @@ for a few optional modules (note that some might not be available on your distri apt-get install libssl-dev libssh-dev libidn11-dev libpcre3-dev \ libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev \ firebird-dev libmemcached-dev libgpg-error-dev \ - libgcrypt11-dev libgcrypt20-dev + libgcrypt11-dev libgcrypt20-dev freetds-dev ``` This enables all optional modules and features with the exception of Oracle, @@ -256,6 +267,7 @@ Examples: -x 1:3:a generate passwords from length 1 to 3 with all lowercase letters -x 2:5:/ generate passwords from length 2 to 5 containing only slashes -x 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers +-x '3:3:aA1&~#\\ "\'<{([-|_^@)]=}>$%*?./ยง,;:!`' -v generates length 3 passwords with all 95 characters, and verbose. ``` Example: diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..225f091 --- /dev/null +++ b/_config.yml @@ -0,0 +1,2 @@ +title: "thc-hydra" +theme: jekyll-theme-midnight diff --git a/configure b/configure index 139c9bf..dc86adb 100755 --- a/configure +++ b/configure @@ -185,6 +185,32 @@ else echo " ... zlib not found, gzip support disabled" fi +echo "Checking for sybdb (sybdb.h) ..." +for i in $INCDIRS; do + if [ -f "$i/sybdb.h" ]; then + HAVE_SYBDB="y" + fi +done + +if [ -n "$HAVE_SYBDB" ]; then + echo " ... found" +else + echo " ... sybdb not found, MSSQL module will lack TDSv7 support" +fi + +echo "Checking for sybfront (sybfront.h) ..." +for i in $INCDIRS; do + if [ -f "$i/sybfront.h" ]; then + HAVE_SYBFRONT="y" + fi +done + +if [ -n "$HAVE_SYBFRONT" ]; then + echo " ... found" +else + echo " ... sybfront not found, MSSQL module will lack TDSv7 support" +fi + echo "Checking for openssl (libssl/libcrypto/ssl.h/sha.h) ..." if [ "X" != "X$DEBUG" ]; then echo DEBUG: SSL_LIB=$LIBDIRS `ls -d /*ssl /usr/*ssl /opt/*ssl /usr/local/*ssl /opt/local/*ssl /*ssl/lib /usr/*ssl/lib /opt/*ssl/lib /usr/local/*ssl/lib /opt/local/*ssl/lib 2> /dev/null` @@ -380,21 +406,21 @@ if [ "X" = "X$CURSES_PATH" -o "X" = "X$CURSES_IPATH" ]; then CURSES_IPATH="" fi -echo "Checking for pcre (libpcre/pcre.h) ..." +echo "Checking for pcre2 (libpcre/pcre.h) ..." for i in $LIBDIRS ; do if [ "X" = "X$PCRE_PATH" ]; then - if [ -f "$i/libpcre.so" -o -f "$i/libpcre.dylib" -o -f "$i/libpcre.a" ]; then + if [ -f "$i/libpcre2-8.so" -o -f "$i/libpcre2-8.dylib" -o -f "$i/libpcre2-8.a" ]; then PCRE_PATH="$i" fi fi if [ "X" = "X$PCRE_PATH" ]; then - TMP_LIB=`/bin/ls $i/libpcre.so* 2> /dev/null | grep libpcre.` + TMP_LIB=`/bin/ls $i/libpcre2*.so* 2> /dev/null | grep libpcre.` if [ -n "$TMP_LIB" ]; then PCRE_PATH="$i" fi fi if [ "X" = "X$PCRE_PATH" ]; then - TMP_LIB=`/bin/ls $i/libpcre.dll* 2> /dev/null | grep libpcre.` + TMP_LIB=`/bin/ls $i/libpcre2*.dll* 2> /dev/null | grep libpcre.` if [ -n "$TMP_LIB" ]; then PCRE_PATH="$i" fi @@ -402,20 +428,20 @@ for i in $LIBDIRS ; do done for i in $INCDIRS ; do if [ "X" != "X$PCRE_PATH" ]; then - if [ -f "$i/pcre.h" ]; then + if [ -f "$i/pcre2.h" ]; then PCRE_IPATH="$i" fi fi done if [ "X" != "X$DEBUG" ]; then echo DEBUG: PCRE_PATH=$PCRE_PATH/libpcre - echo DEBUG: PCRE_IPATH=$PCRE_IPATH/pcre.h + echo DEBUG: PCRE_IPATH=$PCRE_IPATH/pcre2.h fi if [ -n "$PCRE_PATH" -a -n "$PCRE_IPATH" ]; then - echo " ... found" + echo " ... found" fi if [ "X" = "X$PCRE_PATH" -o "X" = "X$PCRE_IPATH" ]; then - echo " ... NOT found, server response checks will be less reliable" + echo " ... NOT found, server response checks will be less reliable" PCRE_PATH="" PCRE_IPATH="" fi @@ -966,7 +992,7 @@ if [ -n "$ORACLE_PATH" -a -n "$ORACLE_IPATH" ]; then fi if [ "X" = "X$ORACLE_PATH" -o "X" = "X$ORACLE_IPATH" ]; then echo " ... NOT found, module Oracle disabled" - echo "Get basic and sdk package from http://www.oracle.com/technetwork/database/features/instant-client/index.html" + echo "Get basic and sdk package from https://www.oracle.com/database/technologies/instant-client/downloads.html" ORACLE_PATH="" ORACLE_IPATH="" fi @@ -998,11 +1024,9 @@ echo "Checking for Memcached (libmemcached/memcached.h) ..." if [ "X" = "X$MCACHED_IPATH" ]; then if [ -f "$i/memcached.h" ]; then MCACHED_IPATH="$i" - fi - if [ -f "$i/libmemcached/memcached.h" ]; then + elif [ -f "$i/libmemcached/memcached.h" ]; then MCACHED_IPATH="$i/libmemcached" - fi - if [ -f "$i/libmemcached-1.0/memcached.h" ]; then + elif [ -f "$i/libmemcached-1.0/memcached.h" ]; then MCACHED_IPATH="$i/libmemcached-1.0" fi fi @@ -1358,10 +1382,14 @@ echo "Checking for Android specialities ..." TMPC=comptest$$ STRRCHR=" not" echo '#include ' > $TMPC.c -echo '#include ' >> $TMPC.c +echo '#include ' >> $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 test -x $TMPC && STRRCHR="" +rm -f $TMPC +$CC -o $TMPC -Wl,--allow-multiple-definition $TMPC.c > /dev/null 2>&1 +WALLOW="no" +test -x $TMPC && WALLOW="yes" rm -f $TMPC $TMPC.c echo " ... strrchr()$STRRCHR found" if [ -n "$CRYPTO_PATH" ]; then @@ -1392,6 +1420,11 @@ rm -f $TMPC $TMPC.c $TMPC.c.err echo " Compiling... $GCCSEC" echo " Linking... $LDSEC" +echo "Checking for --allow-multiple-definition linker option ... $WALLOW" +if [ "$WALLOW" = "yes" ]; then + GCCSECOPT="$GCCSECOPT -Wl,--allow-multiple-definition" +fi + echo XDEFINES="" XLIBS="" @@ -1489,6 +1522,12 @@ fi if [ -n "$RSA" ]; then XDEFINES="$XDEFINES -DNO_RSA_LEGACY" fi +if [ -n "$HAVE_SYBDB" ]; then + XDEFINES="$XDEFINES -DHAVE_SYBDB" +fi +if [ -n "$HAVE_SYBFRONT" ]; then + XDEFINES="$XDEFINES -DHAVE_SYBFRONT" +fi if [ -n "$HAVE_ZLIB" ]; then XDEFINES="$XDEFINES -DHAVE_ZLIB" fi @@ -1620,6 +1659,9 @@ fi if [ -n "$HAVE_ZLIB" ]; then XLIBS="$XLIBS -lz" fi +if [ -n "$HAVE_SYBDB" ]; then + XLIBS="$XLIBS -lsybdb" +fi if [ -n "$CURSES_PATH" ]; then XLIBS="$XLIBS -lcurses" fi @@ -1642,7 +1684,7 @@ if [ -n "$IDN_PATH" ]; then XLIBS="$XLIBS -lidn" fi if [ -n "$PCRE_PATH" ]; then - XLIBS="$XLIBS -lpcre" + XLIBS="$XLIBS -lpcre2-8" fi if [ -n "$MYSQL_PATH" ]; then XLIBS="$XLIBS -lmysqlclient" @@ -1797,4 +1839,4 @@ if [ "x$NOSTRIP" = "x" ]; then else cat Makefile.am | sed 's/^install:.*/install: all/' >> Makefile fi -echo "now type \"make\"" +echo "now type \"make\"" \ No newline at end of file diff --git a/dpl4hydra_full.csv b/dpl4hydra_full.csv index 032c4c6..2f3df58 100644 --- a/dpl4hydra_full.csv +++ b/dpl4hydra_full.csv @@ -2417,8 +2417,6 @@ draytek,Vigor,all,HTTP,admin,admin,Admin,, dreambox,All models,all versions,http, telnet,root,dreambox,, dreambox,All models,all versions,http,telnet,root,dreambox,gives access to a busybox allowing to control the box using basic unix commands embedded into busybox, drupal.org,Drupal,,administrator,admin,admin,,, -ducati,Diavel motorcycles,,console,,last 4 digits of the motorcycle's VIN,Start and drive the motorcycle without a key,This is the ignition password - if you have one of these bikes change the password ASAP as you may be liable for any accident damage caused by the thief!, -ducati,Diavel,,,,Last 4 digits of VIN,,, dupont,Digital Water Proofer,,,root,par0t,,, dynalink,RTA020,,,admin,private,,, dynalink,RTA020,,Admin,admin,private,,, @@ -3061,7 +3059,6 @@ hewlettpackard,Motive Chorus,,HTTP (port 5060),admin,isee,,, hewlettpackard,Officejet,all versions,http,admin,,admin,http interface, hewlettpackard,Power Manager,3,HTTP,admin,admin,Admin,, hewlettpackard,ProcCurve MSC-5100,,,admin,admin,,, -hewlettpackard,Remote Insight Board,,,Administrator,The last eight digits of the serial number,,, hewlettpackard,StoreOnce,,,HPSupport,badg3r5,,, hewlettpackard,Vectra,,Console,,hewlpack,Admin,, hewlettpackard,iLo,,http,Admin,Admin,Admin,, @@ -3611,7 +3608,6 @@ iso sistemi,winwork,,Admin,,,,, iwill,PC BIOS,,,,iwill,,, iwill,PC BIOS,,Admin,,iwill,,, iwill,PC BIOS,,Console,,iwill,Admin,, -jacksoncommunitycollege,My Network Services,,web,(first 7 letters of student's last name + first seven letters of first name + middle initial -- no spaces or punctuation),(First letter of first name Capitalized + First letter of last name in lowercase + day of birth {01-31} + birth year {2 digits} + last 4 digits of student ID),My Network Services access,, jaht,adsl router,AR41/2A,HTTP,admin,epicrouter,Admin,, jamfsoftware,Casper Suite,,,jamfsoftware,jamfsw03,,, janitza,UMG 508,,,Homepage Password,0th,,, @@ -3786,7 +3782,6 @@ kyocera,FS3140MFP,,Web Interface,,admin00,Administrator,, kyocera,FS6025MFP,,system menus,Admin,Admin,Admin,, kyocera,Intermate LAN FS Pro 10/100,K82_0371,HTTP,admin,admin,Admin,, kyocera,KM-4850W,,,admin,,,, -kyocera,KR2,,http,,read notes,,it is the last 6 characters of the mac address, kyocera,TASKalfa 250 Ci,,,Admin,admin00,,if enable local authentification, kyocera,TASKalfa 250ci,,IP,,admin00,,, kyocera,TASKalfa 266ci,,Console Panel,Admin,Admin,Admin,, @@ -5188,82 +5183,42 @@ oce,tcs500, Windows XP, all models,12.3.0(1668),console, http://192.168.0.81,, oce,tcs500,Windows XP,all models,12.3.0(1668),console,http://192.168.0.81,, ods,1094 IS Chassis,,,ods,ods,,4.x, ods,1094,,,ods,ods,,, -oki,9600,,,admin,last six characters of the MAC address (letters uppercase).,,, -oki,B410,,http (dhcp),admin,last six charachter of mac address (upper case),,, -oki,B410dn,,http://169.254.39.211/,admin,Last 6 characters (chars uppercased) from MAC Address,admin,, oki,B411,all ver,Http or AdminManager,root,aaaaaa,Administrator,, -oki,B420,,http (dhcp),admin,last six charachter of mac address (upper case),,, -oki,B430,,http (dhcp),admin,last six charachter of mac address (upper case),,, oki,B431,all ver,Http or AdminManager,root,aaaaaa,Administrator,, oki,B431dn,,http://192.168.1.xxx,root,123456,Admin,, -oki,B43xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), oki,B6100n,,,admin,OkiLAN,admin,with 61e(NIC), oki,B6200n,,,admin,OkiLAN,admin,with 62e(NIC), -oki,B6300,,,root,last six charachter of mac address,root,, oki,B6300n,,,admin,OkiLAN,admin,with 62e(NIC), -oki,B6500,,,root,(last 6 digits of MAC address),root,, oki,B710,all,http://192.168.1.33,root,aaaaaa,Administrator,, oki,B720,all,http://192.168.1.33,root,aaaaaa,Administrator,, oki,B720N,All versions,Web interface,root,aaaaaa,Root access,, oki,B730,all,http://192.168.1.33,root,aaaaaa,Administrator,, oki,B8300n,,,admin,OkiLAN,admin,with 83e(NIC), -oki,B930n,,,root,(last 4 digits of MAC address),root,, -oki,C3200n,,Web Interface - Device IP,root,last 6 of MAC Address - case sensitive,,, oki,C330,all versions etc.,http://192.168.0.1,root,aaaaaa,Admin,Administrator, oki,C3450,,http://192.168.1.50,admin,heslo,admin,, -oki,C3450,,web,admin,last 6 digits of MAC code, Use uppercase letters,, -oki,C3450,,web,admin,last 6 digits of MAC code,Use uppercase letters,Administrator, -oki,C3530,,console,admin,last 6 digits of MAC address,Admin,, -oki,C380,,,admin,last 6 characters of the MAC ADRESS,,, -oki,C51xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), oki,C530dn,A1.02,http://192.168.1.51,root,aaaaaa,Admin,, -oki,C53xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), -oki,C54xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), oki,C5550 MFP,,http,,*blank*,Admin,, -oki,C5650,,Multi,root,Last 6 characters of MAC address (uppercase),Admin,Last 6 digits are also at the end of the default printer name, oki,C5650dn,,,,000000,menu,, oki,C5650n,,,,000000,menu,, -oki,C5700,,HTTP,root,the 6 last digit of the MAC adress,Admin,running with other models, -oki,C5850,,http,admin,last 6 characters of the MAC ADRESS,,, -oki,C5900,,HTTP,root,Last 6 characters (chars uppercased) from MAC Address,admin,, oki,C6050dn,,,,000000,menu,, oki,C6050n,,,,000000,menu,, oki,C610,,,admin,aaaaaa,admin,, -oki,C6100,,HTTP,root,Last 6 characters of MAC address (uppercase),Administrative,seems to work with a variety of oki printers., -oki,C6150,N1.01 Network Firmware 08.51,ZeroConFig Bonjour,root,last six characters of MAC address,Basic Setup,Printer ID,Protocol oki,C6150dn,,,,000000,menu,, oki,C6150dtn,,,,000000,menu,, oki,C6150hdn,,,,000000,menu,, oki,C6150n,,,,000000,menu,, oki,C7000,,,admin,OkiLAN,admin,with 6200e(NIC), -oki,C7000,,,root,(last 6 digits of MAC address),admin,with 7200e(NIC) or 7300e(NIC), -oki,C710,All versions,http,root,Last 6 characters (chars uppercased) from MAC Address,Full acces to printer configuration,, oki,C711,,Web,admin,aaaaaa,Admin access,, -oki,C7300,A3.14, may apply to other versions,Multi,root,Last six digits of default device name,, -oki,C7300,A3.14,may apply to other versions,Multi,root,Last six digits of default device name,Give this a try if the last six digits of the MAC don't work. I believe alpha characters would be uppercased if there were any present., -oki,C7350,,Administrator,root,Last 6 characters (chars uppercased) from MAC Address,,, -oki,C7350,,Multi,root,Last 6 characters (chars uppercased) from MAC Address,Administrator,, -oki,C810,,http://192.168.0.1,root,Last 6 characters (chars uppercased) from MAC Address,,, -oki,C821,all version?,HTTP,root,last six charachter of mac address,Admin,, -oki,C830,all,web,root,last 6 digits of the MAC address,,, -oki,C8800,,Web or Console,root,Last six characters of MAC address,,, oki,C9000,,,admin,OkiLAN,admin,with 6200e(NIC), -oki,C9000,,,root,(last 6 digits of MAC address),admin,with 7200e(NIC) or 7300e(NIC), -oki,C9500,,HTTP / telnet,root,Last 6 characters (chars uppercased) from MAC Address,Administration,, oki,C9650,,,,0000,Print statistics,, oki,C9650,,,,aaaaaa,Administration,, -oki,C9655,,HTTP,root,last 6 digits of MAC address,Administrator,, oki,C9655,,printer menu,,aaaaaa,printer menubutton,, -oki,C9800,,,root,(last 6 digits of MAC address),,, -oki,C9850,,,root,(last 6 digits of MAC address),,, oki,CX1145,,,,123456,,, oki,CX2032 MFP,,http,,*blank*,Admin,, oki,CX2033,,Printer Menu,,,,When asked for password just press OK, oki,CX2633,,Web interface,admin,aaaaaa,admin,, oki,CX2731,,Web interface,admin,aaaaaa,admin,, -oki,CX3641,,,root,(last 6 digits of MAC address),,, oki,Color 8 +14ex,,,admin,OkiLAN,admin,with 6100e(NIC), -oki,ES3640,,,root,(last 6 digits of MAC address),,, oki,ES5460 MFP,,Local configuration menu,,aaaaaa,Admin/Root i guess,, oki,ES7120,,Web,root,aaaaaa,Admin,, oki,ES7411,,web HTTP,admin,aaaaaa,Administrator,, @@ -5275,7 +5230,6 @@ oki,MC160,,Op Panel,,000000,Admin,, oki,MC160,,Web,,sysAdmin,Admin,, oki,MC342w,,,admin,aaaaaa,admin,, oki,MC360,,Console,admin,aaaaaa,Full acces to printer configuration,, -oki,MC360,,HTTP,admin,Last 6 characters (chars uppercased) from MAC Address,Administration,, oki,MC361,,Web interface,admin,aaaaaa,admin,, oki,MC560,,Printer Menu,,,,When asked for password just press OK, oki,MC560,,Printer Menu,,,,When asked for password, @@ -5285,19 +5239,10 @@ oki,MC860,,Web interface,admin,aaaaaa,admin,, oki,ML3xx,,,admin,OkiLAN,admin,with 6010e(NIC),6020e(NIC) oki,ML491n,,http://,Admin,OkiLAN,Admin,, oki,ML4xx,,,admin,OkiLAN,admin,with 6010e(NIC),6020e(NIC) -oki,ML8810,,,root,(last 6 digits of MAC address),,, oki,N22113B,A2.00,http://192.168.1.9,,noe,Admin,, oki,WebTools,,,Administrator,,,, oki,b710,all,http://192.168.1.33,root,aaaaaa,Administrator,, -oki,c3450,All,Multi,admin,last 6 characters of the MAC ADRESS,Admin,, -oki,c3450,All,Multi,admin,last 6 characters of the MAC ADRESS,Admin,no, oki,c511dn,B7.00,,admin,aaaaaa,Full administrator Access,the machine picks up dhcp address,manually configure static on machine directly if required or print a config page to get the dhcp address that was assigned. -oki,c5300,,,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters type them as upper case",,, -oki,c5300,,Console,root,last 6 characters of the MAC ADRESS ""if it contains any alpha characters,type them as upper case"",, -oki,c5300,,Console,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters,type them as upper case",No, -oki,c5300,,Multi,root,last 6 characters of the MAC ADRESS ""if it contains any alpha characters,type them as upper case"",admin, -oki,c5300,,Multi,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters,type them as upper case",No, -oki,c5300,,admin,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters type them as upper case",,, oki,c5750,n1.02,http://192.168.0.200,,,,, oki,c810,1.0,192.100.185.78,admin,admin,admin,, olegkhabarov,Comfy CMS,,,username,password,,, @@ -10100,7 +10045,6 @@ telus,Telephony and internet services,,,(username),telus12,User,Initial password telus,Telephony and internet services,,,(username),telus13,User,Initial password if issued in 2013, telus,Telephony and internet services,,,(username),telus99,User,Initial password if issued in 1999, tenda,W150M,,192.168.1.1,admin,admin,Admin,, -teradyne,4TEL,VRS400,DTMF,(last 5 digits of lineman's SSN),(same as user ID),,, terayon,,,,admin,nms,,6.29, terayon,,Comcast-supplied,HTTP,,,diagnostics page,192.168.100.1/diagnostics_page.html, terayon,TeraLink 1000 Controller,,,admin,password,,, @@ -10403,8 +10347,6 @@ unisys,ClearPath MCP,,Multi,ADMINISTRATOR,ADMINISTRATOR,Admin,, unisys,ClearPath MCP,,Multi,HTTP,HTTP,Web Server Administration,, unisys,ClearPath MCP,,Multi,NAU,NAU,Privileged,Network Administration Utility, unitedtechnologiescorporation,Interlogix truVision IP Camera,,,admin,1234,,, -universityoftennessee,All Employee and Student Services,,, - See Notes,See Notes,Varies with account,Username based on email - eg. if email is smith123@tennessee.edu then NetID (username) is smith123. Def. Password composed of first two letters of birth month in lower case; last two digits of birth; last four digits of UT ID Number; eg. Born Feb 1979 and UT ID Number is 123-45-6789 - default password is fe796789, -universityoftennessee,All Employee and Student Services,,,lt;NetIDgt; - See Notes,See Notes,Varies with account,Username based on email - eg. if email is smith123@tennessee.edu then NetID (username) is smith123. Def. Password composed of first two letters of birth month in lower case; last two digits of birth; last four digits of UT ID Number; eg. Born Feb 1979 and UT ID Number is 123-45-6789 - default password is fe796789, unix,Generic,,,adm,,,, unix,Generic,,,adm,adm,,, unix,Generic,,,admin,admin,,, diff --git a/dpl4hydra_local.csv b/dpl4hydra_local.csv index 032c4c6..2f3df58 100644 --- a/dpl4hydra_local.csv +++ b/dpl4hydra_local.csv @@ -2417,8 +2417,6 @@ draytek,Vigor,all,HTTP,admin,admin,Admin,, dreambox,All models,all versions,http, telnet,root,dreambox,, dreambox,All models,all versions,http,telnet,root,dreambox,gives access to a busybox allowing to control the box using basic unix commands embedded into busybox, drupal.org,Drupal,,administrator,admin,admin,,, -ducati,Diavel motorcycles,,console,,last 4 digits of the motorcycle's VIN,Start and drive the motorcycle without a key,This is the ignition password - if you have one of these bikes change the password ASAP as you may be liable for any accident damage caused by the thief!, -ducati,Diavel,,,,Last 4 digits of VIN,,, dupont,Digital Water Proofer,,,root,par0t,,, dynalink,RTA020,,,admin,private,,, dynalink,RTA020,,Admin,admin,private,,, @@ -3061,7 +3059,6 @@ hewlettpackard,Motive Chorus,,HTTP (port 5060),admin,isee,,, hewlettpackard,Officejet,all versions,http,admin,,admin,http interface, hewlettpackard,Power Manager,3,HTTP,admin,admin,Admin,, hewlettpackard,ProcCurve MSC-5100,,,admin,admin,,, -hewlettpackard,Remote Insight Board,,,Administrator,The last eight digits of the serial number,,, hewlettpackard,StoreOnce,,,HPSupport,badg3r5,,, hewlettpackard,Vectra,,Console,,hewlpack,Admin,, hewlettpackard,iLo,,http,Admin,Admin,Admin,, @@ -3611,7 +3608,6 @@ iso sistemi,winwork,,Admin,,,,, iwill,PC BIOS,,,,iwill,,, iwill,PC BIOS,,Admin,,iwill,,, iwill,PC BIOS,,Console,,iwill,Admin,, -jacksoncommunitycollege,My Network Services,,web,(first 7 letters of student's last name + first seven letters of first name + middle initial -- no spaces or punctuation),(First letter of first name Capitalized + First letter of last name in lowercase + day of birth {01-31} + birth year {2 digits} + last 4 digits of student ID),My Network Services access,, jaht,adsl router,AR41/2A,HTTP,admin,epicrouter,Admin,, jamfsoftware,Casper Suite,,,jamfsoftware,jamfsw03,,, janitza,UMG 508,,,Homepage Password,0th,,, @@ -3786,7 +3782,6 @@ kyocera,FS3140MFP,,Web Interface,,admin00,Administrator,, kyocera,FS6025MFP,,system menus,Admin,Admin,Admin,, kyocera,Intermate LAN FS Pro 10/100,K82_0371,HTTP,admin,admin,Admin,, kyocera,KM-4850W,,,admin,,,, -kyocera,KR2,,http,,read notes,,it is the last 6 characters of the mac address, kyocera,TASKalfa 250 Ci,,,Admin,admin00,,if enable local authentification, kyocera,TASKalfa 250ci,,IP,,admin00,,, kyocera,TASKalfa 266ci,,Console Panel,Admin,Admin,Admin,, @@ -5188,82 +5183,42 @@ oce,tcs500, Windows XP, all models,12.3.0(1668),console, http://192.168.0.81,, oce,tcs500,Windows XP,all models,12.3.0(1668),console,http://192.168.0.81,, ods,1094 IS Chassis,,,ods,ods,,4.x, ods,1094,,,ods,ods,,, -oki,9600,,,admin,last six characters of the MAC address (letters uppercase).,,, -oki,B410,,http (dhcp),admin,last six charachter of mac address (upper case),,, -oki,B410dn,,http://169.254.39.211/,admin,Last 6 characters (chars uppercased) from MAC Address,admin,, oki,B411,all ver,Http or AdminManager,root,aaaaaa,Administrator,, -oki,B420,,http (dhcp),admin,last six charachter of mac address (upper case),,, -oki,B430,,http (dhcp),admin,last six charachter of mac address (upper case),,, oki,B431,all ver,Http or AdminManager,root,aaaaaa,Administrator,, oki,B431dn,,http://192.168.1.xxx,root,123456,Admin,, -oki,B43xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), oki,B6100n,,,admin,OkiLAN,admin,with 61e(NIC), oki,B6200n,,,admin,OkiLAN,admin,with 62e(NIC), -oki,B6300,,,root,last six charachter of mac address,root,, oki,B6300n,,,admin,OkiLAN,admin,with 62e(NIC), -oki,B6500,,,root,(last 6 digits of MAC address),root,, oki,B710,all,http://192.168.1.33,root,aaaaaa,Administrator,, oki,B720,all,http://192.168.1.33,root,aaaaaa,Administrator,, oki,B720N,All versions,Web interface,root,aaaaaa,Root access,, oki,B730,all,http://192.168.1.33,root,aaaaaa,Administrator,, oki,B8300n,,,admin,OkiLAN,admin,with 83e(NIC), -oki,B930n,,,root,(last 4 digits of MAC address),root,, -oki,C3200n,,Web Interface - Device IP,root,last 6 of MAC Address - case sensitive,,, oki,C330,all versions etc.,http://192.168.0.1,root,aaaaaa,Admin,Administrator, oki,C3450,,http://192.168.1.50,admin,heslo,admin,, -oki,C3450,,web,admin,last 6 digits of MAC code, Use uppercase letters,, -oki,C3450,,web,admin,last 6 digits of MAC code,Use uppercase letters,Administrator, -oki,C3530,,console,admin,last 6 digits of MAC address,Admin,, -oki,C380,,,admin,last 6 characters of the MAC ADRESS,,, -oki,C51xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), oki,C530dn,A1.02,http://192.168.1.51,root,aaaaaa,Admin,, -oki,C53xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), -oki,C54xx,,,root,(last 6 digits of MAC address),admin,with 8100e(NIC), oki,C5550 MFP,,http,,*blank*,Admin,, -oki,C5650,,Multi,root,Last 6 characters of MAC address (uppercase),Admin,Last 6 digits are also at the end of the default printer name, oki,C5650dn,,,,000000,menu,, oki,C5650n,,,,000000,menu,, -oki,C5700,,HTTP,root,the 6 last digit of the MAC adress,Admin,running with other models, -oki,C5850,,http,admin,last 6 characters of the MAC ADRESS,,, -oki,C5900,,HTTP,root,Last 6 characters (chars uppercased) from MAC Address,admin,, oki,C6050dn,,,,000000,menu,, oki,C6050n,,,,000000,menu,, oki,C610,,,admin,aaaaaa,admin,, -oki,C6100,,HTTP,root,Last 6 characters of MAC address (uppercase),Administrative,seems to work with a variety of oki printers., -oki,C6150,N1.01 Network Firmware 08.51,ZeroConFig Bonjour,root,last six characters of MAC address,Basic Setup,Printer ID,Protocol oki,C6150dn,,,,000000,menu,, oki,C6150dtn,,,,000000,menu,, oki,C6150hdn,,,,000000,menu,, oki,C6150n,,,,000000,menu,, oki,C7000,,,admin,OkiLAN,admin,with 6200e(NIC), -oki,C7000,,,root,(last 6 digits of MAC address),admin,with 7200e(NIC) or 7300e(NIC), -oki,C710,All versions,http,root,Last 6 characters (chars uppercased) from MAC Address,Full acces to printer configuration,, oki,C711,,Web,admin,aaaaaa,Admin access,, -oki,C7300,A3.14, may apply to other versions,Multi,root,Last six digits of default device name,, -oki,C7300,A3.14,may apply to other versions,Multi,root,Last six digits of default device name,Give this a try if the last six digits of the MAC don't work. I believe alpha characters would be uppercased if there were any present., -oki,C7350,,Administrator,root,Last 6 characters (chars uppercased) from MAC Address,,, -oki,C7350,,Multi,root,Last 6 characters (chars uppercased) from MAC Address,Administrator,, -oki,C810,,http://192.168.0.1,root,Last 6 characters (chars uppercased) from MAC Address,,, -oki,C821,all version?,HTTP,root,last six charachter of mac address,Admin,, -oki,C830,all,web,root,last 6 digits of the MAC address,,, -oki,C8800,,Web or Console,root,Last six characters of MAC address,,, oki,C9000,,,admin,OkiLAN,admin,with 6200e(NIC), -oki,C9000,,,root,(last 6 digits of MAC address),admin,with 7200e(NIC) or 7300e(NIC), -oki,C9500,,HTTP / telnet,root,Last 6 characters (chars uppercased) from MAC Address,Administration,, oki,C9650,,,,0000,Print statistics,, oki,C9650,,,,aaaaaa,Administration,, -oki,C9655,,HTTP,root,last 6 digits of MAC address,Administrator,, oki,C9655,,printer menu,,aaaaaa,printer menubutton,, -oki,C9800,,,root,(last 6 digits of MAC address),,, -oki,C9850,,,root,(last 6 digits of MAC address),,, oki,CX1145,,,,123456,,, oki,CX2032 MFP,,http,,*blank*,Admin,, oki,CX2033,,Printer Menu,,,,When asked for password just press OK, oki,CX2633,,Web interface,admin,aaaaaa,admin,, oki,CX2731,,Web interface,admin,aaaaaa,admin,, -oki,CX3641,,,root,(last 6 digits of MAC address),,, oki,Color 8 +14ex,,,admin,OkiLAN,admin,with 6100e(NIC), -oki,ES3640,,,root,(last 6 digits of MAC address),,, oki,ES5460 MFP,,Local configuration menu,,aaaaaa,Admin/Root i guess,, oki,ES7120,,Web,root,aaaaaa,Admin,, oki,ES7411,,web HTTP,admin,aaaaaa,Administrator,, @@ -5275,7 +5230,6 @@ oki,MC160,,Op Panel,,000000,Admin,, oki,MC160,,Web,,sysAdmin,Admin,, oki,MC342w,,,admin,aaaaaa,admin,, oki,MC360,,Console,admin,aaaaaa,Full acces to printer configuration,, -oki,MC360,,HTTP,admin,Last 6 characters (chars uppercased) from MAC Address,Administration,, oki,MC361,,Web interface,admin,aaaaaa,admin,, oki,MC560,,Printer Menu,,,,When asked for password just press OK, oki,MC560,,Printer Menu,,,,When asked for password, @@ -5285,19 +5239,10 @@ oki,MC860,,Web interface,admin,aaaaaa,admin,, oki,ML3xx,,,admin,OkiLAN,admin,with 6010e(NIC),6020e(NIC) oki,ML491n,,http://,Admin,OkiLAN,Admin,, oki,ML4xx,,,admin,OkiLAN,admin,with 6010e(NIC),6020e(NIC) -oki,ML8810,,,root,(last 6 digits of MAC address),,, oki,N22113B,A2.00,http://192.168.1.9,,noe,Admin,, oki,WebTools,,,Administrator,,,, oki,b710,all,http://192.168.1.33,root,aaaaaa,Administrator,, -oki,c3450,All,Multi,admin,last 6 characters of the MAC ADRESS,Admin,, -oki,c3450,All,Multi,admin,last 6 characters of the MAC ADRESS,Admin,no, oki,c511dn,B7.00,,admin,aaaaaa,Full administrator Access,the machine picks up dhcp address,manually configure static on machine directly if required or print a config page to get the dhcp address that was assigned. -oki,c5300,,,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters type them as upper case",,, -oki,c5300,,Console,root,last 6 characters of the MAC ADRESS ""if it contains any alpha characters,type them as upper case"",, -oki,c5300,,Console,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters,type them as upper case",No, -oki,c5300,,Multi,root,last 6 characters of the MAC ADRESS ""if it contains any alpha characters,type them as upper case"",admin, -oki,c5300,,Multi,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters,type them as upper case",No, -oki,c5300,,admin,root,last 6 characters of the MAC ADRESS "if it contains any alpha characters type them as upper case",,, oki,c5750,n1.02,http://192.168.0.200,,,,, oki,c810,1.0,192.100.185.78,admin,admin,admin,, olegkhabarov,Comfy CMS,,,username,password,,, @@ -10100,7 +10045,6 @@ telus,Telephony and internet services,,,(username),telus12,User,Initial password telus,Telephony and internet services,,,(username),telus13,User,Initial password if issued in 2013, telus,Telephony and internet services,,,(username),telus99,User,Initial password if issued in 1999, tenda,W150M,,192.168.1.1,admin,admin,Admin,, -teradyne,4TEL,VRS400,DTMF,(last 5 digits of lineman's SSN),(same as user ID),,, terayon,,,,admin,nms,,6.29, terayon,,Comcast-supplied,HTTP,,,diagnostics page,192.168.100.1/diagnostics_page.html, terayon,TeraLink 1000 Controller,,,admin,password,,, @@ -10403,8 +10347,6 @@ unisys,ClearPath MCP,,Multi,ADMINISTRATOR,ADMINISTRATOR,Admin,, unisys,ClearPath MCP,,Multi,HTTP,HTTP,Web Server Administration,, unisys,ClearPath MCP,,Multi,NAU,NAU,Privileged,Network Administration Utility, unitedtechnologiescorporation,Interlogix truVision IP Camera,,,admin,1234,,, -universityoftennessee,All Employee and Student Services,,, - See Notes,See Notes,Varies with account,Username based on email - eg. if email is smith123@tennessee.edu then NetID (username) is smith123. Def. Password composed of first two letters of birth month in lower case; last two digits of birth; last four digits of UT ID Number; eg. Born Feb 1979 and UT ID Number is 123-45-6789 - default password is fe796789, -universityoftennessee,All Employee and Student Services,,,lt;NetIDgt; - See Notes,See Notes,Varies with account,Username based on email - eg. if email is smith123@tennessee.edu then NetID (username) is smith123. Def. Password composed of first two letters of birth month in lower case; last two digits of birth; last four digits of UT ID Number; eg. Born Feb 1979 and UT ID Number is 123-45-6789 - default password is fe796789, unix,Generic,,,adm,,,, unix,Generic,,,adm,adm,,, unix,Generic,,,admin,admin,,, diff --git a/hydra-cisco.c b/hydra-cisco.c index 72709ac..e31c749 100644 --- a/hydra-cisco.c +++ b/hydra-cisco.c @@ -5,7 +5,7 @@ #endif extern char *HYDRA_EXIT; -char *buf = NULL; +static char *buf = NULL; int32_t start_cisco(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { char *empty = ""; diff --git a/hydra-cobaltstrike.c b/hydra-cobaltstrike.c new file mode 100644 index 0000000..6c40e64 --- /dev/null +++ b/hydra-cobaltstrike.c @@ -0,0 +1,126 @@ +#include "hydra-mod.h" + +#define CSLEN 256 + +extern char *HYDRA_EXIT; +char *buf; + +int32_t start_cobaltstrike(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { + char *empty = ""; + char *pass, buffer[4 + 1 + 256]; + char cs_pass[CSLEN + 1]; + unsigned char len_pass; + unsigned char reply_byte_0; + unsigned char reply_byte_1; + unsigned char reply_byte_2; + unsigned char reply_byte_3; + int32_t ret = -1; + + if (strlen(pass = hydra_get_next_password()) == 0) + pass = empty; + if (strlen(pass) > CSLEN) + pass[CSLEN - 1] = 0; + len_pass = strlen(pass); + memset(cs_pass, 0, CSLEN + 1); + strcpy(cs_pass, pass); + + memset(buffer, 0x41, sizeof(buffer)); + buffer[0] = 0x00; + buffer[1] = 0x00; + buffer[2] = 0xBE; + buffer[3] = 0xEF; + memcpy(buffer + 4, &len_pass, 1); + memcpy(buffer + 5, cs_pass, len_pass); + + if (hydra_send(s, buffer, sizeof(buffer), 0) < 0) + return 1; + + reply_byte_0 = 0x00; + ret = hydra_recv_nb(s, &reply_byte_0, 1); + if (ret <= 0) + return 3; + + reply_byte_1 = 0x00; + ret = hydra_recv_nb(s, &reply_byte_1, 1); + if (ret <= 0) + return 3; + + reply_byte_2 = 0x00; + ret = hydra_recv_nb(s, &reply_byte_2, 1); + if (ret <= 0) + return 3; + + reply_byte_3 = 0x00; + ret = hydra_recv_nb(s, &reply_byte_3, 1); + if (ret <= 0) + return 3; + + if (reply_byte_0 == 0x00 && reply_byte_1 == 0x00 && reply_byte_2 == 0xCA && reply_byte_3 == 0xFE) { + hydra_report_found_host(port, ip, "cobaltstrike", fp); + hydra_completed_pair_found(); + free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 2; + return 1; + } + + free(buf); + hydra_completed_pair(); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 2; + + return 1; +} + +void service_cobaltstrike(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { + int32_t run = 1, next_run = 1, sock = -1; + int32_t mysslport = PORT_COBALTSTRIKE_SSL; + + hydra_register_socket(sp); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return; + while (1) { + switch (run) { + case 1: /* connect and service init function */ + if (port != 0) + mysslport = port; + sock = hydra_connect_ssl(ip, mysslport, hostname); + port = mysslport; + if (sock < 0) { + hydra_report(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int32_t)getpid()); + hydra_child_exit(1); + } + next_run = start_cobaltstrike(sock, ip, port, options, miscptr, fp); + hydra_disconnect(sock); + break; + case 2: /* clean exit */ + if (sock >= 0) + sock = hydra_disconnect(sock); + hydra_child_exit(0); + return; + case 3: /* clean exit */ + if (sock >= 0) + sock = hydra_disconnect(sock); + hydra_child_exit(2); + return; + default: + hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); + hydra_child_exit(2); + } + run = next_run; + } +} + +int32_t service_cobaltstrike_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { + // called before the childrens are forked off, so this is the function + // which should be filled if initial connections and service setup has to be + // performed once only. + // + // fill if needed. + // + // return codes: + // 0 all OK + // -1 error, hydra will exit, so print a good error message here + + return 0; +} diff --git a/hydra-firebird.c b/hydra-firebird.c index 4898c46..dea104f 100644 --- a/hydra-firebird.c +++ b/hydra-firebird.c @@ -22,6 +22,7 @@ void dummy_firebird() { printf("\n"); } #define DEFAULT_DB "C:\\Program Files\\Firebird\\Firebird_1_5\\security.fdb" +extern hydra_option hydra_options; extern char *HYDRA_EXIT; int32_t start_firebird(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { @@ -124,6 +125,8 @@ void service_firebird(char *ip, int32_t sp, unsigned char options, char *miscptr */ next_run = start_firebird(sock, ip, port, options, miscptr, fp); + if ((next_run == 1 || next_run == 2) && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: diff --git a/hydra-ftp.c b/hydra-ftp.c index 590d671..c6e256c 100644 --- a/hydra-ftp.c +++ b/hydra-ftp.c @@ -26,8 +26,10 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char if (verbose) printf("[INFO] user %s does not exist, skipping\n", login); hydra_completed_pair_skip(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { + free(buf); return 4; + } free(buf); return 1; } @@ -35,8 +37,10 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char if (buf[0] == '2') { hydra_report_found_host(port, ip, "ftp", fp); hydra_completed_pair_found(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { + free(buf); return 4; + } free(buf); return 1; } @@ -61,8 +65,10 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char if (buf[0] == '2') { hydra_report_found_host(port, ip, "ftp", fp); hydra_completed_pair_found(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { + free(buf); return 4; + } free(buf); return 1; } diff --git a/hydra-gtk/configure b/hydra-gtk/configure index 653ba7d..6cd3de7 100755 --- a/hydra-gtk/configure +++ b/hydra-gtk/configure @@ -2391,7 +2391,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - '' \ + '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ '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 (exit $ac_status); }; }; then for ac_declaration in \ - '' \ + '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -3797,8 +3797,8 @@ main () for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); + return 2; + return 0; } _ACEOF rm -f conftest$ac_exeext diff --git a/hydra-gtk/configure.in b/hydra-gtk/configure.in index e4fb923..5bf4e78 100755 --- a/hydra-gtk/configure.in +++ b/hydra-gtk/configure.in @@ -10,7 +10,7 @@ AC_PROG_CC AM_PROG_CC_STDC AC_HEADER_STDC -pkg_modules="gtk+-2.0 >= 2.0.0" +pkg_modules="gtk+-3.0 >= 3.24.24" PKG_CHECK_MODULES(PACKAGE, [$pkg_modules]) AC_SUBST(PACKAGE_CFLAGS) AC_SUBST(PACKAGE_LIBS) diff --git a/hydra-gtk/src/main.c b/hydra-gtk/src/main.c index 72d6dd7..b713e6f 100644 --- a/hydra-gtk/src/main.c +++ b/hydra-gtk/src/main.c @@ -17,6 +17,8 @@ char *hydra_path1 = "./hydra"; char *hydra_path2 = "/usr/local/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; char *HYDRA_BIN; @@ -53,6 +55,10 @@ int main(int argc, char *argv[]) { HYDRA_BIN = hydra_path2; } else if (g_file_test(hydra_path3, G_FILE_TEST_IS_EXECUTABLE)) { 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 { g_error("Please tell me where hydra is, use --hydra-path\n"); return -1; diff --git a/hydra-http-form.c b/hydra-http-form.c old mode 100644 new mode 100755 index 3979e74..af2f457 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -20,33 +20,23 @@ Here's a couple of examples: - ./hydra -S -s 443 -l "" -P pass.txt 10.221.64.2 https-get-form "/irmlab1/vulnapp.php:username=^USER^&pass=^PASS^:incorrect" -The option field (following the service field) takes three ":" separated -values and an optional fourth value, the first is the page on the server -to GET or POST to, the second is the POST/GET variables (taken from either -the browser, or a proxy such as PAROS) with the varying usernames and passwords -in the "^USER^" and "^PASS^" placeholders, the third is the string that it -checks for an *invalid* or *valid* login - any exception to this is counted -as a success. +The option field (following the service field) takes ":" separated values: +The first is the page on the server to GET or POST to. +The second is the POST/GET variables (taken from either the browser, or a proxy +such as ZAP) with the varying usernames and passwords in the "^USER^" and +"^PASS^" placeholders. +The third + are optional parameters like C=, H= etc. (see below) +The final(!) parameter is the string that it checks for an *invalid* or *valid* +login So please: * invalid condition login should be preceded by "F=" * valid condition login should be preceded by "S=". -By default, if no header is found the condition is assume to be a fail, -so checking for *invalid* login. -The fourth optional value, can be a 'C' to define a different page to GET -initial cookies from. +By default, if no header is found the condition is assume to be a fail (F=), +so checking for an *invalid* login string. -If you specify the verbose flag (-v) it will show you the response from the +If you specify the debug flag (-d) it will show you the response from the HTTP server which is useful for checking the result of a failed login to -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 +find something to pattern match against. This should be done together with -t 1. */ @@ -75,6 +65,9 @@ typedef struct cookie_node { int32_t success_cond = 0; int32_t getcookie = 1; int32_t auth_flag = 0; +int32_t code_302_is_success = 0; +int32_t code_401_is_failure = 0; +int32_t multipart_mode = 0; char cookie[4096] = "", cmiscptr[1024]; @@ -258,6 +251,9 @@ int32_t add_header(ptr_header_node *ptr_head, char *header, char *value, char ty ptr_header_node cur_ptr = NULL; ptr_header_node existing_hdr, new_ptr; + if (!header || !value || !strlen(header) || !strlen(value)) + return 0; + // get to the last header for (cur_ptr = *ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next) ; @@ -320,10 +316,15 @@ void hdrrep(ptr_header_node *ptr_head, char *oldvalue, char *newvalue) { for (cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next) { if ((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)) { - cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(newvalue) + 1); - if (cur_ptr->value) - strcpy(cur_ptr->value, newvalue); - else { + size_t oldlen = strlen(oldvalue); + size_t newlen = strlen(newvalue); + if (oldlen != newlen) + cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(cur_ptr->value) - oldlen + newlen + 1); + if (cur_ptr->value) { + char *p = strstr(cur_ptr->value, oldvalue); + memmove(p + newlen, p + oldlen, strlen(p + oldlen) + 1); + memcpy(p, newvalue, newlen); + } else { hydra_report(stderr, "[ERROR] Out of memory (hddrep).\n"); hydra_child_exit(0); } @@ -390,7 +391,7 @@ char *stringify_headers(ptr_header_node *ptr_head) { } int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { - char *ptr, *ptr2; + char *ptr, *ptr2, *tmp; if (miscptr == NULL) return 1; @@ -400,7 +401,7 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { * Beware of the backslashes (\)! */ while (*miscptr != 0) { - if (strlen(miscptr) < 3 || miscptr[1] != '=') { + if (strlen(miscptr) < 2 || miscptr[1] != '=') { hydra_report(stderr, "[ERROR] optional parameters must have the format X=value: %s\n", miscptr); return 0; } @@ -438,6 +439,31 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { sprintf(cookieurl, "%.1000s", hydra_strrep(miscptr + 2, "\\:", ":")); miscptr = ptr; break; + case '1': + code_401_is_failure = 1; + tmp = strchr(miscptr, ':'); + if (tmp) + miscptr = tmp + 1; + else + miscptr += strlen(miscptr); + break; + case '2': + code_302_is_success = 1; + 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': ptr = miscptr + 2; @@ -516,6 +542,97 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { return 1; } +char *build_multipart_body(char *multipart_boundary) { + if (!variables) + return NULL; + + char *body = NULL; + size_t body_size = 0; + + // Duplicate "variables" for tokenizing + char *vars_dup = strdup(variables); + if (!vars_dup) + return NULL; + + // Tokenize the string using '&' as a delimiter + char *pair = strtok(vars_dup, "&"); + while (pair != NULL) { + // Find the '=' separator in each pair + char *equal_sign = strchr(pair, '='); + if (!equal_sign) { + pair = strtok(NULL, "&"); + continue; + } + *equal_sign = '\0'; + char *key = pair; + char *value = equal_sign + 1; + + // Build the multipart section for the field + int section_len = snprintf(NULL, 0, + "--%s\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + multipart_boundary, key, value); + + char *section = malloc(section_len + 1); + if (!section) { + free(body); + free(vars_dup); + return NULL; + } + snprintf(section, section_len + 1, + "--%s\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + multipart_boundary, key, value); + + // Reallocate the body buffer to add this section + size_t new_body_size = body_size + section_len; + char *new_body = realloc(body, new_body_size + 1); // +1 for null terminator + if (!new_body) { + free(section); + free(body); + free(vars_dup); + return NULL; + } + body = new_body; + if (body_size == 0) + strcpy(body, section); + else + strcat(body, section); + body_size = new_body_size; + free(section); + + pair = strtok(NULL, "&"); + } + free(vars_dup); + + // Append the closing boundary: ----\r\n + int closing_len = snprintf(NULL, 0, "--%s--\r\n", multipart_boundary); + char *closing = malloc(closing_len + 1); + if (!closing) { + free(body); + return NULL; + } + snprintf(closing, closing_len + 1, "--%s--\r\n", multipart_boundary); + + size_t final_size = body_size + closing_len; + char *final_body = realloc(body, final_size + 1); + if (!final_body) { + free(closing); + free(body); + return NULL; + } + body = final_body; + strcat(body, closing); + free(closing); + + return body; +} + + char *prepare_http_request(char *type, char *path, char *params, char *headers) { uint32_t reqlen = 0; char *http_request = NULL; @@ -572,17 +689,17 @@ char *html_encode(char *string) { if (ret == NULL) return NULL; - if (index(ret, '%') != NULL) + if (strchr(ret, '%') != NULL) ret = hydra_strrep(ret, "%", "%25"); - if (index(ret, ' ') != NULL) + if (strchr(ret, ' ') != NULL) ret = hydra_strrep(ret, " ", "%20"); - if (index(ret, '&') != NULL) + if (strchr(ret, '&') != NULL) ret = hydra_strrep(ret, "&", "%26"); - if (index(ret, '#') != NULL) + if (strchr(ret, '#') != NULL) ret = hydra_strrep(ret, "#", "%23"); - if (index(ret, '=') != NULL) + if (strchr(ret, '=') != NULL) ret = hydra_strrep(ret, "=", "%3D"); - if (index(ret, '+') != NULL) + if (strchr(ret, '+') != NULL) ret = hydra_strrep(ret, "+", "%2B"); return ret; @@ -646,17 +763,17 @@ int32_t analyze_server_response(int32_t s) { } else if (endcookie2 != NULL) *endcookie2 = 0; // is the cookie already there? if yes, remove it! - if (index(startcookie, '=') != NULL && (ptr = index(startcookie, '=')) - startcookie + 1 <= sizeof(tmpname)) { + if (strchr(startcookie, '=') != NULL && (ptr = strchr(startcookie, '=')) - startcookie + 1 <= sizeof(tmpname)) { strncpy(tmpname, startcookie, sizeof(tmpname) - 2); tmpname[sizeof(tmpname) - 2] = 0; - ptr = index(tmpname, '='); + ptr = strchr(tmpname, '='); *(++ptr) = 0; // is the cookie already in the cookiejar? (so, does it have to be // replaced?) if ((ptr = hydra_strcasestr(cookie, tmpname)) != NULL) { // yes it is. // if the cookie is not in the beginning of the cookiejar, copy the - // ones before + // ones before if (ptr != cookie && *(ptr - 1) == ' ') { strncpy(tmpcookie, cookie, ptr - cookie - 2); tmpcookie[ptr - cookie - 2] = 0; @@ -675,7 +792,7 @@ int32_t analyze_server_response(int32_t s) { strcpy(cookie, tmpcookie); } } - ptr = index(str, '='); + ptr = strchr(str, '='); // only copy the cookie if it has a value (otherwise the server wants to // delete the cookie) if (ptr != NULL && *(ptr + 1) != ';' && *(ptr + 1) != 0 && *(ptr + 1) != '\n' && *(ptr + 1) != '\r') { @@ -724,7 +841,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options char *http_request = NULL; int32_t found = !success_cond, i, j; char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; - + char content_type[256]; memset(header, 0, sizeof(header)); cookie[0] = 0; // reset cookies from potential previous attempt @@ -744,10 +861,23 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options clogin[sizeof(clogin) - 1] = 0; strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); cpass[sizeof(cpass) - 1] = 0; - upd3variables = hydra_strrep(variables, "^USER^", clogin); - upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); - upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login); - upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass); + + if (multipart_mode) { + snprintf(content_type, sizeof(content_type), "multipart/form-data; boundary=----THC-HydraBoundaryz2Z2z"); + char *multipart_body = build_multipart_body("----THC-HydraBoundaryz2Z2z"); + upd3variables = multipart_body; + +}else{ + snprintf(content_type, sizeof(content_type), "application/x-www-form-urlencoded"); + upd3variables = variables; +} + + upd3variables = hydra_strrep(upd3variables, "^USER^", clogin); + upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); + upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login); + upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass); + + // Replace the user/pass placeholders in the user-supplied headers hdrrep(&ptr_head, "^USER^", clogin); @@ -759,7 +889,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 (getcookie) { memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); @@ -773,14 +903,14 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options // now prepare for the "real" request if (strcmp(type, "POST") == 0) { memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", content_length); else add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); if (cookie_header != NULL) free(cookie_header); cookie_header = stringify_cookies(ptr_cookie); @@ -794,8 +924,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); return 1; + } } else { if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -812,8 +944,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); return 1; + } } } else { if (use_proxy == 1) { @@ -821,7 +955,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (getcookie) { // doing a GET to get cookies memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); @@ -835,14 +969,14 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options // now prepare for the "real" request if (strcmp(type, "POST") == 0) { memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", content_length); else add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); if (cookie_header != NULL) free(cookie_header); cookie_header = stringify_cookies(ptr_cookie); @@ -856,8 +990,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); return 1; + } } else { if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -874,8 +1010,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); return 1; + } } } else { // direct web server, no proxy @@ -905,7 +1043,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options else add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); if (cookie_header != NULL) free(cookie_header); cookie_header = stringify_cookies(ptr_cookie); @@ -919,8 +1057,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("POST", url, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); return 1; + } } else { if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -937,8 +1077,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("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; + } } } } @@ -948,12 +1090,21 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options found = analyze_server_response(s); - if (auth_flag) { // we received a 401 error - user is using wrong module - hydra_report(stderr, - "[ERROR] the target is using HTTP auth, not a web form, received HTTP " - "error code 401. Use module \"http%s-get\" instead.\n", - (options & OPTION_SSL) > 0 ? "s" : ""); - return 4; + if (redirected_flag && code_302_is_success) { + 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, + "[ERROR] received HTTP error code 401. The target may be using HTTP auth, " + "not a web form. Use module \"http%s-get\" instead, or set \"1=\".\n", + (options & OPTION_SSL) > 0 ? "s" : ""); + return 2; + } } if (strlen(cookie) > 0) @@ -964,12 +1115,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (debug) printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); - while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { + while (found == 0 && redirected_flag && !code_302_is_success && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { // we have to split the location char *startloc, *endloc; - char str[2048]; - char str2[2048]; - char str3[2048]; + char str[2048], str2[2048], str3[2048], str4[2048]; redirected_cpt--; redirected_flag = 0; @@ -988,19 +1137,21 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options startloc += strlen("://"); if ((endloc = strchr(startloc, '\r')) != NULL) { - startloc[endloc - startloc] = 0; + *endloc = 0; } if ((endloc = strchr(startloc, '\n')) != NULL) { - startloc[endloc - startloc] = 0; + *endloc = 0; } - strcpy(str, startloc); + strncpy(str, startloc, sizeof(str) - 1); + str[sizeof(str) - 1] = 0; endloc = strchr(str, '/'); if (endloc != NULL) { strncpy(str2, str, endloc - str); str2[endloc - str] = 0; - } else - strncpy(str2, str, sizeof(str)); + } else { + strcpy(str2, str); + } if (strlen(str) - strlen(str2) == 0) { strcpy(str3, "/"); @@ -1009,7 +1160,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options str3[strlen(str) - strlen(str2)] = 0; } } else { - strncpy(str2, webtarget, sizeof(str2)); + strncpy(str2, webtarget, sizeof(str2) - 1); + str2[sizeof(str2) - 1] = 0; if (redirected_url_buff[0] != '/') { // it's a relative path, so we have to concatenate it // with the path from the first url given @@ -1025,8 +1177,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options } else { sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff); } - } else - strncpy(str3, redirected_url_buff, sizeof(str3)); + } else { + strncpy(str3, redirected_url_buff, sizeof(str3) - 1); + str3[sizeof(str3) - 1] = 0; + } if (debug) hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url); } @@ -1038,12 +1192,13 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options str3[0] = '/'; } - if (strrchr(url, ':') == NULL && port != 80) { - sprintf(str2, "%.2040s:%d", str2, port); + if (strrchr(str2, ':') == NULL && (port != 80 || port != 443)) { + sprintf(str4, "%.2000s:%d", str2, port); + strcpy(str2, str4); } if (verbose) - hydra_report(stderr, "[VERBOSE] Page redirected to http://%s%s\n", str2, str3); + hydra_report(stderr, "[VERBOSE] Page redirected to http[s]://%s%s\n", str2, str3); if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -1062,7 +1217,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options // proxy with authentication hdrrepv(&ptr_head, "Host", str2); memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); if (normal_request != NULL) free(normal_request); normal_request = stringify_headers(&ptr_head); @@ -1074,7 +1229,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options // proxy without authentication hdrrepv(&ptr_head, "Host", str2); memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); if (normal_request != NULL) free(normal_request); normal_request = stringify_headers(&ptr_head); @@ -1095,8 +1250,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options hydra_reconnect(s, ip, port, options, hostname); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); return 1; + } found = analyze_server_response(s); if (strlen(cookie) > 0) @@ -1105,7 +1262,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 (found != -1 && found == success_cond && (redirected_flag == 0 || success_cond == 1) && redirected_cpt >= 0) { + if (found != -1 && found == success_cond && ((redirected_flag && code_302_is_success) || redirected_flag == 0 || success_cond == 1) && redirected_cpt >= 0) { hydra_report_found_host(port, ip, "www-form", fp); hydra_completed_pair_found(); } else { @@ -1270,8 +1427,7 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) { ptr = ptr2 = NULL; sprintf(bufferurl, "%.6096s", miscptr); - url = bufferurl; - ptr = url; + ptr = url = bufferurl; while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) ptr++; @@ -1284,39 +1440,41 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) { if (*ptr != 0) *ptr++ = 0; - cond = ptr; + optional1 = cond = ptr; - if ((ptr2 = index(ptr, ':')) != NULL) { + ptr2 = ptr + strlen(ptr); + + while (ptr2 > ptr && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2--; + + if (*ptr2 == ':') { *ptr2++ = 0; - if (*ptr2) - optional1 = ptr2; - else - optional1 = NULL; - } else + cond = ptr2; + } + + if (optional1 == cond) optional1 = NULL; if (strstr(url, "\\:") != NULL) { - if ((ptr = malloc(strlen(url))) != NULL) { + if ((ptr = malloc(strlen(url) + 1)) != NULL) { strcpy(ptr, hydra_strrep(url, "\\:", ":")); url = ptr; } } if (strstr(variables, "\\:") != NULL) { - if ((ptr = malloc(strlen(variables))) != NULL) { + if ((ptr = malloc(strlen(variables) + 1)) != NULL) { strcpy(ptr, hydra_strrep(variables, "\\:", ":")); variables = ptr; } } if (strstr(cond, "\\:") != NULL) { - if ((ptr = malloc(strlen(cond))) != NULL) { + if ((ptr = malloc(strlen(cond) + 1)) != NULL) { strcpy(ptr, hydra_strrep(cond, "\\:", ":")); 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 */) hydra_child_exit(2); @@ -1340,8 +1498,7 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) { 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. @@ -1414,27 +1571,29 @@ void usage_http_form(const char *service) { "redirections in\n" "a row. It always gathers a new cookie from the same URL without " "variables\n" - "The parameters take three \":\" separated values, plus optional " - "values.\n" + "The parameters requires at a minimum three \":\" separated values,\n" + "plus optional values.\n" "(Note: if you need a colon in the option string as value, escape it " "with \"\\:\", but do not escape a \"\\\" with \"\\\\\".)\n" - "\nSyntax: :
:[:[:]\n" - "First is the page on the server to GET or POST to (URL).\n" - "Second is the POST/GET variables (taken from either the browser, proxy, " - "etc.\n" - " with url-encoded (resp. base64-encoded) usernames and passwords being " - "replaced in the\n" - " \"^USER^\" (resp. \"^USER64^\") and \"^PASS^\" (resp. \"^PASS64^\") " - "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" + "\nSyntax: :[:[:]:\n" + "\nFirst is the page on the server to GET or POST to (URL), e.g. \"/login\".\n" + "Second is the POST/GET variables (taken from either the browser, proxy, etc.)\n" + " without the initial '?' character and the usernames and passwords being\n" + " replaced with \"^USER^\" (\"^USER64^\" for base64 encodings) and \"^PASS^\"\n" + " (\"^PASS64^\" for base64 encodings).\n" + "Third are optional parameters (see below)\n" + "Last 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" - " This is where most people get it wrong. You have to check the webapp " - "what a\n" - " failed string looks like and put it in this parameter!\n" - "The following parameters are optional:\n" + " This is where most people get it wrong! You have to check the webapp what a\n" + " failed string looks like and put it in this parameter! Add the -d switch to see\n" + " the sent/received data!\n" + " Note that using invalid login condition checks can result in false positives!\n" + "\nThe following parameters are optional and are put between the form parameters\n" + "and the condition string; seperate them too with colons:\n" + " 1= 401 error response is interpreted as user/pass wrong\n" + " 2= 302 page forward return codes identify a successful attempt\n" + " M= attack forms that use multipart format\n" " (c|C)=/page/uri to define a different page to gather initial " "cookies from\n" " (g|G)= skip pre-requests - only use this when no pre-cookies are required\n" @@ -1448,25 +1607,29 @@ void usage_http_form(const char *service) { "exists, by the\n" " one supplied by the user, or add the header at the " "end\n" - "Note that if you are going to put colons (:) in your headers you should " - "escape them with a backslash (\\).\n" - " All colons that are not option separators should be escaped (see the " - "examples above and below).\n" - " You can specify a header without escaping the colons, but that way you " - "will not be able to put colons\n" - " in the header value itself, as they will be interpreted by hydra as " - "option separators.\n" + "\nNote that if you are going to put colons (:) in your headers you should escape\n" + "them with a backslash (\\). All colons that are not option separators should be\n" + "escaped (see the examples above and below).\n" + "You can specify a header without escaping the colons, but that way you will not\n" + "be able to put colons in the header value itself, as they will be interpreted by\n" + "hydra as option separators.\n" "\nExamples:\n" " \"/login.php:user=^USER^&pass=^PASS^:incorrect\"\n" " \"/" - "login.php:user=^USER64^&pass=^PASS64^&colon=colon\\:escape:S=authlog=.*" + "login.php:user=^USER64^&pass=^PASS64^&colon=colon\\:escape:S=result=" "success\"\n" " \"/login.php:user=^USER^&pass=^PASS^&mid=123:authlog=.*failed\"\n" - " \"/:user=^USER&pass=^PASS^:failed:H=Authorization\\: Basic " + " \"/:user=^USER&pass=^PASS^:H=Authorization\\: Basic " "dT1w:H=Cookie\\: sessid=aaaa:h=X-User\\: ^USER^:H=User-Agent\\: wget\"\n" - " \"/exchweb/bin/auth/" + " \"/exchweb/bin/auth/:F=failed" "owaauth.dll:destination=http%%3A%%2F%%2F%%2Fexchange&flags=0&" "username=%%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:" - "reason=:C=/exchweb\"\n", + "C=/exchweb\":reason=\n" + "To attack multiple targets, you can use the -M option with a file " + "containing the targets and their parameters.\n" + "Example file content:\n" + " localhost:8443/login:type=login&login=^USER^&password=^PASS^:h=test\\: header:F=401\n" + " localhost:9443/login2:type=login&login=^USER^&password=^PASS^:h=test\\: header:F=302\n" + " ...\n\n", service); } diff --git a/hydra-http-proxy-urlenum.c b/hydra-http-proxy-urlenum.c index 434b4e4..306d755 100644 --- a/hydra-http-proxy-urlenum.c +++ b/hydra-http-proxy-urlenum.c @@ -28,17 +28,17 @@ int32_t start_http_proxy_urlenum(int32_t s, char *ip, int32_t port, unsigned cha ptr++; strncpy(mhost, ptr, sizeof(mhost) - 1); mhost[sizeof(mhost) - 1] = 0; - if ((ptr = index(mhost, '/')) != NULL) + if ((ptr = strchr(mhost, '/')) != NULL) *ptr = 0; - if ((ptr = index(mhost, ']')) != NULL) + if ((ptr = strchr(mhost, ']')) != NULL) *ptr = 0; - else if ((ptr = index(mhost, ':')) != NULL) + else if ((ptr = strchr(mhost, ':')) != NULL) *ptr = 0; - if (miscptr != NULL && index(miscptr, ':') != NULL) { + if (miscptr != NULL && strchr(miscptr, ':') != NULL) { strncpy(mlogin, miscptr, sizeof(mlogin) - 1); mlogin[sizeof(mlogin) - 1] = 0; - ptr = index(mlogin, ':'); + ptr = strchr(mlogin, ':'); *ptr++ = 0; strncpy(mpass, ptr, sizeof(mpass) - 1); mpass[sizeof(mpass) - 1] = 0; @@ -215,7 +215,7 @@ int32_t start_http_proxy_urlenum(int32_t s, char *ip, int32_t port, unsigned cha } } // result analysis - ptr = ((char *)index(buf, ' ')) + 1; + ptr = ((char *)strchr(buf, ' ')) + 1; if (*ptr == '2' || (*ptr == '3' && (*(ptr + 2) == '1' || *(ptr + 2) == '2')) || strncmp(ptr, "404", 4) == 0 || strncmp(ptr, "403", 4) == 0) { hydra_report_found_host(port, ip, "http-proxy", fp); if (fp != stdout) diff --git a/hydra-http-proxy.c b/hydra-http-proxy.c index 3a97da9..3aeeb41 100644 --- a/hydra-http-proxy.c +++ b/hydra-http-proxy.c @@ -24,9 +24,9 @@ int32_t start_http_proxy(int32_t s, char *ip, int32_t port, unsigned char option sprintf(url, "%.500s", miscptr); ptr = strstr(miscptr, "://"); // :// check is in hydra.c sprintf(host, "Host: %.50s", ptr + 3); - if ((ptr = index(host, '/')) != NULL) + if ((ptr = strchr(host, '/')) != NULL) *ptr = 0; - if ((ptr = index(host + 6, ':')) != NULL && host[0] != '[') + if ((ptr = strchr(host + 6, ':')) != NULL && host[0] != '[') *ptr = 0; strcat(host, "\r\n"); } @@ -185,7 +185,7 @@ int32_t start_http_proxy(int32_t s, char *ip, int32_t port, unsigned char option char *pbuffer, *result; http_proxy_auth_mechanism = AUTH_DIGESTMD5; - auth_hdr == NULL; + auth_hdr = NULL; pbuffer = hydra_strcasestr(http_proxy_buf, "Proxy-Authenticate: Digest "); strncpy(buffer, pbuffer + strlen("Proxy-Authenticate: Digest "), sizeof(buffer)); buffer[sizeof(buffer) - 1] = '\0'; @@ -232,7 +232,7 @@ int32_t start_http_proxy(int32_t s, char *ip, int32_t port, unsigned char option } } - ptr = ((char *)index(http_proxy_buf, ' ')) + 1; + ptr = ((char *)strchr(http_proxy_buf, ' ')) + 1; if (*ptr == '2' || (*ptr == '3' && *(ptr + 2) == '1') || (*ptr == '3' && *(ptr + 2) == '2') || (*ptr == '4' && *(ptr + 2) == '4')) { hydra_report_found_host(port, ip, "http-proxy", fp); hydra_completed_pair_found(); @@ -240,7 +240,7 @@ int32_t start_http_proxy(int32_t s, char *ip, int32_t port, unsigned char option http_proxy_buf = NULL; } else { if (*ptr != '4') - hydra_report(stderr, "[INFO] Unusual return code: %c for %s:%s\n", (char)*(index(http_proxy_buf, ' ') + 1), login, pass); + hydra_report(stderr, "[INFO] Unusual return code: %c for %s:%s\n", (char)*(strchr(http_proxy_buf, ' ') + 1), login, pass); else if (verbose && *(ptr + 2) == '3') hydra_report(stderr, "[INFO] Potential success, could be false positive: %s:%s\n", login, pass); hydra_completed_pair(); diff --git a/hydra-http.c b/hydra-http.c old mode 100644 new mode 100755 index 7f1d56d..e78f865 --- a/hydra-http.c +++ b/hydra-http.c @@ -52,17 +52,17 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha /* again: no snprintf to be portable. don't worry, buffer can't overflow */ if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) sprintf(buffer, - "%s http://%s:%d%.250s HTTP/1.1\r\nHost: %s\r\nConnection: " + "%s http://%s%.250s HTTP/1.1\r\nHost: %s\r\nConnection: " "close\r\nAuthorization: Basic %s\r\nProxy-Authorization: Basic " "%s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", - type, webtarget, webport, miscptr, webtarget, buffer2, proxy_authentication[selected_proxy], header); + type, webtarget, miscptr, webtarget, buffer2, proxy_authentication[selected_proxy], header); else { if (use_proxy == 1) sprintf(buffer, - "%s http://%s:%d%.250s HTTP/1.1\r\nHost: %s\r\nConnection: " + "%s http://%s%.250s HTTP/1.1\r\nHost: %s\r\nConnection: " "close\r\nAuthorization: Basic %s\r\nUser-Agent: Mozilla/4.0 " "(Hydra)\r\n%s\r\n", - type, webtarget, webport, miscptr, webtarget, buffer2, header); + type, webtarget, miscptr, webtarget, buffer2, header); else sprintf(buffer, "%s %.250s HTTP/1.1\r\nHost: %s\r\nConnection: " @@ -110,16 +110,16 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha // send the first.. if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) sprintf(buffer, - "%s http://%s:%d%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " + "%s http://%s%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " "%s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 " "(Hydra)\r\n%s\r\n", - type, webtarget, webport, miscptr, webtarget, buf1, proxy_authentication[selected_proxy], header); + type, webtarget, miscptr, webtarget, buf1, proxy_authentication[selected_proxy], header); else { if (use_proxy == 1) sprintf(buffer, - "%s http://%s:%d%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " + "%s http://%s%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " "%s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", - type, webtarget, webport, miscptr, webtarget, buf1, header); + type, webtarget, miscptr, webtarget, buf1, header); else sprintf(buffer, "%s %s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " @@ -174,16 +174,16 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha // create the auth response if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) sprintf(buffer, - "%s http://%s:%d%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " + "%s http://%s%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " "%s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 " "(Hydra)\r\n%s\r\n", - type, webtarget, webport, miscptr, webtarget, buf1, proxy_authentication[selected_proxy], header); + type, webtarget, miscptr, webtarget, buf1, proxy_authentication[selected_proxy], header); else { if (use_proxy == 1) sprintf(buffer, - "%s http://%s:%d%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " + "%s http://%s%s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " "%s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", - type, webtarget, webport, miscptr, webtarget, buf1, header); + type, webtarget, miscptr, webtarget, buf1, header); else sprintf(buffer, "%s %s HTTP/1.1\r\nHost: %s\r\nAuthorization: NTLM " @@ -208,7 +208,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha complete_line = 0; tmpreplybuf[0] = 0; - while (http_buf != NULL && (strstr(http_buf, "HTTP/1.") == NULL || (index(http_buf, '\n') == NULL && complete_line == 0))) { + while (http_buf != NULL && (strstr(http_buf, "HTTP/1.") == NULL || (strchr(http_buf, '\n') == NULL && complete_line == 0))) { if (debug) printf("il: %d, tmpreplybuf: %s, http_buf: %s\n", complete_line, tmpreplybuf, http_buf); if (tmpreplybuf[0] == 0 && strstr(http_buf, "HTTP/1.") != NULL) { @@ -245,7 +245,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha if (debug) hydra_report(stderr, "S:%s\n", http_buf); - ptr = ((char *)index(http_buf, ' ')); + ptr = ((char *)strchr(http_buf, ' ')); if (ptr != NULL) ptr++; if (ptr != NULL && (*ptr == '2' || *ptr == '3' || strncmp(ptr, "403", 3) == 0 || strncmp(ptr, "404", 3) == 0)) { @@ -451,7 +451,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis start--; memset(start, '\0', condition_len); if (debug) - hydra_report(stderr, "Modificated options:%s\n", miscptr); + hydra_report(stderr, "Modified options:%s\n", miscptr); } else { if (debug) hydra_report(stderr, "Condition not found\n"); @@ -474,6 +474,12 @@ void usage_http(const char *service) { " combination is invalid. Note: this must be the last option " "supplied.\n" "For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: " - "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n", + "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n" + "To attack multiple targets, you can use the -M option with a file " + "containing the targets and their parameters.\n" + "Example file content:\n" + " localhost:5000/protected:A=BASIC\n" + " localhost:5002/protected_path:A=NTLM\n" + " ...\n\n", service); } diff --git a/hydra-memcached.c b/hydra-memcached.c index ca21d26..5a7c112 100644 --- a/hydra-memcached.c +++ b/hydra-memcached.c @@ -13,6 +13,7 @@ void dummy_mcached() { printf("\n"); } extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); +extern hydra_option hydra_options; extern char *HYDRA_EXIT; int mcached_send_com_quit(int32_t sock) { @@ -117,6 +118,8 @@ void service_mcached(char *ip, int32_t sp, unsigned char options, char *miscptr, switch (run) { case 1: next_run = start_mcached(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 2: hydra_child_exit(0); diff --git a/hydra-mod.c b/hydra-mod.c index 65f7725..c988c1d 100644 --- a/hydra-mod.c +++ b/hydra-mod.c @@ -7,7 +7,8 @@ #include #endif #ifdef HAVE_PCRE -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #endif #define MAX_CONNECT_RETRY 1 @@ -295,13 +296,13 @@ int32_t internal__hydra_connect(char *host, int32_t port, int32_t type, int32_t send(s, buf, strlen(buf), 0); if (debug) { - char *ptr = index(buf, '\r'); + char *ptr = strchr(buf, '\r'); if (ptr != NULL) *ptr = 0; printf("DEBUG_CONNECT_PROXY_SENT: %s\n", buf); } recv(s, buf, 4096, 0); - if (strncmp("HTTP/", buf, 5) == 0 && (tmpptr = index(buf, ' ')) != NULL && *++tmpptr == '2') { + if (strncmp("HTTP/", buf, 5) == 0 && (tmpptr = strchr(buf, ' ')) != NULL && *++tmpptr == '2') { if (debug) printf("DEBUG_CONNECT_PROXY_OK\n"); } else { @@ -637,9 +638,11 @@ void hydra_child_exit(int32_t code) { __fck = write(intern_socket, "C", 1); else if (code == 2) /* application protocol error or service shutdown */ __fck = write(intern_socket, "E", 1); - // code 3 means exit without telling mommy about it - a bad idea. mommy should + else if (code == 3) /* application protocol error or service shutdown */ + __fck = write(intern_socket, "D", 1); + // code 4 means exit without telling mommy about it - a bad idea. mommy should // know - else if (code == -1 || code > 3) { + else if (code == -1 || code > 4) { fprintf(stderr, "[TOTAL FUCKUP] a module should not use " "hydra_child_exit(-1) ! Fix it in the source please ...\n"); __fck = write(intern_socket, "E", 1); @@ -659,10 +662,10 @@ char *hydra_get_next_pair() { pair[sizeof(pair) - 1] = 0; __fck = read(intern_socket, pair, sizeof(pair) - 1); // if (debug) hydra_dump_data(pair, __fck, "CHILD READ PAIR"); - if (memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0) - return HYDRA_EXIT; - if (pair[0] == 0) + if (pair[0] == 0 || __fck <= 0) return HYDRA_EMPTY; + if (__fck >= sizeof(HYDRA_EXIT) && memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0) + return HYDRA_EXIT; } return pair; } @@ -1289,19 +1292,23 @@ void hydra_set_srcport(int32_t port) { src_port = port; } #ifdef HAVE_PCRE int32_t hydra_string_match(char *str, const char *regex) { - pcre *re = NULL; - int32_t offset_error = 0; - const char *error = NULL; + pcre2_code *re = NULL; + int32_t error_code = 0; + PCRE2_SIZE error_offset; int32_t rc = 0; - re = pcre_compile(regex, PCRE_CASELESS | PCRE_DOTALL, &error, &offset_error, NULL); + re = pcre2_compile(regex, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS | PCRE2_DOTALL, &error_code, &error_offset, NULL); if (re == NULL) { - fprintf(stderr, "[ERROR] PCRE compilation failed at offset %d: %s\n", offset_error, error); + fprintf(stderr, "[ERROR] PCRE compilation failed at offset %d: %d\n", error_offset, error_code); return 0; } - rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, NULL, 0); - if (rc >= 0) { + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL); + rc = pcre2_match(re, str, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); + pcre2_match_data_free(match_data); + pcre2_code_free(re); + + if (rc >= 1) { return 1; } return 0; diff --git a/hydra-mod.h b/hydra-mod.h index cb9c342..f0c22c4 100644 --- a/hydra-mod.h +++ b/hydra-mod.h @@ -67,7 +67,16 @@ char proxy_string_type[MAX_PROXY_COUNT][10]; char *proxy_authentication[MAX_PROXY_COUNT]; char *cmdlinetarget; +#ifndef __APPLE__ typedef int32_t BOOL; +#else /* __APPLE__ */ +/* ensure compatibility with objc libraries */ +#if (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH +typedef bool BOOL; +#else +typedef signed char BOOL; +#endif +#endif /* __APPLE__ */ #define hydra_report fprintf diff --git a/hydra-mongodb.c b/hydra-mongodb.c index 5b38a42..66269be 100644 --- a/hydra-mongodb.c +++ b/hydra-mongodb.c @@ -14,6 +14,7 @@ void dummy_mongodb() { printf("\n"); } extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); +extern hydra_option hydra_options; extern char *HYDRA_EXIT; char *buf; @@ -72,10 +73,17 @@ int32_t start_mongodb(int32_t s, char *ip, int32_t port, unsigned char options, mongoc_log_set_handler(NULL, NULL); bson_init(&q); - snprintf(uri, sizeof(uri), "mongodb://%s:%s@%s/?authSource=%s", login, pass, hydra_address2string(ip), miscptr); + 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); + } + client = mongoc_client_new(uri); - if (!client) + if (!client) { + hydra_completed_pair_skip(); return 3; + } mongoc_client_set_appname(client, "hydra"); collection = mongoc_client_get_collection(client, miscptr, "test"); @@ -90,11 +98,11 @@ int32_t start_mongodb(int32_t s, char *ip, int32_t port, unsigned char options, mongoc_collection_destroy(collection); mongoc_client_destroy(client); mongoc_cleanup(); - hydra_completed_pair_skip(); + hydra_completed_pair(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { return 3; } - return 2; + return 1; } } @@ -129,6 +137,8 @@ void service_mongodb(char *ip, int32_t sp, unsigned char options, char *miscptr, switch (run) { case 1: next_run = start_mongodb(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 2: hydra_child_exit(0); diff --git a/hydra-mssql.c b/hydra-mssql.c index ee273ca..1133641 100644 --- a/hydra-mssql.c +++ b/hydra-mssql.c @@ -1,10 +1,14 @@ #include "hydra-mod.h" - -#define MSLEN 30 - extern char *HYDRA_EXIT; char *buf; +#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB) +#include +#include +#endif + +#define MSLEN 30 + unsigned char p_hdr[] = "\x02\x00\x02\x00\x00\x00\x02\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" @@ -56,6 +60,7 @@ unsigned char p_lng[] = "\x02\x01\x00\x47\x00\x00\x02\x00\x00\x00\x00" int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { char *empty = ""; char *login, *pass, buffer[1024]; + char *ipaddr_str = hydra_address2string(ip); char ms_login[MSLEN + 1]; char ms_pass[MSLEN + 1]; unsigned char len_login, len_pass; @@ -65,6 +70,42 @@ int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, ch login = empty; if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; +#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB) + if ((strlen(login) > MSLEN) || (strlen(pass) > MSLEN)){ + + DBPROCESS *dbproc; + LOGINREC *attempt; + + attempt = dblogin(); + + DBSETLUSER(attempt, login); + DBSETLPWD(attempt, pass); + + // Connect without specifying a database + dbproc = dbopen(attempt, ipaddr_str); + + if (dbproc != NULL) { + dbclose(dbproc); + dbexit(); + hydra_report_found_host(port, ip, "mssql", fp); + hydra_completed_pair_found(); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 2; + return 1; + } + + hydra_completed_pair(); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 2; + + return 1; + + } +#else + if ((strlen(login) > MSLEN) || (strlen(pass) > MSLEN)){ + fprintf(stderr,"[WARNING] To crack credentials longer than 30 characters, install freetds and recompile\n"); + } +#endif if (strlen(login) > MSLEN) login[MSLEN - 1] = 0; if (strlen(pass) > MSLEN) @@ -119,6 +160,10 @@ void service_mssql(char *ip, int32_t sp, unsigned char options, char *miscptr, F int32_t run = 1, next_run = 1, sock = -1; int32_t myport = PORT_MSSQL, mysslport = PORT_MSSQL_SSL; + #if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB) + dbinit(); + #endif + hydra_register_socket(sp); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return; diff --git a/hydra-mysql.c b/hydra-mysql.c index eae5fd9..01a258e 100644 --- a/hydra-mysql.c +++ b/hydra-mysql.c @@ -35,6 +35,7 @@ char *hydra_scramble(char *to, const char *message, const char *password); extern int32_t internal__hydra_recv(int32_t socket, char *buf, int32_t length); extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); +extern hydra_option hydra_options; extern char *HYDRA_EXIT; char mysqlsalt[9]; @@ -332,6 +333,8 @@ void service_mysql(char *ip, int32_t sp, unsigned char options, char *miscptr, F break; case 2: /* run the cracking function */ next_run = start_mysql(sock, ip, port, options, miscptr, fp); + if ((next_run == 1 || next_run == 2) && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) { diff --git a/hydra-oracle-listener.c b/hydra-oracle-listener.c index e6b77ec..563670b 100644 --- a/hydra-oracle-listener.c +++ b/hydra-oracle-listener.c @@ -19,6 +19,7 @@ void dummy_oracle_listener() { printf("\n"); } #include #define HASHSIZE 17 +extern hydra_option hydra_options; extern char *HYDRA_EXIT; char *buf; unsigned char *hash; @@ -304,6 +305,8 @@ void service_oracle_listener(char *ip, int32_t sp, unsigned char options, char * } /* run the cracking function */ next_run = start_oracle_listener(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) diff --git a/hydra-oracle-sid.c b/hydra-oracle-sid.c index c2db73a..32ac557 100644 --- a/hydra-oracle-sid.c +++ b/hydra-oracle-sid.c @@ -16,6 +16,7 @@ void dummy_oracle_sid() { printf("\n"); } #include #define HASHSIZE 16 +extern hydra_option hydra_options; extern char *HYDRA_EXIT; char *buf; unsigned char *hash; @@ -113,6 +114,8 @@ void service_oracle_sid(char *ip, int32_t sp, unsigned char options, char *miscp } /* run the cracking function */ next_run = start_oracle_sid(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) diff --git a/hydra-oracle.c b/hydra-oracle.c index 46deb44..2ae18de 100644 --- a/hydra-oracle.c +++ b/hydra-oracle.c @@ -21,6 +21,7 @@ void dummy_oracle() { printf("\n"); } #include #include +extern hydra_option hydra_options; extern char *HYDRA_EXIT; OCIEnv *o_environment; @@ -165,6 +166,8 @@ void service_oracle(char *ip, int32_t sp, unsigned char options, char *miscptr, break; case 2: next_run = start_oracle(sock, ip, port, options, miscptr, fp); + if ((next_run == 1 || next_run == 2) && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) diff --git a/hydra-pop3.c b/hydra-pop3.c index acd6c2e..3671a95 100644 --- a/hydra-pop3.c +++ b/hydra-pop3.c @@ -109,7 +109,7 @@ char *pop3_read_server_capacity(int32_t sock) { buf[strlen(buf) - 1] = 0; if (buf[strlen(buf) - 1] == '\r') buf[strlen(buf) - 1] = 0; - if (*(ptr) == '.' || *(ptr) == '-') + if (buf[strlen(buf) - 1] == '.' || *(ptr) == '.' || *(ptr) == '-') resp = 1; } } diff --git a/hydra-postgres.c b/hydra-postgres.c index 7f958f7..3b2cac9 100644 --- a/hydra-postgres.c +++ b/hydra-postgres.c @@ -16,6 +16,7 @@ void dummy_postgres() { printf("\n"); } #define DEFAULT_DB "template1" +extern hydra_option hydra_options; extern char *HYDRA_EXIT; int32_t start_postgres(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { @@ -40,7 +41,7 @@ int32_t start_postgres(int32_t s, char *ip, int32_t port, unsigned char options, * Building the connection string */ - snprintf(connection_string, sizeof(connection_string), "host = '%s' dbname = '%s' user = '%s' password = '%s' ", hydra_address2string(ip), database, login, pass); + snprintf(connection_string, sizeof(connection_string), "host = '%s' port = '%d' dbname = '%s' user = '%s' password = '%s' ", hydra_address2string(ip), port, database, login, pass); if (verbose) hydra_report(stderr, "connection string: %s\n", connection_string); @@ -99,6 +100,8 @@ void service_postgres(char *ip, int32_t sp, unsigned char options, char *miscptr * Here we start the password cracking process */ next_run = start_postgres(sock, ip, port, options, miscptr, fp); + if ((next_run == 2 || next_run == 1) && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: if (sock >= 0) diff --git a/hydra-radmin2.c b/hydra-radmin2.c index 8c417d3..bc6b461 100644 --- a/hydra-radmin2.c +++ b/hydra-radmin2.c @@ -366,6 +366,7 @@ 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_child_exit(2); } + free(msg); } #endif } diff --git a/hydra-rdp.c b/hydra-rdp.c index 6a000a4..0b3c690 100644 --- a/hydra-rdp.c +++ b/hydra-rdp.c @@ -9,23 +9,37 @@ #include "hydra-mod.h" +extern hydra_option hydra_options; extern char *HYDRA_EXIT; #ifndef LIBFREERDP void dummy_rdp() { printf("\n"); } #else #include +#include freerdp *instance = 0; BOOL rdp_connect(char *server, int32_t port, char *domain, char *login, char *password) { int32_t err = 0; - instance->settings->Username = login; - instance->settings->Password = password; - instance->settings->IgnoreCertificate = TRUE; - instance->settings->AuthenticationOnly = TRUE; - instance->settings->ServerHostname = server; - instance->settings->ServerPort = port; - instance->settings->Domain = domain; + rdpSettings* settings = instance->context->settings; + + settings->Username = login; + settings->Password = password; + settings->IgnoreCertificate = TRUE; + if (password[0] == 0) + settings->AuthenticationOnly = FALSE; + else + settings->AuthenticationOnly = TRUE; + settings->ServerHostname = server; + settings->ServerPort = port; + settings->Domain = domain; + +#if FREERDP_VERSION_MAJOR == 2 + settings->MaxTimeInCheckLoop = 100; +#endif + // freerdp timeout format is microseconds -> default:15000 + settings->TcpConnectTimeout = hydra_options.waittime * 1000; + settings->TlsSecLevel = 0; freerdp_connect(instance); err = freerdp_get_last_error(instance->context); return err; @@ -54,6 +68,8 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr, } login_result = rdp_connect(server, port, domain, login, pass); + if (debug) + hydra_report(stderr, "[DEBUG] rdp reported %08x\n", login_result); switch (login_result) { case 0: // login success @@ -66,6 +82,10 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr, // login failure hydra_completed_pair(); break; + case 0x0002000f: + // login failure + hydra_completed_pair_skip(); + break; case 0x0002000d: hydra_report(stderr, "[%d][rdp] account on %s might be valid but account not " @@ -94,6 +114,7 @@ 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) { int32_t run = 1, next_run = 1; int32_t myport = PORT_RDP; + int32_t __first_rdp_connect = 1; if (port != 0) myport = port; @@ -105,7 +126,13 @@ void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL next_run = 0; switch (run) { 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); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 2: /* clean exit */ freerdp_disconnect(instance); diff --git a/hydra-redis.c b/hydra-redis.c index 179007c..5a81cec 100644 --- a/hydra-redis.c +++ b/hydra-redis.c @@ -24,6 +24,11 @@ int32_t start_redis(int32_t s, char *ip, int32_t port, unsigned char options, ch return 1; } buf = hydra_receive_line(s); + if (buf == NULL) { + hydra_report(stderr, "[ERROR] Failed to receive response from Redis server.\n"); + return 3; + } + if (buf[0] == '+') { hydra_report_found_host(port, ip, "redis", fp); hydra_completed_pair_found(); diff --git a/hydra-rtsp.c b/hydra-rtsp.c index 1bc6f4d..5526f9b 100644 --- a/hydra-rtsp.c +++ b/hydra-rtsp.c @@ -6,6 +6,10 @@ // // +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include "hydra-mod.h" #include "sasl.h" #include @@ -16,7 +20,7 @@ char packet[500]; char packet2[500]; int32_t is_Unauthorized(char *s) { - if (strstr(s, "401 Unauthorized") != NULL) { + if (strcasestr(s, "401 Unauthorized") != NULL) { return 1; } else { return 0; @@ -24,7 +28,7 @@ int32_t is_Unauthorized(char *s) { } int32_t is_NotFound(char *s) { - if (strstr(s, "404 Stream Not Found") != NULL) { + if (strcasestr(s, "404 Stream") != NULL || strcasestr(s, "404 Not") != NULL) { return 1; } else { return 0; @@ -32,7 +36,7 @@ int32_t is_NotFound(char *s) { } int32_t is_Authorized(char *s) { - if (strstr(s, "200 OK") != NULL) { + if (strcasestr(s, "200 OK") != NULL) { return 1; } else { return 0; @@ -40,7 +44,7 @@ int32_t is_Authorized(char *s) { } int32_t use_Basic_Auth(char *s) { - if (strstr(s, "WWW-Authenticate: Basic") != NULL) { + if (strcasestr(s, "WWW-Authenticate: Basic") != NULL) { return 1; } else { return 0; @@ -48,7 +52,7 @@ int32_t use_Basic_Auth(char *s) { } int32_t use_Digest_Auth(char *s) { - if (strstr(s, "WWW-Authenticate: Digest") != NULL) { + if (strcasestr(s, "WWW-Authenticate: Digest") != NULL) { return 1; } else { return 0; @@ -104,42 +108,37 @@ int32_t start_rtsp(int32_t s, char *ip, int32_t port, unsigned char options, cha } else { create_core_packet(1, ip, port); - if (use_Basic_Auth(lresp) == 1) { + if (use_Digest_Auth(lresp) == 1) { + char aux[500] = "", dbuf[500] = "", *result = NULL; + char *pbuffer = hydra_strcasestr(lresp, "WWW-Authenticate: Digest "); + + strncpy(aux, pbuffer + strlen("WWW-Authenticate: Digest "), sizeof(aux)); + aux[sizeof(aux) - 1] = '\0'; + free(lresp); +#ifdef LIBOPENSSL + result = sasl_digest_md5(dbuf, login, pass, aux, miscptr, "rtsp", hydra_address2string(ip), port, ""); +#else + hydra_report(stderr, "[ERROR] Digest auth required but compiled " + "without OpenSSL/MD5 support\n"); + return 3; +#endif + if (result == NULL) { + hydra_report(stderr, "[ERROR] digest generation failed\n"); + return 3; + } + sprintf(buffer, "%.500sAuthorization: Digest %.500s\r\n\r\n", packet2, dbuf); + if (debug) + 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) { + if (debug) hydra_report(stderr, "C:%s\n", buffer); - } } else { - if (use_Digest_Auth(lresp) == 1) { - char aux[500] = "", dbuf[500] = "", *result = NULL; - char *pbuffer = hydra_strcasestr(lresp, "WWW-Authenticate: Digest "); - - strncpy(aux, pbuffer + strlen("WWW-Authenticate: Digest "), sizeof(aux)); - aux[sizeof(aux) - 1] = '\0'; - free(lresp); -#ifdef LIBOPENSSL - result = sasl_digest_md5(dbuf, login, pass, aux, miscptr, "rtsp", hydra_address2string(ip), port, ""); -#else - hydra_report(stderr, "[ERROR] Digest auth required but compiled " - "without OpenSSL/MD5 support\n"); - return 3; -#endif - - if (result == NULL) { - hydra_report(stderr, "[ERROR] digest generation failed\n"); - return 3; - } - sprintf(buffer, "%.500sAuthorization: Digest %.500s\r\n\r\n", packet2, dbuf); - - if (debug) { - hydra_report(stderr, "C:%s\n", buffer); - } - } + hydra_report(stderr, "[ERROR] unknown authentication protocol\n"); + return 1; } if (strlen(buffer) == 0) { @@ -159,7 +158,7 @@ int32_t start_rtsp(int32_t s, char *ip, int32_t port, unsigned char options, cha return 1; } - if ((is_NotFound(lresp))) { + if (is_NotFound(lresp) || is_Authorized(lresp)) { free(lresp); hydra_completed_pair_found(); diff --git a/hydra-sapr3.c b/hydra-sapr3.c index 26024da..76ce7b7 100644 --- a/hydra-sapr3.c +++ b/hydra-sapr3.c @@ -14,6 +14,7 @@ const int32_t *__ctype_b; extern void flood(); /* for -lm */ +extern hydra_option hydra_options; extern char *HYDRA_EXIT; RFC_ERROR_INFO_EX error_info; @@ -99,6 +100,8 @@ void service_sapr3(char *ip, int32_t sp, unsigned char options, char *miscptr, F switch (run) { case 1: /* connect and service init function */ next_run = start_sapr3(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 2: hydra_child_exit(0); diff --git a/hydra-sip.c b/hydra-sip.c index 6be4d93..c9d71d2 100644 --- a/hydra-sip.c +++ b/hydra-sip.c @@ -42,7 +42,7 @@ int32_t get_sip_code(char *buf) { int32_t code; char tmpbuf[SIP_MAX_BUF], word[SIP_MAX_BUF]; - if (sscanf(buf, "%s %i %s", tmpbuf, &code, word) != 3) + if (sscanf(buf, "%256s %i %256s", tmpbuf, &code, word) != 3) return -1; return code; } @@ -71,14 +71,12 @@ int32_t start_sip(int32_t s, char *ip, char *lip, int32_t port, int32_t lport, u } int32_t has_sip_cred = 0; - int32_t try - = 0; + int32_t try = 0; /* We have to check many times because server may begin to send "100 Trying" * before "401 Unauthorized" */ while (try < 2 && !has_sip_cred) { - try - ++; + try++; if (hydra_data_ready_timed(s, 3, 0) > 0) { i = hydra_recv(s, (char *)buf, sizeof(buf) - 1); if (i > 0) @@ -160,14 +158,12 @@ int32_t start_sip(int32_t s, char *ip, char *lip, int32_t port, int32_t lport, u if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 3; } - try - = 0; + try = 0; int32_t has_resp = 0; int32_t sip_code = 0; while (try < 2 && !has_resp) { - try - ++; + try++; if (hydra_data_ready_timed(s, 5, 0) > 0) { memset(buf, 0, sizeof(buf)); if ((i = hydra_recv(s, (char *)buf, sizeof(buf) - 1)) >= 0) diff --git a/hydra-smb.c b/hydra-smb.c index 20fd1cf..0db54da 100644 --- a/hydra-smb.c +++ b/hydra-smb.c @@ -1280,8 +1280,8 @@ int32_t start_smb(int32_t s, char *ip, int32_t port, unsigned char options, char } else if (SMBerr == 0x000193) { /* Valid password, account expired */ hydra_report(stdout, "[%d][smb] Host: %s Account: %s Valid password, account expired\n", port, ipaddr_str, login); hydra_report_found_host(port, ip, "smb", fp); - hydra_completed_pair_found(); - } else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, account expired */ + hydra_completed_pair_skip(); + } else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, password expired */ hydra_report(stdout, "[%d][smb] Host: %s Account: %s Valid password, password " "expired and must be changed on next logon\n", @@ -1304,14 +1304,13 @@ int32_t start_smb(int32_t s, char *ip, int32_t port, unsigned char options, char hydra_report(stderr, "[INFO] LM dialect may be disabled, try LMV2 instead\n"); hydra_completed_pair_skip(); } else if (SMBerr == 0x000024) { /* change password on next login [success] */ - hydra_report(stdout, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login); + hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login); hydra_completed_pair_found(); } else if (SMBerr == 0x00006D) { /* STATUS_LOGON_FAILURE */ hydra_completed_pair(); } else if (SMBerr == 0x000071) { /* password expired */ - if (verbose) - fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: PASSWORD EXPIRED\n", port, ipaddr_str, login); - hydra_completed_pair_skip(); + hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: PASSWORD EXPIRED\n", port, ipaddr_str, login); + hydra_completed_pair_found(); } else if ((SMBerr == 0x000072) || (SMBerr == 0xBF0002)) { /* account disabled */ /* BF0002 on w2k */ if (verbose) fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_DISABLED\n", port, ipaddr_str, login); @@ -1494,7 +1493,7 @@ int32_t service_smb_init(char *ip, int32_t sp, unsigned char options, char *misc ctime = time(NULL); do { usleepn(300); - } while ((ready = hydra_data_ready(sock)) <= 0 && ctime + 5 <= time(NULL)); + } while ((ready = hydra_data_ready(sock)) <= 0 && ctime + 5 >= time(NULL)); if (ready <= 0) { fprintf(stderr, "[ERROR] no reply from target smb://%s:%d/\n", hostname, port); diff --git a/hydra-smb2.c b/hydra-smb2.c index 275bbae..d1d220d 100644 --- a/hydra-smb2.c +++ b/hydra-smb2.c @@ -27,6 +27,7 @@ #include #include +extern hydra_option hydra_options; extern char *HYDRA_EXIT; typedef struct creds { @@ -126,6 +127,11 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) { */ switch (errno) { + case 0: + // maybe false positive? unclear ... :( ... needs more testing + smbc_free_context(ctx, 1); + return true; + break; case ENOENT: // Noticed this when connecting to older samba servers on linux // where any credentials are accepted. @@ -168,10 +174,15 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) { } void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { + static int first_run = 0; hydra_register_socket(sp); + while (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT))) { char *login, *pass; + if (first_run && hydra_options.conwait) + sleep(hydra_options.conwait); + login = hydra_get_next_login(); pass = hydra_get_next_password(); @@ -186,6 +197,8 @@ void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FI } else { hydra_completed_pair(); } + + first_run = 1; } EXIT_NORMAL; } diff --git a/hydra-smtp-enum.c b/hydra-smtp-enum.c index ddc0355..d887307 100644 --- a/hydra-smtp-enum.c +++ b/hydra-smtp-enum.c @@ -128,13 +128,13 @@ int32_t start_smtp_enum(int32_t s, char *ip, int32_t port, unsigned char options //#endif // hydra_report(stderr, "Server %s", err); // } - if (strncmp(buf, "500 ", 4) == 0) { + if (strncmp(buf, "500 ", 4) == 0 || strncmp(buf, "502 ", 4) == 0) { hydra_report(stderr, "[ERROR] command is disabled on the server (choose " "different method): %s", buf); free(buf); - return 3; + return 4; } memset(buffer, 0, sizeof(buffer)); // 503 5.5.1 Error: nested MAIL command @@ -245,6 +245,12 @@ void service_smtp_enum(char *ip, int32_t sp, unsigned char options, char *miscpt } hydra_child_exit(0); return; + case 4: /* unsupported exit */ + if (sock >= 0) { + sock = hydra_disconnect(sock); + } + hydra_child_exit(3); + return; default: hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); hydra_child_exit(0); diff --git a/hydra-smtp.c b/hydra-smtp.c index dc6e54a..97d5b72 100644 --- a/hydra-smtp.c +++ b/hydra-smtp.c @@ -61,6 +61,10 @@ int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, cha return 1; if (strstr(buf, "334") == NULL) { hydra_report(stderr, "[ERROR] SMTP PLAIN AUTH : %s\n", buf); + if (strstr(buf, "503") != NULL) { + free(buf); + return 4; + } free(buf); return 3; } @@ -438,6 +442,12 @@ void service_smtp(char *ip, int32_t sp, unsigned char options, char *miscptr, FI } hydra_child_exit(0); return; + case 4: /* error exit */ + if (sock >= 0) { + sock = hydra_disconnect(sock); + } + hydra_child_exit(3); + return; default: hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); hydra_child_exit(0); diff --git a/hydra-ssh.c b/hydra-ssh.c index ef4a691..6ccae4e 100644 --- a/hydra-ssh.c +++ b/hydra-ssh.c @@ -34,11 +34,12 @@ int32_t start_ssh(int32_t s, char *ip, int32_t port, unsigned char options, char if (new_session) { if (session) { ssh_disconnect(session); - ssh_finalize(); + // ssh_finalize(); ssh_free(session); + } else { + ssh_init(); } - ssh_init(); session = ssh_new(); ssh_options_set(session, SSH_OPTIONS_PORT, &port); ssh_options_set(session, SSH_OPTIONS_HOST, hydra_address2string(ip)); @@ -46,6 +47,9 @@ int32_t start_ssh(int32_t s, char *ip, int32_t port, unsigned char options, char ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &hydra_options.waittime); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none"); + // might be better to add the legacy (first two for KEX and HOST) to the default instead of specifying the full list + ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256"); + ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256"); if (ssh_connect(session) != 0) { // if the connection was drop, exit and let hydra main handle it if (verbose) @@ -118,6 +122,8 @@ void service_ssh(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL switch (run) { case 1: /* connect and service init function */ next_run = start_ssh(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 2: ssh_disconnect(session); @@ -173,6 +179,7 @@ int32_t service_ssh_init(char *ip, int32_t sp, unsigned char options, char *misc // 3 skip target because its unreachable #ifdef LIBSSH int32_t rc, method; + ssh_init(); ssh_session session = ssh_new(); if (verbose || debug) @@ -188,6 +195,9 @@ int32_t service_ssh_init(char *ip, int32_t sp, unsigned char options, char *misc ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &hydra_options.waittime); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none"); + // might be better to add the legacy (first two for KEX and HOST) to the default instead of specifying the full list + ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256"); + ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256"); if (ssh_connect(session) != 0) { fprintf(stderr, "[ERROR] could not connect to ssh://%s:%d - %s\n", hydra_address2string_beautiful(ip), port, ssh_get_error(session)); return 2; diff --git a/hydra-sshkey.c b/hydra-sshkey.c index 113d6de..cac66e0 100644 --- a/hydra-sshkey.c +++ b/hydra-sshkey.c @@ -16,6 +16,7 @@ void dummy_sshkey() { printf("\n"); } #if LIBSSH_VERSION_MAJOR >= 0 && LIBSSH_VERSION_MINOR >= 4 extern ssh_session session; +extern hydra_option hydra_options; extern char *HYDRA_EXIT; extern int32_t new_session; @@ -33,8 +34,9 @@ int32_t start_sshkey(int32_t s, char *ip, int32_t port, unsigned char options, c if (new_session) { if (session) { ssh_disconnect(session); - ssh_finalize(); ssh_free(session); + } else { + ssh_init(); } session = ssh_new(); @@ -116,6 +118,8 @@ void service_sshkey(char *ip, int32_t sp, unsigned char options, char *miscptr, switch (run) { case 1: /* connect and service init function */ next_run = start_sshkey(sock, ip, port, options, miscptr, fp); + if (next_run == 1 && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 2: ssh_disconnect(session); diff --git a/hydra-svn.c b/hydra-svn.c index 063f12c..0664924 100644 --- a/hydra-svn.c +++ b/hydra-svn.c @@ -4,7 +4,9 @@ #ifdef LIBSVN /* needed on openSUSE */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #if !defined PATH_MAX && defined HAVE_SYS_PARAM_H #include @@ -30,6 +32,7 @@ void dummy_svn() { printf("\n"); } extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); +extern hydra_option hydra_options; extern char *HYDRA_EXIT; #define DEFAULT_BRANCH "trunk" @@ -195,6 +198,8 @@ void service_svn(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL break; case 2: next_run = start_svn(sock, ip, port, options, miscptr, fp); + if ((next_run == 1 || next_run == 2) && hydra_options.conwait) + sleep(hydra_options.conwait); break; case 3: if (sock >= 0) diff --git a/hydra-telnet.c b/hydra-telnet.c index 762ade1..183621a 100644 --- a/hydra-telnet.c +++ b/hydra-telnet.c @@ -36,7 +36,7 @@ int32_t start_telnet(int32_t s, char *ip, int32_t port, unsigned char options, c if ((buf = hydra_receive_line(s)) == NULL) return 1; - if (index(buf, '/') != NULL || index(buf, '>') != NULL || index(buf, '%') != NULL || index(buf, '$') != NULL || index(buf, '#') != NULL) { + if (strchr(buf, '/') != NULL || strchr(buf, '>') != NULL || strchr(buf, '%') != NULL || strchr(buf, '$') != NULL || strchr(buf, '#') != NULL) { hydra_report_found_host(port, ip, "telnet", fp); hydra_completed_pair_found(); free(buf); @@ -75,16 +75,41 @@ int32_t start_telnet(int32_t s, char *ip, int32_t port, unsigned char options, c } /*win7 answering with do terminal type = 0xfd 0x18 */ - while ((buf = hydra_receive_line(s)) != NULL && make_to_lower(buf) && (strstr(buf, "login:") == NULL || strstr(buf, "last login:") != NULL) && strstr(buf, "sername:") == NULL) { - if ((miscptr != NULL && strstr(buf, miscptr) != NULL) || (miscptr == NULL && strstr(buf, "invalid") == NULL && strstr(buf, "failed") == NULL && strstr(buf, "bad ") == NULL && (index(buf, '/') != NULL || index(buf, '>') != NULL || index(buf, '$') != NULL || index(buf, '#') != NULL || index(buf, '%') != NULL || ((buf[1] == '\xfd') && (buf[2] == '\x18'))))) { + while ((buf = hydra_receive_line(s)) != NULL && make_to_lower(buf) && (strstr(buf, "password:") == NULL || strstr(buf, "login:") == NULL || strstr(buf, "last login:") != NULL) && strstr(buf, "sername:") == NULL) { + if ((miscptr != NULL && strstr(buf, miscptr) != NULL) || (miscptr == NULL && strstr(buf, "invalid") == NULL && strstr(buf, "incorrect") == NULL && strstr(buf, "bad ") == NULL && (strchr(buf, '/') != NULL || strchr(buf, '>') != NULL || strchr(buf, '$') != NULL || strchr(buf, '#') != NULL || strchr(buf, '%') != NULL || ((buf[1] == '\xfd') && (buf[2] == '\x18'))))) { hydra_report_found_host(port, ip, "telnet", fp); hydra_completed_pair_found(); free(buf); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; return 1; - } - free(buf); + } else if (buf && strstr(buf, "assword:")) { + hydra_completed_pair(); + // printf("password prompt\n"); + free(buf); + if (strlen(pass = hydra_get_next_password()) == 0) + pass = empty; + sprintf(buffer, "%s\r", pass); + if (no_line_mode) { + for (i = 0; i < strlen(buffer); i++) { + if (strcmp(&buffer[i], "\r") == 0) { + send(s, "\r\0", 2, 0); + } else { + send(s, &buffer[i], 1, 0); + } + usleepn(20); + } + } else { + if (hydra_send(s, buffer, strlen(buffer) + 1, 0) < 0) { + return 1; + } + } + } else if (buf && strstr(buf, "login:")) { + free(buf); + hydra_completed_pair(); + return 2; + } else + free(buf); } hydra_completed_pair(); diff --git a/hydra-vnc.c b/hydra-vnc.c index aeecd59..c836371 100644 --- a/hydra-vnc.c +++ b/hydra-vnc.c @@ -19,7 +19,7 @@ int32_t vnc_client_version = RFB33; int32_t failed_auth = 0; extern char *HYDRA_EXIT; -char *buf; +static char *buf; /* * Encrypt CHALLENGESIZE bytes in memory using a password. diff --git a/hydra-wizard.sh b/hydra-wizard.sh index 1370661..d4e3c3f 100755 --- a/hydra-wizard.sh +++ b/hydra-wizard.sh @@ -33,10 +33,10 @@ test -e "$pass" && passs="-P $pass" test -e "$pass" || passs="-p $pass" test -n "$port" && ports="-s $port" test -n "$pw" && pws="-e $pw" -test -n "$opt" && opts="-m '$opt'" +test -n "$opt" && { opts="-m $opt" ; dopts="-m '$opt'" ; } echo The following command will be executed now: -echo " hydra $users $passs -u $pws $ports $opts $targets $service" +echo " hydra $users $passs -u $pws $ports $dopts $targets $service" echo read -p "Do you want to run the command now? [Y/n] " yn test "$yn" = "n" -o "$yn" = "N" && { echo Exiting. ; exit 0 ; } diff --git a/hydra.1 b/hydra.1 index 039d55f..b9cb7a5 100644 --- a/hydra.1 +++ b/hydra.1 @@ -1,4 +1,4 @@ -.TH "HYDRA" "1" "01/01/2021" +.TH "HYDRA" "1" "01/01/2023" .SH NAME hydra \- a very fast network logon cracker which supports many different services .SH SYNOPSIS diff --git a/hydra.c b/hydra.c index 1a00976..416cf25 100644 --- a/hydra.c +++ b/hydra.c @@ -1,5 +1,5 @@ /* - * hydra (c) 2001-2021 by van Hauser / THC + * hydra (c) 2001-2023 by van Hauser / THC * https://github.com/vanhauser-thc/thc-hydra * * Parallized network login hacker. @@ -78,6 +78,7 @@ extern void service_http_post_form(char *ip, int32_t sp, unsigned char options, extern void service_icq(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern void service_pcnfs(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern void service_mssql(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); +extern void service_cobaltstrike(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern void service_cvs(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern void service_snmp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern void service_smtp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); @@ -178,6 +179,7 @@ extern int32_t service_imap_init(char *ip, int32_t sp, unsigned char options, ch extern int32_t service_irc_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern int32_t service_ldap_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern int32_t service_mssql_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); +extern int32_t service_cobaltstrike_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern int32_t service_nntp_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern int32_t service_pcanywhere_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); extern int32_t service_pcnfs_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); @@ -202,7 +204,7 @@ extern int32_t service_rtsp_init(char *ip, int32_t sp, unsigned char options, ch extern int32_t service_rpcap_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname); // ADD NEW SERVICES HERE -char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cvs firebird ftp[s] " +char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cobaltstrike cvs firebird ftp[s] " "http[s]-{head|get|post} http[s]-{get|post}-form http-proxy " "http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3[-{cram|digest}md5][s] " "memcached mongodb mssql mysql ncp nntp oracle oracle-listener oracle-sid " @@ -226,7 +228,7 @@ char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cvs firebird ftp[s] " #define RESTOREFILE "./hydra.restore" #define PROGRAM "Hydra" -#define VERSION "v9.2" +#define VERSION "v9.6dev" #define AUTHOR "van Hauser/THC" #define EMAIL "" #define AUTHOR2 "David Maciejak" @@ -265,6 +267,7 @@ typedef struct { typedef struct { char *target; + char *miscptr; char ip[36]; char *login_ptr; char *pass_ptr; @@ -341,6 +344,11 @@ int32_t prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed int32_t child_head_no = -1, child_socket; int32_t total_redo_count = 0; +// requred for distributed attack capability +uint32_t num_segments = 0; +uint32_t my_segment = 0; +char junk_file[50]; + // moved for restore feature int32_t process_restore = 0, dont_unlink; char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL; @@ -386,7 +394,7 @@ static const struct { {"http-get-form", service_http_form_init, service_http_get_form, usage_http_form}, {"http-head", service_http_init, service_http_head, NULL}, {"http-form", service_http_form_init, NULL, usage_http_form}, - {"http-post", NULL, service_http_post, usage_http}, + {"http-post", service_http_init, service_http_post, usage_http}, {"http-post-form", service_http_form_init, service_http_post_form, usage_http_form}, SERVICE3("http-proxy", http_proxy), SERVICE3("http-proxy-urlenum", http_proxy_urlenum), @@ -402,6 +410,7 @@ static const struct { {"memcached", service_mcached_init, service_mcached, NULL}, #endif SERVICE(mssql), + SERVICE(cobaltstrike), #ifdef LIBMONGODB SERVICE3("mongodb", mongodb), #endif @@ -516,6 +525,8 @@ void help(int32_t ext) { "instead of -L/-P options\n" " -M FILE list of servers to attack, one entry per " "line, ':' to specify port\n"); + PRINT_NORMAL(ext, " -D XofY Divide wordlist into Y segments and use the " + "Xth segment.\n"); PRINT_EXTEND(ext, " -o FILE write found login/password pairs to FILE instead of stdout\n" " -b FORMAT specify the format for the -o FILE: text(default), json, " "jsonv1\n" @@ -593,8 +604,6 @@ void help_bfg() { "others,\n" " just add their real representation.\n" " -y disable the use of the above letters as placeholders\n" - " -r use a shuffling method called 'rain' to try to break\n" - " the linearity of the bruteforce\n" "Examples:\n" " -x 3:5:a generate passwords from length 3 to 5 with all " "lowercase letters\n" @@ -807,7 +816,7 @@ void hydra_restore_read() { fprintf(stderr, "[WARNING] restore file was created by version %c.%c, this is " "version %s\n", - buf[0], buf[2], VERSION); + buf[0], buf[1], VERSION); if (buf[2] != sizeof(int32_t) % 256 || buf[3] != sizeof(hydra_head *) % 256) { fprintf(stderr, "[ERROR] restore file was created on a different, " "incompatible processor platform!\n"); @@ -883,11 +892,19 @@ void hydra_restore_read() { printf("[DEBUG] reading restore file: Step 8 complete\n"); login_ptr = malloc(hydra_brains.sizelogin + hydra_brains.countlogin + 8); + if (!login_ptr) { + fprintf(stderr, "Error: malloc(%lu) failed\n", hydra_brains.sizelogin + hydra_brains.countlogin + 8); + exit(-1); + } fck = (int32_t)fread(login_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, 1, f); if (debug) printf("[DEBUG] reading restore file: Step 9 complete\n"); if (!check_flag(hydra_options.mode, MODE_COLON_FILE)) { // NOT colonfile mode pass_ptr = malloc(hydra_brains.sizepass + hydra_brains.countpass + 8); + if (!pass_ptr) { + fprintf(stderr, "Error: malloc(%lu) failed\n", hydra_brains.sizepass + hydra_brains.countpass + 8); + exit(-1); + } fck = (int32_t)fread(pass_ptr, hydra_brains.sizepass + hydra_brains.countpass + 8, 1, f); } else { // colonfile mode hydra_options.colonfile = empty_login; // dummy @@ -897,8 +914,16 @@ void hydra_restore_read() { printf("[DEBUG] reading restore file: Step 10 complete\n"); hydra_targets = (hydra_target **)malloc((hydra_brains.targets + 3) * sizeof(hydra_target *)); + if (!hydra_targets) { + fprintf(stderr, "Error: malloc(%lu) failed\n", (hydra_brains.targets + 3) * sizeof(hydra_target *)); + exit(-1); + } for (j = 0; j < hydra_brains.targets; j++) { hydra_targets[j] = malloc(sizeof(hydra_target)); + if (!hydra_targets[j]) { + fprintf(stderr, "Error: malloc(%lu) failed\n", sizeof(hydra_target)); + exit(-1); + } fck = (int32_t)fread(hydra_targets[j], sizeof(hydra_target), 1, f); sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') @@ -950,8 +975,16 @@ void hydra_restore_read() { if (debug) printf("[DEBUG] reading restore file: Step 11 complete\n"); hydra_heads = malloc(sizeof(hydra_head *) * hydra_options.max_use); + if (!hydra_heads) { + fprintf(stderr, "Error: malloc(%lu) failed\n", sizeof(hydra_head *) * hydra_options.max_use); + exit(-1); + } for (j = 0; j < hydra_options.max_use; j++) { hydra_heads[j] = malloc(sizeof(hydra_head)); + if (!hydra_heads[j]) { + fprintf(stderr, "Error: malloc(%lu) failed\n", sizeof(hydra_head)); + exit(-1); + } fck = (int32_t)fread(hydra_heads[j], sizeof(hydra_head), 1, f); hydra_heads[j]->sp[0] = -1; hydra_heads[j]->sp[1] = -1; @@ -1001,7 +1034,7 @@ void killed_childs(int32_t signo) { int32_t pid, i; killed++; - pid = wait3(NULL, WNOHANG, NULL); + pid = waitpid(-1, NULL, WNOHANG); for (i = 0; i < hydra_options.max_use; i++) { if (pid == hydra_heads[i]->pid) { hydra_heads[i]->pid = -1; @@ -1107,7 +1140,7 @@ void fill_mem(char *ptr, FILE *fd, int32_t colonmode) { tmp[len] = 0; } if (colonmode) { - if ((ptr2 = index(tmp, ':')) == NULL) { + if ((ptr2 = strchr(tmp, ':')) == NULL) { fprintf(stderr, "[ERROR] invalid line in colon file (-C), missing colon " "in line: %s\n", @@ -1149,13 +1182,12 @@ void hydra_service_init(int32_t target_no) { int32_t x = 99; int32_t i; hydra_target *t = hydra_targets[target_no]; - char *miscptr = hydra_options.miscptr; FILE *ofp = hydra_brains.ofp; for (i = 0; x == 99 && i < sizeof(services) / sizeof(services[0]); i++) { if (strcmp(hydra_options.service, services[i].name) == 0) { if (services[i].init) { - x = services[i].init(t->ip, -1, options, miscptr, ofp, t->port, t->target); + x = services[i].init(t->ip, -1, options, t->miscptr, ofp, t->port, t->target); break; } } @@ -1239,13 +1271,13 @@ int32_t hydra_spawn_head(int32_t head_no, int32_t target_no) { hydra_target *t = hydra_targets[target_no]; int32_t sp = hydra_heads[head_no]->sp[1]; - char *miscptr = hydra_options.miscptr; + // char *miscptr = hydra_options.miscptr; FILE *ofp = hydra_brains.ofp; hydra_target *head_target = hydra_targets[hydra_heads[head_no]->target_no]; for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) { if (strcmp(hydra_options.service, services[i].name) == 0) { if (services[i].exec) { - services[i].exec(t->ip, sp, options, miscptr, ofp, t->port, head_target->target); + services[i].exec(t->ip, sp, options, t->miscptr, ofp, t->port, head_target->target); // just in case a module returns (which it shouldnt) we let it exit // here exit(-1); @@ -1320,6 +1352,7 @@ int32_t hydra_lookup_port(char *service) { {"memcached", PORT_MCACHED, PORT_MCACHED_SSL}, {"mongodb", PORT_MONGODB, PORT_MONGODB}, {"mssql", PORT_MSSQL, PORT_MSSQL_SSL}, + {"cobaltstrike", PORT_COBALTSTRIKE, PORT_COBALTSTRIKE_SSL}, {"mysql", PORT_MYSQL, PORT_MYSQL_SSL}, {"postgres", PORT_POSTGRES, PORT_POSTGRES_SSL}, {"pcanywhere", PORT_PCANYWHERE, PORT_PCANYWHERE_SSL}, @@ -1421,7 +1454,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] = // NULL; } - (void)wait3(NULL, WNOHANG, NULL); + (void)waitpid(-1, NULL, WNOHANG); } void hydra_increase_fail_count(int32_t target_no, int32_t head_no) { @@ -1461,7 +1494,7 @@ void hydra_increase_fail_count(int32_t target_no, int32_t head_no) { hydra_heads[head_no]->current_pass_ptr = empty_login; } if (hydra_targets[target_no]->fail_count >= MAXFAIL + hydra_options.tasks * hydra_targets[target_no]->ok) { - if (hydra_targets[target_no]->done == TARGET_ACTIVE && hydra_options.max_use == hydra_targets[target_no]->failed) { + if (hydra_targets[target_no]->done == TARGET_ACTIVE && hydra_options.max_use <= hydra_targets[target_no]->failed) { if (hydra_targets[target_no]->ok == 1) hydra_targets[target_no]->done = TARGET_ERROR; // mark target as done by errors else @@ -1470,13 +1503,16 @@ void hydra_increase_fail_count(int32_t target_no, int32_t head_no) { fprintf(stderr, "[ERROR] Too many connect errors to target, disabling " "%s://%s%s%s:%d\n", - hydra_options.service, hydra_targets[target_no]->ip[0] == 16 && index(hydra_targets[target_no]->target, ':') != NULL ? "[" : "", hydra_targets[target_no]->target, hydra_targets[target_no]->ip[0] == 16 && index(hydra_targets[target_no]->target, ':') != NULL ? "]" : "", hydra_targets[target_no]->port); + hydra_options.service, hydra_targets[target_no]->ip[0] == 16 && strchr(hydra_targets[target_no]->target, ':') != NULL ? "[" : "", hydra_targets[target_no]->target, hydra_targets[target_no]->ip[0] == 16 && strchr(hydra_targets[target_no]->target, ':') != NULL ? "]" : "", hydra_targets[target_no]->port); + } else { + hydra_targets[target_no]->failed++; } - if (hydra_brains.targets > hydra_brains.finished) + if (hydra_brains.targets <= hydra_brains.finished) hydra_kill_head(head_no, 1, 0); else hydra_kill_head(head_no, 1, 2); - } // we keep the last one alive as long as it make sense + } + // we keep the last one alive as long as it make sense } else { // we need to put this in a list, otherwise we fail one login+pw test if (hydra_targets[target_no]->done == TARGET_ACTIVE && hydra_options.skip_redo == 0 && hydra_targets[target_no]->redo <= hydra_options.max_use * 2 && ((hydra_heads[head_no]->current_login_ptr != empty_login && hydra_heads[head_no]->current_pass_ptr != empty_login) || (hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL))) { @@ -1491,12 +1527,14 @@ void hydra_increase_fail_count(int32_t target_no, int32_t head_no) { hydra_heads[head_no]->current_login_ptr = empty_login; hydra_heads[head_no]->current_pass_ptr = empty_login; } - hydra_targets[target_no]->fail_count--; - if (k < 5 && hydra_targets[target_no]->ok) - hydra_targets[target_no]->fail_count--; - if (k == 2 && hydra_targets[target_no]->ok) - hydra_targets[target_no]->fail_count--; - if (hydra_brains.targets > hydra_brains.finished) + /* + hydra_targets[target_no]->fail_count--; + if (k < 5 && hydra_targets[target_no]->ok) + hydra_targets[target_no]->fail_count--; + if (k == 2 && hydra_targets[target_no]->ok) + hydra_targets[target_no]->fail_count--; + */ + if (hydra_brains.targets <= hydra_brains.finished) hydra_kill_head(head_no, 1, 0); else { hydra_kill_head(head_no, 1, 2); @@ -1560,13 +1598,80 @@ char *hydra_reverse_login(int32_t head_no, char *login) { return hydra_heads[head_no]->reverse; } +void delete_junk_files(){ + remove(junk_file); +} + +FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ + + if(my_segment > num_segments){ + fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile); + return NULL; + } + + FILE *output_file; + char line[500]; + char output_file_name[50]; + + uint32_t line_number = 0; + + double total_lines = countlines(file,0); + + if(num_segments > total_lines){ + fprintf(stderr, "[ERROR] in option -D XofY, Y must not be greater than the total number of lines in the file to be divided: %s\n", hydra_options.passfile); + return NULL; + } + + double segment_size_double = total_lines / num_segments; + + // round up segment_size_float to integer + uint64_t segment_size = (uint64_t)segment_size_double; + if(segment_size < segment_size_double) + segment_size++; + + uint64_t segment_start = segment_size * (my_segment - 1) + 1; + uint64_t segment_end = segment_size * my_segment; + + + + srand(time(NULL)); + int filetag = rand(); + + sprintf(output_file_name, "segment_%d_%d.txt",filetag, my_segment); + output_file = fopen(output_file_name, "w"); + + if(!output_file){ + fprintf(stderr, "[ERROR] Segment file empty: %s\n", hydra_options.passfile); + return NULL; + } + + strcpy(junk_file, output_file_name); + + atexit(delete_junk_files); + + while(fgets(line, sizeof line, file) != NULL && line_number < segment_end){ + line_number++; + + if(line_number >= segment_start && line_number <= segment_end) + fprintf(output_file, "%s", line); + + } + + rewind(file); + fclose(output_file); + output_file = fopen(output_file_name, "r"); + + return output_file; + + } + int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { // variables moved to save stack snpdone = 0; snp_is_redo = 0; snpdont = 0; loop_cnt++; - if (hydra_heads[head_no]->redo && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { + if (hydra_heads[head_no]->redo == 1 && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { hydra_heads[head_no]->redo = 0; snp_is_redo = 1; snpdone = 1; @@ -1598,7 +1703,7 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { return -1; } - if (hydra_heads[head_no]->redo && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { + if (hydra_heads[head_no]->redo == 1 && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { hydra_heads[head_no]->redo = 0; snp_is_redo = 1; snpdone = 1; @@ -1607,7 +1712,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 - " "%" 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_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 <= 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]; @@ -1907,8 +2012,11 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { // the above line } if (debug || hydra_options.showAttempt) { - printf("[%sATTEMPT] target %s - login \"%s\" - pass \"%s\" - %" hPRIu64 " of %" hPRIu64 " [child %d] (%d/%d)\n", hydra_targets[target_no]->redo_state ? "REDO-" : snp_is_redo ? "RE-" : "", hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo, head_no, hydra_targets[target_no]->redo_state ? hydra_targets[target_no]->redo_state - 1 : 0, - hydra_targets[target_no]->redo); + printf("[%sATTEMPT] target %s - login \"%s\" - pass \"%s\" - %" hPRIu64 " of %" hPRIu64 " [child %d] (%d/%d)\n", + hydra_targets[target_no]->redo_state ? "REDO-" + : snp_is_redo ? "RE-" + : "", + hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo, head_no, hydra_targets[target_no]->redo_state ? hydra_targets[target_no]->redo_state - 1 : 0, hydra_targets[target_no]->redo); } loop_cnt = 0; return 0; @@ -1933,7 +2041,7 @@ void hydra_skip_user(int32_t target_no, char *username) { hydra_targets[target_no]->skipcnt++; } if (hydra_options.loop_mode == 0 && !check_flag(hydra_options.mode, MODE_COLON_FILE)) { - if (memcmp(username, hydra_targets[target_no]->login_ptr, strlen(username)) == 0) { + if (strcmp(username, hydra_targets[target_no]->login_ptr) == 0) { if (debug) printf("[DEBUG] skipping username %s\n", username); // increase count @@ -2011,7 +2119,7 @@ void process_proxy_line(int32_t type, char *string) { string[strlen(string) - 1] = 0; if (string[strlen(string) - 1] == '\r') string[strlen(string) - 1] = 0; - if (proxy_count > MAX_PROXY_COUNT) { + if (proxy_count >= MAX_PROXY_COUNT) { fprintf(stderr, "[WARNING] maximum amount of proxies loaded, ignoring this entry: %s\n", string); return; } @@ -2023,11 +2131,11 @@ void process_proxy_line(int32_t type, char *string) { } *sep = 0; target_string = sep + 3; - if ((sep = index(target_string, '@')) != NULL) { + if ((sep = strchr(target_string, '@')) != NULL) { auth_string = target_string; *sep = 0; target_string = sep + 1; - if (index(auth_string, ':') == NULL) { + if (strchr(auth_string, ':') == NULL) { fprintf(stderr, "[WARNING] %s has an invalid authentication definition %s, must " "be in the format login:pass, entry ignored\n", @@ -2035,14 +2143,14 @@ void process_proxy_line(int32_t type, char *string) { return; } } - if ((sep = index(target_string, ':')) != NULL) { + if ((sep = strchr(target_string, ':')) != NULL) { *sep = 0; port_string = sep + 1; - if ((sep = index(port_string, '%')) != NULL) { + if ((sep = strchr(port_string, '%')) != NULL) { *sep = 0; device_string = sep + 1; } - if ((sep = index(port_string, '/')) != NULL) + if ((sep = strchr(port_string, '/')) != NULL) *sep = 0; port = atoi(port_string); if (port < 1 || port > 65535) { @@ -2137,13 +2245,13 @@ void process_proxy_line(int32_t type, char *string) { int main(int argc, char *argv[]) { char *proxy_string = NULL, *device = NULL, *memcheck; char *outfile_format_tmp; - FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp; + FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp, *filecloser=NULL; size_t countinfile = 1, sizeinfile = 0; uint64_t math2; int32_t i = 0, j = 0, k, error = 0, modusage = 0, ignore_restore = 0, do_switch; int32_t head_no = 0, target_no = 0, exit_condition = 0, readres; time_t starttime, elapsed_status, elapsed_restore, status_print = 59, tmp_time; - char *tmpptr, *tmpptr2; + char *tmpptr, *tmpptr2, *tmpptr3; char rc, buf[MAXBUF]; time_t last_attempt = 0; fd_set fdreadheads; @@ -2152,7 +2260,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in6 *ipv6 = NULL; struct sockaddr_in *ipv4 = NULL; - printf("%s %s (c) 2021 by %s & %s - Please do not use in military or secret " + printf("%s %s (c) 2023 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", PROGRAM, VERSION, AUTHOR, AUTHOR2); #ifndef LIBAFP @@ -2191,6 +2299,10 @@ int main(int argc, char *argv[]) { SERVICES = hydra_string_replace(SERVICES, "radmin2 ", ""); strcat(unsupported, "radmin2 "); #endif +#ifndef LIBFREERDP + SERVICES = hydra_string_replace(SERVICES, "rdp ", ""); + strcat(unsupported, "rdp "); +#endif #ifndef LIBSAPR3 SERVICES = hydra_string_replace(SERVICES, "sapr3 ", ""); strcat(unsupported, "sapr3 "); @@ -2238,11 +2350,6 @@ int main(int argc, char *argv[]) { strcat(unsupported, "SSL-services (ftps, sip, rdp, oracle-services, ...) "); #endif -#ifndef LIBFREERDP - // for rdp - SERVICES = hydra_string_replace(SERVICES, " rdp", ""); -#endif - #ifndef HAVE_MATH_H if (strlen(unsupported) > 0) strcat(unsupported, "and "); @@ -2274,6 +2381,7 @@ int main(int argc, char *argv[]) { hydra_options.loginfile = NULL; hydra_options.pass = NULL; hydra_options.passfile = NULL; + hydra_options.distributed = NULL; hydra_options.tasks = TASKS; hydra_options.max_use = MAXTASKS; hydra_options.outfile_format = FORMAT_PLAIN_TEXT; @@ -2287,8 +2395,18 @@ int main(int argc, char *argv[]) { help(1); if (argc < 2) help(0); - while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) { + while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:D:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) { switch (i) { + case 'D': + hydra_options.distributed = optarg; + if (sscanf(hydra_options.distributed, "%dof%d", &my_segment, &num_segments) != 2) { + fprintf(stderr, "Invalid format. Expected format -D XofY where X and Y are integers.\n"); + exit(EXIT_FAILURE); + } + else{ + fprintf(stdout, "Option \'D\': successfully set X to %d and Y to %d\n", my_segment, num_segments); + } + break; case 'h': help(1); break; @@ -2571,23 +2689,23 @@ int main(int argc, char *argv[]) { if (*target_pos == '[') { target_pos++; - if ((param_pos = index(target_pos, ']')) == NULL) + if ((param_pos = strchr(target_pos, ']')) == NULL) bail("no closing ']' found in target definition"); *param_pos++ = 0; if (*param_pos == ':') port_pos = ++param_pos; - if ((param_pos = index(param_pos, '/')) != NULL) + if ((param_pos = strchr(param_pos, '/')) != NULL) *param_pos++ = 0; } else { - port_pos = index(target_pos, ':'); - param_pos = index(target_pos, '/'); + port_pos = strchr(target_pos, ':'); + param_pos = strchr(target_pos, '/'); if (port_pos != NULL && param_pos != NULL && port_pos > param_pos) port_pos = NULL; if (port_pos != NULL) *port_pos++ = 0; if (param_pos != NULL) *param_pos++ = 0; - if (port_pos != NULL && index(port_pos, ':') != NULL) { + if (port_pos != NULL && strchr(port_pos, ':') != NULL) { if (prefer_ipv6) bail("Illegal IPv6 target definition must be written within '[' " "']'"); @@ -2776,6 +2894,8 @@ int main(int argc, char *argv[]) { } if (strcmp(hydra_options.service, "mssql") == 0) i = 1; + if (strcmp(hydra_options.service, "cobaltstrike") == 0) + i = 2; if ((strcmp(hydra_options.service, "oracle-listener") == 0) || (strcmp(hydra_options.service, "tns") == 0)) { i = 2; hydra_options.service = malloc(strlen("oracle-listener") + 1); @@ -2870,7 +2990,7 @@ int main(int argc, char *argv[]) { "like parallel connections)\n"); hydra_options.tasks = 1; } - if (hydra_options.login != NULL && (index(hydra_options.login, '\\') != NULL || index(hydra_options.login, '/') != NULL)) + if (hydra_options.login != NULL && (strchr(hydra_options.login, '\\') != NULL || strchr(hydra_options.login, '/') != NULL)) fprintf(stderr, "[WARNING] potential windows domain specification found in " "login. You must use the -m option to pass a domain.\n"); i = 1; @@ -2894,7 +3014,7 @@ int main(int argc, char *argv[]) { #if !defined(LIBSMBCLIENT) bail("Compiled without LIBSMBCLIENT support, module not available!"); #else - if (hydra_options.login != NULL && (index(hydra_options.login, '\\') != NULL || index(hydra_options.login, '/') != NULL)) + if (hydra_options.login != NULL && (strchr(hydra_options.login, '\\') != NULL || strchr(hydra_options.login, '/') != NULL)) fprintf(stderr, "[WARNING] potential windows domain specification found in " "login. You must use the -m option to pass a domain.\n"); if (hydra_options.miscptr == NULL || (strlen(hydra_options.miscptr) == 0)) { @@ -3166,77 +3286,79 @@ int main(int argc, char *argv[]) { bail("Compiled without SSL support, module not available"); #endif } - if (hydra_options.miscptr == NULL) { - fprintf(stderr, "[WARNING] You must supply the web page as an " - "additional option or via -m, default path set to /\n"); - hydra_options.miscptr = malloc(2); - hydra_options.miscptr = "/"; - } - // if (*hydra_options.miscptr != '/' && strstr(hydra_options.miscptr, - // "://") == NULL) - // bail("The web page you supplied must start with a \"/\", \"http://\" - // or \"https://\", e.g. \"/protected/login\""); - if (hydra_options.miscptr[0] != '/') - bail("optional parameter must start with a '/' slash!\n"); - if (getenv("HYDRA_PROXY_HTTP") && getenv("HYDRA_PROXY")) - bail("Found HYDRA_PROXY_HTTP *and* HYDRA_PROXY environment variables - " - "you can use only ONE for the service http-head/http-get!"); - if (getenv("HYDRA_PROXY_HTTP")) { - printf("[INFO] Using HTTP Proxy: %s\n", getenv("HYDRA_PROXY_HTTP")); - use_proxy = 1; - } - if (strstr(hydra_options.miscptr, "\\:") != NULL) { - fprintf(stderr, "[INFORMATION] escape sequence \\: detected in module " - "option, no parameter verification is performed.\n"); - } else { - sprintf(bufferurl, "%.6000s", hydra_options.miscptr); - url = strtok(bufferurl, ":"); - variables = strtok(NULL, ":"); - cond = strtok(NULL, ":"); - optional1 = strtok(NULL, "\n"); - if ((variables == NULL) || (strstr(variables, "^USER^") == NULL && strstr(variables, "^PASS^") == NULL && strstr(variables, "^USER64^") == NULL && strstr(variables, "^PASS64^") == NULL)) { - fprintf(stderr, - "[ERROR] the variables argument needs at least the strings " - "^USER^, ^PASS^, ^USER64^ or ^PASS64^: %s\n", - STR_NULL(variables)); - exit(-1); + if (hydra_options.infile_ptr == NULL) { + if (hydra_options.miscptr == NULL) { + fprintf(stderr, "[WARNING] You must supply the web page as an " + "additional option or via -m, default path set to /\n"); + hydra_options.miscptr = malloc(2); + hydra_options.miscptr = "/"; } - if ((url == NULL) || (cond == NULL)) { - fprintf(stderr, - "[ERROR] Wrong syntax, requires three arguments separated by " - "a colon which may not be null: %s\n", - bufferurl); - exit(-1); + // if (*hydra_options.miscptr != '/' && strstr(hydra_options.miscptr, + // "://") == NULL) + // bail("The web page you supplied must start with a \"/\", \"http://\" + // or \"https://\", e.g. \"/protected/login\""); + if (hydra_options.miscptr[0] != '/') + bail("optional parameter must start with a '/' slash!\n"); + if (getenv("HYDRA_PROXY_HTTP") && getenv("HYDRA_PROXY")) + bail("Found HYDRA_PROXY_HTTP *and* HYDRA_PROXY environment variables - " + "you can use only ONE for the service http-head/http-get!"); + if (getenv("HYDRA_PROXY_HTTP")) { + printf("[INFO] Using HTTP Proxy: %s\n", getenv("HYDRA_PROXY_HTTP")); + use_proxy = 1; } - while ((optional1 = strtok(NULL, ":")) != NULL) { - if (optional1[1] != '=' && optional1[1] != ':' && optional1[1] != 0) { - fprintf(stderr, "[ERROR] Wrong syntax of optional argument: %s\n", optional1); + if (strstr(hydra_options.miscptr, "\\:") != NULL) { + fprintf(stderr, "[INFORMATION] escape sequence \\: detected in module " + "option, no parameter verification is performed.\n"); + } else { + sprintf(bufferurl, "%.6000s", hydra_options.miscptr); + url = strtok(bufferurl, ":"); + variables = strtok(NULL, ":"); + cond = strtok(NULL, ":"); + optional1 = strtok(NULL, "\n"); + if ((variables == NULL) || (strstr(variables, "^USER^") == NULL && strstr(variables, "^PASS^") == NULL && strstr(variables, "^USER64^") == NULL && strstr(variables, "^PASS64^") == NULL)) { + fprintf(stderr, + "[ERROR] the variables argument needs at least the strings " + "^USER^, ^PASS^, ^USER64^ or ^PASS64^: %s\n", + STR_NULL(variables)); exit(-1); } + if ((url == NULL) || (cond == NULL)) { + fprintf(stderr, + "[ERROR] Wrong syntax, requires three arguments separated by " + "a colon which may not be null: %s\n", + bufferurl); + exit(-1); + } + while ((optional1 = strtok(NULL, ":")) != NULL) { + if (optional1[1] != '=' && optional1[1] != ':' && optional1[1] != 0) { + fprintf(stderr, "[ERROR] Wrong syntax of optional argument: %s\n", optional1); + exit(-1); + } - switch (optional1[0]) { - case 'C': // fall through - case 'c': - if (optional1[1] != '=' || optional1[2] != '/') { - fprintf(stderr, - "[ERROR] Wrong syntax of parameter C, must look like " - "'C=/url/of/page', not http:// etc.: %s\n", - optional1); - exit(-1); + switch (optional1[0]) { + case 'C': // fall through + case 'c': + if (optional1[1] != '=' || optional1[2] != '/') { + fprintf(stderr, + "[ERROR] Wrong syntax of parameter C, must look like " + "'C=/url/of/page', not http:// etc.: %s\n", + optional1); + exit(-1); + } + break; + case 'H': // fall through + case 'h': + if (optional1[1] != '=' || strtok(NULL, ":") == NULL) { + fprintf(stderr, + "[ERROR] Wrong syntax of parameter H, must look like " + "'H=X-My-Header: MyValue', no http:// : %s\n", + optional1); + exit(-1); + } + break; + default: + fprintf(stderr, "[ERROR] Unknown optional argument: %s\n", optional1); } - break; - case 'H': // fall through - case 'h': - if (optional1[1] != '=' || strtok(NULL, ":") == NULL) { - fprintf(stderr, - "[ERROR] Wrong syntax of parameter H, must look like " - "'H=X-My-Header: MyValue', no http:// : %s\n", - optional1); - exit(-1); - } - break; - default: - fprintf(stderr, "[ERROR] Unknown optional argument: %s\n", optional1); } } } @@ -3286,6 +3408,9 @@ int main(int argc, char *argv[]) { hydra_options.port = port; } + if (hydra_options.login == NULL && hydra_options.loginfile == NULL && hydra_options.colonfile == NULL) + hydra_options.exit_found = 1; + if (hydra_options.ssl == 0 && hydra_options.port == 443) fprintf(stderr, "[WARNING] you specified port 443 for attacking a http " "service, however did not specify the -S ssl switch nor " @@ -3364,6 +3489,13 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile); exit(-1); } + else if (hydra_options.passfile == NULL){ + if(my_segment && num_segments){ + filecloser = lfp; + lfp = hydra_divide_file(lfp, my_segment, num_segments); + fclose(filecloser); + } + } hydra_brains.countlogin = countlines(lfp, 0); hydra_brains.sizelogin = size_of_data; if (hydra_brains.countlogin == 0) { @@ -3396,6 +3528,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile); exit(-1); } + else if(my_segment && num_segments){ + filecloser = pfp; + pfp = hydra_divide_file(pfp, my_segment, num_segments); + fclose(filecloser); + } hydra_brains.countpass = countlines(pfp, 0); hydra_brains.sizepass = size_of_data; if (hydra_brains.countpass == 0) { @@ -3450,6 +3587,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile); exit(-1); } + else if(my_segment && num_segments){ + filecloser = cfp; + cfp = hydra_divide_file(cfp, my_segment, num_segments); + fclose(filecloser); + } hydra_brains.countlogin = countlines(cfp, 1); hydra_brains.sizelogin = size_of_data; if (hydra_brains.countlogin == 0) { @@ -3505,7 +3647,7 @@ int main(int argc, char *argv[]) { fclose(rfp); } - if (hydra_options.infile_ptr != NULL) { + if (hydra_options.infile_ptr != NULL) { if ((ifp = fopen(hydra_options.infile_ptr, "r")) == NULL) { fprintf(stderr, "[ERROR] File for targets not found: %s\n", hydra_options.infile_ptr); exit(-1); @@ -3547,13 +3689,14 @@ int main(int argc, char *argv[]) { if (*tmpptr == '[') { tmpptr++; hydra_targets[i]->target = tmpptr; - if ((tmpptr2 = index(tmpptr, ']')) != NULL) { + if ((tmpptr2 = strchr(tmpptr, ']')) != NULL) { *tmpptr2++ = 0; tmpptr = tmpptr2; } } else hydra_targets[i]->target = tmpptr; - if ((tmpptr2 = index(hydra_targets[i]->target, ':')) != NULL) { + + if ((tmpptr2 = strchr(tmpptr, ':')) != NULL) { *tmpptr2++ = 0; tmpptr = tmpptr2; hydra_targets[i]->port = atoi(tmpptr2); @@ -3562,6 +3705,13 @@ int main(int argc, char *argv[]) { } if (hydra_targets[i]->port == 0) hydra_targets[i]->port = hydra_options.port; + + if ((tmpptr3 = strchr(tmpptr, '/')) != NULL) { + hydra_targets[i]->miscptr = tmpptr3; + } + else + hydra_targets[i]->miscptr = "/"; + while (*tmpptr != 0) tmpptr++; tmpptr++; @@ -3569,13 +3719,13 @@ int main(int argc, char *argv[]) { } else if (hydra_options.server == NULL) { fprintf(stderr, "Error: no target server given, nor -M option used\n"); exit(-1); - } else if (index(hydra_options.server, '/') != NULL) { + } else if (strchr(hydra_options.server, '/') != NULL) { if (cmdlinetarget == NULL) bail("You seem to mix up \"service://target:port/options\" syntax with " "\"target service options\" syntax. Read the README on how to use " "hydra correctly!"); if (strstr(cmdlinetarget, "://") != NULL) { - tmpptr = index(hydra_options.server, '/'); + tmpptr = strchr(hydra_options.server, '/'); if (tmpptr != NULL) *tmpptr = 0; countservers = hydra_brains.targets = 1; @@ -3584,6 +3734,7 @@ int main(int argc, char *argv[]) { memset(hydra_targets[0], 0, sizeof(hydra_target)); hydra_targets[0]->target = servers_ptr = hydra_options.server; hydra_targets[0]->port = hydra_options.port; + hydra_targets[0]->miscptr = hydra_options.miscptr; sizeservers = strlen(hydra_options.server) + 1; } else { /* CIDR notation on command line, e.g. 192.168.0.0/24 */ @@ -3598,7 +3749,7 @@ int main(int argc, char *argv[]) { exit(-1); } strcpy(tmpptr, hydra_options.server); - tmpptr2 = index(tmpptr, '/'); + tmpptr2 = strchr(tmpptr, '/'); *tmpptr2++ = 0; if ((k = atoi(tmpptr2)) < 16 || k > 31) { fprintf(stderr, "Error: network size may only be between /16 and /31: %s\n", hydra_options.server); @@ -3628,6 +3779,7 @@ int main(int argc, char *argv[]) { memcpy(&target.sin_addr.s_addr, (char *)&addr_cur2, 4); hydra_targets[i]->target = strdup(inet_ntoa((struct in_addr)target.sin_addr)); hydra_targets[i]->port = hydra_options.port; + hydra_targets[i]->miscptr = hydra_options.miscptr; addr_cur++; i++; } @@ -3643,6 +3795,7 @@ int main(int argc, char *argv[]) { memset(hydra_targets[0], 0, sizeof(hydra_target)); hydra_targets[0]->target = servers_ptr = hydra_options.server; hydra_targets[0]->port = hydra_options.port; + hydra_targets[0]->miscptr = hydra_options.miscptr; sizeservers = strlen(hydra_options.server) + 1; } for (i = 0; i < hydra_brains.targets; i++) { @@ -3764,7 +3917,7 @@ int main(int argc, char *argv[]) { printf(" per task\n"); if (hydra_brains.targets == 1) { - if (index(hydra_targets[0]->target, ':') == NULL) { + if (strchr(hydra_targets[0]->target, ':') == NULL) { printf("[DATA] attacking %s%s://%s:", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_targets[0]->target); printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); } else { @@ -3840,7 +3993,7 @@ int main(int argc, char *argv[]) { #ifdef AF_INET6 ipv6 = NULL; #endif - if ((device = index(hydra_targets[i]->target, '%')) != NULL) + if ((device = strchr(hydra_targets[i]->target, '%')) != NULL) *device++ = 0; if (getaddrinfo(hydra_targets[i]->target, NULL, &hints, &res) != 0) { if (use_proxy == 0) { @@ -3906,9 +4059,10 @@ int main(int argc, char *argv[]) { } freeaddrinfo(res); } - // restore device information if present + // restore device information if present (overwrite null bytes) if (device != NULL) { - *(device - 1) = '%'; + char *tmpptr = device - 1; + *tmpptr = '%'; // you can ignore the compiler warning fprintf(stderr, "[WARNING] not all modules support BINDTODEVICE for IPv6 " "link local addresses, e.g. SSH does not\n"); } @@ -4074,7 +4228,7 @@ int main(int argc, char *argv[]) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); } else - printf("[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); + printf("[%d][%s] host: %s misc: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_targets[hydra_heads[head_no]->target_no]->miscptr, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); } if (hydra_options.outfile_format == FORMAT_JSONV1 && hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { fprintf(hydra_brains.ofp, @@ -4129,6 +4283,21 @@ int main(int argc, char *argv[]) { fck = write(hydra_heads[head_no]->sp[1], "n", 1); // small hack break; + case 'D': // disable target, unknown protocol or feature + for (j = 0; j < hydra_brains.targets; j++) + if (hydra_targets[j]->done == TARGET_ACTIVE) { + hydra_targets[j]->done = TARGET_FINISHED; + hydra_brains.finished++; + } + for (j = 0; j < hydra_options.max_use; j++) + if (hydra_heads[j]->active >= 0 && hydra_heads[j]->target_no == target_no) { + if (hydra_brains.targets > hydra_brains.finished) + hydra_kill_head(j, 1, 0); // kill all heads working on the target + else + hydra_kill_head(j, 1, 2); // kill all heads working on the target + } + break; + // we do not make a difference between 'C' and 'E' results - yet case 'E': // head reports protocol error case 'C': // head reports connect error @@ -4197,7 +4366,7 @@ int main(int argc, char *argv[]) { // hydra_brains.sent); usleepn(USLEEP_LOOP); - (void)wait3(NULL, WNOHANG, NULL); + (void)waitpid(-1, NULL, WNOHANG); // write restore file and report status if (process_restore == 1 && time(NULL) - elapsed_restore > 299) { hydra_restore_write(0); @@ -4300,7 +4469,7 @@ int main(int argc, char *argv[]) { for (i = 0; i < hydra_options.max_use; i++) if (hydra_heads[i]->active == HEAD_ACTIVE && hydra_heads[i]->pid > 0) hydra_kill_head(i, 1, 3); - (void)wait3(NULL, WNOHANG, NULL); + (void)waitpid(-1, NULL, WNOHANG); #define STRMAX (10 * 1024) char json_error[STRMAX + 2], tmp_str[STRMAX + 2]; @@ -4335,6 +4504,7 @@ int main(int argc, char *argv[]) { strncat(json_error, tmp_str, STRMAX); strncat(json_error, "\"", STRMAX); error = 1; + hydra_restore_write(1); } // yeah we did it printf("%s (%s) finished at %s\n", PROGRAM, RESOURCE, hydra_build_time()); @@ -4353,4 +4523,4 @@ int main(int argc, char *argv[]) { return -1; else return 0; -} +} \ No newline at end of file diff --git a/hydra.h b/hydra.h index 6698eaf..24b63e8 100644 --- a/hydra.h +++ b/hydra.h @@ -101,6 +101,8 @@ #define PORT_MYSQL_SSL 3306 #define PORT_MSSQL 1433 #define PORT_MSSQL_SSL 1433 +#define PORT_COBALTSTRIKE 50050 +#define PORT_COBALTSTRIKE_SSL 50050 #define PORT_POSTGRES 5432 #define PORT_POSTGRES_SSL 5432 #define PORT_ORACLE 1521 @@ -192,6 +194,7 @@ typedef struct { int32_t cidr; int32_t time_next_attempt; output_format_t outfile_format; + char *distributed; // Use distributed computing by splitting user files on the fly char *login; char *loginfile; char *pass; diff --git a/pw-inspector.1 b/pw-inspector.1 index 90bff65..c9f228c 100644 --- a/pw-inspector.1 +++ b/pw-inspector.1 @@ -42,7 +42,7 @@ upcase characters (A,B,C,D, etc.) numbers (1,2,3,4, etc.) .TP .B \-p -printable characters (which are not \-l/\-n/\-p, e.g. $,!,/,(,*, etc.) +printable characters (which are not \-l/\-n/\-n, e.g. $,!,/,(,*, etc.) .TP .B \ -s special characters \- all others not withint the sets above diff --git a/pw-inspector.c b/pw-inspector.c index 2f53e05..8b87a5a 100644 --- a/pw-inspector.c +++ b/pw-inspector.c @@ -30,7 +30,7 @@ void help() { printf(" -l lowcase 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(" -p printable characters (which are not -l/-n/-p, e.g. " + printf(" -p printable characters (which are not -l/-u/-n, e.g. " "$,!,/,(,*, etc.)\n"); printf(" -s special characters - all others not within the sets " "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 set_low = 0, set_up = 0, set_no = 0, set_print = 0, set_other = 0; FILE *in = stdin, *out = stdout; - char buf[MAXLENGTH + 1]; + unsigned char buf[MAXLENGTH + 1]; prg = argv[0]; if (argc < 2) @@ -124,9 +124,9 @@ int main(int argc, char *argv[]) { if (countsets == 0) countsets = sets; - while (fgets(buf, sizeof(buf), in) != NULL) { - i = -1; - if (buf[0] == 0) + while (fgets((void *)buf, sizeof(buf), in) != NULL) { + int is_low = 0, is_up = 0, is_no = 0, is_print = 0, is_other = 0; + if (!buf[0]) continue; if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; @@ -134,40 +134,31 @@ int main(int argc, char *argv[]) { buf[strlen(buf) - 1] = 0; if (strlen(buf) >= minlen && strlen(buf) <= maxlen) { i = 0; - if (countsets > 0) { - if (set_low) - if (strpbrk(buf, "abcdefghijklmnopqrstuvwxyz") != NULL) - i++; - if (set_up) - if (strpbrk(buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") != NULL) - i++; - if (set_no) - if (strpbrk(buf, "0123456789") != NULL) - i++; - if (set_print) { - j = 0; - for (k = 0; k < strlen(buf); k++) - if (isprint((int32_t)buf[k]) != 0 && isalnum((int32_t)buf[k]) == 0) - j = 1; - if (j) - i++; - } - if (set_other) { - j = 0; - for (k = 0; k < strlen(buf); k++) - if (isprint((int32_t)buf[k]) == 0 && isalnum((int32_t)buf[k]) == 0) - j = 1; - if (j) - i++; + j = 1; + for (i = 0; i < strlen(buf) && j; i++) { + j = 0; + if (set_low && islower(buf[i])) { + j = 1; + is_low = 1; + } else if (set_up && isupper(buf[i])) { + j = 1; + is_up = 1; + } else if (set_no && isdigit(buf[i])) { + j = 1; + is_no = 1; + } else if (set_print && isprint(buf[i]) && !isalnum(buf[i])) { + j = 1; + is_print = 1; + } else if (set_other && !isprint(buf[i])) { + j = 1; + is_other = 1; } } - if (i >= countsets) { + if (j && countsets <= is_low + is_up + is_no + is_print + is_other) { fprintf(out, "%s\n", buf); count++; } } - /* fprintf(stderr, "[DEBUG] i: %d minlen: %d maxlen: %d len: %d\n", i, - * minlen, maxlen, strlen(buf)); */ } fclose(in); fclose(out); diff --git a/xhydra.desktop b/xhydra.desktop new file mode 100644 index 0000000..69debb5 --- /dev/null +++ b/xhydra.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=XHydra +GenericName=Hydra very fast network log-on cracker +Comment=GUI frontend for Hydra network log-on cracker +Version=1.0 +Exec=xhydra +Icon=xhydra +Terminal=false +Type=Application +Categories=System;Security;GTK; diff --git a/xhydra.png b/xhydra.png new file mode 100644 index 0000000..39f2704 Binary files /dev/null and b/xhydra.png differ