This repository has been archived by the owner on Dec 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from druffko/build-poc
Build poc
- Loading branch information
Showing
11 changed files
with
524 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<Application xmlns="https://github.com/avaloniaui" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
x:Class="kaelus.App" | ||
RequestedThemeVariant="Default"> | ||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. --> | ||
|
||
<Application.Styles> | ||
<FluentTheme /> | ||
</Application.Styles> | ||
</Application> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using Avalonia; | ||
using Avalonia.Controls.ApplicationLifetimes; | ||
using Avalonia.Markup.Xaml; | ||
|
||
namespace kaelus | ||
{ | ||
public partial class App : Application | ||
{ | ||
public override void Initialize() | ||
{ | ||
AvaloniaXamlLoader.Load(this); | ||
} | ||
|
||
public override void OnFrameworkInitializationCompleted() | ||
{ | ||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) | ||
{ | ||
desktop.MainWindow = new MainWindow(); | ||
} | ||
|
||
base.OnFrameworkInitializationCompleted(); | ||
} | ||
} | ||
} |
Binary file not shown.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
using HtmlAgilityPack; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
using System.Threading.Tasks; | ||
using System.Xml; | ||
|
||
namespace kaelus | ||
{ | ||
internal class Engine | ||
{ | ||
#region statics | ||
|
||
internal static HashSet<string> foundEmails = new HashSet<string>(); | ||
|
||
internal static string finishedResults = ""; | ||
|
||
#endregion | ||
|
||
#region static methods | ||
|
||
internal static void ExtractSourceCode(string url) | ||
{ | ||
|
||
bool isUrl = IsUrl(url); | ||
|
||
if (isUrl) | ||
{ | ||
|
||
} | ||
else | ||
{ | ||
url = "https://" + url; | ||
} | ||
|
||
// Scan the main index page and get all links on it | ||
ScanLinks(url); | ||
|
||
// Display the collected emails at the end | ||
DisplayCollectedEmails(); | ||
} | ||
|
||
public static string kaelusScan(string url) | ||
{ | ||
bool isUrl = IsUrl(url); | ||
|
||
if (isUrl) | ||
{ | ||
|
||
} | ||
else | ||
{ | ||
url = "https://" + url; | ||
} | ||
|
||
// Scan the main index page and get all links on it | ||
ScanLinks(url); | ||
|
||
// Display the collected emails at the end | ||
DisplayCollectedEmails(); | ||
return finishedResults; | ||
} | ||
|
||
internal static void ScanLinks(String url) | ||
{ | ||
List<string> links = new List<string>(); | ||
|
||
// Fetch page source | ||
string pageContent = FetchPageContent(url); | ||
|
||
if (string.IsNullOrEmpty(pageContent)) | ||
{ | ||
Console.WriteLine("No content found on the page."); | ||
return; | ||
} | ||
|
||
// Use HtmlAgilityPack to parse the HTML and find all links | ||
HtmlDocument doc = new HtmlDocument(); | ||
doc.LoadHtml(pageContent); | ||
|
||
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]")) | ||
{ | ||
string href = link.GetAttributeValue("href", string.Empty); | ||
|
||
// If it's a relative link, convert it to an absolute URL | ||
Uri baseUri = new Uri(url); | ||
Uri fullUri = new Uri(baseUri, href); | ||
|
||
if (fullUri.Host == baseUri.Host) // Ensure it's the same domain | ||
{ | ||
links.Add(fullUri.ToString()); | ||
} | ||
} | ||
|
||
// Scan each link for email addresses | ||
foreach (string link in links) | ||
{ | ||
//Console.WriteLine(kaleidolib.lib.Formatting.dim($"Scanning {link} for email addresses...")); | ||
string content = FetchPageContent(link); | ||
if (!string.IsNullOrEmpty(content)) | ||
{ | ||
GetMails(content); | ||
} | ||
} | ||
} | ||
|
||
// Method to fetch the page content | ||
internal static string FetchPageContent(string url) | ||
{ | ||
try | ||
{ | ||
using (HttpClient client = new()) | ||
{ | ||
HttpResponseMessage response = client.GetAsync(url).Result; | ||
if (response.IsSuccessStatusCode) | ||
{ | ||
return response.Content.ReadAsStringAsync().Result; | ||
} | ||
else | ||
{ | ||
Console.WriteLine($"Failed to fetch {url}"); | ||
} | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"Error fetching page content: {ex.Message}"); | ||
} | ||
return string.Empty; | ||
} | ||
|
||
// Method to collect emails found on a page | ||
internal static void GetMails(String sourceCode) | ||
{ | ||
string emailPattern = @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"; | ||
|
||
// Use Regex.Matches to find all occurrences of email addresses in the input string | ||
MatchCollection matches = Regex.Matches(sourceCode, emailPattern, RegexOptions.IgnoreCase); | ||
|
||
if (matches.Count > 0) | ||
{ | ||
foreach (Match match in matches) | ||
{ | ||
// Add to the HashSet to ensure uniqueness | ||
foundEmails.Add(match.Value); | ||
} | ||
} | ||
} | ||
|
||
// Display collected emails and filter duplicates | ||
internal static void DisplayCollectedEmails() | ||
{ | ||
if (foundEmails.Count > 0) | ||
{ | ||
//Console.WriteLine(Color.green("Good news! I found the following unique email addresses:")); | ||
foreach (var email in foundEmails) | ||
{ | ||
Console.WriteLine(email); | ||
finishedResults = finishedResults + email + "\n"; | ||
} | ||
} | ||
else | ||
{ | ||
//Console.WriteLine(Color.red("No email addresses found.")); | ||
finishedResults = "No email addresses found"; | ||
} | ||
} | ||
|
||
static bool IsUrl(string input) | ||
{ | ||
return Uri.TryCreate(input, UriKind.Absolute, out Uri result) && | ||
(result.Scheme == Uri.UriSchemeHttp || result.Scheme == Uri.UriSchemeHttps); | ||
} | ||
|
||
public static String GetTimestamp(DateTime value) | ||
{ | ||
return value.ToString("yyyyMMddHHmmss"); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<Window xmlns="https://github.com/avaloniaui" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="250" | ||
Width="500" Height="250" | ||
x:Class="kaelus.MainWindow" | ||
CanResize="False" | ||
WindowStartupLocation="CenterScreen" | ||
Title="KAELUS - Ultimate Email Extractor."> | ||
|
||
<Grid Margin="10,10,10,10"> | ||
<Grid.RowDefinitions> | ||
<RowDefinition Height="auto"/> | ||
<RowDefinition Height="auto"/> | ||
<RowDefinition Height="*"/> | ||
<RowDefinition Height="auto"/> | ||
<RowDefinition Height="auto"/> | ||
</Grid.RowDefinitions> | ||
<Grid.ColumnDefinitions> | ||
<ColumnDefinition Width="*"/> | ||
<ColumnDefinition Width="*"/> | ||
<ColumnDefinition Width="*"/> | ||
</Grid.ColumnDefinitions> | ||
|
||
<Label Grid.Row="0" Grid.Column="0">Domain to scan</Label> | ||
<TextBox x:Name="URLBox" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,20" Text=""/> | ||
<TextBox x:Name="ResultBox" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="True" Text=""/> | ||
<ProgressBar x:Name="ScanProgress" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" Margin="0 10" Minimum="0" Maximum="100" Value="0" ShowProgressText="True" IsVisible="False"/> | ||
<Button Click="ShowHelp" Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left" Margin="0,20,0,0"> Help</Button> | ||
<Button Click="StartScan" Grid.Row="4" Grid.Column="2" HorizontalAlignment="Right" Margin="0,20,0,0"> Start</Button> | ||
</Grid> | ||
</Window> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
using Avalonia.Controls; | ||
using Avalonia.Interactivity; | ||
using MsBox.Avalonia; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace kaelus | ||
{ | ||
public partial class MainWindow : Window | ||
{ | ||
|
||
public string resultBoxText; | ||
|
||
public MainWindow() | ||
{ | ||
InitializeComponent(); | ||
} | ||
public async void StartScan(object sender, RoutedEventArgs args) | ||
{ | ||
string url = URLBox.Text; | ||
|
||
// Create a CancellationTokenSource to manage the cancellation | ||
var cancellationTokenSource = new CancellationTokenSource(); | ||
|
||
// Run both tasks concurrently | ||
var progressTask = makeProgress(cancellationTokenSource.Token); | ||
var resultTask = RunKaelusScanAsync(url); | ||
|
||
// When the resultTask completes, cancel the progressTask | ||
await resultTask; | ||
cancellationTokenSource.Cancel(); | ||
|
||
// Await progressTask to ensure proper cleanup | ||
try | ||
{ | ||
await progressTask; | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
ScanProgress.IsVisible = false; | ||
} | ||
} | ||
|
||
public void ShowHelp(object sender, RoutedEventArgs args) | ||
{ | ||
var helpBox = MessageBoxManager.GetMessageBoxStandard("KAELUS Help", "Just enter the desired URL and click Start. KAELUS will do the rest", MsBox.Avalonia.Enums.ButtonEnum.Ok); | ||
var result = helpBox.ShowAsPopupAsync(this); | ||
} | ||
|
||
public async Task makeProgress(CancellationToken cancellationToken) | ||
{ | ||
// Fake Progress bar (to indicate work) | ||
ScanProgress.Value = 0; | ||
ScanProgress.IsVisible = true; | ||
ResultBox.Text = "Scanning for email addresses..."; | ||
|
||
while (ScanProgress.Value < ScanProgress.Maximum) | ||
{ | ||
if (cancellationToken.IsCancellationRequested) | ||
{ | ||
break; | ||
} | ||
|
||
await Task.Delay(2000, cancellationToken); | ||
ScanProgress.Value = Math.Min(ScanProgress.Value + 1, ScanProgress.Maximum); | ||
} | ||
|
||
} | ||
|
||
private async Task RunKaelusScanAsync(string url) | ||
{ | ||
string result = await Task.Run(() => Engine.kaelusScan(url)); | ||
|
||
ResultBox.Text = result; | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Avalonia; | ||
using System; | ||
|
||
namespace kaelus | ||
{ | ||
internal class Program | ||
{ | ||
// Initialization code. Don't use any Avalonia, third-party APIs or any | ||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized | ||
// yet and stuff might break. | ||
[STAThread] | ||
public static void Main(string[] args) => BuildAvaloniaApp() | ||
.StartWithClassicDesktopLifetime(args); | ||
|
||
// Avalonia configuration, don't remove; also used by visual designer. | ||
public static AppBuilder BuildAvaloniaApp() | ||
=> AppBuilder.Configure<App>() | ||
.UsePlatformDetect() | ||
.WithInterFont() | ||
.LogToTrace(); | ||
} | ||
} |
Oops, something went wrong.