Hyrda is a beloved tool for penetration testers to brute-force online passwords. Hydra is featured filled, open-source and supports any protocol you could think of. You can see all the protocols supported by Hydra on their GitHub under the INTRODUCTION header.
Hydra has a graphical user interface with the xhyrdra package but I am only covering the command line use of hydra in this article.
This is the general syntax for brute-forcing logins.
hydra -l user -P passlist.txt ftp://10.10.193.105 -t 4 or hydra -l user -P passlist.txt 10.10.193.105 -t 4 ftp <-- you can change this out
|-P||List of passwords|
|-t||The number of threads used|
|-V||Outputs every attempted password|
Using hydra on web forms is slightly harder. First off, you need to know whether the form you are submitting is using the GET or POST methods. The easiest way is to press ctrl+u to see the page source or use the network tab in the developer settings. You also need to know what the names of the headers are for the data you are submitting. Generally, they will be "username" and "password" but it is good to double-check. An example of what a form looks like is below:
from view-source:http://form.xyz/login <body class="text-center"> <form class="form-signin" action="/login" method="post"> <a href='/'><img class="mb-4" style='width: 200px;' src="/img/herc.gif" alt=""></a> <h1 class="h3 mb-3 font-weight-normal">Login</h1> <label for="inputEmail" class="sr-only">Username</label> <input type="text" name="username" class="form-control" placeholder="Username" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="password" class="form-control" placeholder="Password" required> <button class="btn btn-lg btn-primary btn-block" type="submit">Login</button> <p class="mt-5 mb-3 text-muted">© HydraSite 2012 - 2020</p> </form> </body>
You can see that this form is using the post method and is using the headers username & password. In addition, we need to know the subpage on the form where the login page is. In this case, it is "\login". We then can use the structure below.
hydra -l <username> -P <wordlist> IP http-post-form "/login:username=^USER^&password=^PASS^:F=incorrect"
|-P||Indicates the use of apassword list|
|http-post-form||indicates the type of form|
|/login url||the login page URL|
|:username||the Form field where the username is entered|
|^USER^||tells Hydra to use the username|
|password||the Form field where the password is entered|
|^PASS^||tells Hydra to use the password list supplied earlier|
|Login||indicates to Hydra the Login Failed message|
|F=incorrect||If this word appears on the page, its incorrect and continue brute-forcing|
The easiest way to use proxies is to set the HYDRA_PROXY variable. You can do this by:
The other way to use is proxychains. I have done an article about this here if you want to learn more about it. Sadly, TOR will not work.
If you want to resume your hydra session use
If you want more information about a specific module use the flag
┌──(root㉿desktop)-[~] └─$ hydra https-get-form -U Hydra v9.3 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-06-16 21:08:17 Help for module https-get-form: ============================================================================ Module http-get-form requires the page and the parameters for the web form. By default this module is configured to follow a maximum of 5 redirections in a row. It always gathers a new cookie from the same URL without variables The parameters take three ":" separated values, plus optional values. (Note: if you need a colon in the option string as value, escape it with "\:", but do not escape a "\" with "\\".) Syntax: <url>:<form parameters>:<condition string>[:<optional>[:<optional>] First is the page on the server to GET or POST to (URL). Second is the POST/GET variables (taken from either the browser, proxy, etc. with url-encoded (resp. base64-encoded) usernames and passwords being replaced in the "^USER^" (resp. "^USER64^") and "^PASS^" (resp. "^PASS64^") placeholders (FORM PARAMETERS) Third is the string that it checks for an *invalid* login (by default) Invalid condition login check can be preceded by "F=", successful condition login check must be preceded by "S=". This is where most people get it wrong. You have to check the webapp what a failed string looks like and put it in this parameter! The following parameters are optional: (c|C)=/page/uri to define a different page to gather initial cookies from (g|G)= skip pre-requests - only use this when no pre-cookies are required (h|H)=My-Hdr\: foo to send a user defined HTTP header with each request ^USER^ and ^PASS^ can also be put into these headers! Note: 'h' will add the user-defined header at the end regardless it's already being sent by Hydra or not. 'H' will replace the value of that header if it exists, by the one supplied by the user, or add the header at the end Note that if you are going to put colons (:) in your headers you should escape them with a backslash (\). All colons that are not option separators should be escaped (see the examples above and below). You can specify a header without escaping the colons, but that way you will not be able to put colons in the header value itself, as they will be interpreted by hydra as option separators. Examples: "/login.php:user=^USER^&pass=^PASS^:incorrect" "/login.php:user=^USER64^&pass=^PASS64^&colon=colon\:escape:S=authlog=.*success" "/login.php:user=^USER^&pass=^PASS^&mid=123:authlog=.*failed" "/:user=^USER&pass=^PASS^:failed:H=Authorization\: Basic dT1w:H=Cookie\: sessid=aaaa:h=X-User\: ^USER^:H=User-Agent\: wget" "/exchweb/bin/auth/owaauth.dll:destination=http%3A%2F%2F<target>%2Fexchange&flags=0&username=<domain>%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:reason=:C=/exchweb"