Rating:

Blog

Description

We made a new blogging website for everyone to use! It's pretty basic for now,
and it has a few limitations like:

1. No comments
2. Semi-working authentication system
3. Lots of random checks slowing down the entire website honestly (i don't know
   what's going on so i'm not touching it)

To mitigate that, we made it such that only you can view your own posts. No one
can hack us now >:)

(im not sure what kind of blog that is tho...)

\- @i\_use\_vscode

http://34.141.16.87:30000

The flag can be found in the root directory.

Solution

Enclosed with the challenge there was the project folder of the web applications.

dist
├── chal
│   ├── db
│   ├── flag.txt
│   └── html
│       ├── create.php
│       ├── images
│       │   └── real_programmers.png
│       ├── index.php
│       ├── login.php
│       ├── register.php
│       ├── static
│       └── util.php
├── docker-compose.yml
└── Dockerfile

So I started looking at the Dockerfile, which looked like that:

FROM php:8.0-apache

COPY ./chal/html /var/www/html
COPY ./chal/db /sqlite3/db
COPY ./chal/flag.txt /02d92f5f-a58c-42b1-98c7-746bbda7abe9/flag.txt
RUN chmod -R 777 /sqlite3/
RUN chmod -R 777 /var/www/html/

We can see that the flag file gets move into the directory 02d92f5f-a58c-42b1-98c7-746bbda7abe9/ which sits in root. Hmm good to know... Next step would be looking at the php files that make up the site. I started looking at the index.php and found this interesting php snippet:

<?php
include("util.php");
if (!isset($_COOKIE["user"])) {
    header("Location: /login.php");
    die();
} else {
    $user = unserialize(base64_decode($_COOKIE["user"]));
}
?>

This basically looks whether the user cookie is set. If its not set we get redirected to the login site. If it is set it base64 decodes the cookie and unserialized it... The result of this is then saved as the user variable. This looks like something we could leverage. So I registered an account and looked at the user cookie I got. I base64 decoded it using CyberChef and got a serialized string. After throwing it into a unserializer it looked like this:

unserialized string

So the user cookie stores the username and an image file, which turned out to be the profile picture.

At this point I was wondering if I could leak the flag file by changing the path to the users profile picture to be the path of the flag file. After some failed attempts i figured out, that the correct payload would be:

O:4:"User":2:{s:7:"profile";O:7:"Profile":2:{s:8:"username";s:8:"testuser";s:12:"picture_path";s:54:"../../../02d92f5f-a58c-42b1-98c7-746bbda7abe9/flag.txt";}s:5:"posts";a:0:{}}

The trick was changing the picture_path to ../../../02d92f5f-a58c-42b1-98c7-746bbda7abe9/flag.txt and the integer before the string to the length of the string. Otherwise the unserialize command runs into an error. Now I used a relative path when I could just as well have used an absolute path (like /02d92f5f-a58c-42b1-98c7-746bbda7abe9/flag.txt) which would have been shorter, but didn't matter in this case. After making this change I base64 decoded it again and changed the value of the user cookie to the exploit string.

changing the user cookie in developer tools

After refreshing the page the image is not displayed correctly. When we look at the source code of the page we see the string that was put as image.

flag leaked through the image tag

Now we just have to copy the base64 encoded part and after decoding we get the flag:

HackTM{r3t__toString_1s_s0_fun_13c573f6}
Original writeup (https://gitlab.com/importantigravity/2023-ctf-writeups/-/blob/main/hacktm/blog.md).