RaidForums - First Web Hacking Contest

I happened to come across this post on RaidForums, and decided to give it a go.

Code Review

We were given a link to a Github repo, which turned out to be a fork of flox.

https://github.com/Anas7asiaM00N/flox/

The first thing I noticed in the repo is that it’s ahead 12 commits from the original project that it was forked off. So Anas7asiaM00N did some code changes.

Commit review

SQL Injection

Going through the commits, I come across this piece of code, which immediately indicates there is a SQL injection vulnerability here.

Knowing that the framework that was being used was Laravel, I was able to also search through the code to determine where SQL injection might occur. SQL queries in Laravel, done right, are done using Eloquent models.

You are however able to perform raw DB queries on the database as well, and this is where the human error normally comes in.

Search for it in Visual Code brings up the same finding.

How to get here

Looking at the code, if I can control $type, $mediaType or $value, I’ll be able to execute SQL queries making use of this statement.

The three variables are being password to the method call.

I start looking at all the places in the code that calls this method. I come across one in FileParser.php that looks like a good candidate to target.

Tracing back to where the above is called from, we find the following.

The above seems to execute the validateStore() method when the status is equal to ‘added’.

I then look for where handleStatus() is being called from.

Further searching and I finally find the entry point to this chain of calls.

Looking at the route.php file, I’m able to see how the HTTP routing works to get to the receive() method.

Creating the payload

You’ll notice in my screenshot above, I had added some debug code in for myself while testing this locally.

The first we target is where we are setting the type value of the object.

In Laravel the $request will contain GET and POST. So using ?type=evil_code attached to the URL, will allow us to set the $type variable here.

This means we can successfully control the value being parsed to the updateDatabase) method, the subsequent updateDatabase() call too.

The next part would be to have the $files variable in such a structure that it would traverse through the array, and call the handleStatus() method.

It’s basically expecting an array of items within an array of items. If that makes sense?

I basically setup the following array, and converted it to JSON to use.

$arr = [
        "type1" => ["type2" => [
          "status" => "added",
          "name" => "name1",
        ]]
      ];

The resulted in a JSON string:

{"type1":{"type2":{"status":"added","name":"name1"}}}

Using all the above information, I knew I as now able to execute SQL queries, but adjusting my ?type= value.

API access

I finally got the following to take advantage of the end point /api/updates-files to execute the SQL.

This gave me the output I was looking for.

Great, I had the api_key to work with now.

eval

The other finding I notice is that we have an eval() being used. This could possibly be used to inject arbitrary PHP code.

This is also one of the vulnerabilities you would search for in a PHP code base when doing code review.

How to get here

Looking through all the calls to methods of the name handle(), I can across an interesting one.

Searching in the web.php file this time for web routes, I find where this call is being triggered.

Going through the middleware’s code, you see that you will need an api_key to access this endpoint.

Luckily we were able to find that with the SQL injection.

Creating the payload

The first thing we need to do is send a JSON payload in a ‘payload’ parameter, with a POST request.

This is then passed to the handle() method that we found. You will notice that the Plex class doesn’t have a handle() method, but because it is a child of the Api class, the Api’s handle() is called.

The first hurdle to overcome was making sure our payload contained a title and type.

Another check to pass is to make sure the title can bt found on the TMDB website, and that it is not already added in our database. For this you can just look up a random title on the TMDB website.

Finally we can get to the part that executes our PHP code.

Code execution

Eventually able to get code execution with the following payload.

The flag

Having code execution meant that I could begin with enumeration.

The very first thing I did was list the files in the current folder.

This file looked like the flag…

Written on August 25, 2021