C# – Elevation of Applications, Runas (Jump)

email me

This is a work in progress, but I have created a program to elevate a specified application. The idea is, you need to run an application under a restricted user profile, but cannot because it requires admin privileges—this gets around that. The program also bypasses UAC! Written in C#. I use the SecureStringProcessStartInfo, and MemoryStream classes to do exactly what I needed—securely elevate an application. Originally written for Windows 7 (back in 2014) to only elevate executable files, but I’m adding support for Windows 10 and scripting languages as well.

Current Features
   
 --Accepts executables
 --Accepts batch files
 --Accepts any passed parameters for program
 --Accepts an AES string for password
 --Accepts an encrypted reg key for password
 --Option to wait for program to exit
 --Create tighter try/catches (done 04/11/2017)
 --Remove second console window on batch files (done 04/14/2017) 
 --Create more methods from existing code (done 04/11/2017)
 --Add logging in registry (done 11/29/2017)
 --Add logging in event log (done 11/29/2017)
 --Add VBScript support (done 12/15/2017)

Future Ideas

 --Add a required pin number for internal script use
 --Add domain support 

 

AES Information

AES has three fixed 128-bit block ciphers with cryptographic key sizes of 128, 192 and 256 bits. Key size is unlimited, whereas the block size maximum is 256 bits. The AES design is based on a substitution-permutation network (SPN) and does not use the Data Encryption Standard (DES) Feistel network.

In 1997, the NIST initiated a five-year algorithm development process to replace DES and Triple DES. The NIST algorithm selection process facilitated open collaboration and communication and included a close review of 15 candidates. After an intense evaluation, the Rijndael design, created by two Belgian cryptographers, was the final choice.

AES replaced DES with new and updated features:

  • Block encryption implementation
  • 128-bit group encryption with 128, 192 and 256-bit key lengths
  • Symmetric algorithm requiring only one encryption and decryption key
  • Data security for 20-30 years
  • Worldwide access
  • No royalties
  • Easy overall implementation

 

How doe AES work?

 

What does the diagram mean?

• AES is a block cipher with a block length of 128 bits.

• AES allows for three different key lengths: 128, 192, or 256 bits.

• Encryption consists of 10 rounds of processing for 128-bit keys, 12 rounds for 192-bit keys, and 14 rounds for 256-bit keys.

• Except for the last round in each case, all other rounds are identical.

• Each round of processing includes one single-byte based substitution step, a row-wise permutation step, a column-wise mixing.

• To appreciate the processing steps used in a single round, it is best to think of a 128-bit block as consisting of a 4 × 4 matrix of bytes, arranged as follows:

• Therefore, the first four bytes of a 128-bit input block occupy the first column in the 4 × 4 matrix of bytes. The next four bytes occupy the second column, and so on.  more on AES…

 

Screenshot of Jump tool in action

 

Screenshot of elevation working

 

The Code (click to view source code)


using System;
using System.IO;                      // used by MemoryStream
using System.Diagnostics;             // used by Process
using System.Linq;                    // used by ToArray
using System.Security;                // used by SecureString
using System.Text;                    // used by Encoding
using System.Security.Cryptography;   // used by aes
using Microsoft.Win32;                // used by registry
using System.Collections.Generic;     // used by List (quotes)
using System.Text.RegularExpressions;

namespace Jump
{
    class JumpUtil
    {

        //////////////////////////////////////////////////
        // See all class declarations at the bottom
        //////////////////////////////////////////////////

        //////////////////////////////////////////////////
        // See notes at the bottom
        //////////////////////////////////////////////////


        static void Main(string[] args)

        {

            // CONSOLE HEADER
            //----------------------------------------------------
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("\nJump v1.0.0.1 December 2017");
            Console.WriteLine("\nLaunch Windows-based applications in elevated mode");
            Console.WriteLine("\nEddie Jackson | mrnettek@gmail.com | eddiejackson.net");
            Console.WriteLine("\nUsage: -app \"notepad.exe\" -opt \"name.txt\" -secure \"rEqnfiteGwLsktuW==\" -wait\n");

            // QUOTE
            // returns the random quote
            SubQuote();


            // BEGIN
            // load items into array
            // this loads arguments from the command line into an array
            foreach (string s in args)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    array = args[i].ToString();
                }

                // contains contents of array
                arrayString = arrayString + s.ToString() + " ";
            }
            // END - LOAD ITEMS INTO ARRAY            


            // SPACES
            // initialized to detect spaces and assign variables accordingly 
            // regex wasn't working properly when I added spaces
            string inputstring = arrayString.ToString();
            string[] inputstringarray = inputstring.Split(' ');



            // APP
            // does the command line contain the -app parameter?
            if (arrayString.Contains(parameterApp))
            {
                // found the -app parameter
                returnIndex = Array.IndexOf(inputstringarray, parameterApp);
                returnedApp = args[returnIndex + 1];                
               
                //returnedApp = FindNextValue(arrayString, parameterApp);  // regex doesn't work right. Disabled for now.
                if (returnedApp != parameterSecure &&
                    returnedApp != parameterOpt &&
                    returnedApp != parameterWait &&
                    returnedApp != "")
                {
                    appName = returnedApp;
                }
            }
            else
            {
                // the -app parameter is completely missing
                Messenger(Message1);
                Environment.Exit(6);
            }


            // OPTION
            // does the command line contain the -opt parameter?
            // I use string[] and IndexOf to read spaces in the options parameter
            // regex wasn't working properly when I added spaces
            if (arrayString.Contains("-opt"))
            {
                // found the -opt parameter
                returnIndex = Array.IndexOf(inputstringarray, parameterOpt);

                // return what follows the -opt parameter
                returnedOpt = args[returnIndex + 1];
                // accommodate extra spaces in file name - useful for vbs files
                if (returnedOpt == parameterSecure) {
                        returnedOpt = args[returnIndex + 0];
                    }

                // make sure returnedOpt isn't the AES variable
                if (returnedOpt.Contains("=="))
                {                    
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("\n\nMissing data from the -opt parameter!\n");
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Environment.Exit(6);
                }               

                // validate return option meets conditions
                if (
                    returnedOpt != parameterSecure &&
                    returnedOpt != parameterApp &&
                    returnedOpt != parameterWait &&
                    returnedOpt != "")
                {
                    // set options
                    appOpt = returnedOpt;               

                }
                else {

                    
                    // check for data following -opt parameter
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("\n\nMissing data from the -opt parameter!\n");
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Environment.Exit(6);
                }

            }



            // SECURE
            // does the command line contain the -secure parameter?
            if (arrayString.Contains(parameterSecure))
            {
                // found the -secure parameter
                returnedSecure = FindNextValue(arrayString, parameterSecure);
                if (returnedSecure != parameterApp &&
                    returnedSecure != parameterOpt &&
                    returnedSecure != parameterWait &&
                    returnedSecure != "")
                {
                    appPassword = (Decrypt(returnedSecure.ToString()));
                }
                else {

                    // check for data following -secure parameter
                    Messenger(Message2);
                    Environment.Exit(6);                    
                }
            }
            else
            {
                // the -secure parameter is completely missing                
                Messenger(Message6);                
                Environment.Exit(6);
            }
         

            // WAIT
            // does command line contain the -wait parameter?
            if (arrayString.Contains(parameterWait))
            {
                // found the -wait parameter
                appWait = "True";
            }
            else
            {
                // did not find the -wait parameter
                appWait = "False";

            }
            
            
            // DETERMINE FILE TYPE 
            // mostly made for handling batch files
            // had no issues with EXEs
            //----------------------------------------------------
            string retVBS = "FALSE";
            string retBAT = "FALSE";            
            string extension = Path.GetExtension(appName);

            if (extension.ToLower() == ".cmd") { retBAT = "TRUE"; }
            if (extension.ToLower() == ".bat") { retBAT = "TRUE"; }
            if (extension.ToLower() == ".vbs") { retVBS = "TRUE"; }            


            // BEGIN - ELEVATED APP LAUNCH            
            // use SecureString
            //----------------------------------------------------

            SecureString securePassword = new SecureString();
            Array.ForEach(appPassword.ToArray(), securePassword.AppendChar);
            securePassword.MakeReadOnly();

            // instantiate process from Process
            Process process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                // set up default properties
                UserName = appUser,
                Domain = "",
                Password = securePassword,
                LoadUserProfile = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };


            // CMD, BAT
            // IF A BATCH FILE, DO THIS
            // the reason I created this was because there is
            // an EXTRA black window when launching batch files 
            // using SecureString :: quite annoying MS hasn't 
            // done something about this
            //----------------------------------------------------
            if (retBAT == "TRUE")
            {
                try
                {
                    // DOES THE FILE EXIST???
                    if (!File.Exists(appName))
                    {
                        Messenger(Message10);
                        Environment.Exit(4);
                    }

                    startInfo.FileName = @"C:\Windows\SysWOW64\Wscript.exe";
                    startInfo.Arguments = "_hide.vbs";

                    string path = "_hide.vbs";
                    string text0 = "On error resume next:";
                    File.WriteAllText(path, text0);

                    // builds the vbscript
                    using (StreamWriter sw = File.AppendText(path))
                    {
                        string text1 = "";
                        string text2 = "";

                        if (appOpt != "")
                        {
                            // with option                            
                            text1 = "Set WshShell = CreateObject(\"WScript.Shell\"):";
                            text2 = "WshShell.Run chr(34) & " + "\"" + appName + "\"" + " & chr(34) & \" \" & chr(34) & " + "\"" + appOpt + "\"" + " & chr(34)" + ",0, true";
                                                       
                        }
                        else {
                            // without option                            
                            text1 = "Set WshShell = CreateObject(\"WScript.Shell\"):";
                            text2 = "WshShell.Run chr(34) & " + "\"" + appName + "\"" + " & chr(34)" + ",0, true";
                                                      
                        }

                        // writes the vbs to file
                        sw.WriteLine(text1);
                        sw.WriteLine(text2);
                    }

                    // instantiates the process
                    process = Process.Start(startInfo);

                    // checks to see if -wait is true
                    if (appWait == "True") { process.WaitForExit(); }

                    Console.ForegroundColor = ConsoleColor.Green;                    
                    Console.WriteLine("\nGreat Success!\n");
                    Console.ForegroundColor = ConsoleColor.White;

                    System.Threading.Thread.Sleep(1000);

                    // if this gets lost, I'll probably just add a %temp% path
                    if (File.Exists("_hide.vbs"))
                    {
                        File.Delete("_hide.vbs");
                    }
                    Audit();
                    Environment.Exit(0);
                }

                catch (Exception)
                {
                    Messenger(Message8);
                }
            }



            // VBS
            // IF A VBSCRIPT FILE, DO THIS
            //----------------------------------------------------
            if (retVBS == "TRUE")
            {
                try
                {
                    // DOES THE FILE EXIST???
                    if (!File.Exists(appName))
                    {
                        Messenger(Message10);
                        Environment.Exit(4);
                    }

                    startInfo.FileName = @"C:\Windows\SysWOW64\Wscript.exe";

                    if (appOpt != "")
                    {
                        //startInfo.Arguments = appName + " " + "\"" + appOpt + "\"";
                        startInfo.Arguments = "\"" + appName + "\"" + " " + "\"" + appOpt + "\"";
                        process = Process.Start(startInfo);                        
                        
                    }
                    else
                    {
                        startInfo.Arguments = "\"" + appName + "\"";
                        process = Process.Start(startInfo);
                    }

                    

                    if (appWait == "True") { process.WaitForExit(); }

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("\nGreat Success!\n");
                    Console.ForegroundColor = ConsoleColor.White;

                    System.Threading.Thread.Sleep(1000);
                    
                    Audit();
                    Environment.Exit(0);                    
                }
                catch (Exception)
                {
                    Messenger(Message8);
                }
            }


            // EXE
            // IF AN EXECUTABLE FILE, DO THIS
            //----------------------------------------------------

            // does app exist?                

            try
            {
                // I have added a little bit of extra logic for EXEs, specifically 'system' EXEs that may be in Windows or System32 folders
                // I append the .EXE and relative system paths just as an extra feature to find 'known' EXEs. Otherwise, EXEs like ping, 
                // calc, notepad, net, reg, etc., would fail without the path being explicitly defined
                if (!File.Exists(appName) && (!File.Exists(appName + ".exe")))
                {
                    if (!File.Exists("C:\\Windows\\" + appName + ".exe") && (!File.Exists("C:\\Windows\\" + appName)))
                    {
                        if (!File.Exists("C:\\Windows\\system32\\" + appName + ".exe") && (!File.Exists("C:\\Windows\\system32\\" + appName)))
                        {
                            Messenger(Message10);
                            Environment.Exit(4);
                        }
                    }
                }


                startInfo.FileName = appName;                
                if (appOpt != "") { startInfo.Arguments = "\"" + appOpt  + "\""; }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Elevating...");
                Console.ForegroundColor = ConsoleColor.White;

                process = Process.Start(startInfo);                

                if (appWait == "True") { process.WaitForExit(); }

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("\nGreat Success!\n");
                Console.ForegroundColor = ConsoleColor.White;
                Audit();
                Environment.Exit(0);
            }

            catch (Exception)
            {
                Messenger(Message8);
            }


        }
        // END - ELEVATED APP LAUNCH


        // RETURN NEXT VALUE        
        public static string FindNextValue(string inputArray, string inputSearch)
        {
            sNext = "";

            if (arrayString.Contains(inputSearch))
            {

                string[] sRegX = Regex.Split(inputArray, @"[^’a-zA-Z0-9\\\:\=\-\._]+");

                int index = Array.IndexOf(sRegX, inputSearch);
                if (index < sRegX.Count() - 1)
                    sNext = sRegX[index + 1];
            }

            return sNext;
        }

        
        // BASIC LOGGING
        static void Audit()
        {
            // create registry key

            string reg1 = "HKEY_CURRENT_USER";
            string reg2 = @"SOFTWARE\Jump\";
            string regPath = reg1 + @"\" + reg2;
            string UName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            string regVal = appName + " " + UName;
            
            DateTime dt = DateTime.Now;
            Registry.SetValue(regPath, dt.ToString(), regVal, RegistryValueKind.String);

            
            // log event

            string sSource;
            string sLog;
            string sEvent;

            sSource = "Jump.exe";
            sLog = "Application";
            
            sEvent = appName + " was installed using the Jump tool by " + UName;

            if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);

            EventLog.WriteEntry(sSource, sEvent);

            // output to console
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("{{{ Security log has been updated }}}\n");
            Console.ForegroundColor = ConsoleColor.Gray;
        }
                    


        
        // Just show header of jump util

        static void Help()
        {
            Console.ForegroundColor = ConsoleColor.White;
            Environment.Exit(0);
        }

        // import and show message
        static void Messenger(string message)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("\n{0}\n", message);
            Console.ForegroundColor = ConsoleColor.White;
            Environment.Exit(2);
        }


        // returns random quote
        static void SubQuote()
        {
            QuoteGenerator quoteGenerator = new QuoteGenerator();
            string retQuote = quoteGenerator.ReturnRandomQuote();
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("{0}\n", retQuote);
            Console.WriteLine("");
            Console.ForegroundColor = ConsoleColor.White;
        }

       
       
        // decoding
        public static string Decrypt(string strData)
        {
            try
            {
                if ((strData.Length % 4) == 0)
                {
                    //aes string length is good
                    return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(strData)));
                }

                Messenger(Message9);
                Environment.Exit(6);             
                return null; 

            }
            catch (Exception)
            {
                Messenger(Message9);
                Environment.Exit(6);                
                return null; // prevents return error message
            }         
}

        // decrypt
        public static byte[] Decrypt(byte[] strData)
        {

            try
            {
                PasswordDeriveBytes passbytes =
                new PasswordDeriveBytes(strPermutation,
                new byte[] {            bytePermutation1,
                                        bytePermutation2,
                                        bytePermutation3,
                                        bytePermutation4
                //Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.passwordderivebytes%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
            });
                

                MemoryStream memstream = new MemoryStream();
                Aes aes = new AesManaged();
                aes.Key = passbytes.GetBytes(aes.KeySize / 8);
                aes.IV = passbytes.GetBytes(aes.BlockSize / 8);
                //Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged(v=vs.110).aspx

                CryptoStream cryptostream = new CryptoStream(memstream,
                aes.CreateDecryptor(), CryptoStreamMode.Write);
                cryptostream.Write(strData, 0, strData.Length);
                cryptostream.Close();
                return memstream.ToArray();
                //Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream(v=vs.110).aspx
            }
            catch (Exception)
            {
                Messenger(Message8);
                Environment.Exit(6); // exits in case the password fails
                //return strData;
                return null; // prevents return error message
            }

        }

        class QuoteGenerator
        {
            Random random = new Random();
            List<string> Quotes = new List<string>();

            public QuoteGenerator()
            {
                Quotes.Add("Intelligence is the ability to adapt to change - Stephen Hawking");
                Quotes.Add("Nothing endures but change - Heraclitus");
                Quotes.Add("Dream big and dare to fail - Normal Vaughan");
                Quotes.Add("If it doesn’t challenge you, it won’t change you - Fred DeVito");
                Quotes.Add("Genius is talent set on fire by courage Henry Van Dyke");
                Quotes.Add("Energy and persistence conquer all things - Benjamin Franklin");
                Quotes.Add("The secret of getting ahead is getting started - Mark Twain");
                Quotes.Add("The measure of who we are is what we do with what we have - Vince Lombardi");
                Quotes.Add("With self-discipline most anything is possible - Theodore Roosevelt");
                Quotes.Add("The price of greatness is responsibility - Winston Churchill");
                Quotes.Add("Action is the foundational key to all success - Picasso");
                Quotes.Add("Try not to become a man of success, but rather a man of value - Albert Einstein");
                Quotes.Add("Learning never exhausts the mind - Leonardo da Vinci");
            }

            public string ReturnRandomQuote()
            {
                int quoteCount = Quotes.Count;
                int randomNumber = random.Next(0, (quoteCount - 1));
                return Quotes[randomNumber];
            }
        }


        // the admin user account name
        public const string appUser = "Administrator";        

        // use these permutations - change these
        public const string strPermutation = "eqyshqfqhjk";
        public const int bytePermutation1 = 0x11;
        public const int bytePermutation2 = 0x19;
        public const int bytePermutation3 = 0x17;
        public const int bytePermutation4 = 0x11;

        public const string strRegHive = "HKEY_LOCAL_MACHINE";
        public const string strRegKey = @"SOFTWARE\Serial\";
        public const string strRegPath = strRegHive + @"\" + strRegKey;
        public const string strRegVal = "Serial1";

        // general console messages
        public const string Message1 = "Slow down there, Skippy. Did you forget the -app parameter?";
        public const string Message2 = "Ohhh, man...did you forget to add the AES string?";
        public const string Message3 = "Yo, where is the -opt parameter? Use -opt.";
        public const string Message4 = "Wait a minute. Looks like -wait is missing.";
        public const string Message5 = "Hey, dude, you forgot to enter an app name.";
        public const string Message6 = "Houston, we have a problem. Did you forget to add the -secure parameter?";
        public const string Message7 = "Too much, man...too much. You have too much in the command line.";
        public const string Message8 = "Hold on, Chief. This isn't good...the app wasn't elevated.";
        public const string Message9 = "Come on man...the AES string is too short.";
        public const string Message10 = "The file seems to have taken a vacation. It can't be found!";        

                
        // the array, working space
        public static string array = "";

        // the items in the array
        public static string arrayString = "";

        // appVar(i) becomes appName, appOpt, appWait, appPassword            
        public static string appPassword = "";
        public static string appName = "";
        public static string appOpt = "";
        public static string appWait = "";
        private static string sNext;

        public static string parameterApp = "-app";
        public static string parameterWait = "-wait";
        public static string parameterOpt = "-opt";
        public static string parameterSecure = "-secure";        
        public static string returnedApp = "";
        public static string returnedSecure = "";
        public static string returnedOpt = "";
        public static int returnIndex;
    }

}

/*NOTES

       SPACES IN THE DECRYPT STRING
       64-bit encoding does not work well with spaces in the string for some odd reason. 
       Add the following: stringToDecrypt = stringToDecrypt.Replace(" ","+");
       before this line "int len = stringToDecrypt.Length; inputByteArray = Convert.FromBase64String(stringToDecrypt);"
       to replace blank spaces with '+'. Plus sign will be interpreted as a space when you call the FromBase64String method.

       EXTRA BLACK WINDOW (CONSOLE WINDOW)
       When using SecureString, and passing a username and password to a BATCH file process, an EXTRA black window appears.
       The window is tied to the batch file :-( , and from what I can tell, cannot be so easily hidden. Yes, you can hide the main
       process window, but not the child window. If you close the child window, it kills the batch file. Arrrrrg.
       I was able to create a workaround using VBS output and hiding the batch process, but I will be looking for a better solution.

*/



 

Screenshot of Visual Studio (click to zoom)

* no longer uses a password – I’m passing in an AES string

Fun Fact

It would take a supercomputer 1 billion billion years to crack the 128-bit AES key using brute force attack. This is more than the age of the universe (13.75 billion years).

VBScript – Translating Characters that have been Substituted

email me

This is the second part of a substitution program I wrote (this is the decoder portion); the first part was in C# (the encoder). Originally, I wrote both parts in C#, but had people asking me for something that did not require compiling to use in their scripts, so I created this VBScript. The idea is…the encoded string is accepted by the script and then translated into its original form.

This script could be utilized for encoding and decoding if you reverse (or create a function to reverse) the translation sequences (permutations).

Note, you want to make sure you change the sequences, to provide a level of uniqueness for your environment.

 

Option Explicit

Dim strShift, strPassword, WshShell, bufferLength, i, retValue

Set WshShell = WScript.CreateObject("WScript.Shell")


'Verify if reg key exists
KeyExists "SOFTWARE\Wow6432Node\ZWT", "ZWT1"
if retValue = "False" then WScript.Quit(1)

'Return Password
Translate()

'strPassword is translated password
'this will be what is used for elevated apps
msgbox strPassword

WScript.Quit()


'do not edit below this line unless changing permutations
'---------------------------------------------------
sub Translate()

'clip or output file could be used to grab output
CreateObject("WScript.Shell").Run "cmd /c RegRead.exe | clip", 0, True

strShift = CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text")
strShift = trim(strShift)
strShift = replace(strShift,chr(13),"")

Dim buffer()
bufferLength = Len(strShift)
ReDim buffer(bufferLength)
For i = 1 To Len(strShift)
buffer(i) = Mid(strShift,i,1)

Do While True
if buffer(i) = "O" then buffer(i) = "A" : exit do
if buffer(i) = "K" then buffer(i) = "B" : exit do
if buffer(i) = "I" then buffer(i) = "C" : exit do
if buffer(i) = "R" then buffer(i) = "D" : exit do
if buffer(i) = "B" then buffer(i) = "E" : exit do
if buffer(i) = "H" then buffer(i) = "F" : exit do
if buffer(i) = "P" then buffer(i) = "G" : exit do
if buffer(i) = "W" then buffer(i) = "H" : exit do
if buffer(i) = "J" then buffer(i) = "I" : exit do
if buffer(i) = "V" then buffer(i) = "J" : exit do
if buffer(i) = "G" then buffer(i) = "K" : exit do
if buffer(i) = "A" then buffer(i) = "L" : exit do
if buffer(i) = "C" then buffer(i) = "M" : exit do
if buffer(i) = "T" then buffer(i) = "N" : exit do
if buffer(i) = "N" then buffer(i) = "O" : exit do
if buffer(i) = "Q" then buffer(i) = "P" : exit do
if buffer(i) = "U" then buffer(i) = "Q" : exit do
if buffer(i) = "E" then buffer(i) = "R" : exit do
if buffer(i) = "F" then buffer(i) = "S" : exit do
if buffer(i) = "Y" then buffer(i) = "T" : exit do
if buffer(i) = "D" then buffer(i) = "U" : exit do
if buffer(i) = "Z" then buffer(i) = "V" : exit do
if buffer(i) = "S" then buffer(i) = "W" : exit do
if buffer(i) = "L" then buffer(i) = "X" : exit do
if buffer(i) = "M" then buffer(i) = "Y" : exit do
if buffer(i) = "X" then buffer(i) = "Z" : exit do

if buffer(i) = "o" then buffer(i) = "a" : exit do
if buffer(i) = "k" then buffer(i) = "b" : exit do
if buffer(i) = "i" then buffer(i) = "c" : exit do
if buffer(i) = "r" then buffer(i) = "d" : exit do
if buffer(i) = "b" then buffer(i) = "e" : exit do
if buffer(i) = "h" then buffer(i) = "f" : exit do
if buffer(i) = "p" then buffer(i) = "g" : exit do
if buffer(i) = "w" then buffer(i) = "h" : exit do
if buffer(i) = "j" then buffer(i) = "i" : exit do
if buffer(i) = "v" then buffer(i) = "j" : exit do
if buffer(i) = "g" then buffer(i) = "k" : exit do
if buffer(i) = "a" then buffer(i) = "l" : exit do
if buffer(i) = "c" then buffer(i) = "m" : exit do
if buffer(i) = "t" then buffer(i) = "n" : exit do
if buffer(i) = "n" then buffer(i) = "o" : exit do
if buffer(i) = "q" then buffer(i) = "p" : exit do
if buffer(i) = "u" then buffer(i) = "q" : exit do
if buffer(i) = "e" then buffer(i) = "r" : exit do
if buffer(i) = "f" then buffer(i) = "s" : exit do
if buffer(i) = "y" then buffer(i) = "t" : exit do
if buffer(i) = "d" then buffer(i) = "u" : exit do
if buffer(i) = "z" then buffer(i) = "v" : exit do
if buffer(i) = "s" then buffer(i) = "w" : exit do
if buffer(i) = "l" then buffer(i) = "x" : exit do
if buffer(i) = "m" then buffer(i) = "y" : exit do
if buffer(i) = "x" then buffer(i) = "z" : exit do

if buffer(i) = "7" then buffer(i) = "0" : exit do
if buffer(i) = "4" then buffer(i) = "1" : exit do
if buffer(i) = "9" then buffer(i) = "2" : exit do
if buffer(i) = "5" then buffer(i) = "3" : exit do
if buffer(i) = "3" then buffer(i) = "4" : exit do
if buffer(i) = "6" then buffer(i) = "5" : exit do
if buffer(i) = "0" then buffer(i) = "6" : exit do
if buffer(i) = "1" then buffer(i) = "7" : exit do
if buffer(i) = "2" then buffer(i) = "8" : exit do
if buffer(i) = "8" then buffer(i) = "9" : exit do

if ASC(buffer(i)) = ASC("$") then buffer(i) = CHR(ASC("?")) : exit do
if ASC(buffer(i)) = ASC("?") then buffer(i) = CHR(ASC("$")) : exit do

if ASC(buffer(i)) = ASC("~") then buffer(i) = CHR(ASC("@")) : exit do
if ASC(buffer(i)) = ASC("@") then buffer(i) = CHR(ASC("~")) : exit do

if ASC(buffer(i)) = ASC("%") then buffer(i) = CHR(ASC("!")) : exit do
if ASC(buffer(i)) = ASC("!") then buffer(i) = CHR(ASC("%")) : exit do

if ASC(buffer(i)) = ASC("-") then buffer(i) = CHR(ASC("#")) : exit do
if ASC(buffer(i)) = ASC("#") then buffer(i) = CHR(ASC("-")) : exit do

if ASC(buffer(i)) = ASC("*") then buffer(i) = CHR(ASC("(")) : exit do
if ASC(buffer(i)) = ASC("(") then buffer(i) = CHR(ASC("*")) : exit do

if ASC(buffer(i)) = ASC("&") then buffer(i) = CHR(ASC("'")) : exit do
if ASC(buffer(i)) = ASC("'") then buffer(i) = CHR(ASC("&")) : exit do

if ASC(buffer(i)) = ASC("_") then buffer(i) = CHR(ASC(")")) : exit do
if ASC(buffer(i)) = ASC(")") then buffer(i) = CHR(ASC("_")) : exit do

if ASC(buffer(i)) = ASC("^") then buffer(i) = CHR(ASC("+")) : exit do
if ASC(buffer(i)) = ASC("+") then buffer(i) = CHR(ASC("^")) : exit do

if ASC(buffer(i)) = ASC("`") then buffer(i) = CHR(ASC(".")) : exit do
if ASC(buffer(i)) = ASC(".") then buffer(i) = CHR(ASC("`")) : exit do

if ASC(buffer(i)) = ASC(",") then buffer(i) = CHR(ASC("=")) : exit do
if ASC(buffer(i)) = ASC("=") then buffer(i) = CHR(ASC(",")) : exit do

if ASC(buffer(i)) = ASC("\") then buffer(i) = CHR(ASC("/")) : exit do
if ASC(buffer(i)) = ASC("/") then buffer(i) = CHR(ASC("\")) : exit do

if ASC(buffer(i)) = ASC(">") then buffer(i) = CHR(ASC("<")) : exit do
if ASC(buffer(i)) = ASC("{") then buffer(i) = CHR(ASC("}")) : exit do

if ASC(buffer(i)) = ASC("}") then buffer(i) = CHR(ASC("{")) : exit do
if ASC(buffer(i)) = ASC("<") then buffer(i) = CHR(ASC(">")) : exit do

if ASC(buffer(i)) = ASC("]") then buffer(i) = CHR(ASC("[")) : exit do
if ASC(buffer(i)) = ASC("[") then buffer(i) = CHR(ASC("]")) : exit do

if ASC(buffer(i)) = ASC(";") then buffer(i) = CHR(ASC(":")) : exit do
if ASC(buffer(i)) = ASC("|") then buffer(i) = CHR(ASC("|")) : exit do

if ASC(buffer(i)) = ASC(":") then buffer(i) = CHR(ASC("""")) : exit do
if ASC(buffer(i)) = ASC("""") then buffer(i) = CHR(ASC(":")) : exit do
exit do
loop
Next

strPassword = ""

For i = 0 to bufferLength
strPassword = strPassword & buffer(i)
Next

CreateObject("WScript.Shell").Run "cmd /c echo. | clip", 0, True

end sub


sub KeyExists(RegPath, RegKey)
	Const HKEY_LOCAL_MACHINE = &H80000002
	Dim strComputer, objRegistry, RegValue, objWshShell	

	Set objWshShell = CreateObject("WScript.shell")
	
	strComputer = "."
	Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

	objRegistry.GetStringValue HKEY_LOCAL_MACHINE,RegPath,RegKey,RegValue
	
	If Not IsNull(RegValue) Then
	    retValue = True
	Else
	    retValue = False
	End If	
end sub

Batch – LANDesk Local Admin Password Change (Obfuscation)

email me

Simple LANDesk Delivery Script (to be compiled)

This can be used by LANDesk to reset the local admin password. I have added the encrypted reg key for elevated apps.

Only deploy compiled scripts! I use ExeScript.

@echo on
title Local Admin Password Reset
cls
color 0a

call :SHIFTER

Set Cypher=tU2igtOeEfJxRfK43bDTDw==
set RegPath=HKLM\SOFTWARE\Wow6432Node\ZYT
set SysPath=C:\Windows\system32

:START
:: Set password using shifter variables
%SysPath%\NET USER Administrator "%P4%%P1%%P2%%P5%%P2%%P6%%P3%%P6%" && goto NEXT || goto END

:NEXT
:: Remove old cypher
%SysPath%\REG DELETE "%RegPath%" /f /REG:64
goto END

:: Add new cypher. Used for SecureString - Elevated apps
%SysPath%\REG ADD "%RegPath%" /v ZYT1 /t REG_SZ /d "%Cypher%" /f /REG:64

:END
exit /b 0

:SHIFTER
:: Scramble the password here
set P0=a
set P1=g
set P2=#
set P3=0
set P4=A
set P5=I
set P6=e
set P7=B
set P8=v
set P9=D

VBScript – Check to See if Web File exists, Download It

email me

Dim varHTTP, varBinaryString, varFileName, varLink

set objShell = CreateObject("WScript.Shell")
 
Set varHTTP = CreateObject("Microsoft.XMLHTTP")
Set varBinaryString = CreateObject("Adodb.Stream")

varFileName = "Foo.exe"
varLink = "http://TheWebURL/" & varFileName
varHTTP.Open "GET", varLink, False
varHTTP.Send


'Sequencing...
CheckFile()
DownloadFile()

'add other stuff to do here


sub CheckFile()
	Select Case Cint(varHTTP.status)
		Case 200, 202, 302 
			'it exists
			msgbox "File exists!"
			Exit Sub
		Case Else
			'does not exist			
			msgbox "File does not exist!"
			WScript.quit
	End Select
end sub

sub DownloadFile()
		With varBinaryString
			.Type = 1 'my type has been set to binary
			.Open
			.Write varHTTP.responseBody
			.SaveToFile ".\" & varFileName, 2 'if exist, overwrite
		End With
		varBinaryString.close
		msgbox "Download complete!"
end sub

 
Notes

200 – OK (standard successful http request)
202 – Accepted (request accepted for processing, but not completed)
302 – Found (via redirection)

PowerShell Return True or False for Certificates

email me

This is something I created to return a True or False whether or not specified computer certificates are installed. It writes this information to the registry for desktop management software scanning. My original objective was just to determine whether or not an old (about to expire) cert still existed, but I went ahead and added detection for the new one as well.

# AUTHOR: Eddie Jackson
# DATE: 03/28/2017
# USAGE: To verify if specified certs are in local
# store
# NOTES: Desktop Management will report on reg keys
# set to TRUE or FALSE

Clear-Host

# OLD Cert Thumbprint
$Cert1 = "12345678912C7409FBF28C86D208637123456789"

# New Cert Thumbprint
$Cert2 = "FD5C3FC1F3C405D1D468EF0A0A12345678912345"

# Reg Path
$RegPath = 'HKLM:\SOFTWARE\COMPANY\AppName\Cert'

# Clear Session
$OLD = ""
$NEW = ""
Remove-ItemProperty -Path $RegPath -Name "$Cert1" | Out-Null
Remove-ItemProperty -Path $RegPath -Name "$Cert2" | Out-Null
New-Item -Path $RegPath -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "$Cert1" -Value "FALSE"
New-ItemProperty -Path $RegPath -Name "$Cert2" -Value "FALSE"
Start-Sleep 5 # time to verify reg keys are reset

# Assign Current Certs to variables
$OLD = Get-ChildItem Cert:\LocalMachine\My | Select -Property Thumbprint |
Where-Object {$_.Thumbprint -eq "$Cert1"} |
foreach { $_.Thumbprint }

$NEW = Get-ChildItem Cert:\LocalMachine\My | Select -Property Thumbprint |
Where-Object {$_.Thumbprint -eq "$Cert2"} |
foreach { $_.Thumbprint }

# Determine if Certs exist
if ($OLD -eq "$Cert1") {
#Write-Host "Old Exists"
New-ItemProperty -Path $RegPath -Name "$Cert1" -Value "TRUE" -Force | Out-Null

}

if ($NEW -eq "$Cert2") {
#Write-Host "New Exists"
New-ItemProperty -Path $RegPath -Name "$Cert2" -Value "TRUE" -Force | Out-Null
}

 
Screenshot of registry

Enable/Disable SMBv1, SMBv2, SMBv3

email me

Microsoft has released a security update to address a vulnerability in implementations of Server Message Block 1.0 (SMBv1). Exploitation of this vulnerability could allow a remote attacker to take control of an affected system.

US-CERT encourages users and administrators to review Microsoft Security Bulletin MS17-010 and apply the update. For more information, see the Information Assurance Advisory and US-CERT’s SMB Security Best Practices guidance.

Note, ever since Windows 10 Build 1709, the reg keys don’t work so great (that’s because MS has removed the SMBv1 feature, altogether). Use dism or PowerShell cmdlets instead.

 

Return all protocols

dism /online /get-features /format:table


Enable SMBv1 via PowerShell

Enable-WindowsOptionalFeature -Online -FeatureName smb1protocol -norestart


Enable SMBv1 via Dism

dism /online /enable-feature /featurename:SMB1Protocol-Server -NoRestart

To check the status of SMB versions on your servers (from PowerShell)

Get-SMBServerConfiguration

Snapshot 

 

This is the reg key for SMBv1:

Steps to enable and disable the SMBv1 on the SMB server using the registry:

Registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Registry entry: SMB1
REG_DWORD: 0 = Disabled
REG_DWORD: 1 = Enabled
Default: 1 = Enabled

For SMBv2…

Registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Registry entry: SMB2
REG_DWORD: 0 = Disabled
REG_DWORD: 1 = Enabled
Default: 1 = Enabled

 

Notes

https://technet.microsoft.com/en-us/library/security/mt745122.aspx

https://support.microsoft.com/en-gb/help/2696547/how-to-enable-and-disable-smbv1,-smbv2,-and-smbv3-in-windows-vista,-windows-server-2008,-windows-7,-windows-server-2008-r2,-windows-8,-and-windows-server-2012

Other Bulletins (yes, you should be reading these)
https://technet.microsoft.com/en-us/library/security/mt745122.aspx

 

Commands

Disables the SMBv1 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi
sc.exe config mrxsmb10 start= disabled

Enables the SMBv1 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb10 start= auto

Disables the SMBv2 and SMBv3 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/nsi
sc.exe config mrxsmb20 start= disabled

Enables the SMBv2 and SMBv3 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb20 start= auto

 

Script to Disable SMB

@echo off
Title Manage SMB
cls

:DISABLE
%windir%\system32\sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi >log.txt
%windir%\system32\sc.exe config mrxsmb10 start= disabled >>log.txt

%windir%\system32\sc.exe config lanmanworkstation depend= bowser/mrxsmb10/nsi >>log.txt
%windir%\system32\sc.exe config mrxsmb20 start= disabled >>log.txt

%windir%\system32\EVENTCREATE.exe /T INFORMATION  /l Application  /ID 777 /d “Disabled SMB”
exit

 

 

PowerShell

Disables the SMBv1 on the SMB server by running the below command

Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB1 -Value 0 –Force


Disables the SMBv2 and SMBv3 on the SMB server by running the below command

Set-ItemProperty –Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB2 –Value 0 –Force


Enables the SMBv1 on the SMB server by running the below command

Set-ItemProperty –Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB1 –Value 1 –Force

Enables the SMBv2 and SMBv3 on the SMB server by running the below command

Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB2 -Value 1 -Force

SCCM Change Site Code

email me

This is a quick way to update a client’s site code. Make sure you run as admin.

I ended up needing this, because while our SCCM was being configured at the forest level (which took a while), I was already testing the SCCM server. Without this, the clients could not communicate with the server.

Set objShell = CreateObject("WScript.Shell")
set objSMSClient = CreateObject ("Microsoft.SMS.Client")

'update site code
objSMSClient.SetAssignedSite "ABC",0

'restart process
objShell.Run "C:\Windows\CCM\CcmRestart.exe",0,true

msgbox " Site code has been changed!"

PowerShell – Return Computer name, Count of Missing Updates, Missing KBs

email me

This will return missing patches (missing security and critical updates) based upon a KB text file. I used a fully patched computer + the published KBs from a patch server to create a master KBs.txt file. The KB file contains KBs by the numbers: KB11111, KB22222, etc (one per line). I also have a computers.txt file which permits you to query missing updates on multiple computers, remotely. Just to verify it was at least hitting the right ballpark number, I installed Belarc to crosscheck missing updates. So far, it has been 100% accurate.

The data comes out in CSV format (click image to zoom)

 

What you need

  • KBs.txt
  • Computers.txt
  • Admin access
  • The script I created below

 

Clear-Host

# Path to files
$filePath = "C:\scripts"

# the computers to check
$computerList = Get-Content -Path "$filePath\computers.txt" 

# the KBs to check
$patchList = Get-Content -Path "$filePath\KBs.txt" 

$E_Total = "" # exists total
$NE_Total = "" # not exists total
$Count = 0 # missing updates counter
$BoolCheck = 0 

 
foreach ($computer in $computerList)
{  
    
    # is machine online?
    $Ping = test-connection -ComputerName $computer -Count 2 -quiet 
 
    # yes, online
     if($Ping) 
        {         
       
        # get current list of hotfixes on machine
        $HotfixList = Get-HotFix -ComputerName $computer | select -Property "HotFixID"
 
        # cycle through each patch in list
        foreach($patch in $patchList)
        {         
            $BoolCheck=0
            
            
            # cycle through hotfixes on local machine
            foreach ($Hotfix in $HotfixList)                
            { 

                # compare local machine hotfixes with our list
                # if it matches, exists
                if ($patch -eq $Hotfix.HotFixID) 
                    {       
                        $BoolCheck=1                          
                        break
                      }             
                      
                       
                  }
               
               if ($found -eq 1) {
               $E_Total = "$E_Total,$patch"
               }
               
               if ($BoolCheck -eq 0) {
               # $patch
               $NE_Total = "$NE_Total,$patch"
               $Count=$Count+1
               }                
                   
            }
            # Write-Host "Found:   $Computer$E_Total"            
            Write-Host "$Computer,Missing $count$NE_Total"
            Write-Host " "
            
            # Clear session
            $E_Total = ""
            $NE_Total = ""
            $Count = 0
            $BoolCheck = 0
            
            
}
 
# no, not online
else 
{ 
Write-Host "$Computer,Not Online"
Write-Host " "
} 
}

 

The KBs in the KBs.txt file I used…though, yours will most likely be different due to imaging practices and new KB releases.

KB2305420
KB2393802
KB2479943
KB2491683
KB2506014
KB2506212
KB2506928
KB2509553
KB2511455
KB2515325
KB2533552
KB2536275
KB2536276
KB2538242
KB2544893
KB2545698
KB2547666
KB2552343
KB2560656
KB2563227
KB2564958
KB2565063
KB2570947
KB2574819
KB2579686
KB2584146
KB2585542
KB2592687
KB2603229
KB2604115
KB2619339
KB2620704
KB2621440
KB2631813
KB2640148
KB2644615
KB2647753
KB2654428
KB2660075
KB2661254
KB2667402
KB2670838
KB2676562
KB2685811
KB2685813
KB2685939
KB2690533
KB2698365
KB2705219
KB2709630
KB2709981
KB2712808
KB2718704
KB2719857
KB2726535
KB2727528
KB2729094
KB2732059
KB2732487
KB2732500
KB2736422
KB2742599
KB2750841
KB2761217
KB2763523
KB2770660
KB2773072
KB2786081
KB2791765
KB2799926
KB2803821
KB2807986
KB2808679
KB2813170
KB2813347
KB2813430
KB2820331
KB2832414
KB2834140
KB2835361
KB2839894
KB2840631
KB2841134
KB2843630
KB2846960
KB2847077
KB2847311
KB2847927
KB2849696
KB2849697
KB2852386
KB2853952
KB2861191
KB2861698
KB2861855
KB2862152
KB2862330
KB2862335
KB2862966
KB2862973
KB2864058
KB2864202
KB2868038
KB2868116
KB2868626
KB2872339
KB2884256
KB2887069
KB2888049
KB2891804
KB2892074
KB2893294
KB2893519
KB2900986
KB2910978
KB2911501
KB2912390
KB2913152
KB2913431
KB2918077
KB2919469
KB2920680
KB2929733
KB2929755
KB3072305
KB3085538
KB3085635
KB3087038
KB3101512
KB3114518
KB3115041
KB3115103
KB3115135
KB3115858
KB3122648
KB3124280
KB3126446
KB3127220
KB3127986
KB3178656
KB3178673
KB3178674
KB3210131
KB4012204
KB4012212
KB4013867
KB954430
KB958488
KB971033
KB976902
KB976932
KB982018

Dimming and Lighting Through Opacity

email me

This is a simple way to control the opacity and color of objects and elements on a web form.

<script type="text/javascript">
function HideBox() {
	document.body.style.filter = "alpha(opacity=35)";
	document.body.style.backgroundColor = "#002e4d";
}

function ShowBox() {
	document.body.style.filter = "alpha(opacity=100)";
	document.body.style.backgroundColor = "#99ccff";
}
</script>

 

Notes

I used this in an HTA to dim the form when a dialog box appears.

Screenshot

 

A C# method, taken from a forum

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace WindowsApplication1 { 
  public partial class FMask : Form { 
    public FMask(Form parent) { 
      InitializeComponent(); 
      this.FormBorderStyle = FormBorderStyle.None; 
      this.BackColor = Color.Black; 
      this.Opacity = 0.50; 
      this.ShowInTaskbar = false; 
      this.StartPosition = FormStartPosition.Manual; 
      this.Size = parent.ClientSize; 
      this.Location = parent.PointToScreen(Point.Empty); 
      parent.Move += AdjustPosition; 
      parent.SizeChanged += AdjustPosition; 
    } 
    private void AdjustPosition(object sender, EventArgs e) { 
      Form parent = sender as Form; 
      this.Location = parent.PointToScreen(Point.Empty); 
      this.ClientSize = parent.ClientSize; 
    } 
  } 
} 

Then in your original Form1, remove the TransPanel code and add a Load event:

    private FMask overlay; 
    private void Form1_Load(object sender, EventArgs e) { 
      overlay = new FMask(this); 
      overlay.Show(this); 
    } 

To remove the overlay, just call overlay.Close() and set overlay = null.

 

From MSDN

private void Form1_Load_1(object sender, EventArgs e) 
    { 
        panel1.BackColor = Color.FromArgb(128, 0, 0, 0); 
    } 

More…

Shockwave GUIDs

email me

Perhaps this could be of some use to someone out there

11.6.5.636
msiexec.exe /X{459F2CFC-D6E0-48EA-BF86-C6C9EE5F405F} /qn /norestart

11.6.7.637
msiexec.exe /X{05217ED3-D9CA-4302-BCEF-4753596181B8} /qn /norestart

11.6.8.638
msiexec.exe /X{9B92B20A-6A19-428F-8BD0-52DF859B1C61} /qn /norestart

12.0.3.133
msiexec.exe /X{0099B484-C24C-4D5F-8167-B0F6DF196E72} /qn /norestart

12.0.4.144
msiexec.exe /X{BCFB58FF-181E-472F-A9DB-827B75C1EDF7} /qn /norestart

12.0.5.146
msiexec.exe /X{612C34C7-5E90-47D8-9B5C-0F717DD82726} /qn /norestart

12.0.6.147
msiexec.exe /X{9A3AB849-5758-4C2D-88FD-92FC880AE9F6} /qn /norestart

12.0.7.148
msiexec.exe /X{AA3B06B1-E89A-43C6-A26B-7109DB4BEE7B} /qn /norestart

12.0.5.155
msiexec.exe /X{A04CB48B-B82B-406B-ABAA-209F098F03A4} /qn /norestart

12.2.5.195
msiexec.exe /X{A2116AF9-FA9D-41EA-9874-1E40B227D4DE} /qn /norestart

12.2.5.196
msiexec.exe /X{A2116AF9-FA9D-41EA-9874-1E40B227D4DE} /qn /norestart

12.2.7.197
msiexec.exe /X{2595E6DD-D6D4-42FC-80A8-6A711EBEC344} /qn /norestart

12.2.8.198
msiexec.exe /X{52B66F1A-E977-41EE-8359-3C4040BE72F5} /qn /norestart

C# – Change Admin Password and Add Encrypted Reg Key

email me

Just a few things to note:

— Always store your source code in a secure location.

— If you want to use the encrypted pw in the registry,
I recommend naming the reg key itself to something
obscure (not AdminPassword).

— Don’t forget to change the permutations for every
new password.

— And, only pass the encrypted password between your
compiled apps. Code the application to decrypt the
password.

— I have added all the methods together here—for demo purposes—you want to
separate the encrypt and decrypt into two EXEs.

Screenshot of an encrypted reg key

 

using System;
using System.IO;                    // MemoryStream
using System.Security.Cryptography; // used by aes
using System.Text;                  // used by Encoding
using Microsoft.Win32;              // used by Registry
using System.Windows.Forms;         // used by Messagebox
using System.Diagnostics;           // used by Process

namespace SecurePassword
{
    class ResetPassword
    {       

        public static class Global
        {
            // Set password
            public const string strPassword = "LetMeIn99$";

            // Testing
            //public const String strPassword = "ABCZYZabczyx123890!@\"\\#/:;<>?$%^&*()-_+={}[]";

            // set permutations
            public const string strPermutation = "ouiveyxaqtd";
            public const int bytePermutation1 = 0x19;
            public const int bytePermutation2 = 0x59;
            public const int bytePermutation3 = 0x17;
            public const int bytePermutation4 = 0x41;

            // set reg value
            public const string strRegHive = "HKEY_LOCAL_MACHINE";
            public const string strRegKey = @"SOFTWARE\ZWTValue\";
            public const string strRegPath = strRegHive + @"\" + strRegKey;
            public const string strRegVal = "ZWTValue1";          

        }




        public static void Main(string[] args)
        {
            {

    // BEGIN - ENCRYPT PASSWORD
            
                // encrypt
                string strEncrypted = (Encrypt(Global.strPassword));
    
    // END - ENCRYPT PASSWORD




    // BEGIN - ADD ENCRYPTED PASSWORD TO REGISTRY 

                // try set reg value
                try
                {
                    //requires admin access
                    Registry.SetValue(Global.strRegPath, Global.strRegVal, strEncrypted, RegistryValueKind.String);
                    // reference https://msdn.microsoft.com/en-us/library/3dwk5axy(v=vs.110).aspx                

                }

                // catch if there is an error in encrypt
                // ex.Exception
                catch (Exception)
                {
                    //MessageBox.Show(ex.ToString());
                }
    // END - ADD ENCRYPTED PASSWORD TO REGISTRY




    // BEGIN - CHANGE PASSWORD

                // try to change password
                // set properties for process                       
                // requires admin access
                ProcessStartInfo cmdProcess = new ProcessStartInfo("net.exe", "user administrator \"" + Global.strPassword + "\"");
                cmdProcess.RedirectStandardOutput = false;
                cmdProcess.WindowStyle = ProcessWindowStyle.Hidden; // hide window
                cmdProcess.UseShellExecute = true;
                Process checkProcess = null;

                try
                {
                    // launch command
                    checkProcess = Process.Start(cmdProcess);
                    checkProcess.WaitForExit();
                    // reference https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx

                    ////MessageBox.Show(checkProcess.ExitCode.ToString());                   

                    if (checkProcess.ExitCode == 0)
                    {

                        // MessageBox.Show("  Local admin password was reset!");
                        // reference https://msdn.microsoft.com/en-us/library/system.environment.exitcode(v=vs.110).aspx
                    }
                }


                catch (Exception)
                // ex.Exception
                {
                    // MessageBox.Show(ex.ToString());
                }

    // END - CHANGE PASSWORD




    // BEGIN - READ PASSWORD FROM REGISTRY

                string strRegTest = "false";

                // sets the encrypted pw value, to What the reg value should be
                string strEncryptedRegValue = strEncrypted;                

                // try opening reg key
                try
                    {
                        // return encrypted key from registry
                        RegistryKey returnKey = Registry.LocalMachine.OpenSubKey(Global.strRegKey);

                        string rkValue = returnKey.GetValue(Global.strRegVal).ToString();
                        //reference https://msdn.microsoft.com/en-us/library/z9f66s0a(v=vs.110).aspx
                        returnKey.Close();

                    if (returnKey != null)
                            
                         // try testing encrypted key with encrypted pw value
                         try
                               {
                                    if (strEncrypted == rkValue)
                                {
                                    //MessageBox.Show("True");
                                    strRegTest = "true";
                                }

                                    else

                                 {
                                //MessageBox.Show("False");
                                strRegTest = "false";
                                }
                            }
                        // will catch errors reading values
                        catch (Exception)
                        {

                        }                   

                }
                // will catch reg error where no key exists
                catch (Exception)
                {
                    //MessageBox.Show("There is no value!");
                    strRegTest = "false";
                }

                 // decrypt
                 //string strDecrypted = (Decrypt(strEncrypted));
                 string strDecrypted = (Decrypt(rkValue.ToString()));
                 //MessageBox.Show(strDecrypted);

    // END - READ PASSWORD FROM REGISTRY




    // BEGIN OUTPUT
                                
                MessageBox.Show("Original: " + Global.strPassword + "\n\n" + 
                               "Encrypted: " + strEncrypted + "\n\n" + 
                               "Decrypted: " + strDecrypted + "\n\n" + 
                               "Reg Test (is key the same?): " + strRegTest);
    // END OUTPUT
               
                
            }
                    
        }
        
        
        
        
        // encoding
        public static string Encrypt(string strData)
        {
            return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(strData)));
            // reference https://msdn.microsoft.com/en-us/library/ds4kkd55(v=vs.110).aspx

        }


        // decoding
        public static string Decrypt(string strData)
        {
            return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(strData)));
            // reference https://msdn.microsoft.com/en-us/library/system.convert.frombase64string(v=vs.110).aspx

        }

        // encrypt
        public static byte[] Encrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize/8);
            aes.IV = passbytes.GetBytes(aes.BlockSize/8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateEncryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }

        // decrypt
        public static byte[] Decrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize/8);
            aes.IV = passbytes.GetBytes(aes.BlockSize/8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateDecryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }
        // reference 
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
    }
}