PowerShell: The Double Edged Sword!

The Windows PC that you have on your desk carries so much legacy. Basically, very little has been dropped from the first version of DOS…

PowerShell: The Double Edged Sword!

The Windows PC that you have on your desk carries so much legacy. Basically, very little has been dropped from the first version of DOS. Okay, Windows is a lot better than Version 1.0, and it runs faster, but under the hood it still supports 32-bit and 64-bit programs, and you can still run BAT files like you did in the 1970s. One of most favouriate errors in Excel — and which shows the legacy of the infrastructure — is that you cannot open two Excel files with the same name, even though they are stored in different locations:

My Mac dumped 32-bit applications a long time ago and has a pseudo-Linux terminal that gives me Python in an instance.

And, so, it took Microsoft until 2006 to come up with a proper command line console and scripting tool: PowerShell 1.0. For Microsoft, they did their usual approach, and where the two versions was not that good, but each version has generally scaled the language up. But, the genius of PowerShell is that it tapped straight into .NET, and so that any C# program could be converted into a scripted form with PowerShell.

The latest version of PowerShell is 7.5, and most of the updates are mainly just bug fixes [here]:

Overall, it has taken Microsoft a while to integrate strong encryption within .NET, but they now support AES GCM mode. For this, we could run from the command prompt:

or create a PowerShell program [here]:

$plaintext =  $Args[0]
$password=$Args[1]

$keygen = [System.Security.Cryptography.Rfc2898DeriveBytes]::new($Args[1], 64, 10000)
$key = $keygen.GetBytes(32)

$aesGcm = [Security.Cryptography.AesGcm]::new($key)

$plainBytes = [System.Text.Encoding]::UTF8.GetBytes($plaintext)

$IV = $keygen.GetBytes(12)

$tag = [byte[]]::new(16)
$associatedData = [byte[]]::new(12)
$cipherText = [byte[]]::new($plainBytes.Length)

$aesGcm.Encrypt($IV, $plainBytes, $cipherText, $tag, $associatedData)


$plain = [byte[]]::new($cipherText.Length)

$aesGcm.Decrypt($IV, $cipherText, $tag, $plain, $associatedData)

"== AES GCM Encryption (using RFC2898 with 10,000 rounds for key derivation) =="
"`nMessage: " + $plaintext
"`nPassword: " + $password
"`nSalt: " + [System.Convert]::ToBase64String($IV)
"key: " + [System.Convert]::ToBase64String($key)
"`nEncryption: " + [System.Convert]::ToBase64String($cipherText)

"Decryption: " + [System.Text.Encoding]::UTF8.GetString($plain)

In .NET, we are using the System.Security.Cryptography.Rfc2898DeriveBytes class, and in C# this is just [here]:

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
var password="Test";
var plaintext="Test2";

if (args.Length >0) plaintext=args[0];
if (args.Length >1) password=args[1];
try {
var keygen = new System.Security.Cryptography.Rfc2898DeriveBytes(password, 64, 10000);
var key = keygen.GetBytes(32);
var aesGcm = new System.Security.Cryptography.AesGcm(key);

var plainBytes = System.Text.Encoding.UTF8.GetBytes(plaintext);

var IV = keygen.GetBytes(12);
var tag = new byte[16];

var associatedData = new byte[12];
var cipherText = new byte[plainBytes.Length];

aesGcm.Encrypt(IV, plainBytes,cipherText, tag, associatedData);


var plain = new byte[cipherText.Length];

aesGcm.Decrypt(IV, cipherText, tag, plain, associatedData);

Console.WriteLine("Plaintext: {0}",plaintext);
Console.WriteLine("Password: {0}",password);

Console.WriteLine("IV: {0} [{1}]",Convert.ToBase64String(IV),Convert.ToHexString(IV));
Console.WriteLine("Key: {0} [{1}]",Convert.ToBase64String(key),Convert.ToHexString(key));
Console.WriteLine("\nCipher: {0} [{1}]",Convert.ToBase64String(cipherText),Convert.ToHexString(cipherText));
Console.WriteLine("Plain text: {0}",System.Text.Encoding.UTF8.GetString(plain));
} catch (Exception e) {
Console.WriteLine("Error: {0}",e.Message);
}

}
}
}

You can thus view a C# code examples, and easily convert it to PowerShell, and vice-versa.

But, why is it a double-edged sword? Well, just like WMI (Windows Management Interface), we can open up the whole computer to enhancement functions and scripting. But, it also means an attacker can simply invoke a PowerShell script on your machine and gain access to virtually every element of it, including running ransomware. And, so, while your virus scanner may be looking for malicious binary code, a PowerShell script can go undetected.

So, here’s PowerShell in all its glory:

and the same programs in C#:

https://asecuritysite.com/csharp