Tuesday, June 16, 2015

Introduction To PowerShell

What is PowerShell:
- Used for task automation and management
- A framework by Microsoft.
- It is supported by .NET Framework. (As you can see below, you can play around with .Net functionality)

PowerShell has:
- Command-line shell, which is similar to cmd in Windows or terminal in Linux.
- Associated scripting language.


How to install:
You can follow the guide at Installing PowerShell Windows.
If you have installed Microsoft Visual Studio, it also have options to install PowerShell.

How to Start with command-line shell after installation:
- You can follow this guide at Starting the 32-bit Version of PowerShell
Normally in Windows, you also can click "Start" and search for PowerShell.

After starting, the screen is as below. You can type: get-command to see all commands.

PowerShell command-line

Getting Started With PowerShell Command-line
You can play around with PowerShell. In the Command-line Shell, 

Below is one way that you can save a password with SecureString to a text file. Although this is not the good way in terms of security, but this is a good start with PowerShell.

Try the following commands !

Command 1:
$key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)

Command 2:
$pw = read-host "Enter Password" –AsSecureString

Command 3:
ConvertFrom-SecureString $pw -key $key | out-file "path\to\password\file\here\textfile.txt"


Now you have a textfile.txt, and its content might look like this:

76492d1116743f0423413b16050a5345MgB8ADMAVQBBAG8AeQAwAC8AdwBaAFgAZgBxAHMAMgBOAHYAUgBhAG8AaQB3AGcAPQA9AHwAMgAwAGIAMQAyADQANwA0ADUAMQBlADAANQA4ADcANwA0AGMAYwA1ADEANwA2AGMAYQAyAGYAMgBhADQAOAA0ADcANAA2ADYAYgBiADAAYwA3AGIAZABlADIAMgAwADgAYQBlADYANAA1ADUAYwBmADMAMwA2ADMAMwA4ADcAMQA=


In order to decrypt the content, try the following command from the command-line Shell:

Command 4:
$password = cat  "path\to\password\file\here\textfile.txt" | convertto-securestring -key $key

Command 5:
$Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($password)

command 6:
$result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)

Command 7:
[System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)

Command 8:
$result


Here it is, $result is the "password" you entered in command 1

Just play around with it and you will get more experienced!

UPDATE 1:
Links

It is a little bit off the scope. Below is the C# code to convert the text of a SecureString stored in a text file to an in-memory SecureString.

public static SecureString ConvertToSecureString(string psProtectedString, byte[] key)
        {
            // '|' is indeed the separater
            byte[] asBytes = Convert.FromBase64String(psProtectedString);
            string[] strArray = Encoding.Unicode.GetString(asBytes).Split(new[] { '|' });

            if (strArray.Length != 3) throw new InvalidDataException("input had incorrect format");

            // strArray[0] is a static/magic header or signature (different passwords produce
            //    the same header)  It unused in our case, looks like 16 bytes as hex-string
            // you know strArray[1] is a base64 string by the '=' at the end
            //    the IV is shorter than the body, and you can verify that it is the IV, 
            //    because it is exactly 16bytes=128bits and it decrypts the password correctly
            // you know strArray[2] is a hex-string because it is [0-9a-f]
            byte[] magicHeader = HexStringToByteArray(psProtectedString.Substring(0, 32));
            byte[] rgbIV = Convert.FromBase64String(strArray[1]);
            byte[] cipherBytes = HexStringToByteArray(strArray[2]);

            // setup the decrypter
            SecureString str = new SecureString();
            SymmetricAlgorithm algorithm = SymmetricAlgorithm.Create();
            ICryptoTransform transform = algorithm.CreateDecryptor(key, rgbIV);
            using (var stream = new CryptoStream(new MemoryStream(cipherBytes), transform, CryptoStreamMode.Read))
            {
                // using this silly loop format to loop one char at a time
                // so we never store the entire password naked in memory
                int numRed = 0;
                byte[] buffer = new byte[2]; // two bytes per unicode char
                while ((numRed = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    str.AppendChar(Encoding.Unicode.GetString(buffer).ToCharArray()[0]);
                }
            }

            //
            // non-production code
            // recover the SecureString; just to check
            // from http://stackoverflow.com/questions/818704/how-to-convert-securestring-to-system-string
            //
            IntPtr valuePtr = IntPtr.Zero;
            string secureStringValue = "";
            try
            {
                // get the string back
                valuePtr = Marshal.SecureStringToGlobalAllocUnicode(str);
                secureStringValue = Marshal.PtrToStringUni(valuePtr);
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
            }

            return str;
        }

        // from http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa
       
public static byte[] HexStringToByteArray(String hex)
        {
            int NumberChars = hex.Length;
            byte[] bytes = new byte[NumberChars / 2];
            for (int i = 0; i < NumberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);

            return bytes;
        }

       
public static SecureString DecryptPassword(string psPasswordFile, byte[] key)
        {
            if (!File.Exists(psPasswordFile)) throw new ArgumentException("file does not exist: " + psPasswordFile);

            string formattedCipherText = File.ReadAllText(psPasswordFile);

            return ConvertToSecureString(formattedCipherText, key);
        }



No comments:

Post a Comment