Created
February 17, 2025 15:15
-
-
Save AldeRoberge/65214928413d8402714977fc2ef8796b to your computer and use it in GitHub Desktop.
Scan all open ports in local LAN subnet, gets their title
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Concurrent; | |
using System.Text.RegularExpressions; | |
namespace ADG.Playground._2; | |
internal static class Program | |
{ | |
private static readonly HttpClient Client = new() { Timeout = TimeSpan.FromMilliseconds(500) }; | |
private static readonly ConcurrentQueue<string> Results = new(); | |
private static readonly SemaphoreSlim Semaphore = new(50); // Limits concurrent requests | |
private const string Subnet = "10.42."; // Subnet for 10.x.x.x range | |
private const int Start = 0; // Start from 0 (10.0.0.0) | |
private const int End = 255; // End at 255 (10.255.255.255) | |
private const int TimeoutMs = 500; | |
private static async Task Main() | |
{ | |
using var cts = new CancellationTokenSource(); | |
Console.CancelKeyPress += (_, e) => | |
{ | |
e.Cancel = true; | |
Console.WriteLine("\nScan cancelled. Saving results..."); | |
cts.Cancel(); | |
}; | |
Client.Timeout = TimeSpan.FromMilliseconds(TimeoutMs); | |
var tasks = new List<Task>(); | |
// Scan all the possible IPs within the 10.x.x.x range | |
for (int i = 0; i < 256; i++) // First octet (0-255) | |
{ | |
for (int j = 0; j < 256; j++) // Second octet (0-255) | |
{ | |
var ip = $"{Subnet}{i}.{j}"; | |
tasks.Add(ScanAsync(ip, cts.Token)); | |
} | |
} | |
await Task.WhenAll(tasks); | |
await File.WriteAllLinesAsync("scan_results.txt", Results, cts.Token); | |
Console.WriteLine("Scan completed. Results saved to scan_results.txt"); | |
} | |
private static async Task ScanAsync(string ip, CancellationToken token) | |
{ | |
await Semaphore.WaitAsync(token); | |
try | |
{ | |
var url = $"http://{ip}/"; | |
var response = await Client.GetAsync(url, token); | |
var content = await response.Content.ReadAsStringAsync(token); | |
var title = ExtractTitle(content); | |
var result = $"{url} - {response.StatusCode} - {title}"; | |
Results.Enqueue(result); | |
Console.WriteLine(result); | |
} | |
catch (HttpRequestException) | |
{ | |
Console.WriteLine($"http://{ip}/ - No Response"); | |
} | |
catch (TaskCanceledException) | |
{ | |
Console.WriteLine($"http://{ip}/ - Timed Out"); | |
} | |
finally | |
{ | |
Semaphore.Release(); | |
} | |
} | |
private static string ExtractTitle(string html) | |
{ | |
var match = Regex.Match(html, @"<title>\s*(.+?)\s*</title>", RegexOptions.IgnoreCase); | |
return match.Success | |
? match.Groups[1].Value | |
: "No Title"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment