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.
Invoke Expression Walkthrough
Level 1:
.('i'+'e'+'x') '$l2'
This concatenates the alias of Invoke-Expression (IEX) and runs the next command which is level 2
Level 2:
&('i'+'e'+'x') '$l3'
Duplicate of level 1 but has & instead of . to run the command and calls Level 3
Level 3:
&(('{2}{1}{0}' -f 'x', 'e', 'i')) '$l4'
This one is a string jumble where it puts together the following string in the order specified; in this case {2} = I, {1} = e, {0} = x
This one gets the preference above: SilentlyContinue, it extracts out ie and joins them to x and runs
Level 8:
&IE`x '$l9'
This one runs the ` which is an escape character in PowerShell, typically this is used for escaping \ and special characters that you want to print ou. But since x is not a special character the ` doesn’t do much but obfuscate the code.
Level 9:
&($PSHome[21]+$PSHOme[34]+'x') '$l10'
$pshome = C:\Windows\System32\WindowsPowerShell\v1.0, so this just pulls out the I and e from another variable
Level 10:
&('DEX'.replace('D','I')) '$l11'
This command takes DEX and replaces the D for an I so when ran it becomes IEX
This command takes the XEI and reverses it to become IEX
Getting to the Answer:
We can see that the original order of the script is out of order, so just going through you may get things jumbled.
But essentially to find the flag we need to run the last part of each line in order, all the invoke-expressions did was unscramble the order for us.
For example, we run for the last line we have #2, if we run the code after that separately, we get the following:
or Zml2 which if you don’t recognize this it is base64 for fiv
Let’s look closer at what is going on here
There is a variable called $flag that equals “n2ltZNWV22fZGhldbln29nZvcNbZtVma2Xp0” and in the code above we are calling in the positions of the letters in this jumbled up mess. So, the 23rd letter is Z … and so on (there is an empty space in the front of the letters so that is why it starts at 1 and not 0).
Pulling the letters out in order:
There are several ways to do this…
Manually pull them out… but this is time consuming and prone to human error.
2. You can run the echo commands one at a time
3. Or create a script that will pull it all together and convert from base64 (I like this one!)
#Z m l 2 Z W N 0 Z n t p b n Z v a 2 V f d G h l X 2 V 2 b 2 t l c n N 9
#23 31 18 2 5 7 26 36 28 19 29 35 27 1 23 24 32 20 30 11 16 13 14 3 34 10 8 33 17 9 4 15 25 22 6 21
#n 2 l t Z N W V 2 2 f Z G h l d b l n 2 9 n Z v c N b Z t V m a 2 X p 0
#1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6