Wordpress Logins

Automated hacking attempts into Wordpress

Introduction

Wordpress is the most popular blog and website management system. As such, it is a frequent target of attacks, like a recent wave of hacks by ISIS sympathizers has demonstrated.

My website does not use Wordpress. It never has, and nothing suggests it does. Yet, I found that I was getting a lot of requests for the page wp-index.php, which is the standard name for Wordpress' login page. Until now, there has been no link or mention of a wp-login.php page on this website.

In May 2013, I decided to set up a fake login form at wp-login.php mimicking the standard Wordpress login page. I saved all incoming login requests into a database. This page discusses the thousands of login attempts I have registered in the course of two years.

Numbers at a Glance

It was on May 10th, 2013 that I registered the first login attempt sent to wp-login.php, and now, at the time of writing, May 17th, 2015, the last login attempt was... well, 20 seconds ago. There have been a total of 163,204 login attempts in the span of 737 days, which comes to an average of 221 login attempts per day.

21,865 different IP addresses have tried their luck on my fake login page, so we have about 7.5 login attempts per IP address. As you can imagine, the number of attempts per IP varies: 4,970 IP addresses sent one mere login request, 5,370 sent two requests.

The winner is an IP address from the Ukraine, 94.76.77.146, with a whopping 4,235 login attempts to my page, accounting for 2.6% of all login attempts I registered in two years. IP address 46.182.31.232 also gets a special mention for submitting 1,341 login attempts within 17 hours.

It is clear from the visiting patterns and the rate of login requests that these attacks are automatic and untargeted, i.e. my website isn't specifically being attacked. These login requests come from automatic bots which probe websites for standard page names and then try to brute-force their way into the software, i.e. they try likely passwords and hope to gain access.

Most Tried Usernames

The following table shows the top 10 usernames that have been used in the login requests. The middle column shows how many different IP addresses have used the username to submit at least one login request, while the right column indicates the total number of login requests with that username.
Username Unique IPs Total requests
admin 20345 91226
korn19 9602 28882
administrator 7390 25773
support 885 2597
adm 827 1606
{domain} 703 1140
root 515 1328
user 371 1097
user2 338 753
tester 315 685

There isn't a lot of variety in the usernames. 95% of all IP addresses have used admin as name in at least one login request. We also note that there is a significant decrease in requests and IP addresses between administrator and support, i.e. the top three usernames have been used considerably more. Only 911 IP addresses (4%) never used admin or korn19, while 13,129 IP addresses (60%) exclusively used admin and korn19 as usernames.

It is no surprise that most of the top usernames are very generic names such as admin or user since these attacks are automated and want to get the highest possible success rate on many different websites. It's interesting to see how often korn19 has been tried, which is obviously derived from this website's domain, korn19.ch.

One oddity is that 703 different IP addresses sent login requests with {domain} as username, which was obviously meant to be replaced with something more meaningful before the login request is sent, such as with korn19.

In the database, additional technical problems are noticeable: korn19 and {domain} have been used as username by 287 and 30 different IP addresses, respectively. The starting characters  are byte order marks in UTF-8 and should not be displayed. However, if interpreted as ISO-8859-1, they appear as . Before the request arrived to the server, there was some issue with the character encoding. Similarly, I've registered a total of 60 login requests with àäìèí, which, when interpreting in another character encoding, yields админ ("admin" in Cyrillic).

168 IP addresses have tried the username ch, probably because of the fairly uncommon .ch ending of my domain. I could imagine that these automated scripts would also use parts of a subdomain as potential username, e.g. given name.example.org, both example and name would be potential usernames. Here it probably thinks that ch is part of the domain name.

Frequent Passwords

The following table shows the top 15 passwords that have been tried, along with the number of unique IP addreses which have used the password at least once and the total number of login requests observed with the given password.
Password Unique IPs Total requests
admin 755 1596
123456 486 770
123123 345 508
password 296 460
12345678 288 491
12345 279 478
pass 274 439
admin123 255 400
123 230 352
1234 203 391
test 201 297
korn19 197 430
123456789 191 320
secret 184 255
qwerty 178 346

The top passwords don't really contain any surprises for us, either. We can see again that the domain name is sometimes incorporated into the login request – korn19 has been used as password by 197 IP addresses in at least one login attempt, and 171 have tried korn19.ch. Other passwords in this category include korn19!, korn19888 and 1234korn19.

Further down the list, it becomes apparent that passwords based on keyboard layout are being considered as well: 110 different IPs have tried 1q2w3e at least once, 76 have used 1qazxsw2.

starwars, michael, mustang and trustno1 all have been used over 100 times, which was a little surprising to me. A quick search reveals that they belong to a list of the worst passwords of 2014, and indeed, many of the most frequent passwords that have been tried on my bogus login form are present in that list.

A very important difference compared to the table of frequent usernames is that the most frequent password has only been used by 762 different IP address, i.e. by less than 3.5% of all IP addresses. There is a much higher variety of passwords than of usernames: 40,241 different passwords have been tried. 39,014 passwords (97%) were used by less than 10 IP addresses; 81.8% of the passwords have been tried by one or two IP addresses only.

Randomly selecting ten passwords used by only one or two IP addresses, we get liebevolles, mk327204, overemotionally, mjolkurvorur, feelinglier, 11111982, jubels, irenic, outgeneralled and 08091999. The passwords are fairly random and seem to incorporate various languages; liebevolles is German (I registered a lot of German passwords), and mjolkurvorur looks Icelandic. There are also a lot of passwords with cuss words. For example, 42 different passwords containing the F-word have been used.

It's important to remember that it only takes one right guess for an attacker to gain access to one's Wordpress installation, i.e. even if you don't use password or mustang as password, it's only a matter of time until a random, undirected attack will guess weak passwords such as cisco12 or irontrees. Therefore, it makes sense that the bots use a broad variety of passwords. Additionally, given the sheer amount of IP addresses using my wp-login.php page, it also makes sense to use a bot which creates passwords from dictionaries, rather than just trying the 50 most likely passwords.

The password 1,23456E+11 has been submitted by various IP addresses, which I assume is a programming error. For instance, the number 123456789 is 1,23456789E+8 in scientific notation, which certain programming languages may use to display large numbers. Therefore, it is likely that a password such as 123456789000 was actually meant to be submitted.

Password Types

We now assign one category to every password, based on the characters it consists of.
Format Passwords Uses Example
All lowercase 27721 69947 gougers, sleep
All digits 8845 18524 04071974, 2603
Lowercase + number 1584 6500 chance1, year2005
Other 1024 2411 hot-spotted, cat&dog
Lowercase/digits mixed 339 1494 ziablw4u00bq, jys6wz
Capitalized word 276 444 Www, Brianna
Digit(s) before lowercase 191 1058 1monkey
All uppercase 115 241 WIZARD, PPP
Mix of A-Z/a-z/0-9 80 178 Qwerty1, Prince27
Number + lowercase + number 48 313 1qaz2, 21wer21
Upper-/lowercase mixed 18 31 INNgft, VQsaBLPzLa


The table shows the figures relating to the different password categories. The Passwords column denotes how many different passwords are present in the category; the Uses column displays how many times these passwords have been used in a login request, whereby the password only counts once for each IP address. For instance, if the same IP address has used the password admin with various usernames, it will only count as one use.

Note that the categories Mix of A-Z/a-z/0-9, Upper-/lowercase mixed and Lowercase/digits mixed only contain the remaining passwords that cannot be assigned a (more specific) category, e.g. the password year2005 goes to Lowercase + number.

It's hardly surprising that the most used password category is the all-lowercase one, followed by all-digit passwords and lowercase passwords with an ending number. These first three categories account for 94% of all distinct passwords as well as for 94% of all uses.

Only 169 different passwords have been tried that have at least one uppercase and one lowercase letter which aren't capitalized words (i.e. something like 4rf5tgTJ or 11Admin11 counts but simple capitalized words such as Admin or Pass do not). This is a mere 0.04% of all passwords that have been used.

Conclusions

The attacks I've observed and discussed on this page are automated and are going for the low-hanging fruit. Introducing some security precautions can already make a big difference: keep an eye on your errors logs and traffic, and look into the possibilities you have to mitigate those brute-force attacks.

Specifically, rename standard admin filenames for login/admin/installation pages that popular software uses, such as wp-login.php. As a developer, add the noindex meta tag in the HTML of installation and login pages as shown below. This will prevent sensitive pages to be indexed in search engines, which can be used to find websites with vulnerable software.

<meta name="robots" content="noindex">

The folder name of your installation is also a factor: the traffic on my domain suggests that primitive bots will look if folders like admin, wp or login exist and give up if this is not the case.

This applies not only to your own password but to those of your other users. Training your users to be conscious of their safety is worth its time, in my opinion.

Usernames are also part of the login data. While it is easy to scan the usernames of a Wordpress installation [1, 2, 3], it is still sensible to avoid using admin or the domain name as username. Some software allow nicknames, i.e. the public name of the writer doesn't correspond to the actual username. Make use of such a feature if it is present.

Wordpress has security-related plugins which can be considered. Specifically, renaming wp-login.php and limiting the login attempts per IP address per IP address is possible to achieve with the help of plugins. Another effective way is password-protecting access to wp-login.php with a fairly easy password which you can share among your administrators and editors. Alternatively, if you have a static IP address, you could allow access to wp-login.php only to your IP address, provided that you don't have more users.

Banning individual IP addresses only makes sense if they are aggressively trying to brute-force your login page, e.g. if they send thousands of requests, or hundreds per seconds. As shown on this page, the majority of the IP addresses only try a handful of attempts, rendering IP address bans ineffective.

In the course of the two years, I have noticed activity from botnets too, i.e. login requests from an array of various IP addresses, each submitting only a handful of requests, which can be grouped together logically (same pattern, short time span, same technical problem not otherwise observed). For an effective security mechanism, the number of failed login attempts per username should also be considered and accounts locked for a certain time during increased activity.

I have seen various software and discussions about checking the browser's referrer and denying access if it doesn't come from the same page. In fact, many bots spoof the referrer and send one from the same domain. This will most likely cause more trouble for legitimate users whose browser is configured not to send a referrer than inconvenience any attackers.

Finally, it may make sense to set up a bogus login page that will just always say that the login information is wrong. This does not guarantee that a bot or an attacker won't look for other potential pages, but it certainly doesn't hurt to let them bark up the wrong tree for a while. ;)