mirror of
https://github.com/openbullet/openbullet.git
synced 2023-10-21 07:33:42 -05:00
279 lines
11 KiB
C#
279 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using CommandLine;
|
|
using CommandLine.Text;
|
|
using Extreme.Net;
|
|
using RuriLib;
|
|
using RuriLib.Models;
|
|
using RuriLib.Runner;
|
|
using RuriLib.ViewModels;
|
|
using Console = Colorful.Console;
|
|
|
|
namespace OpenBulletCLI
|
|
{
|
|
/*
|
|
* THIS IS A POC (Proof Of Concept) IMPLEMENTATION OF RuriLib IN CLI (Command Line Interface).
|
|
* The functionalities supported here don't even come close to the ones of the WPF GUI implementation.
|
|
* Feel free to contribute to the versatility of this project by adding the missing functionalities.
|
|
*
|
|
* */
|
|
|
|
|
|
class Program
|
|
{
|
|
private static string envFile = @"Settings/Environment.ini";
|
|
private static string settFile = @"Settings/RLSettings.json";
|
|
private static string outFile = "";
|
|
|
|
public static EnvironmentSettings Env { get; set; }
|
|
public static RLSettingsViewModel RLSettings { get; set; }
|
|
private static Random random = new Random();
|
|
public static RunnerViewModel Runner { get; set; }
|
|
public static bool Verbose { get; set; } = false;
|
|
public static string ProxyFile { get; set; }
|
|
public static ProxyType ProxyType { get; set; }
|
|
|
|
class Options
|
|
{
|
|
[Option('c', "config", Required = true, HelpText = "Configuration file to be processed.")]
|
|
public string ConfigFile { get; set; }
|
|
|
|
[Option('w', "wordlist", Required = true, HelpText = "Wordlist file to be processed.")]
|
|
public string WordlistFile { get; set; }
|
|
|
|
[Option('o', "output", Default = "", HelpText = "Output file for the hits.")]
|
|
public string OutputFile { get; set; }
|
|
|
|
[Option("wltype", Required = true, HelpText = "Type of the wordlist loaded (see Environment.ini for all allowed types).")]
|
|
public string WordlistType { get; set; }
|
|
|
|
[Option("useproxies", HelpText = "Enable / Disable the usage of proxies (uses config default if not set).")]
|
|
public bool? UseProxies { get; set; }
|
|
|
|
[Option('p', "proxies", Default = null, HelpText = "Proxy file to be processed.")]
|
|
public string ProxyFile { get; set; }
|
|
|
|
[Option("ptype", Default = ProxyType.Http, HelpText = "Type of proxies loaded (Http, Socks4, Socks4a, Socks5).")]
|
|
public ProxyType ProxyType { get; set; }
|
|
|
|
[Option('v', "verbose", Default = false, HelpText = "Prints all bots behaviour.")]
|
|
public bool Verbose { get; set; }
|
|
|
|
[Option('s', "skip", Default = 1, HelpText = "Number of lines to skip in the Wordlist.")]
|
|
public int Skip { get; set; }
|
|
|
|
[Option('b', "bots", Default = 0, HelpText = "Number of concurrent bots working. If not specified, the config default will be used.")]
|
|
public int BotsNumber { get; set; }
|
|
|
|
[Usage(ApplicationAlias = "OpenBulletCLI.exe")]
|
|
public static IEnumerable<Example> Examples
|
|
{
|
|
get
|
|
{
|
|
return new List<Example>() {
|
|
new Example("Simple POC CLI Implementation of RuriLib that executes a Runner.",
|
|
new Options {
|
|
ConfigFile = "config.loli",
|
|
WordlistFile = "rockyou.txt",
|
|
WordlistType = "Default",
|
|
ProxyFile = "proxies.txt",
|
|
OutputFile = "hits.txt",
|
|
ProxyType = ProxyType.Http,
|
|
UseProxies = true,
|
|
Verbose = false,
|
|
Skip = 1,
|
|
BotsNumber = 1
|
|
}
|
|
)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Main(string[] args)
|
|
{
|
|
// Read Environment file
|
|
Env = IOManager.ParseEnvironmentSettings(envFile);
|
|
|
|
// Read Settings file
|
|
if (!File.Exists(settFile)) IOManager.SaveSettings(settFile, new RLSettingsViewModel());
|
|
RLSettings = IOManager.LoadSettings<RLSettingsViewModel>(settFile);
|
|
|
|
// Initialize the Runner (and hook event handlers)
|
|
Runner = new RunnerViewModel(Env, RLSettings, random);
|
|
Runner.AskCustomInputs += AskCustomInputs;
|
|
Runner.DispatchAction += DispatchAction;
|
|
Runner.FoundHit += FoundHit;
|
|
Runner.MessageArrived += MessageArrived;
|
|
Runner.ReloadProxies += ReloadProxies;
|
|
Runner.SaveProgress += SaveProgress;
|
|
Runner.WorkerStatusChanged += WorkerStatusChanged;
|
|
|
|
// Parse the Options
|
|
CommandLine.Parser.Default.ParseArguments<Options>(args)
|
|
.WithParsed<Options>(opts => Run(opts))
|
|
.WithNotParsed<Options>((errs) => HandleParseError(errs));
|
|
}
|
|
|
|
private static void WorkerStatusChanged(IRunnerMessaging obj)
|
|
{
|
|
// Nothing to do here since the Title is updated every 100 ms anyways
|
|
}
|
|
|
|
private static void SaveProgress(IRunnerMessaging obj)
|
|
{
|
|
// TODO: Implement progress saving (maybe to a file)
|
|
}
|
|
|
|
private static void ReloadProxies(IRunnerMessaging obj)
|
|
{
|
|
// Set Proxies
|
|
if (ProxyFile == null) return;
|
|
var proxies = File.ReadLines(ProxyFile)
|
|
.Select(p => new CProxy(p, ProxyType))
|
|
.ToList();
|
|
|
|
List<CProxy> toAdd;
|
|
if (Runner.Config.Settings.OnlySocks) toAdd = proxies.Where(x => x.Type != ProxyType.Http).ToList();
|
|
else if (Runner.Config.Settings.OnlySsl) toAdd = proxies.Where(x => x.Type == ProxyType.Http).ToList();
|
|
else toAdd = proxies;
|
|
|
|
Runner.ProxyPool = new ProxyPool(toAdd);
|
|
|
|
}
|
|
|
|
private static void MessageArrived(IRunnerMessaging obj, LogLevel level, string message, bool prompt, int timeout)
|
|
{
|
|
// Do not print anything if no verbose argument was declared
|
|
if (!Verbose) return;
|
|
|
|
// Select the line color based on the level
|
|
Color color = Color.White;
|
|
switch (level)
|
|
{
|
|
case LogLevel.Warning:
|
|
color = Color.Orange;
|
|
break;
|
|
|
|
case LogLevel.Error:
|
|
color = Color.Tomato;
|
|
break;
|
|
}
|
|
|
|
// Print the message to the screen
|
|
Console.WriteLine($"[{DateTime.Now}][{level}] {message}", color);
|
|
}
|
|
|
|
private static void FoundHit(IRunnerMessaging obj, Hit hit)
|
|
{
|
|
// Print the hit information to the screen
|
|
Console.WriteLine($"[{DateTime.Now}][{hit.Type}][{hit.Proxy}] {hit.Data}", Color.GreenYellow);
|
|
|
|
// If an output file was specified, print them to the output file as well
|
|
if (outFile != string.Empty)
|
|
{
|
|
lock (FileLocker.GetLock(outFile))
|
|
{
|
|
File.AppendAllText(outFile, $"[{ DateTime.Now}][{hit.Type}][{hit.Proxy}] {hit.Data}{Environment.NewLine}");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void DispatchAction(IRunnerMessaging obj, Action action)
|
|
{
|
|
// No need to delegate the action to the UI thread in CLI, so just invoke it
|
|
action.Invoke();
|
|
}
|
|
|
|
private static void AskCustomInputs(IRunnerMessaging obj)
|
|
{
|
|
// Ask all the custom inputs in the console and set their values in the Runner
|
|
foreach (var input in Runner.Config.Settings.CustomInputs)
|
|
{
|
|
Console.WriteLine($"Set custom input ({input.Description}): ", Color.Aquamarine);
|
|
Runner.CustomInputs.Add(new KeyValuePair<string, string>(input.VariableName, Console.ReadLine()));
|
|
}
|
|
}
|
|
|
|
private static void Run(Options opts)
|
|
{
|
|
// Set Runner settings from the specified Options
|
|
LoadOptions(opts);
|
|
|
|
// Create the hits file
|
|
if (opts.OutputFile != string.Empty)
|
|
{
|
|
File.Create(outFile).Close();
|
|
Console.WriteLine($"The hits file is {outFile}", Color.Aquamarine);
|
|
}
|
|
|
|
// Start the runner
|
|
Runner.Start();
|
|
|
|
// Wait until it finished
|
|
while (Runner.Busy)
|
|
{
|
|
Thread.Sleep(100);
|
|
UpdateTitle();
|
|
}
|
|
|
|
// Print colored finish message
|
|
Console.Write($"Finished. Found: ");
|
|
Console.Write($"{Runner.HitCount} hits, ", Color.GreenYellow);
|
|
Console.Write($"{Runner.CustomCount} custom, ", Color.DarkOrange);
|
|
Console.WriteLine($"{Runner.ToCheckCount} to check.", Color.Aquamarine);
|
|
|
|
// Prevent console from closing until the user presses return, then close
|
|
Console.ReadLine();
|
|
Environment.Exit(0);
|
|
}
|
|
|
|
private static void HandleParseError(IEnumerable<Error> errs)
|
|
{
|
|
|
|
}
|
|
|
|
private static void LoadOptions(Options opts)
|
|
{
|
|
// Load the user-defined options into local variables or into the local Runner instance
|
|
Verbose = opts.Verbose;
|
|
outFile = opts.OutputFile;
|
|
ProxyFile = opts.ProxyFile;
|
|
ProxyType = opts.ProxyType;
|
|
Runner.SetConfig(IOManager.LoadConfig(opts.ConfigFile), false);
|
|
Runner.SetWordlist(new Wordlist(opts.WordlistFile, opts.WordlistFile, opts.WordlistType, ""));
|
|
Runner.StartingPoint = opts.Skip;
|
|
if (opts.BotsNumber <= 0) Runner.BotsAmount = Runner.Config.Settings.SuggestedBots;
|
|
else Runner.BotsAmount = opts.BotsNumber;
|
|
|
|
if (opts.ProxyFile != null && opts.UseProxies != null)
|
|
{
|
|
Runner.ProxyMode = (bool)opts.UseProxies ? ProxyMode.On : ProxyMode.Off;
|
|
}
|
|
}
|
|
|
|
private static void LogErrorAndExit(string message)
|
|
{
|
|
Console.WriteLine($"ERROR: {message}", Color.Tomato);
|
|
Console.ReadLine();
|
|
Environment.Exit(0);
|
|
}
|
|
|
|
private static void UpdateTitle()
|
|
{
|
|
Console.Title = $"OpenBulletCLI - {Runner.Master.Status} | " +
|
|
$"Config: {Runner.ConfigName} | " +
|
|
$"Wordlist {Runner.WordlistName} | " +
|
|
$"Bots {Runner.BotsAmount} | " +
|
|
$"CPM: {Runner.CPM} | " +
|
|
$"Progress: {Runner.ProgressCount} / {Runner.WordlistSize} ({Runner.Progress}%) | " +
|
|
$"Hits: {Runner.HitCount} Custom: {Runner.CustomCount} ToCheck: {Runner.ToCheckCount} Fails: {Runner.FailCount} Retries: {Runner.RetryCount} | " +
|
|
$"Proxies: {Runner.AliveProxiesCount} / {Runner.TotalProxiesCount}";
|
|
}
|
|
}
|
|
}
|