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.

312 lines
13 KiB

9 months ago
  1. using System;
  2. using System.DirectoryServices.AccountManagement;
  3. using System.Runtime.InteropServices;
  4. using System.Text;
  5. using System.Threading;
  6. using Ameliorated.ConsoleUtils;
  7. namespace amecs.Actions
  8. {
  9. public class AutoLogon
  10. {
  11. internal static class SafeNativeMethods
  12. {
  13. #region Structures
  14. [StructLayout(LayoutKind.Sequential)]
  15. public struct LSA_UNICODE_STRING : IDisposable
  16. {
  17. public UInt16 Length;
  18. public UInt16 MaximumLength;
  19. public IntPtr Buffer;
  20. public void Dispose()
  21. {
  22. this = new LSA_UNICODE_STRING();
  23. }
  24. }
  25. public struct LSA_OBJECT_ATTRIBUTES
  26. {
  27. public int Length;
  28. public IntPtr RootDirectory;
  29. public LSA_UNICODE_STRING ObjectName;
  30. public UInt32 Attributes;
  31. public IntPtr SecurityDescriptor;
  32. public IntPtr SecurityQualityOfService;
  33. }
  34. public enum LSA_AccessPolicy : long
  35. {
  36. POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
  37. POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
  38. POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
  39. POLICY_TRUST_ADMIN = 0x00000008L,
  40. POLICY_CREATE_ACCOUNT = 0x00000010L,
  41. POLICY_CREATE_SECRET = 0x00000020L,
  42. POLICY_CREATE_PRIVILEGE = 0x00000040L,
  43. POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
  44. POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
  45. POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
  46. POLICY_SERVER_ADMIN = 0x00000400L,
  47. POLICY_LOOKUP_NAMES = 0x00000800L,
  48. POLICY_NOTIFICATION = 0x00001000L
  49. }
  50. #endregion
  51. #region DLL Imports
  52. [DllImport("advapi32")]
  53. public static extern IntPtr FreeSid(IntPtr pSid);
  54. [DllImport("advapi32.dll", PreserveSig = true)]
  55. public static extern UInt32 LsaOpenPolicy(
  56. ref LSA_UNICODE_STRING SystemName,
  57. ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
  58. Int32 DesiredAccess,
  59. out IntPtr PolicyHandle);
  60. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  61. public static extern uint LsaStorePrivateData(
  62. IntPtr PolicyHandle,
  63. LSA_UNICODE_STRING[] KeyName,
  64. LSA_UNICODE_STRING[] PrivateData);
  65. [DllImport("advapi32.dll", PreserveSig = true)]
  66. public static extern uint LsaRetrievePrivateData(
  67. IntPtr PolicyHandle,
  68. LSA_UNICODE_STRING[] KeyName,
  69. out IntPtr PrivateData);
  70. [DllImport("advapi32.dll", PreserveSig = true)]
  71. public static extern uint LsaNtStatusToWinError(uint status);
  72. [DllImport("advapi32.dll")]
  73. public static extern uint LsaClose(IntPtr ObjectHandle);
  74. #endregion
  75. }
  76. #region Functions
  77. /// <summary>
  78. /// Store Encrypted Data
  79. /// </summary>
  80. /// <param name="keyName"></param>
  81. /// <param name="Data"></param>
  82. /// <returns></returns>
  83. public static long StoreData(String keyName, String Data)
  84. {
  85. long winErrorCode = 0;
  86. IntPtr sid = IntPtr.Zero;
  87. int sidSize = 0;
  88. //allocate buffers
  89. sid = Marshal.AllocHGlobal(sidSize);
  90. //initialize an empty unicode-string
  91. SafeNativeMethods.LSA_UNICODE_STRING systemName = new SafeNativeMethods.LSA_UNICODE_STRING();
  92. //Set desired access rights (requested rights)
  93. int access = (int)(SafeNativeMethods.LSA_AccessPolicy.POLICY_CREATE_SECRET);
  94. //initialize a pointer for the policy handle
  95. IntPtr policyHandle = IntPtr.Zero;
  96. //these attributes are not used, but LsaOpenPolicy wants them to exists
  97. SafeNativeMethods.LSA_OBJECT_ATTRIBUTES ObjectAttributes = new SafeNativeMethods.LSA_OBJECT_ATTRIBUTES();
  98. ObjectAttributes.Length = 0;
  99. ObjectAttributes.RootDirectory = IntPtr.Zero;
  100. ObjectAttributes.Attributes = 0;
  101. ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
  102. ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
  103. //get a policy handle
  104. uint resultPolicy = SafeNativeMethods.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
  105. winErrorCode = SafeNativeMethods.LsaNtStatusToWinError(resultPolicy);
  106. if (winErrorCode != 0)
  107. {
  108. ConsoleTUI.OpenFrame.WriteCenteredLine("OpenPolicy failed: " + winErrorCode);
  109. }
  110. else
  111. {
  112. //initialize an unicode-string for the keyName
  113. SafeNativeMethods.LSA_UNICODE_STRING[] uKeyName = new SafeNativeMethods.LSA_UNICODE_STRING[1];
  114. uKeyName[0] = new SafeNativeMethods.LSA_UNICODE_STRING();
  115. uKeyName[0].Buffer = Marshal.StringToHGlobalUni(keyName);
  116. uKeyName[0].Length = (UInt16)(keyName.Length * UnicodeEncoding.CharSize);
  117. uKeyName[0].MaximumLength = (UInt16)((keyName.Length + 1) * UnicodeEncoding.CharSize);
  118. //initialize an unicode-string for the Data to encrypt
  119. SafeNativeMethods.LSA_UNICODE_STRING[] uData = new SafeNativeMethods.LSA_UNICODE_STRING[1];
  120. uData[0] = new SafeNativeMethods.LSA_UNICODE_STRING();
  121. uData[0].Buffer = Marshal.StringToHGlobalUni(Data);
  122. uData[0].Length = (UInt16)(Data.Length * UnicodeEncoding.CharSize);
  123. uData[0].MaximumLength = (UInt16)((Data.Length + 1) * UnicodeEncoding.CharSize);
  124. //Store Encrypted Data:
  125. SafeNativeMethods.LsaStorePrivateData(policyHandle, uKeyName, uData);
  126. //winErrorCode = LsaNtStatusToWinError(res);
  127. if (winErrorCode != 0)
  128. {
  129. ConsoleTUI.OpenFrame.WriteCenteredLine("LsaStorePrivateData failed: " + winErrorCode);
  130. }
  131. SafeNativeMethods.LsaClose(policyHandle);
  132. }
  133. SafeNativeMethods.FreeSid(sid);
  134. return winErrorCode;
  135. }
  136. /// <summary>
  137. /// Retrieve Encrypted Data
  138. /// </summary>
  139. /// <param name="keyName"></param>
  140. /// <returns></returns>
  141. public static string RetrieveData(String keyName)
  142. {
  143. string sout = "";
  144. long winErrorCode = 0;
  145. IntPtr sid = IntPtr.Zero;
  146. int sidSize = 0;
  147. //allocate buffers
  148. sid = Marshal.AllocHGlobal(sidSize);
  149. //initialize an empty unicode-string
  150. SafeNativeMethods.LSA_UNICODE_STRING systemName = new SafeNativeMethods.LSA_UNICODE_STRING();
  151. //Set desired access rights (requested rights)
  152. int access = (int)(SafeNativeMethods.LSA_AccessPolicy.POLICY_CREATE_SECRET);
  153. //initialize a pointer for the policy handle
  154. IntPtr policyHandle = IntPtr.Zero;
  155. //these attributes are not used, but LsaOpenPolicy wants them to exists
  156. SafeNativeMethods.LSA_OBJECT_ATTRIBUTES ObjectAttributes = new SafeNativeMethods.LSA_OBJECT_ATTRIBUTES();
  157. ObjectAttributes.Length = 0;
  158. ObjectAttributes.RootDirectory = IntPtr.Zero;
  159. ObjectAttributes.Attributes = 0;
  160. ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
  161. ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
  162. //get a policy handle
  163. uint resultPolicy = SafeNativeMethods.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
  164. winErrorCode = SafeNativeMethods.LsaNtStatusToWinError(resultPolicy);
  165. if (winErrorCode != 0)
  166. {
  167. ConsoleTUI.OpenFrame.WriteCenteredLine("OpenPolicy failed: " + winErrorCode);
  168. }
  169. else
  170. {
  171. //initialize an unicode-string for the keyName
  172. SafeNativeMethods.LSA_UNICODE_STRING[] uKeyName = new SafeNativeMethods.LSA_UNICODE_STRING[1];
  173. uKeyName[0] = new SafeNativeMethods.LSA_UNICODE_STRING();
  174. uKeyName[0].Buffer = Marshal.StringToHGlobalUni(keyName);
  175. uKeyName[0].Length = (UInt16)(keyName.Length * UnicodeEncoding.CharSize);
  176. uKeyName[0].MaximumLength = (UInt16)((keyName.Length + 1) * UnicodeEncoding.CharSize);
  177. //Store Encrypted Data:
  178. IntPtr pData;
  179. long result = SafeNativeMethods.LsaRetrievePrivateData(policyHandle, uKeyName, out pData);
  180. //winErrorCode = LsaNtStatusToWinError(res);
  181. if (winErrorCode != 0)
  182. {
  183. ConsoleTUI.OpenFrame.WriteCenteredLine("LsaStorePrivateData failed: " + winErrorCode);
  184. }
  185. SafeNativeMethods.LSA_UNICODE_STRING ss = (SafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(pData, typeof(SafeNativeMethods.LSA_UNICODE_STRING));
  186. sout = Marshal.PtrToStringAuto(ss.Buffer);
  187. SafeNativeMethods.LsaClose(policyHandle);
  188. }
  189. SafeNativeMethods.FreeSid(sid);
  190. return sout;
  191. }
  192. #endregion
  193. private const string LogonKey = @"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon";
  194. public static bool Disable() => amecs.RunBasicAction("Disabling AutoLogon", "AutoLogon disabled successfully", new Action(() =>
  195. {
  196. new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultUserName", Data = "", Type = Reg.RegistryValueType.REG_SZ}.Apply();
  197. new Reg.Value() { KeyName = LogonKey, ValueName = "AutoAdminLogon", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  198. new Reg.Value() { KeyName = LogonKey, ValueName = "AutoLogonCount", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  199. new Reg.Value() { KeyName = LogonKey, ValueName = "ForceAutoLogon", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  200. new Reg.Value() { KeyName = LogonKey, ValueName = "DisableCAD", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  201. new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultPassword", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  202. StoreData("DefaultPassword", "");
  203. Thread.Sleep(1700);
  204. }));
  205. public static bool Enable()
  206. {
  207. PrincipalContext context = new PrincipalContext(ContextType.Machine);
  208. string password = "";
  209. while (true)
  210. {
  211. password = new InputPrompt() { MaskInput = true, Text = "Enter your password, or press escape to quit: " }.Start();
  212. if (password == null)
  213. return true;
  214. if (String.IsNullOrEmpty(password))
  215. {
  216. try
  217. {
  218. Globals.User.ChangePassword("", "");
  219. break;
  220. } catch {}
  221. }
  222. else if (context.ValidateCredentials(Globals.Username, password))
  223. break;
  224. ConsoleTUI.OpenFrame.WriteLine("Incorrect password.");
  225. Console.WriteLine();
  226. }
  227. try
  228. {
  229. ConsoleTUI.OpenFrame.WriteCentered("\r\nEnabling AutoLogon");
  230. using (new ConsoleUtils.LoadingIndicator(true))
  231. {
  232. new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultUserName", Data = Globals.Username, Type = Reg.RegistryValueType.REG_SZ}.Apply();
  233. new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultDomainName", Data = Environment.MachineName, Type = Reg.RegistryValueType.REG_SZ}.Apply();
  234. new Reg.Value() { KeyName = LogonKey, ValueName = "AutoAdminLogon", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply();
  235. new Reg.Value() { KeyName = LogonKey, ValueName = "AutoLogonCount", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  236. new Reg.Value() { KeyName = LogonKey, ValueName = "DisableCAD", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply();
  237. new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultPassword", Operation = Reg.RegistryValueOperation.Delete}.Apply();
  238. StoreData("DefaultPassword", password);
  239. Thread.Sleep(1700);
  240. }
  241. } catch (Exception e)
  242. {
  243. Console.WriteLine();
  244. ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
  245. {
  246. AnyKey = true,
  247. Text = "Press any key to return to the Menu: "
  248. });
  249. return false;
  250. }
  251. Console.WriteLine();
  252. ConsoleTUI.OpenFrame.Close($"AutoLogon enabled successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
  253. {
  254. AnyKey = true,
  255. Text = "Press any key to return to the Menu: "
  256. });
  257. return true;
  258. }
  259. }
  260. }