Now supports both syntaxes Currently, doesn't tab complete service options but does show help
		
			
				
	
	
		
			240 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #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
 |