Beyond good ol’ Run key, Part 16

Documenting various persistence mechanisms would not be complete without mentioning these that could be based on legitimate and fully-documented system features. One such mechanism we are going to talk about is called ‘custom Power Shell profile’. It is a distant cousin of autoexec.bat and it can be abused to ensure some malware component is loaded anytime someone starts powershell host.

There is actually a full article describing this mechanism here, so I will just quote the most important (from the forensics perspective) bit:

  • %windir%\system32\Windows­PowerShell\v1.0\profile.ps1
    • This is for all users of the computer and for all shells.
  • %windir%\system32\Windows­PowerShell\v1.0\Microsoft.Power­Shell_profile.ps1
    • This is for all users of the computer, but it is only for the Microsoft.PowerShell shell.
  • %UserProfile%\Documents\Windows­PowerShell\profile.ps1
    • This is for the current user only and all shells.
  • %UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
    • This is for the current user only and only for the Microsoft.PowerShell shell.

You can test it by running the following commands (obviously file writing restrictions apply depending on the OS and the user privileges):

md %UserProfile%\Documents\WindowsPowerShell\
md %windir%\system32\WindowsPowerShell
md %windir%\system32\WindowsPowerShell\v1.0\

echo echo profile1 >%windir%\system32\WindowsPowerShell\v1.0\profile.ps1
echo echo profile2 >%windir%\system32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
echo echo profile3 >%UserProfile%\Documents\WindowsPowerShell\profile.ps1
echo echo profile4 >%UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

and then run PowerShell.

Btw. If you are wondering what these commands are doing – first 3 ensure the respective directories exist; the next 4 ones create dummy profile files with a simple command ‘echo xyz’, where xyz is a number of the profile. When executed for testing purposes they will simply show you which profile has been loaded by PowerShell. In a real-case scenario these would be replaced with an instruction to launch malware or could be any PowerShell command.

Anyway, back to the test. You will most likely be surprised to see that PowerShell does not load these profiles without a fight i.e. you may see a couple of error messages.

This is because by default the OS policy prevents executing PowerShell scripts (including the profile scripts) and one has to enable them first as documented here.

The Windows Registry values guarding this policy are stored under respective hkcu/hklm branches:

software\policies\microsoft\windows\powershell\
         EnableScripts (REG_DWORD)
         ExecutionPolicy (REG_SZ)

One can enforce then script execution by running the following commands (hklm may replace hkcu):

reg add hkcu\Software\Policies\Microsoft\Windows\PowerShell /f /v EnableScripts /t reg_dword /d 1
reg add hkcu\Software\Policies\Microsoft\Windows\PowerShell /f /v ExecutionPolicy /t reg_sz /d Unrestricted

Launching PowerShell now will show the following:

powershell_profile

You can download a batch file that I used to test the commands here.

Tested on Windows 8.1 and Windows 7.

Protecting VMWare from CPUID hypervisor detection

One of the less-known anti-sandbox detection tricks relies on the instruction CPUID that is executed with EAX=1 as an input parameter. When executed the values returned by general purpose registers describe the various Processor Info and Feature Bits. Some malware samples analyse the bit 31th of the value returned in the register ECX; the bit is equal to zero on the real CPU/hypervisor and 1 on the guest VM.

You can test this trick by running the following program.

When executed on a real CPU it should give you the following output:

cpuid_novm

 

On the guest OS it should (not surprisingly) show the following output:

cpuid_vm

Depending on your hardware set up and the way your Virtual Platform is executing code you may get different results (modification of virtualization and dynamic translation settings may affect the results).

Bypassing this trick on the code level (e.g. during debugging session or via patching) is not easy as you need to find a sequence of code that is responsible for the detection first. And if the code is metamorphic that won’t be easy (CPUID is just 2 bytes long i.e. 0F A2 and the input values may be initiated using random sequence of code).

It turns out VMWare (tested on 10.0.3) supports a mechanism that allows to modify the CPUID instruction results. All you have to do is add the following line to your .vmx file:

cpuid.1.ecx="0---:----:----:----:----:----:----:----"

It instructs the VMWare to mask the 31st bit of ECX when the CPUID instruction is executed. As such, running the same program on the re-configured VM will give you the output as seen on the first screenshot i.e. CPUID returns value observed on the real CPU; malware running on such re-configured VM will get fooled and the sandbox detection can be bypassed.

Note: I am not an expert in VMWare configuration – any modification you do to your VM is on your own risk. If you break anything it’s your own fault 🙂

I encourage you to explore VMWare forums before doing any modification to your setup. Also, remember that you need to fully restart the VM (and the guest system) for the change to take place (it won’t work for a restart from a snapshot).