#compdef hydra tokens=(${(z)LBUFFER}) if [[ "${LBUFFER[-1]}" == " " ]]; then previousArg="${tokens[-1]}" else previousArg="${tokens[-2]}" fi services=( "adam6500" "asterisk" "afp" "cisco" "cisco-enable" "cvs" "firebird" "ftp" "ftps" "http-head" "https-head" "http-get" "https-get" "http-post" "https-post" "http-get-form" "https-get-form" "http-post-form" "https-post-form" "http-proxy" "http-proxy-urlenum" "icq" "imap" "imaps" "irc" "ldap2" "ldap2s" "ldap3" "ldap3s" "ldap3-crammd5" "ldap3-crammd5s" "ldap3-digestmd5" "ldap3-digestmd5s" "mssql" "mysql" "nntp" "oracle-listener" "oracle-sid" "pcanywhere" "pcnfs" "pop3" "pop3s" "postgres" "radmin2" "redis" "rexec" "rlogin" "rpcap" "rsh" "rtsp" "s7-300" "sip" "smb" "smtp" "smtps" "smtp-enum" "snmp" "socks5" "ssh" "sshkey" "svn" "teamspeak" "telnet" "telnets" "vmauthd" "vnc" "xmpp" ) min_max_charset(){ _message -r "$(hydra -x -h)" } service_help(){ if [ "$1" = "new" ]; then service="$( echo "${tokens[-1]}" | cut -d':' -f1)" _message -r "$(hydra -U $service)" else _message -r "$(hydra -U $previousArg)" fi } service_list(){ _describe "Services" services } args=( "-R[restore a previous aborted/crashed session]" "-I[ignore an existing restore file (don't wait 10 seconds)]" "-S[perform an SSL connect]" "-s[if the service is on a different default port, define it here]:value" "-l[login with LOGIN name]:value" "-L[load several logins from a file]:filename:_files" "-p[try password PASS]:value" "-P[load several passwords from a file]:filename:_files" "-C[colon separated \"login:pass\" format, instead of -L/-P options]:filename:_files" "-x[MIN:MAX:CHARSET password bruteforce generation, type \"-x -h\" to get help]:min-max:min_max_charset" "-y[disable use of symbols in bruteforce, see above]" "-e[Extra passowrds to try options (nsr)]:nsr:_values -s '' \"Options\" \"n[Null Password]\" \"s[Login as Password]\" \"r[Reversed Login as Password]\"" "-u[loop around users, not passwords (effective! implied with -x)]" "-M[list of servers to attack, one entry per line, ':' to specify port]:filename:_files" "-o[write found login/password pairs to FILE instead of stdout]:filename:_files" "-b[specify the format for the -o FILE]:format:_values \"Ouptut type\" text json jsonv1" "-f[exit when a login/pass pair is found (-M: -f per host)]" "-F[exit when a login/pass pair is found (-M: -F global)]" "-t[run X number of connects in parallel per target (default: 16)]:value" "-T[run X connects in parallel overall (for -M, default: 64)]:value" "-w[wait x time for a response (32)]:value" "-W[wait x time between connects per thread (0)]" "-c[wait x time per login attempt over all threads (enforces -t 1)]" "-4[use IPv4 (default)]" "-6[use IPv6 addresses (put always in \[\] also in -M)]" "-v[verbose mode]" "-V[show login+pass for each attempt]" "-d[debug mode]" "-O[use old SSL v2 and v3]" "-q[do not print messages about connection errors]" "-U[service module usage details]:services:service_list" "-h[COMPLETE HELP]" ) declare -a delete if (( ${tokens[(I)-l]} )); then delete=("-L" "-C") elif (( ${tokens[(I)-L]} )); then delete=("-l" "-C") elif (( ${tokens[(I)-p]} )); then delete=("-P" "-C") elif (( ${tokens[(I)-P]} )); then delete=("-p" "-C") elif (( ${tokens[(I)-C]} )); then delete=("-l" "-L" "-p" "-P") fi for target in "${delete[@]}"; do args=("${(f)$(echo -e "${(pj:\n:)args}" | grep -v "^${target}")}") done #&& fzf_dirs "$current" || fzf_files "$current" local -a line expl local -i ret=1 typeset -A opt_args # Hydra has 2 syntaxes. They are: # # hydra [some command line options] [-s PORT] TARGET PROTOCOL [MODULE-OPTIONS] # or # hydra [some command line options] PROTOCOL://TARGET:PORT/MODULE-OPTIONS # # The protocol:// option is considered the new version but can only be used if there is 1 target newSyntax="either" targetNeeded="true" # If the -M option is given, we need to use the old syntax if (( ${tokens[(I)-M]} )); then newSyntax="false" targetNeeded="false" fi if $(echo "$BUFFER" | grep -Eq "(${(j:|:)services}) "); then newSyntax="false" fi #if [ "$newSyntax" != "false" ]; then # _arguments -C -s "${args[@]}" ':service:->hydra_service' && return # case $state in # hydra_service) # if compset -P "(${(j:|:)services})://*/"; then # service_help "new" # elif compset -P "(${(j:|:)services})://*:"; then # _message -r "service://host:port/options" # elif compset -P "(${(j:|:)services})://"; then # _hosts -S ':' && ret=0 # else # compadd -S '://' -q -a services && ret=0 # fi # ;; # esac #else _arguments -C -s "${args[@]}" ':target:->param1' ':service:->param2' ':options:->param3' && return case $state in param1) if [ "$newSyntax" != "false" ]; then if compset -P "(${(j:|:)services})://*/"; then newSyntax="true" service_help "new" elif compset -P "(${(j:|:)services})://*:"; then _message -r "service://host:port/options" newSyntax="true" elif compset -P "(${(j:|:)services})://"; then _hosts -S ':' newSyntax="true" else compadd -S '://' -q -a services fi fi if [ "$newSyntax" != "true" ]; then if [ "$targetNeeded" = "true" ]; then _hosts else compadd -q -a services fi fi ;; param2) if [ "$newSyntax" != "true" ]; then if [ "$targetNeeded" = "true" ]; then compadd -q -a services else service_help fi fi ;; param3) if [ "$newSyntax" != "true" ]; then if [ "$targetNeeded" = "true" ]; then service_help fi fi ;; esac #fi