CLI tool for running Playbooks
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.

331 lines
12 KiB

1 year ago
1 year ago
1 year ago
1 year ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Management;
  8. using System.Net;
  9. using System.Reflection;
  10. using System.Runtime.InteropServices;
  11. using System.Threading.Tasks;
  12. using System.Windows;
  13. using System.Xml.Serialization;
  14. using Microsoft.Win32;
  15. using TrustedUninstaller.Shared;
  16. using TrustedUninstaller.Shared.Actions;
  17. namespace TrustedUninstaller.Shared
  18. {
  19. public static class Requirements
  20. {
  21. [Serializable]
  22. public enum Requirement
  23. {
  24. [XmlEnum("Internet")]
  25. Internet = 0,
  26. [XmlEnum("NoInternet")]
  27. NoInternet = 1,
  28. [XmlEnum("DefenderDisabled")]
  29. DefenderDisabled = 2,
  30. [XmlEnum("DefenderToggled")]
  31. DefenderToggled = 3,
  32. [XmlEnum("NoPendingUpdates")]
  33. NoPendingUpdates = 4,
  34. [XmlEnum("Activation")]
  35. Activation = 5,
  36. [XmlEnum("NoAntivirus")]
  37. NoAntivirus = 6,
  38. [XmlEnum("PasswordSet")]
  39. PasswordSet = 7,
  40. [XmlEnum("AdministratorPasswordSet")]
  41. AdministratorPasswordSet = 8,
  42. }
  43. public static async Task<Requirement[]> MetRequirements(this Requirement[] requirements)
  44. {
  45. var requirementEnum = (Requirement[])Enum.GetValues(typeof(Requirement));
  46. if (requirements == null)
  47. {
  48. return requirementEnum;
  49. }
  50. // Add all requirements that are not included
  51. var metRequirements = requirementEnum.Except(requirements).ToList();
  52. if (requirements.Contains (Requirement.Internet))
  53. if (await new Internet().IsMet()) metRequirements.Add(Requirement.Internet);
  54. else metRequirements.Add(Requirement.NoInternet);
  55. if (requirements.Contains (Requirement.NoAntivirus))
  56. if (await new NoAntivirus().IsMet()) metRequirements.Add(Requirement.NoAntivirus);
  57. if (requirements.Contains (Requirement.NoPendingUpdates))
  58. if (await new NoPendingUpdates().IsMet()) metRequirements.Add(Requirement.NoPendingUpdates);
  59. if (requirements.Contains (Requirement.Activation))
  60. if (await new Activation().IsMet()) metRequirements.Add(Requirement.Activation);
  61. if (requirements.Contains (Requirement.DefenderDisabled))
  62. if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderDisabled);
  63. if (requirements.Contains (Requirement.DefenderToggled))
  64. if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderToggled);
  65. if (requirements.Contains(Requirement.PasswordSet))
  66. metRequirements.Add(Requirement.PasswordSet);
  67. if (requirements.Contains(Requirement.AdministratorPasswordSet))
  68. metRequirements.Add(Requirement.AdministratorPasswordSet);
  69. return metRequirements.ToArray();
  70. }
  71. public interface IRequirements
  72. {
  73. Task<bool> IsMet();
  74. Task<bool> Meet();
  75. }
  76. public class RequirementBase
  77. {
  78. public class ProgressEventArgs : EventArgs
  79. {
  80. public int PercentAdded;
  81. public ProgressEventArgs(int percent)
  82. {
  83. PercentAdded = percent;
  84. }
  85. }
  86. public event EventHandler<ProgressEventArgs> ProgressChanged;
  87. protected void OnProgressAdded(int percent)
  88. {
  89. ProgressChanged?.Invoke(this, new ProgressEventArgs(percent));
  90. }
  91. }
  92. public class Internet : RequirementBase, IRequirements
  93. {
  94. [DllImport("wininet.dll", SetLastError = true)]
  95. private static extern bool InternetCheckConnection(string lpszUrl, int dwFlags, int dwReserved);
  96. [DllImport("wininet.dll", SetLastError=true)]
  97. extern static bool InternetGetConnectedState(out int lpdwFlags, int dwReserved);
  98. public async Task<bool> IsMet()
  99. {
  100. try
  101. {
  102. try
  103. {
  104. if (!InternetCheckConnection("http://archlinux.org", 1, 0))
  105. {
  106. if (!InternetCheckConnection("http://google.com", 1, 0))
  107. return false;
  108. }
  109. return true;
  110. }
  111. catch
  112. {
  113. var request = (HttpWebRequest)WebRequest.Create("http://google.com");
  114. request.KeepAlive = false;
  115. request.Timeout = 5000;
  116. using (var response = (HttpWebResponse)request.GetResponse())
  117. return true;
  118. }
  119. }
  120. catch
  121. {
  122. return false;
  123. }
  124. }
  125. public Task<bool> Meet() => throw new NotImplementedException();
  126. }
  127. public class DefenderDisabled : RequirementBase, IRequirements
  128. {
  129. public async Task<bool> IsMet()
  130. {
  131. if (Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\WinDefend") != null)
  132. return false;
  133. return Process.GetProcessesByName("MsMpEng").Length == 0;
  134. }
  135. public async Task<bool> Meet()
  136. {
  137. OnProgressAdded(30);
  138. try
  139. {
  140. //Scheduled task to run the program on logon, and remove defender notifications
  141. var runOnLogOn = new CmdAction()
  142. {
  143. Command = $"schtasks /create /tn \"AME Wizard\" /tr \"{Assembly.GetExecutingAssembly().Location}\" /sc onlogon /RL HIGHEST /f",
  144. Wait = false
  145. };
  146. await runOnLogOn.RunTask();
  147. OnProgressAdded(10);
  148. var disableNotifs = new CmdAction()
  149. {
  150. Command = $"reg add \"HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows Defender Security Center\\Notifications\" /v DisableNotifications /t REG_DWORD /d 1 /f"
  151. };
  152. await disableNotifs.RunTask();
  153. OnProgressAdded(10);
  154. var defenderService = new RunAction()
  155. {
  156. Exe = $"NSudoLC.exe",
  157. Arguments = "-U:T -P:E -M:S -Priority:RealTime -UseCurrentConsole -Wait reg delete \"HKLM\\SYSTEM\\CurrentControlSet\\Services\\WinDefend\" /f",
  158. BaseDir = true,
  159. CreateWindow = false
  160. };
  161. await defenderService.RunTask();
  162. OnProgressAdded(20);
  163. // MpOAV.dll normally in use by a lot of processes. This prevents that.
  164. var MpOAVCLSID = new RunAction()
  165. {
  166. Exe = $"NSudoLC.exe",
  167. Arguments = @"-U:T -P:E -M:S -Priority:RealTime -Wait reg delete ""HKCR\CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32"" /f",
  168. BaseDir = true,
  169. CreateWindow = false
  170. };
  171. await MpOAVCLSID.RunTask();
  172. OnProgressAdded(20);
  173. if (Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\WinDefend") != null)
  174. {
  175. throw new Exception("Could not remove WinDefend service.");
  176. }
  177. OnProgressAdded(10);
  178. return true;
  179. }
  180. catch (Exception exception)
  181. {
  182. ErrorLogger.WriteToErrorLog(exception.Message, exception.StackTrace,
  183. $"Could not remove Windows Defender.");
  184. return false;
  185. // TODO: Move this to requirements page view if any Meet calls return false
  186. try
  187. {
  188. var saveLogDir = System.Windows.Forms.Application.StartupPath + "\\AME Logs";
  189. if (Directory.Exists(saveLogDir)) Directory.Delete(saveLogDir, true);
  190. Directory.Move(Directory.GetCurrentDirectory() + "\\Logs", saveLogDir);
  191. }
  192. catch (Exception) { }
  193. //MessageBox.Show("Could not remove Windows Defender. Check the error logs and contact the team " +
  194. // "for more information and assistance.", "Could not remove Windows Defender.", MessageBoxButton.OK, MessageBoxImage.Error);
  195. }
  196. }
  197. }
  198. public class DefenderToggled : RequirementBase, IRequirements
  199. {
  200. public async Task<bool> IsMet()
  201. {
  202. var defenderKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows Defender");
  203. RegistryKey realtimeKey = null;
  204. try
  205. {
  206. realtimeKey = defenderKey.OpenSubKey("Real-Time Protection");
  207. }
  208. catch
  209. {
  210. }
  211. if (realtimeKey != null)
  212. {
  213. try
  214. {
  215. if (!((int)realtimeKey.GetValue("DisableRealtimeMonitoring") != 1))
  216. return false;
  217. }
  218. catch (Exception exception)
  219. {
  220. return false;
  221. }
  222. }
  223. try
  224. {
  225. if (!((int)defenderKey.OpenSubKey("SpyNet").GetValue("SpyNetReporting") != 0))
  226. return false;
  227. }
  228. catch
  229. {
  230. }
  231. try
  232. {
  233. if (!((int)defenderKey.OpenSubKey("SpyNet").GetValue("SubmitSamplesConsent") != 0))
  234. return false;
  235. }
  236. catch
  237. {
  238. }
  239. try
  240. {
  241. if (!((int)defenderKey.OpenSubKey("Features").GetValue("TamperProtection") != 4))
  242. return false;
  243. }
  244. catch
  245. {
  246. }
  247. return true;
  248. }
  249. public async Task<bool> Meet()
  250. {
  251. throw new NotImplementedException();
  252. }
  253. }
  254. public class NoPendingUpdates : RequirementBase, IRequirements
  255. {
  256. public async Task<bool> IsMet()
  257. {
  258. //TODO: This
  259. return true;
  260. }
  261. public Task<bool> Meet() => throw new NotImplementedException();
  262. }
  263. public class NoAntivirus : RequirementBase, IRequirements
  264. {
  265. public async Task<bool> IsMet()
  266. {
  267. return !WinUtil.GetEnabledAvList(false).Any();
  268. }
  269. public Task<bool> Meet() => throw new NotImplementedException();
  270. }
  271. public class Activation : RequirementBase, IRequirements
  272. {
  273. public async Task<bool> IsMet()
  274. {
  275. return WinUtil.IsGenuineWindows();
  276. }
  277. public Task<bool> Meet() => throw new NotImplementedException();
  278. }
  279. public class WindowsBuild
  280. {
  281. public bool IsMet(string[] builds)
  282. {
  283. return builds.Any(x => x.Equals(Globals.WinVer.ToString()));
  284. }
  285. public Task<bool> Meet() => throw new NotImplementedException();
  286. }
  287. }
  288. }