From 0b09e749bcf0bfe333e577d4ad65f37706f19767 Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Sat, 8 Jan 2022 19:33:35 +0100 Subject: [PATCH] - Add async packet processing --- FraudCapturer/DomainHelper.cs | 15 ++++-- FraudCapturer/FirewallHelper.cs | 81 ++++++++++++++++++--------------- FraudCapturer/IpHelper.cs | 13 +++++- FraudCapturer/Program.cs | 29 +++++++----- 4 files changed, 86 insertions(+), 52 deletions(-) diff --git a/FraudCapturer/DomainHelper.cs b/FraudCapturer/DomainHelper.cs index 26e8ec7..53ed20d 100644 --- a/FraudCapturer/DomainHelper.cs +++ b/FraudCapturer/DomainHelper.cs @@ -22,7 +22,7 @@ internal class DomainHelper return domains.Distinct().ToArray(); } - public static DomainInfo? GetDomainReputation(string domain) + public static async Task GetDomainReputation(string domain) { try { @@ -41,10 +41,19 @@ internal class DomainHelper }; HttpContent httpContent = new StringContent(JsonSerializer.Serialize(reqestBody), Encoding.UTF8, "application/json"); + HttpResponseMessage responseMessage; - HttpResponseMessage responseMessage = httpClient.PostAsync("https://anti-fish.bitflow.dev/check", httpContent).GetAwaiter().GetResult(); ; + try + { + responseMessage = await httpClient.PostAsync("https://anti-fish.bitflow.dev/check", httpContent); + } + catch (HttpRequestException ex) + { + Console.WriteLine($"error: {ex.Message}"); + return null; + } - string resultString = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); ; + string resultString = await responseMessage.Content.ReadAsStringAsync(); AntiFishResultBody? resultBody = JsonSerializer.Deserialize(resultString); AntiFishResult? result = resultBody?.Matches?.FirstOrDefault(m => m.Domain == domain); diff --git a/FraudCapturer/FirewallHelper.cs b/FraudCapturer/FirewallHelper.cs index b4e678e..e1bb141 100644 --- a/FraudCapturer/FirewallHelper.cs +++ b/FraudCapturer/FirewallHelper.cs @@ -11,21 +11,24 @@ internal class FirewallHelper throw new ArgumentNullException(nameof(ipAddress)); } - AddRuleIfDoesnotExist(ipAddress); - - File.AppendAllText(Program.IpStorePath, $"{Environment.NewLine}{ipAddress}"); - - string[] iPs = File.ReadAllLines(Program.IpStorePath); - - System.Diagnostics.Process process = new System.Diagnostics.Process(); - System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo + lock (Program.IpStorePath) { - WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, - FileName = "cmd.exe", - Arguments = $"/C netsh advfirewall firewall set rule name=\"{Program.AppName} IP Block\" new remoteIp={string.Join(',', iPs)}" - }; - process.StartInfo = startInfo; - _ = process.Start(); + AddRuleIfDoesnotExist(ipAddress); + + File.AppendAllText(Program.IpStorePath, $"{Environment.NewLine}{ipAddress}"); + + string[] iPs = File.ReadAllLines(Program.IpStorePath); + + System.Diagnostics.Process process = new System.Diagnostics.Process(); + System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo + { + WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, + FileName = "cmd.exe", + Arguments = $"/C netsh advfirewall firewall set rule name=\"{Program.AppName} IP Block\" new remoteIp={string.Join(',', iPs)}" + }; + process.StartInfo = startInfo; + _ = process.Start(); + } } public static void UnblockIp(IPAddress? ipAddress) @@ -35,33 +38,39 @@ internal class FirewallHelper throw new ArgumentNullException(nameof(ipAddress)); } - List iPs = File.ReadAllLines(Program.IpStorePath).ToList(); - iPs.Remove(ipAddress.ToString()); - - File.WriteAllLines(Program.IpStorePath, iPs); - - System.Diagnostics.Process process = new System.Diagnostics.Process(); - System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo + lock (Program.IpStorePath) { - WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, - FileName = "cmd.exe", - Arguments = $"/C netsh advfirewall firewall set rule name=\"{Program.AppName} IP Block\" new remoteIp={string.Join(',', iPs.ToArray())}" - }; - process.StartInfo = startInfo; - _ = process.Start(); + List iPs = File.ReadAllLines(Program.IpStorePath).ToList(); + iPs.Remove(ipAddress.ToString()); + + File.WriteAllLines(Program.IpStorePath, iPs); + + System.Diagnostics.Process process = new System.Diagnostics.Process(); + System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo + { + WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, + FileName = "cmd.exe", + Arguments = $"/C netsh advfirewall firewall set rule name=\"{Program.AppName} IP Block\" new remoteIp={string.Join(',', iPs.ToArray())}" + }; + process.StartInfo = startInfo; + _ = process.Start(); + } } public static void AddRuleIfDoesnotExist(IPAddress ipAddress) { - System.Diagnostics.Process process = new System.Diagnostics.Process(); - System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo + lock (Program.IpStorePath) { - WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, - FileName = "cmd.exe", - Arguments = $"/C netsh advfirewall firewall show rule name=\"{Program.AppName} IP Block\" >nul || netsh advfirewall firewall add rule name=\"{Program.AppName} IP Block\" dir=in interface=any action=block remoteIp={ipAddress} && netsh advfirewall firewall add rule name=\"{Program.AppName} IP Block\" dir=out interface=any action=block remoteIp={ipAddress}" - }; - process.StartInfo = startInfo; - _ = process.Start(); - process.WaitForExit(); + System.Diagnostics.Process process = new System.Diagnostics.Process(); + System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo + { + WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, + FileName = "cmd.exe", + Arguments = $"/C netsh advfirewall firewall show rule name=\"{Program.AppName} IP Block\" >nul || netsh advfirewall firewall add rule name=\"{Program.AppName} IP Block\" dir=in interface=any action=block remoteIp={ipAddress} && netsh advfirewall firewall add rule name=\"{Program.AppName} IP Block\" dir=out interface=any action=block remoteIp={ipAddress}" + }; + process.StartInfo = startInfo; + _ = process.Start(); + process.WaitForExit(); + } } } \ No newline at end of file diff --git a/FraudCapturer/IpHelper.cs b/FraudCapturer/IpHelper.cs index 5a9b04c..2fb7915 100644 --- a/FraudCapturer/IpHelper.cs +++ b/FraudCapturer/IpHelper.cs @@ -7,11 +7,20 @@ internal class IpHelper { public static string? ProxycheckApiKey { get; set; } - public static IpInfo? GetIpReputation(IPAddress ipAddress) + public static async Task GetIpReputation(IPAddress ipAddress) { HttpClient httpClient = new HttpClient(); + string rawResponseData; - string rawResponseData = httpClient.GetStringAsync($"http://proxycheck.io/v2/{ipAddress}?key={ProxycheckApiKey}&risk=2&vpn=1&asn=1&tag={Program.AppName}({Environment.MachineName})").GetAwaiter().GetResult(); + try + { + rawResponseData = await httpClient.GetStringAsync($"http://proxycheck.io/v2/{ipAddress}?key={ProxycheckApiKey}&risk=2&vpn=1&asn=1&tag={Program.AppName}({Environment.MachineName})"); + } + catch (HttpRequestException ex) + { + Console.WriteLine($"error: {ex.Message}"); + return null; + } JsonDocument responseData = JsonDocument.Parse(rawResponseData); diff --git a/FraudCapturer/Program.cs b/FraudCapturer/Program.cs index 4f471cb..a266179 100644 --- a/FraudCapturer/Program.cs +++ b/FraudCapturer/Program.cs @@ -3,6 +3,7 @@ using PacketDotNet; using SharpPcap; +using System.Collections.Concurrent; using System.Net; namespace FraudCapturer; @@ -19,8 +20,8 @@ public class Program private static DateTime lastCacheClear; private static string lastDomain = string.Empty; - private static readonly List capturedIpsCache = new(); - private static readonly Dictionary capturedDomainsCache = new(); + private static readonly ConcurrentBag capturedIpsCache = new(); + private static readonly ConcurrentDictionary capturedDomainsCache = new(); /// /// The main entry point for the application. @@ -101,6 +102,11 @@ public class Program private static void Device_OnPacketArrival(object sender, PacketCapture e) { RawCapture rawPacket = e.GetPacket(); + ProcessRawPacket(rawPacket); + } + + private static async void ProcessRawPacket(RawCapture rawPacket) + { Packet packet = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data); if (packet is EthernetPacket) { @@ -137,27 +143,27 @@ public class Program } //Check if a DNS packet contains a "dangerous" domain. - CheckDns(packet, remoteIpAddress, direction); + await CheckDns(packet, remoteIpAddress, direction); if (capturedIpsCache.Contains(remoteIpAddress.ToString())) { return; } - TimeSpan timeRemainingUntilCacheReset = new TimeSpan(0, 10, 0) - (DateTime.Now - lastCacheClear); - Console.WriteLine($"Next cache reset in {timeRemainingUntilCacheReset.Minutes} minute(s) and {timeRemainingUntilCacheReset.Seconds} second(s)"); - capturedIpsCache.Add(remoteIpAddress.ToString()); //Check if ip address is "dangerous" or blocked - CheckIpAddress(remoteIpAddress, direction); + await CheckIpAddress(remoteIpAddress, direction); + + TimeSpan timeRemainingUntilCacheReset = new TimeSpan(0, 10, 0) - (DateTime.Now - lastCacheClear); + Console.WriteLine($"Next cache reset in {timeRemainingUntilCacheReset.Minutes} minute(s) and {timeRemainingUntilCacheReset.Seconds} second(s)"); } } } - private static void CheckIpAddress(IPAddress remoteIpAddress, string direction) + private static async Task CheckIpAddress(IPAddress remoteIpAddress, string direction) { - IpInfo? ipInfo = IpHelper.GetIpReputation(remoteIpAddress); + IpInfo? ipInfo = await IpHelper.GetIpReputation(remoteIpAddress); if (IpHelper.IsInternalIpAddress(remoteIpAddress.ToString())) { @@ -200,7 +206,7 @@ public class Program Console.ResetColor(); } - private static void CheckDns(Packet packet, IPAddress remoteIpAddress, string direction) + private static async Task CheckDns(Packet packet, IPAddress remoteIpAddress, string direction) { TransportPacket transportPacket = packet.Extract(); transportPacket ??= packet.Extract(); @@ -219,7 +225,8 @@ public class Program } else { - domainInfo = DomainHelper.GetDomainReputation(domain); + domainInfo = await DomainHelper.GetDomainReputation(domain); + _ = capturedDomainsCache.TryAdd(domain, domainInfo); } if (domainInfo is null)