Today I’m going to write how to get the answers to the security answers for the lost password functionality in OWASP Juice Shop. While there’s no achievement for this, it is a very good exercise that teaches both SQL injection, code diving and cracking.
In order to reset a user’s password, 2 things are required: their email and the answer to their security question. Both are initially relatively easy to get, as I’ll show.
There are a couple places in Juice Shop that are vulnerable to SQL injection. My other Juice Shop post explained how to exploit this vulnerability in the login form, but it also exists in the product search page. Furthermore, this is not a blind SQL injection, so we are able to see the full output.
Testing the product search form I was able to provoke an error message that showed the search query being made, and I found out that I could break out of the query by adding ‘)) to the search query, and then construct my own query terminated by — -.
First, I constructed a UNION query to find the number of columns by adding ‘null’ until the query got accepted:
search?q=')) UNION SELECT null,null,null,null,null,null,null,null FROM Products -- -
Next, I altered this base query to find the name of the tables in the database:
search?q=')) UNION SELECT name,name,name,name,name,name,name,name FROM sqlite_master WHERE type='table' -- -
I got the email addresses of the users with a query for the Users table (and yes, I could as well dump the passwords too, which would be so much easier than what I did last time!):
search?q=')) UNION SELECT id,username,email,null,null,null,null,null FROM Users -- -
And with this information I could start extracting the information from the securityAnswers table:
search?q=')) UNION SELECT id,userid,answer,null,null,null,null,null FROM securityAnswers -- -
Great! One problem though: the answers are not in plaintext (nor should they be if this was a real application!). They appear to be hashed as SHA256, so I tried cracking them with hashcat. No luck though.
This is where it gets interesting. Since Juice Shop is open source, I was able to dig through the code on GitHub and search for the code responsible for hashing the security answer. The relevant file can be found here, and the relevant line below:
exports.hmac = data => crypto.createHmac('sha256', '07-92-75-2C-DB-D3').update(data).digest('hex')
So the script takes the security answer (data), and creates a SHA256 HMAC (signed hash) signed with the key “07-92-75-2C-DB-D3”. Now we are in business!
All that remains is to put it all together and crack the hashes. First, I extracted the hashes from the database dump and put it in a format that hashcat understands, namely HASH:KEY, and then ran hashcat with the following arguments:
hashcat -m 1460 -a 3 -w 3 /usr/share/wordlists/rockyou.txt hash.txt
Within a few seconds I had the first 2 security answers, and a couple hours later I got another. I could imagine that some of the answers are too weird to be brute forced (I know Bender’s is!), so it’s doubtful I’ll be able to crack them all.
I think the most important take-away from this exercise is that if you have access to the source code, anything is possible. There’s absolutely no way I’d have been able to crack the HMAC without the secret key, but doing some GitHub search gave me that (and other secrets that’ll help me on future exercises).
EDIT 24/08/19: Björn Kimminich, the creator of Juice Shop, pointed out below that using the source code is cheating. Which makes sense, as it makes many of the challenges very easy that way. Still, seeing as cracking the hashes is neither required, nor an achievement, I think it’s a good exercise nonetheless.
Feel free to post any comments or questions below and I’ll reply as soon as I’m able.