Saturday, December 4, 2021

Hack The Box Cyber Santa CTF - Web Day 4 - Elf Directory Writeup

 

Technique Used:  Bypassing file upload restrictions by changing the magic bytes on the header of a PHP file to make it look like a PNG image file.

Details:
The challenge starts off giving each person a personal Docker instance as a web server, and going to the http://IP:port brings us to a login portal.


Before messing with the site, I started a Nikto scan to get an initial information snapshot of the website:  nikto -h http://<ip_address>:<port>

Nothing interesting other than the web server being Nginx, and it running PHP 7.4.26.

Before even observing what the page had to offer, I immediately went for the easy SQL injection to log in:  ' or 1=1;--

As expected, it failed.  I always try it on all login portals because it takes half a second to figure out if it works or not.  Anyways, taking a second to look at the site, I noticed there is a link to create an account, and create I shall!  However, logging in wasn't too rewarding since there's nothing to look at but a profile page with no permissions to modify it with error message, "You don't have permission to edit your profile, contact the admin elf to approve your account!"  It's my profile!  I should be able to modify it, but no worries, we're hackers.  We can figure it out.



It seems our goal now is to escalate our privileges but to do what though?  Maybe there are more things we can do if we're allowed to edit our profile page?  I haven't looked at the source code yet, so let's take a gander.  Whoa!  What's this at the bottom of the source code!?

    <script>
        $('#upload').change(function(){
        let path = $(this).val().replace('C:\\fakepath\\', '');
        $('#selectFile').html(path);
        })
    </script>

I don't see any kind of upload functionality on the page.  One of the usual web escalation techniques is to mess around with our cookies, so let's take a look at that by pressing F12, and go to the Application->Cookies tab.  We see this Base64 cookie there:

PHPSESSID:  eyJ1c2VybmFtZSI6ImphbmtlciIsImFwcHJvdmVkIjpmYWxzZX0=

At the risk of seeing gibberish, let's decode this Base64 anyway in CyberChef:


It's actually interesting.  Not only is it not gibberish, but it has this field that says "false" on it (FYI, my username was "janker").  I changed it to "true", re-encoded it in base64, put it back into the cookies field on the website, and refreshed the page.


IT WORKED!  An upload portal appeared.  From my Nikto scan earlier, I remember the page is running PHP, so I downloaded the popular "php-reverse-shell.php" from Pentestmonkey's Github, modified the callback IP and port in the PHP file, started a reverse Netcat listener on my public Amazon Cloud instance of Ubuntu to catch the callback since I wasn't on the same network as the target

nc -lvp 1337

The uploaded epic failed so hard with:  Invalid image. Only PNG images are supported.


I proceeded to upload a legitimate PNG image of a Corgi dog to see how it reacts, and it actually changed my profile picture! 


I immediately searched "how to bypass file upload restrictions," and a bunch of links came up.  I went down the list, and tried a bunch of stuff starting with adding the "png" file extension to the end of my filename to "php-reverse-shell.php.png".  It didn't work.

After trying a variety of things like capturing the request in Burp Suite and adding things to the end of my filename like %00, %0a, etc.  I concluded that the filter is based on my actual file type based on the file header, instead of the filename or request name.

My favorite hex editor is HxD in Windows unfortunately, so I swapped OS's and edited the header of the "php-reverse-shell.php" file by inserting 19 copied bytes from the top of a real PNG:  

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 04

I then copied the file back over to my Kali VM, and ran a file on it to prove it looks like a PNG file now.  19 bytes was a random number of bytes I chose willy nilly.  I started by copying the exact number of PNG magic bytes, but for some reason, it didn't work.  When I ran the file command on it, Linux still saw it as the type "data".  However, when I added more bytes (19), it finally recognized it:

file reverse-php-shell.php
PNG image data, 1084 x 1064331376, 13-bit

I uploaded it with the original filename as "reverse-php-shell.php" with full expectations of failure; however, the page refreshed with no errors, and I actually got a shell in my listener!  I quickly cat'd out the flag file before they decide to change it or something! 

HTB{br4k3_au7hs_g3t_5h3lls}

It's always such a warm fuzzy when you see a shell.  It's even more euphoric to see that flag format that starts with "HTB{".  Until next time, keep hacking away!

No comments:

Post a Comment