PicoCTF Login Walkthrough
March 23 2024 - 3 Minutes
picoctf - walkthrough
The login entry in PicoGym
Hello again! I am back again with a new picoCTF challenge walkthrough, This time I am going to walkthrough the challenge "login".
I have had my eye on this challenge for a while now, and so I decided to finally bite the bullet and write this blog post.
You must be aware that this is a more complex challenge than some of the other ones I have done in the past.
Introduction
When we first open the page we see this; A simple website that contains a login screen.
This makes sense as the name of the challenge is literally "login".
Trying to login with any username and password combo, even SQLi, just returns an error about an incorrect password.
Exploration
After seeing this I decided to look into my browser's javascript debugger to see if there is any notable javascript.
Looking in the debugger reveals this:
This looks interesting, but it is impossible to understand what is happening in it with it being minified.
I ran the code thru a de-minifer and we get this, some javascript source code that is actually readable.
(async () => {
await new Promise((e => window.addEventListener("load", e))), document.querySelector("form").addEventListener("submit", (e => {
e.preventDefault();
const r = {
u: "input[name=username]",
p: "input[name=password]"
},
t = {};
for (const e in r) t[e] = btoa(document.querySelector(r[e]).value).replace(/=/g, "");
return "YWRtaW4" !== t.u ? alert("Incorrect Username") : "cGljb0NURns1M3J2M3JfNTNydjNyXzUzcnYzcl81M3J2M3JfNTNydjNyfQ" !== t.p ? alert("Incorrect Password") : void alert(`Correct Password! Your flag is ${atob(t.p)}.`)
}))
})();
After reading through this code, my eye was caught by these two strings.
cGljb0NURns1M3J2M3JfNTNydjNyXzUzcnYzcl81M3J2M3JfNTNydjNyfQ and YWRtaW4, I don't know about you, but to me these look like standard base64 encoded strings.
After seeing that these are probably base64 encoded strings, I decided to look further into the code and mostly at these two lines:
for (const e in r) t[e] = btoa(document.querySelector(r[e]).value).replace(/=/g, "");
return "YWRtaW4" !== t.u ? alert("Incorrect Username") : "cGljb0NURns1M3J2M3JfNTNydjNyXzUzcnYzcl81M3J2M3JfNTNydjNyfQ" !== t.p ? alert("Incorrect Password") : void alert(`Correct Password! Your flag is ${atob(t.p)}.`)
That first line goes through all of the the elements in the object t and runs btoa on them.
The btoa function, base64 encodes strings.
And looking at a part of the second line, "cGljb0NURns1M3J2M3JfNTNydjNyXzUzcnYzcl81M3J2M3JfNTNydjNyfQ" !== t.p ? alert("Incorrect Password").
We can see that the base64 encoded password is compared to one of the base64 strings. This confirms it, that those two strings are the password and username respectively.
Solution
Running both of these through a base64 decoder, lets us see this:
Success! we have the flag and the username!
Mitigation
DO NOT USE BASE64 TO STORE SENSITVE INFORMATION!!!
This is why you shouldn't, as we saw it can be easily decoded into the original data very easily.
It is also a very noticable thing, as any self-respecting hacker would be able to understand and decode base64 very quickly.
As always, thank you for reading this blog post, I hope you have a nice day!