Attacking Password Recovery Facilities

Fri, 06 Jul 2007 08:54:44 GMT
by pagvac

Today, most public websites offer the following 3 functionalities: account login facility (login page), account signup facility (account registration / create new account page) and password recovery facility (forgot password page). This is especially true on e-commerce sites with a large user base.

The nature of password recovery facilities can vary but we usually stumble across the following types: secret answer, email containing the original password, email containing a password reset link, email containing a new password. Again, these are the types of things typical web applications would have. In general, they are essential to the overall security of the web applications we are testing, so it is important to have them in mind. In this post, I am going to talk about attacking password recovery facilities briefly. I am also going to show you a simple trick that I've learned along the way, but before that, let's have look on the various types of password recovery facilities and see what's the most convenient way to attack them.

So, let's take on the first type. In secret-answer password recovery facilities, the user is asked something only he is supposed to know. This is a functionality that can be attacked via social engineering attacks by learning personal information about the victim (date of birth, mom's maiden name, mascot's name, etc...) . This is one of the two options provided by Hotmail ("Forgot your password?" link) to recover passwords, for example. This type is quite common for most of the applications.

In the second type of password recovery facilities (email containing the original password), the user is emailed his/her original password. As a security analyst you're supposed to flag this to your customer because it means that passwords are being stored in the backend DB servers either in the clear or in a reversible form. This is obviously a lack of security for users' sensitive data. Passwords should always be hashed whenever possible, and salted in order to make the process of breaking the hashes (i.e. rainbow tables lookup) unfeasible. Simple!

In the third type of password recovery facilities (email containing a password reset link), the user is emailed a link so that when they click on it, he/she can set a new password for their account. This link is of course supposed to be non-predictable. However, if you can crack how the link is constructed that would mean you could hijack any user account as well.

Finally, the last type of password recovery facilities (email containing a new password) the user is emailed a newly-generated password. Again, these passwords are meant to be non-predictable. However, if you can predict them then you could also hijack any other user account. For example, what if the newly generated password for your account was today's date plus a 4-digit number. i.e.: _02072008-1337_, where '02072008' is today's date, and '1337' is a random 4-digits number. In this case, it is obvious that the attacker could crack the newly generated password by sending around 10,000 requests to the server. If we tried one password per second it would take less than 3 hours to crack the password.

Usually, whenever we want to attempt to break the reset-password link or the newly-generated passwords we need to do sampling, and this is what I would like to bring your attention to. So, basically, we want to collect a relatively big number of strings to crack. Ideally, we want them to be requested one after the other, without waiting too much time between responses, just in case the strings are based on time. The closer they are to each other in time, the more likely it is to notice a pattern.

The problem with sampling such strings is that you need to programmatically check the inbox of the email address that you used to register your account on the target site. If you administrate your own mail server, it can ease the task of reading the emails through your attack script (the attack script would make X number of "forgot my password" requests). A different option would be to programmatically log into your webmail service and parse the strings sent by the target site. However, this is extremely non-practical and annoying. Imagine writing a script that authenticates to your gmail account and parses the content of emails? This is crazy!

Here is the magic. For me, the best way to perform sampling on strings from an email inbox is to use my favourite disposable email service: mailinator.com

Mailinator is one the coolest ideas I've seen on the web. It's meant to be used for junk emails and things you don't care about. You don't have to register to have an account. Just choose any username without even visiting www.mailinator.com. i.e.: myrandomusername. That means that your disposable email address would become: [email protected]. The beauty is that all usernames are pre-created and you don't need to login to check your inbox. Just visit http://mailinator.com/maildir.jsp?email=**myrandomusername**

Reading emails programmatically from your scripts is easy, as the URLs follow a simple syntax and you don't even need cookies to access them. Here is an example:

  • http://mailinator.com/showmail.jsp?email=myrandomusername&msgnum=0
  • http://mailinator.com/showmail.jsp?email=myrandomusername&msgnum=1
  • http://mailinator.com/showmail.jsp?email=myrandomusername&msgnum=2
  • http://mailinator.com/showmail.jsp?email=myrandomusername&msgnum=[\d+]

So, in order to collect our sampling we will do it in 2 steps:

  1. Make X number of requests to receive a new password or password link
  2. Programmatically access http://mailinator.com/showmail.jsp?email=myrandomusername&msgnum=[\d+]

How do we do that? Bash to rescue. Here is the code:

#!/bin/bash
# request 100 new passwords / password links

for ((i=0;i<100;++i))
do
curl -s -d "[email protected]" --url "http://target-domain.com/forgotpassword.php"
done

The script above performs subsequent password-recovery request, while the script above programmatically checks our inbox. Neato!

#!/bin/bash
# access first 100 emails programmatically

for((i=0;i<100;++i))
do
# change grep and cut commands to suit your needs
curl --url "http://mailinator.com/showmail.jsp?email=myrandomusername&msgnum=$i" | grep '<br><table width=600><tr><td class=bodytext>' | cut -d '>' -f 5 | cut -d '<' -f 1
done

Additionally you could use public HTML-parsing services to facilitate the process of extracting information even more. I recommend checking out pdp's research on this subject.

So, this is it; very simple and effective method you can use in your pen-testing toolbox. I hope that it was useful.

Archived Comments

pdppdp
I think that your approach is very interesting. I've never heard of mailinator but it seamed to be a quite interesting service. Good stuff! One thing that I would like to point out is that mailinator supports RSS feeds as well:
http://mailinator.com/rss.jsp?email=myrandomusername
so, it might be easier to extract all email entries with wget/curl in combination with the XMLStarlet toolkit or just grep/awk. Also, GMail supports RSS through the GData services. However, we need cookies for that. So yes, your approach is definitely cleaner. I love it. Here is probably the place to mention that client-side security issues can expand across the traditional boundaries that they currently reside at. I can foresee a worm that can send XSS payloads over email and as such propagate. This is possible due to the existence of services such as mailinator and others that can transform RSS to email, email to RSS, etc. I am planning to release a paper on that soon, so stay tuned.
.mario.mario
Hi! Nice article. Maybe it would be interesting too to write sth about password reminder and header injection - this problem is no news but still very often to find and quite related to the topic of this article. Greetings, .mario
pdppdp
yep, ap is our password hacking guru, :) I am sure he will take on the challenge. sometimes, I get the feeling that he can make a password cracker out of chair or something.
ntpntp
huh. mailinator.com is a staple of mine. i always use it (or dodgeit.com) in the mail (required) fields in blog comments. i don't want my real email address sitting in a database or plaintext email where it can be stolen and used for nefarious purposes. bash, curl, grep, and cut are also staples of mine. if you do
for i in `seq 0 99` ; do stuff ; done
i think the results might come out quite faster, although i didn't check this with time(1).
pagvacpagvac
pdp: didn't know mailinator supports rss feeds. this makes the parsing even easier. well spotted! mario: password reminder and header injection is definitely an interesting topic to discuss. Although I haven't played with this topic, who knows, you might find something on the topic in the future GNUCITIZEN :) ntp: life wouldn't really be the same without GNU tools :-). Especially curl, I'm a huge fan of the project. It even supports proprietary authentication mechanisms like Windows authentication (NTLM auth), proxies, etc ... it really is a must-have tool for server-side attacks.
olol
A paper that shows how to attack password request functionality using buffer truncation attacks.. http://www.sec-1labs.co.uk/papers/BTA_CensoredRelease.pdf
MadCyrilMadCyril
"Imagine writing a script that authenticates to your gmail account and parses the content of emails? This is crazy!" -- not at all, have you met Perl? I bet this could be done in 20 lines or less.
TominatorTominator
Hi, I have a question: why must a password be stored in a hash with salt? Isn't the rest of the data in your database more valuable than the pw, and totally not encrypted whatsoever? What difference does hashing the pw make? Otherwise great read.
Adrian PastorAdrian Pastor
MadCyril: I agree, this can be done with scripting languages like Perl, Ruby or Python. However, wouldn't you rather reduce the number of lines of code to 5 by using a public site (mailinator in this case) that simplifies your work. Tominator: Sometimes the password might be more valuable. Imagine a forum site. The database simply holds public info. Now imagine the admin can see my password in the clear. Since most people reuse passwords he could now try the same password on the email I used to register (which he can see in the clear). Furthermore, some people use site-based patterns for their passwords. i.e.: MYPASS_4_www.forumsite.org In this case the admin who can see my pw in the clear could try using my username on amazon and the following password: MYPASS_4_www.amazon.com The point is, whenever it's feasible for information to be protected it should be. I personally don't want dodgy admins looking up my password :) but yes you're right, other sensitive data is usually in the clear anyways.
estebanesteban
when the provider sends and email with a link + hash, it normally wont allow you to send you another link (lets say password recovery email) unless the timeout for the first one expires...the timeout is normally a time/cost function that limits how long or how much money it would cost you to get the hash predicted the following attempt (usually hours) anyway, nice website mailinator.com, can be handy!!! anyone knows for how long it keeps your emails? probably not much! is anyone aware of cool sampling tools that tries usual tricks (like b8/64/etc encoding, etc) and non-usual ones?
Adrian PastorAdrian Pastor
Hi Esteban! I believe the behaviour you described would occur only if the application is implemented properly. Regarding mailinator, the following URL http://www.mailinator.com/faq.jsp mentions: "after a few hours, all email is auto-deleted." So you're right, received emails are not kept that long.
jubyjuby
can i retrive the password of gmai account
Emmanuel HleahEmmanuel Hleah
#!/bin/bash
#
# resetRootPass script
#
# Recover lost root password of mysql database.
#
# By Willem Bermon
#

echo
echo "Mysql password recovery utility"
echo

# Stop the mysql server
/etc/init.d/mysql stop
/etc/init.d/mysql zap > /dev/null
/bin/killall mysqld > /dev/null

# Run mysqld in permissionless mode
/sbin/start-stop-daemon --start --quiet --exec /usr/bin/mysqld_safe \
        --background -- --skip-grant-tables >/dev/null 2>&1

sleep 1

# Execute queries
mysql -u root mysql -e "UPDATE user SET Password=PASSWORD('$1') WHERE \
                        user='root'; \
                        FLUSH PRIVILEGES;"
if [[ $? -eq 0 ]]
then
        echo " ** SQL root password updated"
else
        echo " ** SQL root password update unsuccesful"
fi

# Restart the mysql server
/bin/killall mysqld > /dev/null
/etc/init.d/mysql start

echo "Succesfully updated password!!"
echo
echo
exit 0
hanyhany
Dear I will be very thankfull of urs if ur retrive my password of my e mail [email protected] plz its very urgent..i will make dua for u if u get back my password. plz e mail me that password on [email protected] thanks hany
LoserLoser
Hi, Interesting post. However, due to lack of technical knowledge, difficult to fathom. Mind elucidating online?
Adrian PastorAdrian Pastor
Loser, I just described a technique that could (for instance) allow you to a sample a large number of passwords that you would get emailed when clicking on a "I forgot my password" link. If a site emails you a newly "randomly" generated password each time you reset it, you might be able to find a pattern by sampling a large number over a continued period of time. i.e.: 10 passwords requested per second for a total of 10 minutes. Feel free to contact me through http://www.gnucitizen.org/contact and I'll give yo u my messenger contact.
dAVYdAVY
mailinator is blocked by aol naw ,it reverts to other aol sugestion
franticfrantic
I need to recover my gmail password. im in college and have forgotten my password. , im scared as hell of the whole hacking/cracking business and i dnt wana be phished (however that verb is supposed to be phrased).My security question has an answer my friend(hu filled the form n made d account for me) cant remember and he put a wrong secondary email id. u c my email id shud have been…[email protected] and he wrote…@yahoo.com. Now i cant get those reset links. Please help me! my internship correspondence is at stake! i cudnt understand the post by emmanuel hleah. Please tell me if the password can be recovered from my comp or if i can by any means access the incorrect secondary mail id.
vijayvijay
want 2 break mail id password