Persistence is a great thing to have on a pentest, especially if testing from the outside. Persistence also seems to be a word that makes clients’ hairs on the back of their necks stand up. Backdoors are a scary thing if you’re in charge of keeping a network secure.
When it comes to installing persistence, there are quite a few options available such as Metasploit’s persistence module or
scheduleme.rb. These modules leave a permanent, like one would think, payload and schedule for phoning home to the tester’s box. But what about when this is out of scope?
Here’s a method to keep a payload phoning home but leaves no permanent effects.
Using WinRAR, we can pack our payload with a vbscript that sleeps for 60 minutes and then restarts the payload. With WinRAR installed, right click your favorite payload and select WinRar > Add to archive… The window below will pop up. Select Create SFX archive and keep the Archive format set to RAR. You should also give your payload wrapper an inconspicuous name.
Now duplicate the payload that you just right-clicked and call it something different, it’s renamed to
persistence_payload.exe here. This will be the secondary payload that is run every 60-ish minutes. Why not just use the one payload? Just in case you can’t migrate of off the original process, a second one is used for the persistence for safety.
Now create a text file named
persistence_script.vbs and paste the following within it:
function launchit() WScript.sleep 90000 set shell = createobject("wscript.shell") shell.run "persistence_payload.exe" WScript.sleep 90000 killit() end function function killit() set objWMIService = GetObject ("winmgmts:") foundProc = False procName = "persistence_payload.exe" for each Process in objWMIService.InstancesOf ("Win32_Process") If StrComp(Process.Name,procName,vbTextCompare) = 0 then foundProc = True procID = Process.ProcessId End If Next If foundProc = True Then Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process where ProcessId =" & procID) For Each objProcess in colProcessList objProcess.Terminate() Next WScript.Sleep(1000) 'wait for a second Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process where ProcessId =" & procID) If colProcessList.count = 0 Then WScript.Sleep(3600000) launchit() End If End If end function launchit()
persistence_payload.exe line to match your persistent payload’s name. After saving this, right click the payload wrapper and select WinRAR > Open with WinRAR. Then drag the persistent payload and
persistence_script.vbs into WinRAR. You should end up with this:
Almost there, but we need this executable to do something when the victim clicks on it. Click the SFX button in the ribbon. Then under the SFX tab, select Advanced SFX Options.
Now we have a number of options we can set, such as having this executable extract to a specified folder (
C:/Temp maybe?), set the Overwrite mode to Overwrite all files (Update tab), and tell WinRAR what to run upon extraction.
After setting the first two options, open the Setup tab and in the Run after extraction box, enter the name of your normal payload (
payload.exe here) and the VBScript (
Now when the payload is run, it will run as expected (by calling
payload.exe) and in Task Manager, a
wscript.exe process will run waiting to re-rerun
persistence_payload.exe every 60-ish minutes. Before re-running the payload, it will kill the process if it’s still running so if you can’t migrate you will lose that session – best to keep it as a backup in those instances.
Restarts and logoffs will kill
wscript.exe resulting in the persistence being lost– no worries about a permanent backdoor. This method can also be used to launch the initial payload multiple times when first run, if you experience flakiness issues with payloads.