Home Wacon2023 WriteUp(Web)
Post
Cancel

Wacon2023 WriteUp(Web)

Wacon2023

Mosaic

Recon

First thing you see are a login and register button

Untitled

After you register and login you see 3 menus

Untitled

  1. Upload : Can Upload .jpg, .zip, .tiff, .png files. After uploading it shows the path to the uploaded file
  2. Mosaic : Able to see an uploaded file mosaicked

The files are as followed (excluding asdasd.png)

Untitled

The weird this is that the password.txt file was given. In most CTFs the password is within the source code.

Objective

The flag is placed as followed

Untitled

  • At the root directory the image file is saved and the path is saved in the FLAG variable

Untitled

  • The flag image will be copied by the copyfile function, to a possibly accessible directory only if the session is username is admin(== admin session) and it is called locally (127.0.0.1)

Untitled

  • Lastly, by using /check_upload@<username>/<file> , you are able to see an image but to see an image in admin, you must have a session with username “admin”

Step 1. Admin Password

Of course you need the admin password to login as admin. The password for admin is saved in password.txt

Untitled

  • FYI the password.txt is saved at /app/password.txt

To read the password you can use the code below.

Untitled

The image file you want to read depends on the username name you input and you cannot use ../ in the file path

But, you can read the password.txt by placing .. in the username and it will form /app/uploads/../password.txt

Untitled

Step 2. Copy Flag Image

The next step is accessing the root URL locally (127.0.0.1) with the admin session.

Untitled

As you can see in the code, depending on the image_url value it is used differently. If we were to use requests.get to call 127.0.0.1 we are able to copy the flag image.

But image_url filters values that start with https:// and http://

Untitled

You can bypass this by using capital letters or using a python vuln like below.

The value goes straight through with the space in front of http

Untitled

It might seem that the logic will work by putting 127.0.0.1 in the image_url parameter but you will get 500 error

Untitled

Untitled

Like you can see the error above an error occurs in the split function because there is no value for the mimetype.

Untitled

The guess_type function in mimetype tries to guess the mimetype of a uri depending on the extension(after the ‘.’)

To bypass this you can do it as below

Untitled

Again you can see a 500 error

Untitled

But this time it occurs in the imageio.imread function and if you look at the log, the request locally worked

Untitled

Thus you can get the flag image by accessing /check_upload/@admin/flag.png

Untitled

Warmup-Revenge

Recon

When access the web page you get to see a page like below

Untitled

After you register and login you will see as below

Untitled

  1. in the board menu, you can see peoples titles, writers and date of writings and you can write one yourself

Untitled

Untitled

Untitled

  1. In the Myinfo page, you can look at infos of yourself and edit it.

    Untitled

  2. Note is a function to send and receive DMs

    Untitled

The environment is as follows

Untitled

Objective

The main goal is to achieve the admin’s cookie which is the “flag” which means there is a 95% chance that it will be an XSS challenge

bot.js

bot.js

The only endpoint where the “User” and “Admin” interact is /report.php

Untitled

The user can send the path and idx of an article to the admin

  • FYI, everything you write in text will be filtered.

Untitled

Step 1. XSS Entry Point

While looking around where I might be able to enter by XSS script, I found a download logic which looked strange.

Untitled

The content-disposition header is setted differently depending on the user-agent, but since you cannot change the admin bot’s UA I didn’t think too big about this.

I thought if I were to delete the header or possibly change(inject) it, I might be able to make a URL that won’t popup a download screen.

Untitled

Untitled

Trying to figure out how, I did a bit of fuzzing and I was able to remove the content-disposition header in my response. (The reason in the link below)

When I put in a “hex” value of \r in filename parameter, it will delete the content-disposition response header due to an error

Untitled

Untitled

Step 2. Bypass CSP

As you can see in the image above, there is a CSP so I cannot not use script right off the bat.

1
Content-Security-Policy: default-src 'self'; style-src 'self' https://stackpath.bootstrapcdn.com 'unsafe-inline'; script-src 'self'; img-src data:

To bypass it, I thought “why not just upload a js file and make script src call it?”

Untitled

Untitled

Untitled

Thus I was able to make the bot send me his cookie by crafting a payload like below.

Untitled

Untitled

Untitled

Untitled

This post is licensed under CC BY 4.0 by the author.

Intigriti Challenge 0423 Write-Up

-