# GZip and Base64 https://github.com/S3cur3Th1sSh1t/PowerSharpPack has a set of prebuilt binaries saved as powershell scripts. You compile the binaries with public methods and then convert them to gzip and base64 and they can then be loaded with reflection. I dug around the web for a while, but didn't find a script to do that binary to base64 conversion for me. The first 4 bytes of a gzip are the length of the byte string, but there's a lot of hit or miss out there on whether or not people choose to honor and do that. Some people xor encode and obfuscate the binary, some use normal zip instead of gzip. Pick your poisons. https://stackoverflow.com/questions/25134897/gzip-compression-and-decompression-in-c-sharp https://stackoverflow.com/questions/62175219/decompressing-a-base-64-encoded-gzip-with-powershell From reading invoke-badpotato, powersharppack uses gzip and does not do the 4 byte length header. https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-BadPotato.ps1 ``` $a=New-Object IO.MemoryStream(,[Convert]::FromBAsE64String("H4sIAAAAAAAEA...") $decompressed = New-Object IO.Compression.GzipStream($a,[IO.Compression.CoMPressionMode]::DEComPress) $output = New-Object System.IO.MemoryStream $decompressed.CopyTo( $output ) [byte[]] $byteOutArray = $output.ToArray() ``` I'm guessing he modified this: https://gist.github.com/marcgeld/bfacfd8d70b34fdf1db0022508b02aca Here's some cobbled together powershell that does that with files instead of strings you gotta grab out of a powershell term. compress.ps1 ``` [Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath $file = [System.IO.File]::ReadAllBytes("input.exe") [System.IO.MemoryStream] $output = New-Object System.IO.MemoryStream $compressed = New-Object System.IO.Compression.GzipStream($output,[IO.Compression.CompressionMode]::Compress) $compressed.Write( $file, 0, $file.Length ) $compressed.Close() $output.Close() [byte[]] $byteOutArray = $output.ToArray() $b64 = [Convert]::ToBase64String($byteOutArray) Add-Content zipped.txt $b64 ``` decompress.ps1 ``` [Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath $b64 = Get-Content zipped.txt $a=New-Object IO.MemoryStream(,[Convert]::FromBAsE64String($b64)) $decompressed = New-Object IO.Compression.GzipStream($a,[IO.Compression.CoMPressionMode]::DEComPress) $output = New-Object System.IO.MemoryStream $decompressed.CopyTo( $output ) [byte[]] $byteOutArray = $output.ToArray() [io.file]::WriteAllBytes("unzipped.exe",$byteOutArray) ``` That's ugly and makes my ape brain hurt. Ain't nobody got time for that, so I made a quick [program](files/convertpsp.exe) to do this conversion for me. ![](images/zipb64/convertpsp.JPG) Here's the source ``` using System; using System.IO; using System.IO.Compression; using System.Windows.Forms; namespace convertme { class Program { [STAThread] public static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please provide a file as the first argument"); System.Environment.Exit(1); } String fname = args[0]; byte[] file = System.IO.File.ReadAllBytes(fname); Console.WriteLine("Original Size: " + file.Length + " bytes"); byte[] compressed = CompressBytes(file); Console.WriteLine("Gzip Compressed: " + compressed.Length + " bytes"); String b64 = Convert.ToBase64String(compressed); Console.WriteLine("The base64 string is " + b64.Length + " characters and has been copied to the clipboard"); Clipboard.SetText(b64); } public static byte[] CompressBytes(byte[] input) { using (var result = new MemoryStream()) { using (var compressionStream = new GZipStream(result, CompressionMode.Compress)) { compressionStream.Write(input, 0, input.Length); compressionStream.Flush(); } return result.ToArray(); } } public static byte[] DecompressBytes(byte[] input) { using (var source = new MemoryStream(input)) { MemoryStream output = new MemoryStream(); using (var decompressionStream = new GZipStream(source, CompressionMode.Decompress)) { decompressionStream.CopyTo(output); return output.ToArray(); } } } } } ``` Here is what it looks like with the 4 byte skip [program](files/convertme.exe) ![](images/zipb64/convert.JPG) ``` using System; using System.IO; using System.IO.Compression; using System.Windows.Forms; namespace convertme { class Program { [STAThread] public static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please provide a file as the first argument"); System.Environment.Exit(1); } String fname = args[0]; byte[] file = System.IO.File.ReadAllBytes(fname); Console.WriteLine("Original Size: " + file.Length + " bytes"); byte[] compressed = CompressBytes(file); Console.WriteLine("Gzip Compressed: " + compressed.Length + " bytes"); String b64 = Convert.ToBase64String(compressed); Console.WriteLine("The base64 string is " + b64.Length + " characters and has been copied to the clipboard"); Clipboard.SetText(b64); } public static byte[] CompressBytes(byte[] input) { using (var result = new MemoryStream()) { var lengthBytes = BitConverter.GetBytes(input.Length); result.Write(lengthBytes, 0, 4); using (var compressionStream = new GZipStream(result, CompressionMode.Compress)) { compressionStream.Write(input, 0, input.Length); compressionStream.Flush(); } return result.ToArray(); } } public static byte[] DecompressBytes(byte[] input) { using (var source = new MemoryStream(input)) { byte[] lengthBytes = new byte[4]; source.Read(lengthBytes, 0, 4); var length = BitConverter.ToInt32(lengthBytes, 0); using (var decompressionStream = new GZipStream(source, CompressionMode.Decompress)) { var result = new byte[length]; decompressionStream.Read(result, 0, length); return result; } } } } } ```