mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-03-12 21:23:13 -07:00
winPEAS: Fix network scanning (arg parsing, race condition, port scanner, auto-mode crash) (#612)
* Fix thread count override and add -z flag to set thread count * Enforce THREADS >= 1 after detection; validate -z range; clarify help text * Strip colours from -z warning; add regression tests for -z getopts/help * Tighten getopts regression test: match 'while getopts' line with regex * Fix WinPEAS network host discovery and port scanner bugs - Fix auto-mode NullReferenceException: change plain 'if' to 'else if' for IPAddressNetmask/IPAddressList branches in NetworkScanner.Scan(), so the auto path no longer falls through and calls AddRange(null) - Fix HostsAlive race condition in NetPinger: replace List<string> with ConcurrentBag<string> so concurrent async ping callbacks don't corrupt the collection - Fix unbound parallelism: cap outer host loop at MaxDegreeOfParallelism=5 and inner port loop at 50; create a PortScanner per host to remove shared-state concerns - Fix port scan output bypassing Beaprint: replace raw Console.WriteLine with Beaprint.GoodPrint so open-port results are colour-highlighted and respect -nocolor - Move network scan into NetworkInfo.PrintInfo(): add PrintNetworkScan() method, wire it into the check list when IsNetworkScan is true, remove the detached scan block from RunChecks(), expose NetworkScanOptions and PortScannerPorts as public, and remove the now-unused using directive * Add compiled binaries (x86/x64/Release), Directory.Build.targets Linux shim, fix Vault enum/struct casing * Fix -network/-ports arg parsing to accept space-separated values * Remove Directory.Build.targets from tracking; add to .gitignore * Dispose Ping per-attempt in NetPinger to prevent handle leaks on large sweeps * Fix TcpClient/WaitHandle leaks in PortScanner: use using block, close wait handle, remove stale AsyncCallback+TcpPortState * Force-select networkinfo check when -network is set with a subset of checks * Remove unused System.Threading.Tasks import from PortScanner * Add tests for space-separated -network/-ports arg normalisation * Remove Thread.Sleep(1) and unused System.Threading import from PortScanner * Replace BeginConnect/WaitOne APM with ConnectAsync+Wait(timeout) in PortScanner * Cap concurrent pings at 50 with SemaphoreSlim in NetPinger to prevent resource exhaustion on large ranges * Isolate per-IP ping exceptions so a single bad target can't abort the sweep; surface errors in debug mode * Observe timed-out ConnectAsync task via ContinueWith to prevent UnobservedTaskException * Broaden ParseOnly reset to cover all arg-parsing-mutable Checks fields to prevent test cross-talk * Add MainPrint/LinkPrint header to PrintNetworkScan; remove misplaced GreatPrint from NetworkScanner.Scan() * Add dedicated 'networkscan' system check to avoid running all NetworkInfo sub-checks when -network is passed with a subset * Delete linpeas_test.sh * Delete winPEAS/winPEASexe/binaries/Release/winPEAS.exe * Delete winPEAS/winPEASexe/binaries/x64/Release/winPEAS.exe * Delete winPEAS/winPEASexe/binaries/x86/Release/winPEAS.exe --------- Co-authored-by: SirBroccoli <carlospolop@gmail.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -29,6 +29,7 @@ linPEAS/builder/linpeas_base_tmp.sh
|
||||
build_lists/regexes.yaml
|
||||
sh2bin
|
||||
sh2bin/*
|
||||
winPEAS/winPEASexe/Directory.Build.targets
|
||||
.dccache
|
||||
./*/.dccache
|
||||
regexes.yaml
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
@@ -14,6 +16,32 @@ namespace winPEAS.Tests
|
||||
return (bool)method.Invoke(null, new object[] { arg });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all public static Checks fields that arg parsing can mutate, then
|
||||
/// invokes Program.Main with the supplied args followed by "--help" so execution
|
||||
/// returns immediately after parsing without running any actual system checks.
|
||||
/// </summary>
|
||||
private static void ParseOnly(params string[] args)
|
||||
{
|
||||
// Reset every field that Checks.Run() can modify during arg parsing.
|
||||
winPEAS.Checks.Checks.IsDomainEnumeration = false;
|
||||
winPEAS.Checks.Checks.IsNoColor = false;
|
||||
winPEAS.Checks.Checks.DontCheckHostname = false;
|
||||
winPEAS.Checks.Checks.Banner = true;
|
||||
winPEAS.Checks.Checks.IsDebug = false;
|
||||
winPEAS.Checks.Checks.IsLinpeas = false;
|
||||
winPEAS.Checks.Checks.IsLolbas = false;
|
||||
winPEAS.Checks.Checks.IsNetworkScan = false;
|
||||
winPEAS.Checks.Checks.SearchProgramFiles = false;
|
||||
winPEAS.Checks.Checks.NetworkScanOptions = string.Empty;
|
||||
winPEAS.Checks.Checks.PortScannerPorts = null;
|
||||
winPEAS.Checks.Checks.LinpeasUrl = "https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh";
|
||||
winPEAS.Checks.Checks.MaxRegexFileSize = 1000000;
|
||||
|
||||
var argsWithHelp = args.Concat(new[] { "--help" }).ToArray();
|
||||
Program.Main(argsWithHelp);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldAcceptValidNetworkTypes()
|
||||
{
|
||||
@@ -32,5 +60,46 @@ namespace winPEAS.Tests
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network=999.999.999.999/24"));
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network=not-an-ip"));
|
||||
}
|
||||
|
||||
// -- Space-separated argument normalisation tests --
|
||||
|
||||
[TestMethod]
|
||||
public void NetworkFlag_SpaceSeparated_Netmask_SetsIsNetworkScan()
|
||||
{
|
||||
ParseOnly("-network", "10.0.0.0/24");
|
||||
Assert.IsTrue(winPEAS.Checks.Checks.IsNetworkScan,
|
||||
"-network 10.0.0.0/24 (space-separated) should set IsNetworkScan");
|
||||
Assert.AreEqual("10.0.0.0/24", winPEAS.Checks.Checks.NetworkScanOptions);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NetworkFlag_SpaceSeparated_Auto_SetsIsNetworkScan()
|
||||
{
|
||||
ParseOnly("-network", "auto");
|
||||
Assert.IsTrue(winPEAS.Checks.Checks.IsNetworkScan,
|
||||
"-network auto (space-separated) should set IsNetworkScan");
|
||||
Assert.AreEqual("auto", winPEAS.Checks.Checks.NetworkScanOptions,
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NetworkFlag_EqualsSeparated_Netmask_SetsIsNetworkScan()
|
||||
{
|
||||
ParseOnly("-network=10.0.0.0/24");
|
||||
Assert.IsTrue(winPEAS.Checks.Checks.IsNetworkScan,
|
||||
"-network=10.0.0.0/24 (equals-separated) should set IsNetworkScan");
|
||||
Assert.AreEqual("10.0.0.0/24", winPEAS.Checks.Checks.NetworkScanOptions);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NetworkAndPortsFlags_SpaceSeparated_BothParsedCorrectly()
|
||||
{
|
||||
ParseOnly("-network", "auto", "-ports", "80,443");
|
||||
Assert.IsTrue(winPEAS.Checks.Checks.IsNetworkScan,
|
||||
"-network auto -ports 80,443 should set IsNetworkScan");
|
||||
var ports = winPEAS.Checks.Checks.PortScannerPorts?.ToList();
|
||||
Assert.IsNotNull(ports, "PortScannerPorts should not be null");
|
||||
CollectionAssert.AreEquivalent(new List<int> { 80, 443 }, ports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ using winPEAS.Helpers.AppLocker;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.Helpers.Search;
|
||||
using winPEAS.Helpers.YamlConfig;
|
||||
using winPEAS.Info.NetworkInfo.NetworkScanner;
|
||||
using winPEAS.Info.UserInfo;
|
||||
|
||||
namespace winPEAS.Checks
|
||||
@@ -27,8 +26,8 @@ namespace winPEAS.Checks
|
||||
public static bool IsNetworkScan = false;
|
||||
public static bool SearchProgramFiles = false;
|
||||
|
||||
private static IEnumerable<int> PortScannerPorts = null;
|
||||
private static string NetworkScanOptions = string.Empty;
|
||||
public static IEnumerable<int> PortScannerPorts = null;
|
||||
public static string NetworkScanOptions = string.Empty;
|
||||
|
||||
// Create Dynamic blacklists
|
||||
public static readonly string CurrentUserName = Environment.UserName;
|
||||
@@ -91,6 +90,7 @@ namespace winPEAS.Checks
|
||||
new SystemCheck("soapclientinfo", new SoapClientInfo()),
|
||||
new SystemCheck("applicationsinfo", new ApplicationsInfo()),
|
||||
new SystemCheck("networkinfo", new NetworkInfo()),
|
||||
new SystemCheck("networkscan", new NetworkScanCheck()),
|
||||
new SystemCheck("activedirectoryinfo", new ActiveDirectoryInfo()),
|
||||
new SystemCheck("cloudinfo", new CloudInfo()),
|
||||
new SystemCheck("windowscreds", new WindowsCreds()),
|
||||
@@ -103,8 +103,18 @@ namespace winPEAS.Checks
|
||||
var systemCheckAllKeys = new HashSet<string>(_systemChecks.Select(i => i.Key));
|
||||
var print_fileanalysis_warn = true;
|
||||
|
||||
foreach (string arg in args)
|
||||
for (int argIdx = 0; argIdx < args.Length; argIdx++)
|
||||
{
|
||||
// Normalise space-separated flags like "-network 10.0.0.0/24" → "-network=10.0.0.0/24"
|
||||
// and "-ports 80,443" → "-ports=80,443" so the rest of the parser only has one case.
|
||||
string arg = args[argIdx];
|
||||
if ((arg.Equals("-network", StringComparison.OrdinalIgnoreCase) ||
|
||||
arg.Equals("-ports", StringComparison.OrdinalIgnoreCase)) &&
|
||||
!arg.Contains('=') &&
|
||||
argIdx + 1 < args.Length)
|
||||
{
|
||||
arg = arg + "=" + args[++argIdx];
|
||||
}
|
||||
if (string.Equals(arg, "--help", StringComparison.CurrentCultureIgnoreCase) ||
|
||||
string.Equals(arg, "help", StringComparison.CurrentCultureIgnoreCase) ||
|
||||
string.Equals(arg, "/h", StringComparison.CurrentCultureIgnoreCase) ||
|
||||
@@ -290,6 +300,13 @@ namespace winPEAS.Checks
|
||||
Beaprint.ColorPrint(" [!] If you want to run the file analysis checks (search sensitive information in files), you need to specify the 'fileanalysis' or 'all' argument. Note that this search might take several minutes. For help, run winpeass.exe --help", Beaprint.YELLOW);
|
||||
}
|
||||
|
||||
// When -network is passed alongside a subset of checks, inject the dedicated
|
||||
// 'networkscan' check so only the scan runs, not all NetworkInfo sub-checks.
|
||||
if (IsNetworkScan && !isAllChecks)
|
||||
{
|
||||
_systemCheckSelectedKeysHashSet.Add("networkscan");
|
||||
}
|
||||
|
||||
if (isAllChecks)
|
||||
{
|
||||
isFileSearchEnabled = true;
|
||||
@@ -315,7 +332,7 @@ namespace winPEAS.Checks
|
||||
|
||||
CheckRunner.Run(() => CreateDynamicLists(isFileSearchEnabled), IsDebug);
|
||||
|
||||
RunChecks(isAllChecks, wait, IsNetworkScan);
|
||||
RunChecks(isAllChecks, wait);
|
||||
|
||||
SearchHelper.CleanLists();
|
||||
|
||||
@@ -387,7 +404,7 @@ namespace winPEAS.Checks
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void RunChecks(bool isAllChecks, bool wait, bool isNetworkScan)
|
||||
private static void RunChecks(bool isAllChecks, bool wait)
|
||||
{
|
||||
for (int i = 0; i < _systemChecks.Count; i++)
|
||||
{
|
||||
@@ -403,12 +420,6 @@ namespace winPEAS.Checks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNetworkScan)
|
||||
{
|
||||
NetworkScanner scanner = new NetworkScanner(NetworkScanOptions, PortScannerPorts);
|
||||
scanner.Scan();
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateDynamicLists(bool isFileSearchEnabled)
|
||||
|
||||
@@ -519,5 +519,21 @@ namespace winPEAS.Checks
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void PrintNetworkScan()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Network Scan");
|
||||
Beaprint.LinkPrint("", "Scanning for alive hosts and open TCP ports (this may take some time)");
|
||||
|
||||
var scanner = new NetworkScanner(Checks.NetworkScanOptions, Checks.PortScannerPorts);
|
||||
scanner.Scan();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
winPEAS/winPEASexe/winPEAS/Checks/NetworkScanCheck.cs
Normal file
23
winPEAS/winPEASexe/winPEAS/Checks/NetworkScanCheck.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Checks
|
||||
{
|
||||
/// <summary>
|
||||
/// Dedicated system check for the -network scan.
|
||||
/// Registered as "networkscan" so that passing -network alongside a subset of
|
||||
/// checks (e.g. "systeminfo -network=auto") runs only the scan and not the full
|
||||
/// NetworkInfo sub-checks (shares, firewall rules, DNS cache, etc.).
|
||||
/// When all checks run (no subset selected), this check silently no-ops unless
|
||||
/// -network was explicitly passed.
|
||||
/// </summary>
|
||||
internal class NetworkScanCheck : ISystemCheck
|
||||
{
|
||||
public void PrintInfo(bool isDebug)
|
||||
{
|
||||
if (!Checks.IsNetworkScan)
|
||||
return;
|
||||
|
||||
CheckRunner.Run(new NetworkInfo().PrintNetworkScan, isDebug);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,7 @@ namespace winPEAS.Helpers
|
||||
Console.WriteLine(LCYAN + " servicesinfo" + GRAY + " Search services information" + NOCOLOR);
|
||||
Console.WriteLine(LCYAN + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR);
|
||||
Console.WriteLine(LCYAN + " networkinfo" + GRAY + " Search network information" + NOCOLOR);
|
||||
Console.WriteLine(LCYAN + " networkscan" + GRAY + " Run only the -network scan (no other NetworkInfo sub-checks)" + NOCOLOR);
|
||||
Console.WriteLine(LCYAN + " activedirectoryinfo" + GRAY + " Quick AD checks (gMSA readable passwords, AD CS template rights)" + NOCOLOR);
|
||||
Console.WriteLine(LCYAN + " cloudinfo" + GRAY + " Enumerate cloud information" + NOCOLOR);
|
||||
Console.WriteLine(LCYAN + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using winPEAS.Checks;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
{
|
||||
internal class NetPinger
|
||||
{
|
||||
private int PingTimeout = 1000;
|
||||
private const int MaxConcurrentPings = 50;
|
||||
|
||||
public List<string> HostsAlive = new List<string>();
|
||||
public ConcurrentBag<string> HostsAlive = new ConcurrentBag<string>();
|
||||
|
||||
private List<string> ipRange = new List<string>();
|
||||
|
||||
@@ -30,26 +35,50 @@ namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
|
||||
public async Task RunPingSweepAsync()
|
||||
{
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var ip in ipRange)
|
||||
using (var semaphore = new SemaphoreSlim(MaxConcurrentPings))
|
||||
{
|
||||
Ping p = new Ping();
|
||||
var task = PingAndUpdateStatus(p, ip);
|
||||
tasks.Add(task);
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var ip in ipRange)
|
||||
{
|
||||
await semaphore.WaitAsync();
|
||||
tasks.Add(PingAndUpdateStatus(ip, semaphore));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private async Task PingAndUpdateStatus(Ping ping, string ip)
|
||||
private async Task PingAndUpdateStatus(string ip, SemaphoreSlim semaphore)
|
||||
{
|
||||
var reply = await ping.SendPingAsync(ip, PingTimeout);
|
||||
|
||||
if (reply.Status == IPStatus.Success)
|
||||
try
|
||||
{
|
||||
HostsAlive.Add(ip);
|
||||
await Console.Out.WriteLineAsync(ip);
|
||||
using (var ping = new Ping())
|
||||
{
|
||||
var reply = await ping.SendPingAsync(ip, PingTimeout);
|
||||
|
||||
if (reply.Status == IPStatus.Success)
|
||||
{
|
||||
HostsAlive.Add(ip);
|
||||
Beaprint.GoodPrint($" [+] Host alive: {ip}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (PingException)
|
||||
{
|
||||
// ICMP blocked, invalid address, or host unreachable — treat as down.
|
||||
}
|
||||
catch (Exception ex) when (Checks.IsDebug)
|
||||
{
|
||||
Beaprint.PrintException($" [!] Ping error for {ip}: {ex.Message}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Isolate per-IP failures so a single bad target can't abort the sweep.
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.GreatPrint("Scanning network (it might take some time)...");
|
||||
|
||||
List<string> aliveHosts = new List<string>();
|
||||
NetPinger netPinger = new NetPinger();
|
||||
@@ -62,25 +61,26 @@ namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
// this is the "auto" mode
|
||||
foreach (var ipAddressAndNetmask in NetworkUtils.GetInternalInterfaces())
|
||||
{
|
||||
netPinger.AddRange(ipAddressAndNetmask.Item1, ipAddressAndNetmask.Item2);
|
||||
netPinger.AddRange(ipAddressAndNetmask.Item1, ipAddressAndNetmask.Item2);
|
||||
}
|
||||
}
|
||||
if (scanMode == ScanMode.IPAddressNetmask)
|
||||
else if (scanMode == ScanMode.IPAddressNetmask)
|
||||
{
|
||||
netPinger.AddRange(baseAddress, netmask);
|
||||
netPinger.AddRange(baseAddress, netmask);
|
||||
}
|
||||
else if (scanMode == ScanMode.IPAddressList)
|
||||
{
|
||||
netPinger.AddRange(ipAddressList);
|
||||
netPinger.AddRange(ipAddressList);
|
||||
}
|
||||
|
||||
var task = netPinger.RunPingSweepAsync();
|
||||
task.Wait();
|
||||
aliveHosts.AddRange(netPinger.HostsAlive);
|
||||
|
||||
PortScanner ps = new PortScanner(this.ports);
|
||||
Parallel.ForEach(aliveHosts, host =>
|
||||
var outerOptions = new ParallelOptions { MaxDegreeOfParallelism = 5 };
|
||||
Parallel.ForEach(aliveHosts, outerOptions, host =>
|
||||
{
|
||||
var ps = new PortScanner(this.ports);
|
||||
ps.Start(host);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
{
|
||||
@@ -49,12 +49,6 @@ namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
|
||||
#endregion
|
||||
|
||||
private struct TcpPortState
|
||||
{
|
||||
public TcpClient MainClient { get; set; }
|
||||
public bool IsTcpPortOpen { get; set; }
|
||||
}
|
||||
|
||||
IEnumerable<int> portsToScan = nmapTop1000TCPPorts;
|
||||
|
||||
public PortScanner(IEnumerable<int> ports)
|
||||
@@ -67,7 +61,8 @@ namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
|
||||
public void Start(string host)
|
||||
{
|
||||
Parallel.ForEach(portsToScan, port =>
|
||||
var innerOptions = new ParallelOptions { MaxDegreeOfParallelism = 50 };
|
||||
Parallel.ForEach(portsToScan, innerOptions, port =>
|
||||
{
|
||||
RunScanTcp(host, port);
|
||||
});
|
||||
@@ -75,48 +70,32 @@ namespace winPEAS.Info.NetworkInfo.NetworkScanner
|
||||
|
||||
public void RunScanTcp(string host, int port)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
|
||||
var newClient = new TcpClient();
|
||||
|
||||
var state = new TcpPortState
|
||||
using (var client = new TcpClient())
|
||||
{
|
||||
MainClient = newClient,
|
||||
IsTcpPortOpen = true
|
||||
};
|
||||
try
|
||||
{
|
||||
var connectTask = client.ConnectAsync(host, port);
|
||||
bool completed = connectTask.Wait(TcpTimeout);
|
||||
|
||||
IAsyncResult ar = newClient.BeginConnect(host, port, AsyncCallback, state);
|
||||
state.IsTcpPortOpen = ar.AsyncWaitHandle.WaitOne(TcpTimeout, false);
|
||||
if (!completed || !client.Connected)
|
||||
{
|
||||
// Timed out: the connect task may still be running and could fault
|
||||
// later. Attach a continuation that observes (and silences) any
|
||||
// subsequent exception so it doesn't surface as an
|
||||
// UnobservedTaskException when the task is GC'd.
|
||||
connectTask.ContinueWith(
|
||||
t => { var _ = t.Exception; },
|
||||
TaskContinuationOptions.OnlyOnFaulted);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.IsTcpPortOpen == false || newClient.Connected == false)
|
||||
{
|
||||
return;
|
||||
Beaprint.GoodPrint($" [+] Open TCP port at: {host}:{port}");
|
||||
}
|
||||
catch (AggregateException)
|
||||
{
|
||||
// Connection refused, host unreachable, etc. — port is closed.
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("[+] Open TCP port at: {0}:{1}", host, port);
|
||||
}
|
||||
|
||||
|
||||
void AsyncCallback(IAsyncResult asyncResult)
|
||||
{
|
||||
var state = (TcpPortState)asyncResult.AsyncState;
|
||||
TcpClient client = state.MainClient;
|
||||
|
||||
try
|
||||
{
|
||||
client.EndConnect(asyncResult);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.Connected && state.IsTcpPortOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user