Writeup: 0x00sec CTF - 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 now 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.

6 Likes

Awesome writeup man!

Clientside auth still happens these days! Thanks for playing :slight_smile:

2 Likes

I use python base64.b64encode() ,result is YXV0aGVudGljYXRlZD10cnVl. I don’t understand

I guess you are missing the newline character at the end.

With newline

➜ echo "authenticated=true" | base64
YXV0aGVudGljYXRlZD10cnVlCg==

without

➜ echo -n "authenticated=true" | base64
YXV0aGVudGljYXRlZD10cnVl
1 Like

Oh,I think I understand. . Thank you very much.