public static byte[] GetBootKey() { // returns the system boot key (aka syskey) that's later used to calculate the LSA key StringBuilder scrambledKey = new StringBuilder(); foreach (string key in new string[] { "JD", "Skew1", "GBG", "Data" }) { string keyPath = String.Format("SYSTEM\\CurrentControlSet\\Control\\Lsa\\{0}", key); StringBuilder classVal = new StringBuilder(1024); int len = 1024; int result = 0; IntPtr hKey = IntPtr.Zero; IntPtr dummy = IntPtr.Zero; // open the specified key with read (0x19) privileges // 0x80000002 == HKLM result = Interop.RegOpenKeyEx(0x80000002, keyPath, 0, 0x19, ref hKey); if (result != 0) { int error = Marshal.GetLastWin32Error(); string errorMessage = new Win32Exception((int)error).Message; Console.WriteLine("Error opening {0} ({1}) : {2}", keyPath, error, errorMessage); return(null); } result = Interop.RegQueryInfoKey(hKey, classVal, ref len, 0, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, IntPtr.Zero); if (result != 0) { int error = Marshal.GetLastWin32Error(); string errorMessage = new Win32Exception((int)error).Message; Console.WriteLine("Error enumerating {0} ({1}) : {2}", keyPath, error, errorMessage); return(null); } Interop.RegCloseKey(hKey); scrambledKey.Append(classVal); } // reference: https://github.com/brandonprry/gray_hat_csharp_code/blob/e1d5fc2a497ae443225d840718adde836ffaeefe/ch14_reading_offline_hives/Program.cs#L74-L82 byte[] skey = Helpers.StringToByteArray(scrambledKey.ToString()); byte[] descramble = new byte[] { 0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 }; byte[] bootkey = new byte[16]; for (int i = 0; i < bootkey.Length; i++) { bootkey[i] = skey[descramble[i]]; } return(bootkey); }
public static byte[] GetRegKeyValue(string keyPath) { // takes a given HKLM key path and returns the registry value int result = 0; IntPtr hKey = IntPtr.Zero; // open the specified key with read (0x19) privileges // 0x80000002 == HKLM result = Interop.RegOpenKeyEx(0x80000002, keyPath, 0, 0x19, ref hKey); if (result != 0) { int error = Marshal.GetLastWin32Error(); string errorMessage = new Win32Exception((int)error).Message; Console.WriteLine("Error opening {0} ({1}) : {2}", keyPath, error, errorMessage); return(null); } int cbData = 0; result = Interop.RegQueryValueEx(hKey, null, 0, IntPtr.Zero, IntPtr.Zero, ref cbData); if (result != 0) { int error = Marshal.GetLastWin32Error(); string errorMessage = new Win32Exception((int)error).Message; Console.WriteLine("Error enumerating {0} ({1}) : {2}", keyPath, error, errorMessage); return(null); } IntPtr dataPtr = Marshal.AllocHGlobal(cbData); result = Interop.RegQueryValueEx(hKey, null, 0, IntPtr.Zero, dataPtr, ref cbData); if (result != 0) { int error = Marshal.GetLastWin32Error(); string errorMessage = new Win32Exception((int)error).Message; Console.WriteLine("Error enumerating {0} ({1}) : {2}", keyPath, error, errorMessage); return(null); } byte[] data = new byte[cbData]; Marshal.Copy(dataPtr, data, 0, cbData); Interop.RegCloseKey(hKey); return(data); }