mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-11-07 09:25:57 -10:00
Auto-merge PR #786 (Chack Agent)
Co-authored-by: HackTricks News Bot <[email protected]>
This commit is contained in:
1 parent
7d438b858a
commit
652ba220e4
3 files changed
+153
No files matched your search
@@ -77,6 +77,15 @@ Enroll ACEs for the current token. These are candidate paths, not proof of
|
||||
effective access: CA-specific publication, enrollment-agent restrictions,
|
||||
issuance policy, and certificate authentication still need manual verification.
|
||||
|
||||
The device-driver audit also reviews registered kernel-driver services whose image
|
||||
is named `WinNotify.sys` or `msft.sys`. It reports service state, image path,
|
||||
SHA-256, file version, and signature details. Only a SHA-256 match to the
|
||||
[LocalStranger PoC driver](https://github.com/nbs32k/LocalStranger) confirms that
|
||||
specific image; filename-only matches require manual review. The bounded,
|
||||
read-only audit does not test the device interface or establish that the driver
|
||||
can be loaded or exploited by the current user. It does not assess current
|
||||
vulnerable-driver blocklist enforcement.
|
||||
|
||||
## Basic information
|
||||
|
||||
The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments.
|
||||
|
||||
@@ -982,6 +982,30 @@ namespace winPEAS.Checks
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
}
|
||||
bool candidateAuditIncomplete;
|
||||
List<VulnerableDriverCandidate> candidates = DeviceDrivers.GetVulnerableDriverCandidates(out candidateAuditIncomplete);
|
||||
if (candidates.Count > 0)
|
||||
{
|
||||
Beaprint.MainPrint("Known vulnerable driver indicators (BYOVD)", "T1068");
|
||||
Beaprint.LinkPrint("https://github.com/nbs32k/LocalStranger", "WinNotify.sys / msft.sys LocalStranger proof of concept");
|
||||
foreach (VulnerableDriverCandidate candidate in candidates)
|
||||
{
|
||||
string finding = candidate.KnownHash
|
||||
? "Confirmed match to the published LocalStranger driver image"
|
||||
: "Filename match only; driver identity not confirmed";
|
||||
if (candidate.KnownHash) Beaprint.BadPrint(" " + finding);
|
||||
else Beaprint.InfoPrint(" " + finding);
|
||||
Beaprint.NoColorPrint(" Service/Image: " + candidate.ServiceName + " / " + candidate.Path);
|
||||
Beaprint.NoColorPrint(" Service registered; image on disk: " + (candidate.ImagePresent ? "yes" : "not found or unresolved") +
|
||||
"; SCM state: " + candidate.State + "; Start: " + (candidate.Start >= 0 ? candidate.Start.ToString() : "unknown"));
|
||||
Beaprint.NoColorPrint(" SHA-256: " + candidate.Sha256);
|
||||
Beaprint.NoColorPrint(" Version: " + candidate.Version + "; Signer: " + candidate.Signer);
|
||||
Beaprint.NoColorPrint(" Authenticode: " + candidate.SignatureStatus);
|
||||
}
|
||||
Beaprint.GrayPrint(" Device access, service-load rights, and vulnerable-driver blocklist enforcement were not verified; a running service or matching image alone does not prove exploitability.");
|
||||
}
|
||||
if (candidateAuditIncomplete)
|
||||
Beaprint.InfoPrint(" Known-driver indicator audit incomplete (registry access, 2-second or 4096-service limit, or 4-candidate limit).");
|
||||
if (inventory.UnknownOrTruncated)
|
||||
Beaprint.InfoPrint(" Driver inventory partial/unknown: " + inventory.Detail);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Management;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
using System.ServiceProcess;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.ApplicationInfo
|
||||
@@ -26,8 +31,27 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
public string Detail;
|
||||
}
|
||||
|
||||
internal sealed class VulnerableDriverCandidate
|
||||
{
|
||||
public string ServiceName;
|
||||
public string Path;
|
||||
public bool ImagePresent;
|
||||
public string State = "unknown";
|
||||
public int Start = -1;
|
||||
public string Sha256 = "unavailable";
|
||||
public bool KnownHash;
|
||||
public string Version = "unavailable";
|
||||
public string Signer = "unavailable";
|
||||
public string SignatureStatus = "not checked";
|
||||
}
|
||||
|
||||
internal static class DeviceDrivers
|
||||
{
|
||||
// SHA-256 of msft.sys in nbs32k/LocalStranger, commit 41fbecee2c9f928abb6306ccb481e715c80d8e8e.
|
||||
private const string LocalStrangerSha256 = "4dc3a03a046c210a7c6cd37db8d6bd34bf3760a612232cc82acf941a9e508e0f";
|
||||
private const int MaxDriverServiceKeys = 4096;
|
||||
private const int MaxDriverCandidates = 4;
|
||||
private const long MaxHashBytes = 8 * 1024 * 1024;
|
||||
internal const int MaxPsapiDrivers = 1024;
|
||||
internal const int MaxWmiDrivers = 1024;
|
||||
internal const int MaxOutputDrivers = 256;
|
||||
@@ -44,6 +68,102 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
return Merge(psapi, wmi, MaxOutputDrivers, string.Join("; ", details));
|
||||
}
|
||||
|
||||
// Inspect only registered kernel-driver images with relevant names. Never contact a driver device.
|
||||
public static List<VulnerableDriverCandidate> GetVulnerableDriverCandidates(out bool incomplete)
|
||||
{
|
||||
var candidates = new List<VulnerableDriverCandidate>();
|
||||
incomplete = false;
|
||||
try
|
||||
{
|
||||
using (RegistryKey services = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services"))
|
||||
{
|
||||
if (services == null) { incomplete = true; return candidates; }
|
||||
string[] names = services.GetSubKeyNames();
|
||||
int inspected = 0;
|
||||
var timer = Stopwatch.StartNew();
|
||||
foreach (string name in names)
|
||||
{
|
||||
if (++inspected > MaxDriverServiceKeys || timer.ElapsedMilliseconds >= 2000 ||
|
||||
candidates.Count >= MaxDriverCandidates)
|
||||
{
|
||||
incomplete = true;
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
using (RegistryKey key = services.OpenSubKey(name))
|
||||
{
|
||||
if (key == null) continue;
|
||||
int type = Convert.ToInt32(key.GetValue("Type", 0));
|
||||
if (type != 1 && type != 2) continue; // kernel and file-system driver services
|
||||
string rawPath = key.GetValue("ImagePath") as string;
|
||||
if (string.IsNullOrWhiteSpace(rawPath))
|
||||
rawPath = @"System32\drivers\" + name + ".sys";
|
||||
string path = NormalizePath(rawPath);
|
||||
string fileName = Path.GetFileName(path);
|
||||
if (!string.Equals(fileName, "WinNotify.sys", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(fileName, "msft.sys", StringComparison.OrdinalIgnoreCase)) continue;
|
||||
|
||||
var candidate = new VulnerableDriverCandidate { ServiceName = name, Path = path };
|
||||
try { candidate.Start = Convert.ToInt32(key.GetValue("Start", -1)); }
|
||||
catch { /* Keep start mode unknown. */ }
|
||||
try
|
||||
{
|
||||
using (var controller = new ServiceController(name))
|
||||
candidate.State = controller.Status.ToString();
|
||||
}
|
||||
catch { /* Loaded state remains unknown. */ }
|
||||
ReadCandidateFile(candidate);
|
||||
candidates.Add(candidate);
|
||||
}
|
||||
}
|
||||
catch { incomplete = true; /* One unreadable service must not stop the audit. */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { incomplete = true; }
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private static void ReadCandidateFile(VulnerableDriverCandidate candidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsLocalFilePath(candidate.Path) || !File.Exists(candidate.Path)) return;
|
||||
candidate.ImagePresent = true;
|
||||
var file = new FileInfo(candidate.Path);
|
||||
if (file.Length > MaxHashBytes)
|
||||
{
|
||||
candidate.Sha256 = "not checked (image exceeds 8 MiB limit)";
|
||||
candidate.Version = "not checked (image exceeds 8 MiB limit)";
|
||||
candidate.SignatureStatus = "not checked (image exceeds 8 MiB limit)";
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using (var stream = new FileStream(candidate.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
using (var sha = SHA256.Create())
|
||||
candidate.Sha256 = BitConverter.ToString(sha.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
|
||||
candidate.KnownHash = string.Equals(candidate.Sha256, LocalStrangerSha256, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch { candidate.Sha256 = "unavailable (image could not be read)"; }
|
||||
try { candidate.Version = FileVersionInfo.GetVersionInfo(candidate.Path).FileVersion ?? "unavailable"; }
|
||||
catch { /* Signature verification can still succeed without version metadata. */ }
|
||||
AuthenticodeHelper.Verify(candidate.Path, out string status);
|
||||
candidate.SignatureStatus = status;
|
||||
try
|
||||
{
|
||||
using (var baseCert = X509Certificate.CreateFromSignedFile(candidate.Path))
|
||||
using (var cert = new X509Certificate2(baseCert))
|
||||
{
|
||||
candidate.Signer = cert.Subject;
|
||||
}
|
||||
}
|
||||
catch { /* A catalog signature may have no embedded signer. */ }
|
||||
}
|
||||
catch { /* Hash and signature remain unknown if the image cannot be read. */ }
|
||||
}
|
||||
|
||||
// Pure merge/filter step: fixtures need no Windows APIs or device access.
|
||||
internal static DeviceDriverInventory Merge(IEnumerable<DeviceDriverRecord> psapi,
|
||||
IEnumerable<DeviceDriverRecord> systemDrivers, int maxOutput, string providerIssue = null)
|
||||
|
||||
Reference in new issue
Block a user