Script for automating a large assortment of AME related actions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
13 KiB

using System;
using System.DirectoryServices.AccountManagement;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Ameliorated.ConsoleUtils;
namespace amecs.Actions
{
public class AutoLogon
{
internal static class SafeNativeMethods
{
#region Structures
[StructLayout(LayoutKind.Sequential)]
public struct LSA_UNICODE_STRING : IDisposable
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
public void Dispose()
{
this = new LSA_UNICODE_STRING();
}
}
public struct LSA_OBJECT_ATTRIBUTES
{
public int Length;
public IntPtr RootDirectory;
public LSA_UNICODE_STRING ObjectName;
public UInt32 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
}
#endregion
#region DLL Imports
[DllImport("advapi32")]
public static extern IntPtr FreeSid(IntPtr pSid);
[DllImport("advapi32.dll", PreserveSig = true)]
public static extern UInt32 LsaOpenPolicy(
ref LSA_UNICODE_STRING SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
Int32 DesiredAccess,
out IntPtr PolicyHandle);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern uint LsaStorePrivateData(
IntPtr PolicyHandle,
LSA_UNICODE_STRING[] KeyName,
LSA_UNICODE_STRING[] PrivateData);
[DllImport("advapi32.dll", PreserveSig = true)]
public static extern uint LsaRetrievePrivateData(
IntPtr PolicyHandle,
LSA_UNICODE_STRING[] KeyName,
out IntPtr PrivateData);
[DllImport("advapi32.dll", PreserveSig = true)]
public static extern uint LsaNtStatusToWinError(uint status);
[DllImport("advapi32.dll")]
public static extern uint LsaClose(IntPtr ObjectHandle);
#endregion
}
#region Functions
/// <summary>
/// Store Encrypted Data
/// </summary>
/// <param name="keyName"></param>
/// <param name="Data"></param>
/// <returns></returns>
public static long StoreData(String keyName, String Data)
{
long winErrorCode = 0;
IntPtr sid = IntPtr.Zero;
int sidSize = 0;
//allocate buffers
sid = Marshal.AllocHGlobal(sidSize);
//initialize an empty unicode-string
SafeNativeMethods.LSA_UNICODE_STRING systemName = new SafeNativeMethods.LSA_UNICODE_STRING();
//Set desired access rights (requested rights)
int access = (int)(SafeNativeMethods.LSA_AccessPolicy.POLICY_CREATE_SECRET);
//initialize a pointer for the policy handle
IntPtr policyHandle = IntPtr.Zero;
//these attributes are not used, but LsaOpenPolicy wants them to exists
SafeNativeMethods.LSA_OBJECT_ATTRIBUTES ObjectAttributes = new SafeNativeMethods.LSA_OBJECT_ATTRIBUTES();
ObjectAttributes.Length = 0;
ObjectAttributes.RootDirectory = IntPtr.Zero;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
//get a policy handle
uint resultPolicy = SafeNativeMethods.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
winErrorCode = SafeNativeMethods.LsaNtStatusToWinError(resultPolicy);
if (winErrorCode != 0)
{
ConsoleTUI.OpenFrame.WriteCenteredLine("OpenPolicy failed: " + winErrorCode);
}
else
{
//initialize an unicode-string for the keyName
SafeNativeMethods.LSA_UNICODE_STRING[] uKeyName = new SafeNativeMethods.LSA_UNICODE_STRING[1];
uKeyName[0] = new SafeNativeMethods.LSA_UNICODE_STRING();
uKeyName[0].Buffer = Marshal.StringToHGlobalUni(keyName);
uKeyName[0].Length = (UInt16)(keyName.Length * UnicodeEncoding.CharSize);
uKeyName[0].MaximumLength = (UInt16)((keyName.Length + 1) * UnicodeEncoding.CharSize);
//initialize an unicode-string for the Data to encrypt
SafeNativeMethods.LSA_UNICODE_STRING[] uData = new SafeNativeMethods.LSA_UNICODE_STRING[1];
uData[0] = new SafeNativeMethods.LSA_UNICODE_STRING();
uData[0].Buffer = Marshal.StringToHGlobalUni(Data);
uData[0].Length = (UInt16)(Data.Length * UnicodeEncoding.CharSize);
uData[0].MaximumLength = (UInt16)((Data.Length + 1) * UnicodeEncoding.CharSize);
//Store Encrypted Data:
SafeNativeMethods.LsaStorePrivateData(policyHandle, uKeyName, uData);
//winErrorCode = LsaNtStatusToWinError(res);
if (winErrorCode != 0)
{
ConsoleTUI.OpenFrame.WriteCenteredLine("LsaStorePrivateData failed: " + winErrorCode);
}
SafeNativeMethods.LsaClose(policyHandle);
}
SafeNativeMethods.FreeSid(sid);
return winErrorCode;
}
/// <summary>
/// Retrieve Encrypted Data
/// </summary>
/// <param name="keyName"></param>
/// <returns></returns>
public static string RetrieveData(String keyName)
{
string sout = "";
long winErrorCode = 0;
IntPtr sid = IntPtr.Zero;
int sidSize = 0;
//allocate buffers
sid = Marshal.AllocHGlobal(sidSize);
//initialize an empty unicode-string
SafeNativeMethods.LSA_UNICODE_STRING systemName = new SafeNativeMethods.LSA_UNICODE_STRING();
//Set desired access rights (requested rights)
int access = (int)(SafeNativeMethods.LSA_AccessPolicy.POLICY_CREATE_SECRET);
//initialize a pointer for the policy handle
IntPtr policyHandle = IntPtr.Zero;
//these attributes are not used, but LsaOpenPolicy wants them to exists
SafeNativeMethods.LSA_OBJECT_ATTRIBUTES ObjectAttributes = new SafeNativeMethods.LSA_OBJECT_ATTRIBUTES();
ObjectAttributes.Length = 0;
ObjectAttributes.RootDirectory = IntPtr.Zero;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
//get a policy handle
uint resultPolicy = SafeNativeMethods.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
winErrorCode = SafeNativeMethods.LsaNtStatusToWinError(resultPolicy);
if (winErrorCode != 0)
{
ConsoleTUI.OpenFrame.WriteCenteredLine("OpenPolicy failed: " + winErrorCode);
}
else
{
//initialize an unicode-string for the keyName
SafeNativeMethods.LSA_UNICODE_STRING[] uKeyName = new SafeNativeMethods.LSA_UNICODE_STRING[1];
uKeyName[0] = new SafeNativeMethods.LSA_UNICODE_STRING();
uKeyName[0].Buffer = Marshal.StringToHGlobalUni(keyName);
uKeyName[0].Length = (UInt16)(keyName.Length * UnicodeEncoding.CharSize);
uKeyName[0].MaximumLength = (UInt16)((keyName.Length + 1) * UnicodeEncoding.CharSize);
//Store Encrypted Data:
IntPtr pData;
long result = SafeNativeMethods.LsaRetrievePrivateData(policyHandle, uKeyName, out pData);
//winErrorCode = LsaNtStatusToWinError(res);
if (winErrorCode != 0)
{
ConsoleTUI.OpenFrame.WriteCenteredLine("LsaStorePrivateData failed: " + winErrorCode);
}
SafeNativeMethods.LSA_UNICODE_STRING ss = (SafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(pData, typeof(SafeNativeMethods.LSA_UNICODE_STRING));
sout = Marshal.PtrToStringAuto(ss.Buffer);
SafeNativeMethods.LsaClose(policyHandle);
}
SafeNativeMethods.FreeSid(sid);
return sout;
}
#endregion
private const string LogonKey = @"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon";
public static bool Disable() => amecs.RunBasicAction("Disabling AutoLogon", "AutoLogon disabled successfully", new Action(() =>
{
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultUserName", Data = "", Type = Reg.RegistryValueType.REG_SZ}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoAdminLogon", Operation = Reg.RegistryValueOperation.Delete}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoLogonCount", Operation = Reg.RegistryValueOperation.Delete}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "ForceAutoLogon", Operation = Reg.RegistryValueOperation.Delete}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "DisableCAD", Operation = Reg.RegistryValueOperation.Delete}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultPassword", Operation = Reg.RegistryValueOperation.Delete}.Apply();
StoreData("DefaultPassword", "");
Thread.Sleep(1700);
}));
public static bool Enable()
{
PrincipalContext context = new PrincipalContext(ContextType.Machine);
string password = "";
while (true)
{
password = new InputPrompt() { MaskInput = true, Text = "Enter your password, or press escape to quit: " }.Start();
if (password == null)
return true;
if (String.IsNullOrEmpty(password))
{
try
{
Globals.User.ChangePassword("", "");
break;
} catch {}
}
else if (context.ValidateCredentials(Globals.Username, password))
break;
ConsoleTUI.OpenFrame.WriteLine("Incorrect password.");
Console.WriteLine();
}
try
{
ConsoleTUI.OpenFrame.WriteCentered("\r\nEnabling AutoLogon");
using (new ConsoleUtils.LoadingIndicator(true))
{
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultUserName", Data = Globals.Username, Type = Reg.RegistryValueType.REG_SZ}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultDomainName", Data = Environment.MachineName, Type = Reg.RegistryValueType.REG_SZ}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoAdminLogon", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoLogonCount", Operation = Reg.RegistryValueOperation.Delete}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "DisableCAD", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply();
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultPassword", Operation = Reg.RegistryValueOperation.Delete}.Apply();
StoreData("DefaultPassword", password);
Thread.Sleep(1700);
}
} catch (Exception e)
{
Console.WriteLine();
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
{
AnyKey = true,
Text = "Press any key to return to the Menu: "
});
return false;
}
Console.WriteLine();
ConsoleTUI.OpenFrame.Close($"AutoLogon enabled successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
{
AnyKey = true,
Text = "Press any key to return to the Menu: "
});
return true;
}
}
}