Friday, April 20, 2012

Using cURL to Brute Force HTTP Login

When doing web application testing, if you are presented with a login page via HTTP, a vulnerability that is definitely worth looking for is user enumeration based on the response from the web server. Basically the tester needs to throw different kinds of usernames and passwords at an application and look for ANY kind of difference in the responses. If the application returns a larger page(even if its only a few bytes), or you see that the URL changes for some types of usernames or passwords, then that is one (of many) possible signs that an application could be vulnerable to this attack. OWASP explains in more detail here.

In one such application, when certain usernames were submitted to the server, the server returned a page that was larger than the typical error page. I needed to find a way to submit lots of usernames via POST requests in hopes of enumerating valid usernames based on the returned page. One application that would be able to do this is THC-Hydra. Hydra is an incredibly powerful brute forcing tool that supports many different types of services, not only HTTP. You can view the supported protocols here.

 I could have used hydra in this scenario, but I wanted to figure out a way to write my own brute forcing script so that I could give it some customization. After some research, I learned that CURL, a program prepackaged in most flavors of linux, would be a great tool for what I needed to do.

So what exactly did I need to do? I needed to take a list of usernames and loop through each one, sticking the username in the data to be submitted via POST requests to the server. I fired up burp suite and grabbed a copy of the extra data that the server needed, including the username and password fields.

Once I had that, I used curl with the -d switch. I then piped the results to grep and searched for a string that was only returned on the pages where the username was a valid one.

Curl -s -d "allthePOSTdatagoes&here&username=USERNAMEHERE&password=PASSWORDHERE" | grep "validpage" 

The -s switch in Curl just says to be "silent" and dont print the results of each request to stdout. Throw that in bash script and you have your very own, simple, fairly fast account brute forcer . At this point, the attacker is halfway done with a successful brute force attack. All he would need to do now is take one of the valid usernames and do the very same thing for the password field until the script successfully guesses the password.


How to fix: To fix this vulnerability, the invalid login pages that are returned must be the EXACT same. As I have stated before, even just a few bytes difference in the pages (for example, a simple spelling error) could tip off an attacker, and allow him to successfully enumerate valid usernames. If an attacker does not know valid usernames, his job is twice as hard and would require MUCH more time to brute force an account, because he has to blindly guess combinations of usernames and password to get access.

Thursday, April 5, 2012

Forefront Threat Management Gateway: IP list with Powershell


I needed to add a *large* list of IP addresses to an installation of Microsoft's Forefront Threat Management Gateway. I was going to try and do this through the GUI, but soon came to find out that I was not able to load ips from a file, and would need to type every IP range in MANUALLY. No thanks.....

Once again, it seems its Powershell to the rescue (at least when it comes to Micro$oft products). Powershell has a COM object that allows FTMG to be configured from powershell using various methods/arrays/objects.

There is not much (in fact, barely any) documentation on this, but I found some very useful info and examples from this site http://merddyn.wordpress.com/2009/05/05/managing-isa-with-powershell-primer/.

For this particular example, I was using a massive list from http://www.countryipblocks.net/ in the "IP Range Format". I just copied those addresses to a file on my machine.

/* Note: IF you choose to do a different format for the IP addresses other than
"192.168.5.1 - 192.168.5.255", this script will not work for you. You will have to do some editing to get yours working properly.*/

Here is the script I ended up with. I put #placeholders# for variables that you will need to fill in for your particular scenario.

  
$rootobject = New-object -com FPC.root
$array = $rootobject.getcontainingarray()
$file = "#ipfile.txt#"
$fileclean = cat $file | foreach-object {$_.split("-")} |
foreach-object {$_.trim()}
$networkname = "#networknamegoeshere#"
$i=1
$array.networkconfiguration.networks.add($networkname)
$fileclean | foreach-object {

           if ($i -eq 1){

                               $ip1 = $_
                        }

           if ($i -eq 2){
                               $ip2 = $_
             $array.networkconfiguration.Networks.item($networkname).IpRangeSet.add($ip1,$ip2)

                        }
       $i++; if ($i -eq 3) {$i = 1}

                            }
$array.networkconfiguration.save()
$array.applychanges()