Compare commits

...

18 Commits

Author SHA1 Message Date
SirBroccoli
4e556fd594 Fix variable reference when parsing URLs 2025-06-06 00:01:17 +02:00
SirBroccoli
c3a93a57fe Merge pull request #473 from Signum21/master
Fix IdentityNotMappedException in Vulnerable Leaked Handlers
2025-05-31 22:36:49 +02:00
Signum21
f62d9fc550 Fix System.Security.Principal.IdentityNotMappedException in Vulnerable Leaked Handlers 2025-05-31 04:56:14 +02:00
SirBroccoli
11e9b8dde6 Merge pull request #472 from Jack-Vaughn/NoEnvVars-Update
Add 4 noisy environment variables to NoEnvVars.sh
2025-05-26 23:57:40 +02:00
Jack Vaughn
b9a9ad5ddf Add 4 noisy and useless environment variables to NoEnvVars.sh
These variables (^PATH=|^INVOCATION_ID=|^WATCHDOG_PID=|^LISTEN_PID=) frequently appear across processes 
on busy systems (10+ each on tested system) and produce a large volume of irrelevant output
2025-05-25 21:32:51 -04:00
carlospolop
88f08a405e l 2025-05-26 02:55:07 +02:00
SirBroccoli
322792c4ec Merge pull request #471 from Jack-Vaughn/environ-check
Add module to check for sensitive environment variables via /proc/*/environ
2025-05-26 02:33:43 +02:00
Jack
c150e63b52 This module scans /proc/*/environ for potentially sensitive environment variables on Linux systems.
It targets common keywords like token, password, secret, AWS, API, etc.

Uses 'tr' instead of 'strings' to improve compatibility in minimal environments like containers.

The check is skipped entirely on MacPEAS.
2025-05-25 12:55:34 -04:00
carlospolop
7b8dcfbe8d f 2025-05-25 08:17:07 +02:00
carlospolop
aac3667247 f l 2025-05-25 08:15:48 +02:00
carlospolop
64ab193d25 f linpeas 2025-05-25 07:05:48 +02:00
carlospolop
aab8241ede f 2025-05-25 02:21:39 +02:00
carlospolop
65b98d11ac only print errors when relevant 2025-05-25 02:10:07 +02:00
carlospolop
1e72dbeb76 impr winpeas networking checks 2025-05-25 01:46:30 +02:00
carlospolop
c9282b4bdb fix winpeas? 2025-05-25 01:37:03 +02:00
carlospolop
b91334e5b3 fix 2025-05-24 23:37:00 +02:00
carlospolop
b7bc20a027 improvement 2025-05-24 23:31:12 +02:00
carlospolop
4fbe6ffd79 winpeas networkinfo test ci/cd 2025-05-24 23:16:31 +02:00
16 changed files with 328 additions and 247 deletions

View File

@@ -99,6 +99,17 @@ jobs:
Write-Error "winPEAS.exe not found at $exePath"
}
- name: Execute winPEAS networkinfo
shell: pwsh
run: |
$Configuration = "Release"
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
if (Test-Path $exePath) {
& $exePath networkinfo
} else {
Write-Error "winPEAS.exe not found at $exePath"
}
# Copy the built versions
- name: Copy all versions
run: |

View File

@@ -26,7 +26,7 @@
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables:
# Global Variables: $NoEnvVars, $EnvVarsRed
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
@@ -35,5 +35,5 @@
print_2title "Environment"
print_info "Any private information inside environment variables?"
(env || printenv || set) 2>/dev/null | grep -v "RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_" | sed -${E} "s,[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME,${SED_RED},g" || echo_not_found "env || set"
(env || printenv || set) 2>/dev/null | grep -Eiv "$NoEnvVars" | sed -${E} "s,$EnvVarsRed,${SED_RED},g" || echo_not_found "env || set"
echo ""

View File

@@ -8,7 +8,7 @@
# Functions Used: check_dns, check_icmp, check_tcp_443, check_tcp_443_bin, check_tcp_80, print_2title, check_external_hostname
# Global Variables:
# Initial Functions:
# Generated Global Variables: $pid4, $pid2, $pid1, $pid3, $pid5, $NOT_CHECK_EXTERNAL_HOSTNAME, $TIMEOUT_INTERNET_SECONDS
# Generated Global Variables: $pid4, $pid2, $pid1, $pid3, $$tcp443_bin_status, $NOT_CHECK_EXTERNAL_HOSTNAME, $TIMEOUT_INTERNET_SECONDS
# Fat linpeas: 0
# Small linpeas: 0
@@ -19,24 +19,30 @@ print_2title "Internet Access?"
TIMEOUT_INTERNET_SECONDS=5
if [ "$SUPERFAST" ]; then
TIMEOUT_INTERNET_SECONDS=2
TIMEOUT_INTERNET_SECONDS=2.5
fi
# Run all checks in background
check_tcp_80 2>/dev/null & pid1=$!
check_tcp_443 2>/dev/null & pid2=$!
check_tcp_443_bin 2>/dev/null & pid3=$!
check_icmp 2>/dev/null & pid4=$!
check_dns 2>/dev/null & pid5=$!
check_tcp_80 "$TIMEOUT_INTERNET_SECONDS" 2>/dev/null & pid1=$!
check_tcp_443 "$TIMEOUT_INTERNET_SECONDS" 2>/dev/null & pid2=$!
check_icmp "$TIMEOUT_INTERNET_SECONDS" 2>/dev/null & pid3=$!
check_dns "$TIMEOUT_INTERNET_SECONDS" 2>/dev/null & pid4=$!
# Kill all after 10 seconds
(sleep $TIMEOUT_INTERNET_SECONDS && kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null) &
(sleep $(( $TIMEOUT_INTERNET_SECONDS + 1 )) && kill -9 $pid1 $pid2 $pid3 $pid4 2>/dev/null) &
check_tcp_443_bin $TIMEOUT_INTERNET_SECONDS 2>/dev/null
tcp443_bin_status=$?
wait $pid1 $pid2 $pid3 $pid4 2>/dev/null
# Wait for all to finish
wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
wait 2>/dev/null
if ! [ "$SUPERFAST" ] && ! [ "$NOT_CHECK_EXTERNAL_HOSTNAME" ]; then
if [ "$tcp443_bin_status" -eq 0 ] && \
[ -z "$SUPERFAST" ] && [ -z "$NOT_CHECK_EXTERNAL_HOSTNAME" ]; then
echo ""
print_2title "Is hostname malicious or leaked?"
print_info "This will check the public IP and hostname in known malicious lists and leaks to find any relevant information about the host."

View File

@@ -0,0 +1,22 @@
# Title: Interesting Files - Interesting Environment Variables
# ID: IF_Interesting_environment_variables
# Author: Jack Vaughn
# Last Update: 25-05-2025
# Description: Searching possible sensitive environment variables inside of /proc/*/environ
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
# Global Variables: $MACPEAS, $NoEnvVars, $EnvVarsRed
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
if [ -z "$MACPEAS" ]; then
print_2title "Checking all env variables in /proc/*/environ removing duplicates and filtering out useless env vars"
cat /proc/[0-9]*/environ 2>/dev/null | \
tr '\0' '\n' | \
grep -Eiv "$NoEnvVars" | \
sort -u | \
sed -${E} "s,$EnvVarsRed,${SED_RED},g"
fi

View File

@@ -8,25 +8,19 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables: $pid, $pids
# Generated Global Variables: $TIMEOUT_INTERNET_SECONDS_DNS, $local_pid
# Fat linpeas: 0
# Small linpeas: 1
check_dns(){
local TIMEOUT_INTERNET_SECONDS_DNS=$1
if ! [ -f "/bin/bash" ]; then
echo " /bin/bash not found"
return
fi
/bin/bash -c '
for ip in 1.1.1.1 8.8.8.8 ; do
(( echo cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001 | xxd -p -r >&3; dd bs=9000 count=1 <&3 2>/dev/null | xxd ) 3>/dev/udp/$ip/53 && echo "DNS available" && exit 0) &
pids+=($!)
done
for pid in ${pids[@]}; do
wait $pid && exit 0
done
echo "DNS not available"
' 2>/dev/null | grep "available" || echo "DNS not available"
# example.com
(bash -c '((( echo cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001 | xxd -p -r >&3; dd bs=9000 count=1 <&3 2>/dev/null | xxd ) 3>/dev/udp/1.1.1.1/53 && echo "DNS accessible") | grep "accessible" && exit 0 ) 2>/dev/null || echo "DNS is not accessible"') & local_pid=$!
sleep $TIMEOUT_INTERNET_SECONDS_DNS && kill -9 $local_pid 2>/dev/null && echo "DNS is not accessible"
}

View File

@@ -8,11 +8,20 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $TIMEOUT_INTERNET_SECONDS_ICMP, $local_pid
# Fat linpeas: 0
# Small linpeas: 1
check_icmp(){
(ping -c 1 1.1.1.1 | grep -E "1 received|1 packets received" && echo "Ping is available" || echo "Ping is not available" 2>/dev/null) | grep -i "available"
local TIMEOUT_INTERNET_SECONDS_ICMP=$1
if ! [ "$(command -v ping 2>/dev/null || echo -n '')" ]; then
echo " ping not found"
return
fi
# example.com
((ping -c 1 1.1.1.1 2>/dev/null | grep -Ei "1 received|1 packets received" && echo "ICMP is accessible" || echo "ICMP is not accessible" 2>/dev/null) | grep "accessible" && exit 0 ) 2>/dev/null || echo "ICMP is not accessible" & local_pid=$!
sleep $TIMEOUT_INTERNET_SECONDS_ICMP && kill -9 $local_pid 2>/dev/null && echo "ICMP is not accessible"
}

View File

@@ -8,30 +8,21 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables: $pid, $pids
# Generated Global Variables: $local_pid, $TIMEOUT_INTERNET_SECONDS_443
# Fat linpeas: 0
# Small linpeas: 1
check_tcp_443(){
local TIMEOUT_INTERNET_SECONDS_443=$1
if ! [ -f "/bin/bash" ]; then
echo " /bin/bash not found"
return
fi
/bin/bash -c '
for ip in 1.1.1.1 8.8.8.8; do
(echo >/dev/tcp/$ip/443 && echo "Port 443 is accessible" && exit 0) &
pids+=($!)
done
for pid in ${pids[@]}; do
wait $pid && exit 0
done
echo "Port 80 is not accessible"
' 2>/dev/null | grep "accessible" || echo "Port 80 is not accessible"
# example.com
(bash -c '(echo >/dev/tcp/104.18.74.230/443 2>/dev/null && echo "Port 443 is accessible" && exit 0) 2>/dev/null || echo "Port 443 is not accessible"') & local_pid=$!
sleep $TIMEOUT_INTERNET_SECONDS_443 && kill -9 $local_pid 2>/dev/null && echo "Port 443 is not accessible"
}

View File

@@ -8,16 +8,39 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $url_lambda, $TIMEOUT_INTERNET_SECONDS_443_BIN
# Fat linpeas: 0
# Small linpeas: 1
check_tcp_443_bin () {
local TIMEOUT_INTERNET_SECONDS_443_BIN=$1
local url_lambda="https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/"
check_tcp_443_bin(){
if command -v curl >/dev/null 2>&1; then
curl -s "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/" -H "User-Agent: linpeas" -H "Content-Type: application/json" >/dev/null 2>&1 && echo "Port 443 is accessible with curl" || echo "Port 443 is not accessible with curl"
if curl -s --connect-timeout $TIMEOUT_INTERNET_SECONDS_443_BIN "$url_lambda" \
-H "User-Agent: linpeas" -H "Content-Type: application/json" >/dev/null 2>&1
then
echo "Port 443 is accessible with curl"
return 0 # ✅ success
else
echo "Port 443 is not accessible with curl"
return 1
fi
elif command -v wget >/dev/null 2>&1; then
wget -q -O - "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/" --header "User-Agent: linpeas" -H "Content-Type: application/json" >/dev/null 2>&1 && echo "Port 443 is accessible with wget" || echo "Port 443 is not accessible with wget"
if wget -q --timeout=$TIMEOUT_INTERNET_SECONDS_443_BIN -O - "$url_lambda" \
--header "User-Agent: linpeas" -H "Content-Type: application/json" >/dev/null 2>&1
then
echo "Port 443 is accessible with wget"
return 0
else
echo "Port 443 is not accessible with wget"
return 1
fi
else
echo "Neither curl nor wget available"
return 1
fi
}
}

View File

@@ -8,25 +8,21 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables: $pid, $pids
# Generated Global Variables: $local_pid, $TIMEOUT_INTERNET_SECONDS_80
# Fat linpeas: 0
# Small linpeas: 1
check_tcp_80(){
local TIMEOUT_INTERNET_SECONDS_80=$1
if ! [ -f "/bin/bash" ]; then
echo " /bin/bash not found"
return
fi
/bin/bash -c '
for ip in 1.1.1.1 8.8.8.8; do
(echo >/dev/tcp/$ip/80 && echo "Port 80 is accessible" && exit 0) &
pids+=($!)
done
for pid in ${pids[@]}; do
wait $pid && exit 0
done
echo "Port 80 is not accessible"
' 2>/dev/null | grep "accessible"
# example.com
(bash -c '(echo >/dev/tcp/104.18.74.230/80 2>/dev/null && echo "Port 80 is accessible" && exit 0) 2>/dev/null || echo "Port 80 is not accessible"') & local_pid=$!
sleep $TIMEOUT_INTERNET_SECONDS_80 && kill -9 $local_pid 2>/dev/null && echo "Port 80 is not accessible"
}

View File

@@ -0,0 +1,18 @@
# Title: Variables - EnvVarsRed
# ID: EnvVarsRed
# Author: Carlos Polop
# Last Update: 26-05-2025
# Description: Useless env vars
# License: GNU GPL
# Version: 1.0
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables: $EnvVarsRed
# Fat linpeas: 0
# Small linpeas: 1
EnvVarsRed="[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME|[aA][pP][iI][_][kK][eE][yY]|[aA][wW][sS]|[aA][zZ][uU][rR][eE]|[gG][cC][pP]|[aA][pP][iI]|[sS][eE][cC][rR][eE][tT]|[sS][qQ][lL]|[dD][aA][tT][aA][bB][aA][sS][eE]|[tT][oO][kK][eE][nN]"

View File

@@ -0,0 +1,16 @@
# Title: Variables - NoEnvVars
# ID: NoEnvVars
# Author: Carlos Polop
# Last Update: 26-05-2025
# Description: Useless env vars
# License: GNU GPL
# Version: 1.0
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables: $NoEnvVars
# Fat linpeas: 0
# Small linpeas: 1
NoEnvVars="LESS_TERMCAP|JOURNAL_STREAM|XDG_SESSION|DBUS_SESSION|systemd\/sessions|systemd_exec|MEMORY_PRESSURE_WATCH|RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_|^PATH=|^INVOCATION_ID=|^WATCHDOG_PID=|^LISTEN_PID="

View File

@@ -97,7 +97,7 @@ class LinpeasBuilder:
for orig_url in urls:
tar_gz_bin_name = ""
if ",,," in orig_url:
tar_gz_bin_name = url.split(",,,")[1]
tar_gz_bin_name = orig_url.split(",,,")[1]
url = orig_url.split(",,,")[0]
else:
url = orig_url

View File

@@ -457,28 +457,35 @@ namespace winPEAS.Checks
{ "Not Accessible", Beaprint.ansi_color_bad },
};
Beaprint.AnsiPrint($" HTTP (80) Access: {(connectivityInfo.HttpAccess ? "Accessible" : "Not Accessible")}", colorsBool);
if (!string.IsNullOrEmpty(connectivityInfo.HttpError))
if (!connectivityInfo.HttpAccess && !string.IsNullOrEmpty(connectivityInfo.HttpError))
{
Beaprint.PrintException($" Error: {connectivityInfo.HttpError}");
}
// HTTPS Access
Beaprint.AnsiPrint($" HTTPS (443) Access: {(connectivityInfo.HttpsAccess ? "Accessible" : "Not Accessible")}", colorsBool);
if (!string.IsNullOrEmpty(connectivityInfo.HttpsError))
if (!connectivityInfo.HttpsAccess && !string.IsNullOrEmpty(connectivityInfo.HttpsError))
{
Beaprint.PrintException($" Error: {connectivityInfo.HttpsError}");
}
// HTTPS By Domain Name
Beaprint.AnsiPrint($" HTTPS (443) Access by Domain Name: {(connectivityInfo.LambdaAccess ? "Accessible" : "Not Accessible")}", colorsBool);
if (!connectivityInfo.LambdaAccess && !string.IsNullOrEmpty(connectivityInfo.LambdaError))
{
Beaprint.PrintException($" Error: {connectivityInfo.LambdaError}");
}
// DNS Access
Beaprint.AnsiPrint($" DNS (53) Access: {(connectivityInfo.DnsAccess ? "Accessible" : "Not Accessible")}", colorsBool);
if (!string.IsNullOrEmpty(connectivityInfo.DnsError))
if (!connectivityInfo.DnsAccess && !string.IsNullOrEmpty(connectivityInfo.DnsError))
{
Beaprint.PrintException($" Error: {connectivityInfo.DnsError}");
}
// ICMP Access
Beaprint.AnsiPrint($" ICMP (ping) Access: {(connectivityInfo.IcmpAccess ? "Accessible" : "Not Accessible")}", colorsBool);
if (!string.IsNullOrEmpty(connectivityInfo.IcmpError))
if (!connectivityInfo.IcmpAccess && !string.IsNullOrEmpty(connectivityInfo.IcmpError))
{
Beaprint.PrintException($" Error: {connectivityInfo.IcmpError}");
}
@@ -505,7 +512,7 @@ namespace winPEAS.Checks
}
else if (!string.IsNullOrEmpty(resolutionInfo.Error))
{
Beaprint.BadPrint($" {resolutionInfo.Error}");
Beaprint.PrintException($" {resolutionInfo.Error}");
}
}
catch (Exception ex)

View File

@@ -81,7 +81,7 @@ namespace winPEAS.Helpers
/---------------------------------------------------------------------------------\
| {1}Do you like PEASS?{0} |
|---------------------------------------------------------------------------------|
| {3}Learn Cloud Hacking{0} : {2}training.hacktricks.xyz {0} |
| {3}Learn Cloud Hacking{0} : {2}training.hacktricks.xyz {0} |
| {3}Follow on Twitter{0} : {2}@hacktricks_live{0} |
| {3}Respect on HTB{0} : {2}SirBroccoli {0} |
|---------------------------------------------------------------------------------|

View File

@@ -1,58 +1,89 @@
using System;
using System.Collections.Generic;
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.Threading;
using System.Threading.Tasks;
namespace winPEAS.Info.NetworkInfo
{
// ───────────────────────────────────────────────────────────────
// POCO returned to the UI
// ───────────────────────────────────────────────────────────────
public class InternetConnectivityInfo
{
public bool HttpAccess { get; set; }
public bool HttpsAccess { get; set; }
public bool LambdaAccess { get; set; }
public bool DnsAccess { get; set; }
public bool IcmpAccess { get; set; }
public string HttpError { get; set; }
public string HttpsError { get; set; }
public string LambdaError { get; set; }
public string DnsError { get; set; }
public string IcmpError { get; set; }
public string SuccessfulHttpIp { get; set; }
public bool HttpAccess { get; set; }
public bool HttpsAccess { get; set; }
public bool LambdaAccess { get; set; }
public bool DnsAccess { get; set; }
public bool IcmpAccess { get; set; }
public string HttpError { get; set; }
public string HttpsError { get; set; }
public string LambdaError { get; set; }
public string DnsError { get; set; }
public string IcmpError { get; set; }
public string SuccessfulHttpIp { get; set; }
public string SuccessfulHttpsIp { get; set; }
public string SuccessfulDnsIp { get; set; }
public string SuccessfulIcmpIp { get; set; }
public string SuccessfulDnsIp { get; set; }
public string SuccessfulIcmpIp { get; set; }
}
// ───────────────────────────────────────────────────────────────
// Connectivity tester
// ───────────────────────────────────────────────────────────────
public static class InternetConnectivity
{
private const int HTTP_TIMEOUT = 5000; // 5 seconds
private const int ICMP_TIMEOUT = 2000; // 2 seconds
private static readonly string[] TEST_IPS = new[] { "1.1.1.1", "8.8.8.8" }; // Cloudflare DNS, Google DNS
private const string LAMBDA_URL = "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/";
private const int HTTP_TIMEOUT_MS = 5000; // 5s
private const int ICMP_TIMEOUT_MS = 2000; // 2s
private static bool TryHttpAccess(string ip, out string error)
// IPs that answer on 80 & 443
private static readonly string[] WEB_TEST_IPS =
{ "93.184.216.34", "151.101.1.69" }; // example.com / Fastly
// Public DNS resolvers for DNS + ICMP checks
private static readonly string[] DNS_ICMP_IPS =
{ "1.1.1.1", "8.8.8.8" };
private const string LAMBDA_URL =
"https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/";
// Shared HttpClient (kept for HTTP & Lambda checks)
private static readonly HttpClient http = new HttpClient
{
Timeout = TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS)
};
// ─── Helpers ───────────────────────────────────────────────
private static bool TryHttpAccess(string ip, out string error) =>
TryWebRequest($"http://{ip}", out error);
// **NEW IMPLEMENTATION** plain TCP connect on port443
private static bool TryHttpsAccess(string ip, out string error)
{
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(HTTP_TIMEOUT));
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(HTTP_TIMEOUT) };
using var client = new TcpClient();
var resp = client.GetAsync($"http://{ip}", cts.Token)
.GetAwaiter().GetResult();
// Start async connect and wait up to the timeout
var connectTask = client.ConnectAsync(ip, 443);
bool completed = connectTask.Wait(HTTP_TIMEOUT_MS);
if (resp.IsSuccessStatusCode)
if (!completed)
{
error = "TCP connect timed out";
return false;
}
if (client.Connected)
{
error = null;
return true;
}
error = $"HTTP status {(int)resp.StatusCode}";
error = "TCP connection failed";
return false;
}
catch (Exception ex)
@@ -62,24 +93,16 @@ namespace winPEAS.Info.NetworkInfo
}
}
private static bool TryHttpsAccess(string ip, out string error)
private static bool TryWebRequest(string url, out string error)
{
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(HTTP_TIMEOUT));
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(HTTP_TIMEOUT) };
using var cts =
new CancellationTokenSource(TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS));
http.GetAsync(url, cts.Token).GetAwaiter().GetResult();
var resp = client.GetAsync($"https://{ip}", cts.Token)
.GetAwaiter().GetResult();
if (resp.IsSuccessStatusCode)
{
error = null;
return true;
}
error = $"HTTPS status {(int)resp.StatusCode}";
return false;
error = null; // any HTTP response == connectivity
return true;
}
catch (Exception ex)
{
@@ -92,24 +115,19 @@ namespace winPEAS.Info.NetworkInfo
{
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(HTTP_TIMEOUT));
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(HTTP_TIMEOUT) };
using var cts =
new CancellationTokenSource(TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS));
var req = new HttpRequestMessage(HttpMethod.Get, LAMBDA_URL);
req.Headers.UserAgent.ParseAdd("winpeas");
req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
req.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var resp = client.SendAsync(req, cts.Token)
.GetAwaiter().GetResult();
var resp = http.SendAsync(req, cts.Token).GetAwaiter().GetResult();
if (resp.IsSuccessStatusCode)
{
error = null;
return true;
}
error = $"Lambda status {(int)resp.StatusCode}";
return false;
error = resp.IsSuccessStatusCode ? null :
$"HTTP {(int)resp.StatusCode}";
return error == null;
}
catch (Exception ex)
{
@@ -118,167 +136,132 @@ namespace winPEAS.Info.NetworkInfo
}
}
private static bool TryDnsAccess(string ip, out string error)
{
try
{
using (var udpClient = new UdpClient())
{
// Set a timeout for the connection attempt
udpClient.Client.ReceiveTimeout = HTTP_TIMEOUT;
udpClient.Client.SendTimeout = HTTP_TIMEOUT;
using var udp = new UdpClient();
udp.Client.ReceiveTimeout = HTTP_TIMEOUT_MS;
udp.Client.SendTimeout = HTTP_TIMEOUT_MS;
// Create DNS server endpoint
var dnsServer = new IPEndPoint(IPAddress.Parse(ip), 53);
var server = new IPEndPoint(IPAddress.Parse(ip), 53);
// Create a simple DNS query for google.com (type A record)
byte[] dnsQuery = new byte[] {
0x00, 0x01, // Transaction ID
0x01, 0x00, // Flags (Standard query)
0x00, 0x01, // Questions: 1
0x00, 0x00, // Answer RRs: 0
0x00, 0x00, // Authority RRs: 0
0x00, 0x00, // Additional RRs: 0
// google.com
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0x00, 0x01, // Type: A
0x00, 0x01 // Class: IN
};
// minimal query for google.com Arecord
byte[] q = {
0x00,0x01, 0x01,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x00,0x00,
0x06,0x67,0x6f,0x6f,0x67,0x6c,0x65, 0x03,0x63,0x6f,0x6d, 0x00,
0x00,0x01, 0x00,0x01
};
// Send the DNS query
udpClient.Send(dnsQuery, dnsQuery.Length, dnsServer);
udp.Send(q, q.Length, server);
// Try to receive a response
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] response = udpClient.Receive(ref remoteEP);
IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
byte[] resp = udp.Receive(ref remote);
// If we got a response, the DNS server is reachable
if (response != null && response.Length > 0)
{
error = null;
return true;
}
error = "No response received from DNS server";
return false;
}
}
catch (SocketException ex)
{
error = $"Socket error: {ex.Message}";
return false;
}
catch (Exception ex)
{
error = ex.Message;
return false;
error = resp?.Length > 0 ? null : "No DNS response";
return error == null;
}
catch (SocketException ex) { error = ex.Message; return false; }
catch (Exception ex) { error = ex.Message; return false; }
}
private static bool TryIcmpAccess(string ip, out string error)
{
try
{
using (var ping = new Ping())
{
var reply = ping.Send(ip, ICMP_TIMEOUT);
if (reply?.Status == IPStatus.Success)
{
error = null;
return true;
}
error = $"Ping failed with status: {reply?.Status}";
return false;
}
}
catch (Exception ex)
{
error = ex.Message;
return false;
using var ping = new Ping();
var reply = ping.Send(ip, ICMP_TIMEOUT_MS);
error = reply?.Status == IPStatus.Success
? null
: $"Ping failed: {reply?.Status}";
return error == null;
}
catch (Exception ex) { error = ex.Message; return false; }
}
// ─── Main entry ───────────────────────────────────────────
public static InternetConnectivityInfo CheckConnectivity()
{
var result = new InternetConnectivityInfo();
var info = new InternetConnectivityInfo();
// Test HTTP (port 80) on each IP until success
foreach (var ip in TEST_IPS)
// -------- HTTP / HTTPS --------------------------------
foreach (var ip in WEB_TEST_IPS)
{
if (TryHttpAccess(ip, out string error))
// HTTP
if (!info.HttpAccess)
{
result.HttpAccess = true;
result.SuccessfulHttpIp = ip;
break;
string httpErr;
if (TryHttpAccess(ip, out httpErr))
{
info.HttpAccess = true;
info.SuccessfulHttpIp = ip;
}
else
{
info.HttpError = httpErr;
}
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
// HTTPS (raw TCP 443)
if (!info.HttpsAccess)
{
result.HttpAccess = false;
result.HttpError = error;
string httpsErr;
if (TryHttpsAccess(ip, out httpsErr))
{
info.HttpsAccess = true;
info.SuccessfulHttpsIp = ip;
}
else
{
info.HttpsError = httpsErr;
}
}
if (info.HttpAccess && info.HttpsAccess) break;
}
// Test HTTPS (port 443) on each IP until success
foreach (var ip in TEST_IPS)
// -------- Lambda --------------------------------------
info.LambdaAccess = TryLambdaAccess(out string lambdaErr);
if (!info.LambdaAccess) info.LambdaError = lambdaErr;
// -------- DNS / ICMP ----------------------------------
foreach (var ip in DNS_ICMP_IPS)
{
if (TryHttpsAccess(ip, out string error))
// DNS
if (!info.DnsAccess)
{
result.HttpsAccess = true;
result.SuccessfulHttpsIp = ip;
break;
string dnsErr;
if (TryDnsAccess(ip, out dnsErr))
{
info.DnsAccess = true;
info.SuccessfulDnsIp = ip;
}
else
{
info.DnsError = dnsErr;
}
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
// ICMP
if (!info.IcmpAccess)
{
result.HttpsAccess = false;
result.HttpsError = error;
string pingErr;
if (TryIcmpAccess(ip, out pingErr))
{
info.IcmpAccess = true;
info.SuccessfulIcmpIp = ip;
}
else
{
info.IcmpError = pingErr;
}
}
if (info.DnsAccess && info.IcmpAccess) break;
}
// Test Lambda URL
result.LambdaAccess = TryLambdaAccess(out string lambdaError);
if (!result.LambdaAccess)
{
result.LambdaError = lambdaError;
}
else
{
result.HttpsAccess = true;
}
// Test DNS on each IP until success
foreach (var ip in TEST_IPS)
{
if (TryDnsAccess(ip, out string error))
{
result.DnsAccess = true;
result.SuccessfulDnsIp = ip;
break;
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
{
result.DnsAccess = false;
result.DnsError = error;
}
}
// Test ICMP (ping) on each IP until success
foreach (var ip in TEST_IPS)
{
if (TryIcmpAccess(ip, out string error))
{
result.IcmpAccess = true;
result.SuccessfulIcmpIp = ip;
break;
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
{
result.IcmpAccess = false;
result.IcmpError = error;
}
}
return result;
return info;
}
}
}
}

View File

@@ -195,11 +195,11 @@ namespace winPEAS.Info.ProcessInfo
continue;
List<string> permsFile = PermissionsHelper.GetPermissionsFile(sFilePath, Checks.Checks.CurrentUserSiDs, PermissionType.WRITEABLE_OR_EQUIVALENT);
IdentityReference sid = null;
try
{
System.Security.AccessControl.FileSecurity fs = System.IO.File.GetAccessControl(sFilePath);
IdentityReference sid = fs.GetOwner(typeof(SecurityIdentifier));
string ownerName = sid.Translate(typeof(NTAccount)).ToString();
sid = fs.GetOwner(typeof(SecurityIdentifier));
// If current user already have permissions over that file or the proc belongs to the owner of the file,
// handler not interesting to elevate privs
@@ -207,6 +207,8 @@ namespace winPEAS.Info.ProcessInfo
continue;
to_add["File Path"] = sFilePath;
string ownerName = sid.Translate(typeof(NTAccount)).ToString();
to_add["File Owner"] = ownerName;
}
catch (System.IO.FileNotFoundException)
@@ -218,7 +220,10 @@ namespace winPEAS.Info.ProcessInfo
{
continue;
}
catch (System.Security.Principal.IdentityNotMappedException)
{
to_add["File Owner"] = sid.ToString();
}
}
else if (typeName == "key")