Add winPEAS online package vulnerability lookup

This commit is contained in:
Carlos Polop
2026-06-29 14:34:27 +02:00
parent 2de2b019ec
commit 4618657125
11 changed files with 617 additions and 71 deletions
+95
View File
@@ -94,6 +94,101 @@ jobs:
} else {
Write-Error "winPEAS.exe not found at $exePath"
}
- name: Execute winPEAS online package vulnerability lookup with mock
shell: pwsh
run: |
$Configuration = "Release"
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
if (!(Test-Path $exePath)) {
Write-Error "winPEAS.exe not found at $exePath"
}
$serverPath = Join-Path $env:RUNNER_TEMP "mock_host_checker.py"
$bodyPath = Join-Path $env:RUNNER_TEMP "host_checker_body.json"
$countPath = Join-Path $env:RUNNER_TEMP "host_checker_count.txt"
@"
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
import sys
body_path = sys.argv[1]
count_path = sys.argv[2]
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("content-length", "0"))
body = self.rfile.read(length).decode("utf-8", "replace")
with open(body_path, "w", encoding="utf-8") as f:
f.write(body)
with open(count_path, "w", encoding="utf-8") as f:
f.write("1")
vulns = []
for i in range(1, 56):
vulns.append({
"name": f"pkg{i}",
"version": f"1.{i}.0",
"manager": "windows-registry",
"vulns": [f"CVE-2026-{10000 + i}"],
})
response = {
"malicious": False,
"results": [],
"package_vulnerabilities": {
"checked": 300,
"affected": 55,
"vulnerable_packages": vulns,
},
}
data = json.dumps(response).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
def log_message(self, fmt, *args):
pass
HTTPServer(("127.0.0.1", 18768), Handler).handle_request()
"@ | Set-Content -Path $serverPath -Encoding utf8
$server = Start-Process python -ArgumentList "`"$serverPath`" `"$bodyPath`" `"$countPath`"" -PassThru -NoNewWindow
try {
Start-Sleep -Seconds 2
$env:HACKTRICKS_HOST_CHECKER_URL = "http://127.0.0.1:18768/api/host-checker"
$output = & $exePath applicationsinfo -vulnpackages notcolor 2>&1 | Out-String
if ($output -notmatch "Online package vulnerabilities found: 55 vulnerable package\(s\), checked 300\.") {
Write-Error "The package vulnerability summary was not printed as expected.`n$output"
}
$vulnLines = ([regex]::Matches($output, "(?m)^\s+- pkg\d+ ")).Count
if ($vulnLines -ne 50) {
Write-Error "Expected 50 vulnerable package lines, got $vulnLines.`n$output"
}
if ($output -notmatch "\.\.\. 5 more vulnerable package\(s\) not shown\.") {
Write-Error "The hidden vulnerable package count was not printed.`n$output"
}
if ($output -match "package_vulnerabilities") {
Write-Error "Raw package_vulnerabilities JSON leaked into the rendered output.`n$output"
}
$requestCount = Get-Content $countPath -Raw
if ([int]$requestCount.Trim() -ne 1) {
Write-Error "Expected exactly one host-checker request, got $requestCount"
}
$request = Get-Content $bodyPath -Raw | ConvertFrom-Json
if (!$request.hostname) {
Write-Error "The host-checker payload did not include hostname."
}
if (!$request.packages -or $request.packages.Count -lt 1) {
Write-Error "The host-checker payload did not include installed packages."
}
} finally {
if (!$server.HasExited) {
Stop-Process -Id $server.Id -Force
}
}
- name: Execute winPEAS networkinfo
shell: pwsh
@@ -49,6 +49,7 @@ namespace winPEAS.Tests
winPEAS.Checks.Checks.IsLinpeas = false;
winPEAS.Checks.Checks.IsLolbas = false;
winPEAS.Checks.Checks.IsNetworkScan = false;
winPEAS.Checks.Checks.CheckOnlineVulnPackages = false;
winPEAS.Checks.Checks.SearchProgramFiles = false;
winPEAS.Checks.Checks.NetworkScanOptions = string.Empty;
winPEAS.Checks.Checks.PortScannerPorts = null;
@@ -240,5 +241,37 @@ namespace winPEAS.Tests
Assert.AreEqual(500000, winPEAS.Checks.Checks.MaxRegexFileSize,
"max-regex-file-size=500000 should set MaxRegexFileSize to 500000.");
}
[TestMethod]
public void VulnPackages_ArgParsed_Correctly()
{
ParseOnly("-vulnpackages");
Assert.IsTrue(winPEAS.Checks.Checks.CheckOnlineVulnPackages,
"-vulnpackages should enable the online package vulnerability lookup.");
}
[TestMethod]
public void All_EnablesOnlinePackageLookup()
{
ParseOnly("all");
Assert.IsTrue(winPEAS.Checks.Checks.CheckOnlineVulnPackages,
"all should enable the online package vulnerability lookup.");
}
[TestMethod]
public void PackageVulnerabilityFormatter_CapsAtFiftyLines()
{
var vulnerablePackages = string.Join(",", Enumerable.Range(1, 55).Select(i =>
$"{{\"name\":\"pkg{i}\",\"version\":\"1.{i}.0\",\"manager\":\"windows-registry\",\"vulns\":[\"CVE-2026-{10000 + i}\"]}}"));
var responseJson = "{\"malicious\":false,\"results\":[],\"package_vulnerabilities\":{\"checked\":300,\"affected\":55,\"vulnerable_packages\":[" + vulnerablePackages + "]}}";
var summary = winPEAS.Info.NetworkInfo.HackTricksHostChecker.ParsePackageVulnerabilities(responseJson, 50);
Assert.AreEqual(300, summary.Checked);
Assert.AreEqual(55, summary.Affected);
Assert.AreEqual(50, summary.Lines.Count);
Assert.AreEqual(5, summary.NotShown);
Assert.IsTrue(summary.Lines[0].StartsWith("- pkg1 1.1.0 [windows-registry]: CVE-2026-10001"));
}
}
}
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using winPEAS.Helpers;
using winPEAS.Info.ApplicationInfo;
using winPEAS.Info.NetworkInfo;
namespace winPEAS.Checks
{
@@ -17,12 +18,55 @@ namespace winPEAS.Checks
{
PrintActiveWindow,
PrintInstalledApps,
PrintOnlinePackageVulnerabilities,
PrintAutoRuns,
PrintScheduled,
PrintDeviceDrivers,
}.ForEach(action => CheckRunner.Run(action, isDebug));
}
void PrintOnlinePackageVulnerabilities()
{
if (!Checks.CheckOnlineVulnPackages)
{
return;
}
try
{
Beaprint.MainPrint("Online package vulnerabilities", "T1518");
Beaprint.LinkPrint("", "Optional HackTricks online lookup enabled with -vulnpackages or all. Output is capped at 50 vulnerable packages.");
var summary = HackTricksHostChecker.GetPackageVulnerabilities(50);
if (!string.IsNullOrEmpty(summary.Error))
{
Beaprint.PrintException(" " + summary.Error);
return;
}
Beaprint.NoColorPrint($" Online package vulnerabilities found: {summary.Affected} vulnerable package(s), checked {summary.Checked}.");
if (summary.Lines.Count == 0)
{
Beaprint.GoodPrint(" No vulnerable packages found by the online lookup.");
return;
}
foreach (var line in summary.Lines)
{
Beaprint.BadPrint(" " + line);
}
if (summary.NotShown > 0)
{
Beaprint.NoColorPrint($" ... {summary.NotShown} more vulnerable package(s) not shown.");
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
void PrintActiveWindow()
{
try
@@ -24,6 +24,7 @@ namespace winPEAS.Checks
public static bool IsLinpeas = false;
public static bool IsLolbas = false;
public static bool IsNetworkScan = false;
public static bool CheckOnlineVulnPackages = false;
public static bool SearchProgramFiles = false;
public static IEnumerable<int> PortScannerPorts = null;
@@ -141,6 +142,7 @@ namespace winPEAS.Checks
if (string.Equals(arg, "all", StringComparison.CurrentCultureIgnoreCase))
{
print_fileanalysis_warn = false;
CheckOnlineVulnPackages = true;
}
if (arg.StartsWith("log", StringComparison.CurrentCultureIgnoreCase))
@@ -184,6 +186,12 @@ namespace winPEAS.Checks
DontCheckHostname = true;
}
if (string.Equals(arg, "-vulnpackages", StringComparison.CurrentCultureIgnoreCase) ||
string.Equals(arg, "vulnpackages", StringComparison.CurrentCultureIgnoreCase))
{
CheckOnlineVulnPackages = true;
}
if (string.Equals(arg, "quiet", StringComparison.CurrentCultureIgnoreCase))
{
Banner = false;
@@ -321,6 +329,11 @@ namespace winPEAS.Checks
_systemCheckSelectedKeysHashSet.Add("networkscan");
}
if (CheckOnlineVulnPackages && !isAllChecks)
{
_systemCheckSelectedKeysHashSet.Add("applicationsinfo");
}
if (isAllChecks)
{
isFileSearchEnabled = true;
@@ -346,6 +359,10 @@ namespace winPEAS.Checks
CheckRunner.Run(() => CreateDynamicLists(isFileSearchEnabled), IsDebug);
Info.NetworkInfo.HackTricksHostChecker.Start(
includeHostname: !DontCheckHostname,
includePackages: CheckOnlineVulnPackages);
RunChecks(isAllChecks, wait);
SearchHelper.CleanLists();
@@ -509,7 +509,7 @@ namespace winPEAS.Checks
if (!string.IsNullOrEmpty(resolutionInfo.ExternalCheckResult))
{
Beaprint.GoodPrint($" External Check Result:");
Beaprint.NoColorPrint(resolutionInfo.ExternalCheckResult);
Beaprint.NoColorPrint(" " + resolutionInfo.ExternalCheckResult.Replace("\n", "\n "));
}
else if (!string.IsNullOrEmpty(resolutionInfo.Error))
{
@@ -149,6 +149,7 @@ namespace winPEAS.Helpers
Console.WriteLine(LCYAN + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
Console.WriteLine(LCYAN + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
Console.WriteLine(LCYAN + " dont-check-hostname" + GRAY + " Don't check the hostname externally" + NOCOLOR);
Console.WriteLine(LCYAN + " -vulnpackages" + GRAY + " Send installed application names/versions to HackTricks for an online vulnerability check. Also enabled by 'all'." + NOCOLOR);
Console.WriteLine(LCYAN + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR);
Console.WriteLine(LCYAN + " max-regex-file-size=1000000" + GRAY + $" Max file size (in Bytes) to search regex in. Default: {Checks.Checks.MaxRegexFileSize}B" + NOCOLOR);
@@ -0,0 +1,102 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
namespace winPEAS.Info.ApplicationInfo
{
public static class InstalledPackageInventory
{
public const int MaxPackages = 300;
public static List<Dictionary<string, string>> GetInstalledPackages(int maxPackages = MaxPackages)
{
var packages = new List<Dictionary<string, string>>();
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
AddRegistryPackages(packages, seen, RegistryHive.LocalMachine, RegistryView.Registry64, maxPackages);
AddRegistryPackages(packages, seen, RegistryHive.LocalMachine, RegistryView.Registry32, maxPackages);
AddRegistryPackages(packages, seen, RegistryHive.CurrentUser, RegistryView.Default, maxPackages);
return packages;
}
private static void AddRegistryPackages(
List<Dictionary<string, string>> packages,
HashSet<string> seen,
RegistryHive hive,
RegistryView view,
int maxPackages)
{
if (packages.Count >= maxPackages)
{
return;
}
try
{
using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
using (var uninstallKey = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"))
{
if (uninstallKey == null)
{
return;
}
foreach (var subkeyName in uninstallKey.GetSubKeyNames())
{
if (packages.Count >= maxPackages)
{
return;
}
using (var appKey = uninstallKey.OpenSubKey(subkeyName))
{
if (appKey == null)
{
continue;
}
var name = CleanValue(appKey.GetValue("DisplayName"));
var version = CleanValue(appKey.GetValue("DisplayVersion"));
if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(version))
{
continue;
}
var key = $"{name}\0{version}";
if (!seen.Add(key))
{
continue;
}
var package = new Dictionary<string, string>
{
{ "name", name },
{ "version", version },
{ "manager", "windows-registry" }
};
var publisher = CleanValue(appKey.GetValue("Publisher"));
if (!string.IsNullOrWhiteSpace(publisher))
{
package["publisher"] = publisher;
}
packages.Add(package);
}
}
}
}
catch
{
// Registry inventory is best-effort; unreadable views should not break winPEAS.
}
}
private static string CleanValue(object value)
{
return Convert.ToString(value)?.Trim().Replace("\r", " ").Replace("\n", " ");
}
}
}
@@ -0,0 +1,317 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using winPEAS.Info.ApplicationInfo;
namespace winPEAS.Info.NetworkInfo
{
public sealed class HostCheckerResult
{
public string Hostname { get; set; }
public string RawResponse { get; set; }
public string HostOnlyResponse { get; set; }
public string Error { get; set; }
}
public sealed class PackageVulnerabilitySummary
{
public int Checked { get; set; }
public int Affected { get; set; }
public int NotShown { get; set; }
public string Error { get; set; }
public List<string> Lines { get; } = new List<string>();
}
public static class HackTricksHostChecker
{
private const int TimeoutSeconds = 15;
private const string DefaultUrl = "https://tools.hacktricks.wiki/api/host-checker";
private static readonly object LockObj = new object();
private static Task<HostCheckerResult> lookupTask;
private static bool startedWithPackages;
private static bool startedWithHostname;
public static void Start(bool includeHostname, bool includePackages)
{
if (!includeHostname && !includePackages)
{
return;
}
lock (LockObj)
{
if (lookupTask != null)
{
if ((includePackages && !startedWithPackages) || (includeHostname && !startedWithHostname))
{
lookupTask = Task.Run(() => ExecuteLookup(includeHostname || startedWithHostname, includePackages || startedWithPackages));
startedWithHostname = includeHostname || startedWithHostname;
startedWithPackages = includePackages || startedWithPackages;
}
return;
}
startedWithHostname = includeHostname;
startedWithPackages = includePackages;
lookupTask = Task.Run(() => ExecuteLookup(includeHostname, includePackages));
}
}
public static HostCheckerResult GetResult()
{
Start(includeHostname: !Checks.Checks.DontCheckHostname, includePackages: Checks.Checks.CheckOnlineVulnPackages);
try
{
return lookupTask.GetAwaiter().GetResult();
}
catch (Exception ex)
{
return new HostCheckerResult { Error = $"Error during online HackTricks check: {ex.Message}" };
}
}
public static PackageVulnerabilitySummary GetPackageVulnerabilities(int maxLines)
{
Start(includeHostname: !Checks.Checks.DontCheckHostname, includePackages: true);
var result = GetResult();
if (!string.IsNullOrEmpty(result.Error))
{
return new PackageVulnerabilitySummary { Error = result.Error };
}
return ParsePackageVulnerabilities(result.RawResponse, maxLines);
}
public static PackageVulnerabilitySummary ParsePackageVulnerabilities(string responseJson, int maxLines)
{
var summary = new PackageVulnerabilitySummary();
if (string.IsNullOrWhiteSpace(responseJson))
{
summary.Error = "No response received from HackTricks online lookup.";
return summary;
}
try
{
using (var doc = JsonDocument.Parse(responseJson))
{
var root = doc.RootElement;
if (!root.TryGetProperty("package_vulnerabilities", out var packageVulns))
{
return summary;
}
summary.Checked = GetInt(packageVulns, "checked");
summary.Affected = GetInt(packageVulns, "affected");
if (packageVulns.TryGetProperty("error", out var error) && error.ValueKind == JsonValueKind.String)
{
summary.Error = "Package vulnerability lookup failed: " + error.GetString();
return summary;
}
if (!packageVulns.TryGetProperty("vulnerable_packages", out var packages) ||
packages.ValueKind != JsonValueKind.Array)
{
return summary;
}
foreach (var package in packages.EnumerateArray())
{
if (summary.Lines.Count >= maxLines)
{
break;
}
var name = GetString(package, "name");
var version = GetString(package, "version");
var ecosystem = GetString(package, "ecosystem");
var manager = GetString(package, "manager");
var vulns = GetStringArray(package, "vulns");
if (string.IsNullOrWhiteSpace(name) || vulns.Count == 0)
{
continue;
}
var source = !string.IsNullOrWhiteSpace(ecosystem) ? ecosystem : manager;
var sourcePart = !string.IsNullOrWhiteSpace(source) ? $" [{source}]" : string.Empty;
summary.Lines.Add($"- {name} {version}{sourcePart}: {string.Join(", ", vulns)}".Trim());
}
summary.NotShown = Math.Max(0, summary.Affected - summary.Lines.Count);
}
}
catch (Exception ex)
{
summary.Error = "Could not parse package vulnerability lookup response: " + ex.Message;
}
return summary;
}
private static HostCheckerResult ExecuteLookup(bool includeHostname, bool includePackages)
{
var result = new HostCheckerResult();
try
{
var hostname = GetHostname();
result.Hostname = hostname;
var payload = new Dictionary<string, object>
{
{ "source", "winpeas" },
{ "os", GetOsInfo() }
};
if (includeHostname && !string.IsNullOrWhiteSpace(hostname))
{
payload["hostname"] = hostname;
}
if (includePackages)
{
payload["packages"] = InstalledPackageInventory.GetInstalledPackages();
}
var url = Environment.GetEnvironmentVariable("HACKTRICKS_HOST_CHECKER_URL");
if (string.IsNullOrWhiteSpace(url))
{
url = DefaultUrl;
}
using (var httpClient = new HttpClient())
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(TimeoutSeconds)))
{
httpClient.Timeout = TimeSpan.FromSeconds(TimeoutSeconds);
var body = JsonSerializer.Serialize(payload);
var req = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(body, Encoding.UTF8, "application/json")
};
req.Headers.UserAgent.ParseAdd("winpeas");
req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var resp = httpClient.SendAsync(req, cts.Token).GetAwaiter().GetResult();
if (!resp.IsSuccessStatusCode)
{
result.Error = $"External check failed (HTTP {(int)resp.StatusCode})";
return result;
}
result.RawResponse = resp.Content.ReadAsStringAsync().GetAwaiter().GetResult();
result.HostOnlyResponse = RemovePackageVulnerabilities(result.RawResponse);
}
}
catch (Exception ex)
{
result.Error = $"Error during online HackTricks check: {ex.Message}";
}
return result;
}
private static string RemovePackageVulnerabilities(string responseJson)
{
if (string.IsNullOrWhiteSpace(responseJson))
{
return responseJson;
}
try
{
using (var doc = JsonDocument.Parse(responseJson))
using (var stream = new MemoryStream())
{
using (var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
{
writer.WriteStartObject();
foreach (var property in doc.RootElement.EnumerateObject())
{
if (!string.Equals(property.Name, "package_vulnerabilities", StringComparison.OrdinalIgnoreCase))
{
property.WriteTo(writer);
}
}
writer.WriteEndObject();
}
return Encoding.UTF8.GetString(stream.ToArray());
}
}
catch
{
return responseJson;
}
}
private static Dictionary<string, object> GetOsInfo()
{
return new Dictionary<string, object>
{
{ "id", "windows" },
{ "name", "Windows" },
{ "version_id", Environment.OSVersion.VersionString },
{ "kernel", new Dictionary<string, string>
{
{ "release", Environment.OSVersion.Version.ToString() },
{ "arch", Environment.Is64BitOperatingSystem ? "x64" : "x86" }
}
}
};
}
private static string GetHostname()
{
try
{
var hostname = Dns.GetHostName();
return string.IsNullOrWhiteSpace(hostname) ? Environment.MachineName : hostname;
}
catch
{
return Environment.MachineName;
}
}
private static int GetInt(JsonElement element, string propertyName)
{
if (element.TryGetProperty(propertyName, out var property) && property.ValueKind == JsonValueKind.Number && property.TryGetInt32(out var value))
{
return value;
}
return 0;
}
private static string GetString(JsonElement element, string propertyName)
{
if (element.TryGetProperty(propertyName, out var property) && property.ValueKind == JsonValueKind.String)
{
return property.GetString();
}
return string.Empty;
}
private static List<string> GetStringArray(JsonElement element, string propertyName)
{
if (!element.TryGetProperty(propertyName, out var property) || property.ValueKind != JsonValueKind.Array)
{
return new List<string>();
}
return property
.EnumerateArray()
.Where(item => item.ValueKind == JsonValueKind.String)
.Select(item => item.GetString())
.Where(value => !string.IsNullOrWhiteSpace(value))
.ToList();
}
}
}
@@ -1,9 +1,4 @@
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
namespace winPEAS.Info.NetworkInfo
{
public class HostnameResolutionInfo
@@ -15,9 +10,6 @@ namespace winPEAS.Info.NetworkInfo
public static class HostnameResolution
{
private const int INTERNET_SEARCH_TIMEOUT = 15;
private static readonly HttpClient httpClient = new HttpClient();
/// <summary>
/// Attempts to resolve the local hostname via the external lambda.
/// Always returns a populated <see cref="HostnameResolutionInfo"/> object.
@@ -28,36 +20,10 @@ namespace winPEAS.Info.NetworkInfo
try
{
// 1. Determine hostname
info.Hostname = Dns.GetHostName();
if (string.IsNullOrEmpty(info.Hostname))
info.Hostname = Environment.MachineName;
// 2. Prepare JSON body
var payload = new StringContent(
JsonSerializer.Serialize(new { hostname = info.Hostname }),
Encoding.UTF8,
"application/json");
// 3. Configure HttpClient (header added once)
if (!httpClient.DefaultRequestHeaders.Contains("User-Agent"))
httpClient.DefaultRequestHeaders.Add("User-Agent", "winpeas");
httpClient.Timeout = TimeSpan.FromSeconds(INTERNET_SEARCH_TIMEOUT);
// 4. Call external checker
var resp = httpClient
.PostAsync("https://tools.hacktricks.wiki/api/host-checker", payload)
.GetAwaiter().GetResult();
if (resp.IsSuccessStatusCode)
{
info.ExternalCheckResult = resp.Content.ReadAsStringAsync()
.GetAwaiter().GetResult();
}
else
{
info.Error = $"External check failed (HTTP {(int)resp.StatusCode})";
}
var result = HackTricksHostChecker.GetResult();
info.Hostname = result.Hostname;
info.ExternalCheckResult = result.HostOnlyResponse;
info.Error = result.Error;
}
catch (Exception ex)
{
@@ -1,11 +1,8 @@
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using System.Threading;
namespace winPEAS.Info.NetworkInfo
@@ -49,9 +46,6 @@ namespace winPEAS.Info.NetworkInfo
private static readonly string[] DNS_ICMP_IPS =
{ "1.1.1.1", "8.8.8.8" };
private const string LAMBDA_URL =
"https://tools.hacktricks.wiki/api/host-checker";
// Shared HttpClient (kept for HTTP & Lambda checks)
private static readonly HttpClient http = new HttpClient
{
@@ -115,32 +109,7 @@ namespace winPEAS.Info.NetworkInfo
private static bool TryLambdaAccess(out string error)
{
try
{
using var cts =
new CancellationTokenSource(TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS));
var payload = new StringContent(
JsonSerializer.Serialize(new { hostname = Environment.MachineName }),
Encoding.UTF8,
"application/json");
var req = new HttpRequestMessage(HttpMethod.Post, LAMBDA_URL);
req.Content = payload;
req.Headers.UserAgent.ParseAdd("winpeas");
req.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var resp = http.SendAsync(req, cts.Token).GetAwaiter().GetResult();
error = resp.IsSuccessStatusCode ? null :
$"HTTP {(int)resp.StatusCode}";
return error == null;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
return TryWebRequest("https://example.com", out error);
}
private static bool TryDnsAccess(string ip, out string error)
@@ -1226,6 +1226,7 @@
<Compile Include="Info\ApplicationInfo\ApplicationInfoHelper.cs" />
<Compile Include="Info\ApplicationInfo\AutoRuns.cs" />
<Compile Include="Info\ApplicationInfo\DeviceDrivers.cs" />
<Compile Include="Info\ApplicationInfo\InstalledPackageInventory.cs" />
<Compile Include="Info\ApplicationInfo\SoapClientProxyAnalyzer.cs" />
<Compile Include="Info\ApplicationInfo\InstalledApps.cs" />
<Compile Include="Helpers\Beaprint.cs" />
@@ -1264,6 +1265,7 @@
<Compile Include="Info\NetworkInfo\Enums\Protocol.cs" />
<Compile Include="Info\NetworkInfo\Enums\TcpTableClass.cs" />
<Compile Include="Info\NetworkInfo\Enums\UdpTableClass.cs" />
<Compile Include="Info\NetworkInfo\HackTricksHostChecker.cs" />
<Compile Include="Info\NetworkInfo\HostnameResolution.cs" />
<Compile Include="Info\NetworkInfo\InternetConnectivity.cs" />
<Compile Include="Info\NetworkInfo\InternetSettings\InternetSettings.cs" />