Visiting the challenge page, it wants us to login - presumably we are given the flag once we are successful.
Viewing the page source, we see a javascript function called "login" that is run whenever the login button is clicked. Analysing the code, we can see that what this function does is checks the SHA256 hash of the user inputted username and password against predetermined values to see whether the user login information was correct. Sneaky, they use hashes to increase their security!
A hash can be thought of as a function that takes in any data, and produces a unique fixed length output where the same input gives the same output, but the input cannot be determined from the output (the function is "one-way"). So from the code, we know the hashes of the valid username and password - these are:
username hash: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
password hash: ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f
but as I just mentioned, surely it's impossible to reverse engineer what the username and password actually are, right?
That's where rainbow tables come in. Although we can't travel backwards through the hash function, what we CAN do is hash a huge number of inputs and store the results in a table. Then if we had a hash we wanted to "crack", we could check whether it was in this table, and if it was then we would know the plaintext! That is all a rainbow table is - a huge database of hash inputs and their outputs. Rainbow tables can be protected against by salting/peppering, but that hasn't been used here.
So, we need to check if our hashes have been stored in a rainbow table somewhere on the internet. This can simply be done by googling the hashes, and we get that the username is "admin" and the password is "password123". Alternatively a website like crackstation can be used. We enter these login details and voila, the login is successful.
Our flag is:
<aside> 💡 flag{challenge3-LnBkpHCZmSZFXXmgHCFmgECKE}
</aside>