Writeup of a PHP Web CTF challenge I built for an event (ft. three vulnerabilities)

 Introduction

One of my professors asked me to build 3 CTF challenges for an event he wanted to organize. He wanted the challenges to be a little bit beginner friendly since some of the participants are quite new to it. I decided to make Web challenges since I guess anyone in computer science can read and google source codes to understand what they do also to make them understand that security is research. I'll present a walkthrough of one of the challenges which was very interesting since it featured 3 vulnerabilies.

Link to the challenge's source code if you want to practice before reading : https://github.com/lowlevel01/coding-rooms-ctf-challenges/tree/main/challenge2 

1- The challenge:

The challenge's source code was fairly short and easy to understand.

 
(1) The challenge's source code  

It's basically a custom authentication mechanism that reads a serialized object encoded in hex from the cookies. The catch is that to be authenticated you have to beat a challenge. You have to guess a number and then a random number is chosen and compared to yours. If they're equal then you win.

2- Insecure Deserialization:

In serialized objects in PHP, a variable can reference another. That is have the same value. Let's take a look at this example:

 

                                                                        (2) example of serialization

 

In this example var2 references var1. That is it will always hold the same value. The serialized object will have the form 

O:7:"Example":2:{s:4:"var1";s:13:"Hello, world!";s:4:"var2";R:2;}
 Notice how we can control which variable points to the other. Now, if we go back to the challenge source code, the way to solve it is to make the variable attempt a reference to the variable challenge.


      3- Type Juggling:

    PHP is a loosely typed language, that is it automatically converts variable types based on context. This is known as Type Juggling. This happens when two equal signs "=" are used instead of three.

(3) Loose comparsion with ==


Notice how the boolean variable true compared to any number with loose comparison always evaluates to true.
 Now, if we go back to the challenge's source code, we notice that the comparison between the random number and the attempt was done with "==" . 

(4) Loose comparison in the challenge's source code

Which means if we set the attempt to true, the check will pass and we'll get the flag.

    4- Weak Randomness:

If you look at the range from which the random number was chosen (1-100000), you'd notice that it's relatively small.

(5) random number's range is very small

Therefore, a way to solve the challenge by creating a simple script in python for example that would send the same number over and over again. The number of necessary requests to get the correct guess is around 100000 which is relatively low.

    Conclusion:

 This is a nice CTF challenge I decided to share because it features three different vulnerabilities. I created another challenge about length extension attack on MD5 to bypass a salt check to exploit a LFI vulnerability. 

The link to the challenges : https://github.com/lowlevel01/coding-rooms-ctf-challenges/


References:

https://www.php.net/manual/en/types.comparisons.php
 

Comments