About this blog

I'm a developer with over 10 years experience who wants to transition to infosec. This blog is an informal record of my experiments with OWASP's Mutillidae II, a web application exhibiting a multitude of deliberate vulnerabilities. I will also take Offensive Security's PWK training course and get the OSCP certificate
Showing posts with label brute force. Show all posts
Showing posts with label brute force. Show all posts

Tuesday, 30 August 2016

Feasibility of brute forcing a remote login

Previously we brute-force mined the admin password using a blind sqli, to get the result adminpass.

But Mutillidae's login mechanism doesn't have a lockout either, and the password was weak, so maybe we could have successfully brute forced this password from a wordlist, without even having a sqli.

However, even something as simple as adminpass may take a very long time to come across, and depend on the wordlist used.  On Kali, out of well  over 100 wordlists, only 4 have it.

$ find -L /usr/share/wordlists -type f | wc -l
169

$ find -L /usr/share/wordlists -type f -exec grep -H ^adminpass$ {} \;
Binary file /usr/share/wordlists/sqlmap.txt matches
/usr/share/wordlists/metasploit/ipmi_passwords.txt:adminpass
/usr/share/wordlists/metasploit/default_pass_for_services_unhash.txt:adminpass
/usr/share/wordlists/metasploit/common_roots.txt:adminpass

Collapsing all the .txt wordlists down into a single list reveals there are about 2 million entries:

$ find -L /usr/share/wordlists "*.txt" -type f -exec cat {} \; | wc -l
2632913

$ find -L /usr/share/wordlists "*.txt" -type f -exec cat {} \; | sort | uniq | wc -l
1942391

If we gave the server 100 logins/sec (across many threads), that would take about 5.5 hours to exhaust that list for one account, which might be worthwhile for an attacker in terms of a quick hit and run.  That is feasible.

But trying all combinations of characters is definitely less attractive over a network at a mere 100s of requests/second.  Even a 5 character password of all lower case letters would be 11 million guesses...

This might still suit some attackers, I'm guessing.  Maybe they could afford to drip-feed guesses in over days, weeks, or even months for the payoff.  Or maybe the organization being targeted is so big and fielding so much traffic that 100s or 1000s of extra logins/sec aren't going to negatively impact anything, and monitoring/alerting may not even pick it up (or if so, maybe not immediately).

Rational guidelines that I can think of for an attacker might be:
  1. Exact account needed = massive wordlist
  2. Volume/any-account-will-do: top N passwords by frequency fitting userbase profile
  3. Short of time or webscale company where traffic will be lost, stealth not needed: hit as hard as possible, parallelize, smash n grab
  4. Small company can't handle load, or stealth needed: drip feed
  5. Probably wouldn't bother at all with brute force combinations, when there are millions of publicly released actual passwords to create wordlists from (and humans are predictable) unless totally desperate for a specific account and not under time pressure
Anyway, just for the hell of it I'll write a single threaded wordlist brute forcer and try it out on Mutillidae.

Result:

*** starting admin
100 passwords done for admin: rps=14 - 1234
200 passwords done for admin: rps=14 - 1986673
300 passwords done for admin: rps=14 - 3ware
400 passwords done for admin: rps=14 - 9ijn7ygv
500 passwords done for admin: rps=14 - CMSBATCH
600 passwords done for admin: rps=14 - HP
700 passwords done for admin: rps=13 - NAU
800 passwords done for admin: rps=14 - POSTMASTER
900 passwords done for admin: rps=14 - SESAME
1000 passwords done for admin: rps=14 - USER2
1100 passwords done for admin: rps=14 - accord
*** password for admin is adminpass (1122 requests)
*** elapsed minutes: 1.3283847778320312
*** starting bryce
...
*** password for bryce is PASSWORD (781 requests)
*** elapsed minutes: 0.9175332845052083
...
*** password for dave not found
*** elapsed minutes: 5.59463681233724
...
*** password for PPan is nottelling (3437 requests)
*** elapsed minutes: 4.195157751464844...

Well, you get the idea.

Monday, 29 August 2016

Brute force data mining with any sqli

So on the first page I looked at - login - there was a sqli.  We can't get any SELECT output from the sqli (e.g. SELECT PASSWORD...), so I think that's called a 'blind' sqli.

Anyway, we can distinguish between an arbitrary proposition passing and failing (in our case by presence/absence of error message, although a timing attack would also do), and in conjunction with already knowing the table and column name (thanks to that chatty error message), it is enough to have a go at brute force mining the password, in case it is in plain text.

I mine the length first, for two reasons:
  1. It will cut the number of requests down (don't have to exhaust the character set at the end)
  2. My testing found that character indexes that didn't exist matched a space, and I couldn't be bothered to make a special case for detecting actual space versus a nonexistent char
I also looked up the frequency of password chars and test for them in that order, to reduce request volume.

Result:

length  9
password 'adminpass'
77  requests in total

It was plain text, which is bad.  I think most people know by now to store salted hashes, and make the hash cost high.

Brute forcing is noisy, but really 77 requests is cheap to get a password!  That sort of volume probably won't attract any attention, and nobody gets locked out of their account either (we aren't passing a username when we fail).

Really, any sqli will do.  And if I didn't know the table/column name, I could get 'meta' and start brute force mining the schema/table/column names themselves and burrow top-down into interesting strings (really noisy, but it'll work if the permissions are good).