Writeup CTF 0x00sec Web - Exercise 2
Writeup CTF 0x00sec Web - Exercise #2
Welcome back to my writeups. Now we will cover the 2nd Exercise in the web category.
Challenge
If we follow the link in the challenge we see again a simple login box.
So let's start with our normal recon. A good start is always to view the page source. You can find a lot of useful information in there like
- Inline javascript
- External javascript files and libs
- Hidden input fields
- Leftover comments
If we take a careful look at the source we see an HTML comment:
<!-- TODO: -->
<!-- * Implement secure sessions -->
And this is our hint. We know need to gather some information about how sessions are working and how we can abuse an insecure implementation.
Sessions
At first, we can take a look at php.net and read up some information.
A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.
And if you want to read more about sessions and flaws in their implementation, you should check out the OWASP Session Management Cheatsheet.
Now take a look at our cookies. As we now know, that the session is stored in the cookie. You can check out the cookies in the dev tools under Application
And if you now remember from the OWASP Cheatsheet:
The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application
So let's try to decrypt the session id. A very basic and very common encoding for data in the web is base64. It is also very common in CTFs, so you should be comfortable with it.
There are multiple ways to decode and encode base64. If you're on Linux or MacOS you will most likely have the base64
binary installed. So you could for example:
echo "base64_string" | base64 -D
Or you can use any of the online encoders. However, one that you should definitely bookmark, is CyberChef! It has many "recipes" you can use. For example multiple baseX permutations, various encodings and decodings and if you do not know what this string is, you are looking at you can try the Magic
Recipe, which tries to guess what kind of data you have there.
Well, I guess most less experienced people will have issues with identifying the content of session id as base64.
Because it does not really look like base64. If we encode a simple string like abc
as base64 we get YWJjCg==
.
➜ echo "abc" | base64
YWJjCg==
And if we encode an even longer string we see a common pattern. Which is the ==
at the end. Which is used for padding. If you read the Wikipedia article you will learn how the padding works and that it does not always end with ==
.
So, but in the end, base64 is very common so let's just try it. And we can select the From Base64
recipe in CyberChef and input our string.
And we have an interesting attribute in there. authenticated=false
. And some very weird characters under this.
But now, after we read the base64 article, we are base64 experts, right? And if we take a closer took at the base64 encoded string, we see some weird characters at the end, which are not base64.
YXV0aGVudGljYXRlZD1mYWxzZQo%3D
And if you go the route over the terminal with the base64 command, you will also run into issues.
➜ echo "YXV0aGVudGljYXRlZD1mYWxzZQo%3D" | base64 -D
Invalid character in input stream.
So this is another proof that something is wrong with our string. If you have a bit of basic web technology knowledge you may recognize the last 3 characters %3D
as URL encoding.
So let's use the URL Decode
recipe in CyberChef.
Gotcha! We have our missing padding!
Now we can properly decode our string:
➜ echo "YXV0aGVudGljYXRlZD1mYWxzZQo=" | base64 -D
authenticated=false
Now you may ask, why all this hassle with the URL encoded characters? Well, for once because if you go the route with terminal base64, you would be forced to see the URL encoded character and fix it, because otherwise, you could not decode it.
But more importantly if you had used an online decoder like CyberChef it would give you a wrong output. This means if we do our attack, we would have a wrong input to begin with and would be not able to solve this.
The Attack
Now let's come to the attack. Let's gather what we already know:
- The session is stored in a cookie
- The session content is base64 encoded
- The decoded content is
authenticated=false
- The session implementation is insecure
Because we know the content of the session, we can assume that the login script may be checking our session and check if authenticated=true
.
So let's change our cookie to this and see what happens. Let's use CyberChef for this and we know our input is authenticated=true
and we want the To Base64
recipe.
Or we can use the terminal:
➜ echo "authenticated=true" | base64
YXV0aGVudGljYXRlZD10cnVlCg==
Now we have the session encoded and can edit our cookie in chrome with a double click on the cookie value and replace the old value with our new one.
And after a page refresh, we should see the flag.
Conclusion
Another fun exercise, which should be easy if you properly research sessions, base64 and URL encoding.