├── 7zip ├── 7za.exe └── readme.md ├── AnomalyUpdater.bat ├── LICENSE ├── OpenBulletCLI ├── App.config ├── DefaultEnvFile.ini ├── OBlogo.ico ├── OBlogoIcon.ico ├── OpenBulletCLI.csproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config └── README.md /7zip/7za.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenBulletAnomaly/OpenBullet-Anomaly/ae33625a5710607987be5a79b8b68952a65aa667/7zip/7za.exe -------------------------------------------------------------------------------- /7zip/readme.md: -------------------------------------------------------------------------------- 1 | - This is just a compression program to unzip the archive. 2 | -------------------------------------------------------------------------------- /AnomalyUpdater.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | SETLOCAL EnableDelayedExpansion 3 | color 9 4 | SET $Echo=FOR %%I IN (1 2) DO IF %%I==2 (SETLOCAL EnableDelayedExpansion ^& FOR %%A IN (^^^!Text:""^^^^^=^^^^^"^^^!) DO ENDLOCAL ^& ENDLOCAL ^& ECHO %%~A) ELSE SETLOCAL DisableDelayedExpansion ^& SET Text= 5 | 6 | SETLOCAL DisableDelayedExpansion 7 | 8 | 9 | %$Echo% " _____ _ _ _____ _____ _ _ _ _ _ ___ ___ _____ _____ ___ ___ " 10 | %$Echo% " ( _ )( ) ( )( _ )/'\_/`\( _ )( ) ( ) ( ) ( ) ( )( _`\ ( _`\ ( _ )(_ _)( _`\ | _`\ " 11 | %$Echo% " | (_) || `\| || ( ) || || (_) || | `\`\_/'/' | | | || |_) )| | ) || (_) | | | | (_(_)| (_) ) " 12 | %$Echo% " | _ || , ` || | | || (_) || _ || | _`\ /' | | | || ,__/'| | | )| _ | | | | _)_ | , / " 13 | %$Echo% " | | | || |`\ || (_) || | | || | | || |_( )| | | (_) || | | |_) || | | | | | | (_( )| |\ \ " 14 | %$Echo% " (_) (_)(_) (_)(_____)(_) (_)(_) (_)(____/'(_) (_____)(_) (____/'(_) (_) (_) (____/'(_) (_) " 15 | 16 | echo. 17 | echo. 18 | color C 19 | echo [*] Downloading Latest Update . . . 20 | cd "%~dp0" 21 | powershell (New-Object System.Net.WebClient).Downloadfile('https://github.com/OpenBulletAnomaly/OpenBullet-Anomaly/releases/download/1.4.5/OpenBullet-v1.4.5.zip', 'OpenBullet-v1.4.5.zip') 22 | color 3 23 | echo [*] Extracting Files 24 | color 4 25 | echo [*] Downloading 7zip to decompress file 26 | powershell -Command "$7zip = New-Object System.Net.WebClient; $7zip.DownloadFile('https://github.com/OpenBulletAnomaly/OpenBullet-Anomaly/raw/main/7zip/7za.exe', '7za.exe')" 27 | color B 28 | echo [*] Unpacking with 7zip 29 | 7za.exe x -y -o"OpenBullet-v1.4.5" "OpenBullet-v1.4.5.zip" >NUL 30 | color 6 31 | echo [*] Cleaning Up Temp Files ! 32 | powershell Remove-Item -Path "OpenBullet-v1.4.5.zip" -Force 33 | powershell Remove-Item -Path "7za.exe" -Force 34 | color A 35 | echo [*] Successfully Updated ! You may Now Run The Program. 36 | ENDLOCAL 37 | PAUSE 38 | ENDLOCAL & EXIT /B 39 | 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 OpenBulletAnomally 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OpenBulletCLI/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /OpenBulletCLI/DefaultEnvFile.ini: -------------------------------------------------------------------------------- 1 | [WLTYPE] 2 | Name=Default 3 | Regex=^.*$ 4 | Verify=False 5 | Separator=: 6 | Slices=DATA 7 | 8 | [WLTYPE] 9 | Name=Email 10 | Regex=^[^@]+@[^\.]+\..+$ 11 | Verify=True 12 | Separator=: 13 | Slices=EMAIL 14 | 15 | [WLTYPE] 16 | Name=Credentials 17 | Regex=^.*:.*$ 18 | Verify=True 19 | Separator=: 20 | Slices=USERNAME,PASSWORD 21 | 22 | [WLTYPE] 23 | Name=Numeric 24 | Regex=^[0-9]*$ 25 | Verify=True 26 | Separator=: 27 | Slices=CODE 28 | 29 | [WLTYPE] 30 | Name=URLs 31 | Regex=^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$ 32 | Verify=True 33 | Separator=: 34 | Slices=URL 35 | 36 | [CUSTOMKC] 37 | Name=CUSTOM 38 | Color=OrangeRed 39 | 40 | [EXPFORMAT] 41 | Format= 42 | 43 | [EXPFORMAT] 44 | Format=:: -------------------------------------------------------------------------------- /OpenBulletCLI/OBlogo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenBulletAnomaly/OpenBullet-Anomaly/ae33625a5710607987be5a79b8b68952a65aa667/OpenBulletCLI/OBlogo.ico -------------------------------------------------------------------------------- /OpenBulletCLI/OBlogoIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenBulletAnomaly/OpenBullet-Anomaly/ae33625a5710607987be5a79b8b68952a65aa667/OpenBulletCLI/OBlogoIcon.ico -------------------------------------------------------------------------------- /OpenBulletCLI/OpenBulletCLI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0B6D8B01-861E-4CAF-B1C9-6670884381DB} 8 | Exe 9 | OpenBulletCLI 10 | OpenBulletCLI 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | publish\ 16 | true 17 | Disk 18 | false 19 | Foreground 20 | 7 21 | Days 22 | false 23 | false 24 | true 25 | 0 26 | 1.0.0.%2a 27 | false 28 | false 29 | true 30 | 31 | 32 | 33 | AnyCPU 34 | true 35 | full 36 | false 37 | bin\Debug\ 38 | DEBUG;TRACE 39 | prompt 40 | 4 41 | 42 | 43 | AnyCPU 44 | pdbonly 45 | true 46 | bin\Release\ 47 | TRACE 48 | prompt 49 | 4 50 | 51 | 52 | OBlogoIcon.ico 53 | 54 | 55 | 56 | ..\packages\Colorful.Console.1.2.10\lib\net461\Colorful.Console.dll 57 | 58 | 59 | ..\packages\CommandLineParser.2.7.82\lib\net461\CommandLine.dll 60 | 61 | 62 | False 63 | ..\Extreme.Net.dll 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | {17E95D0B-C1FD-445C-9FDF-244AF7299A67} 91 | RuriLib 92 | 93 | 94 | 95 | 96 | False 97 | Microsoft .NET Framework 4.6.1 %28x86 e x64%29 98 | true 99 | 100 | 101 | False 102 | .NET Framework 3.5 SP1 103 | false 104 | 105 | 106 | 107 | 108 | if not exist "$(TargetDir)bin" mkdir "$(TargetDir)bin" 109 | if $(ConfigurationName) == Release move "$(TargetDir)*.dll" "$(TargetDir)bin\" 110 | if not exist "$(TargetDir)Settings" mkdir "$(TargetDir)Settings" 111 | if not exist "$(TargetDir)Settings\Environment.ini" copy "$(ProjectDir)DefaultEnvFile.ini" "$(TargetDir)Settings\Environment.ini" 112 | 113 | -------------------------------------------------------------------------------- /OpenBulletCLI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Threading; 7 | using CommandLine; 8 | using CommandLine.Text; 9 | using Extreme.Net; 10 | using RuriLib; 11 | using RuriLib.Models; 12 | using RuriLib.Runner; 13 | using RuriLib.ViewModels; 14 | using Console = Colorful.Console; 15 | 16 | namespace OpenBulletCLI 17 | { 18 | /* 19 | * THIS IS A POC (Proof Of Concept) IMPLEMENTATION OF RuriLib IN CLI (Command Line Interface). 20 | * The functionalities supported here don't even come close to the ones of the WPF GUI implementation. 21 | * Feel free to contribute to the versatility of this project by adding the missing functionalities. 22 | * 23 | * */ 24 | 25 | 26 | class Program 27 | { 28 | private static string envFile = @"Settings/Environment.ini"; 29 | private static string settFile = @"Settings/RLSettings.json"; 30 | private static string outFile = ""; 31 | 32 | public static EnvironmentSettings Env { get; set; } 33 | public static RLSettingsViewModel RLSettings { get; set; } 34 | private static Random random = new Random(); 35 | public static RunnerViewModel Runner { get; set; } 36 | public static bool Verbose { get; set; } = false; 37 | public static string ProxyFile { get; set; } 38 | public static ProxyType ProxyType { get; set; } 39 | 40 | class Options 41 | { 42 | [Option('c', "config", Required = true, HelpText = "Configuration file to be processed.")] 43 | public string ConfigFile { get; set; } 44 | 45 | [Option('w', "wordlist", Required = true, HelpText = "Wordlist file to be processed.")] 46 | public string WordlistFile { get; set; } 47 | 48 | [Option('o', "output", Default = "", HelpText = "Output file for the hits.")] 49 | public string OutputFile { get; set; } 50 | 51 | [Option("wltype", Required = true, HelpText = "Type of the wordlist loaded (see Environment.ini for all allowed types).")] 52 | public string WordlistType { get; set; } 53 | 54 | [Option("useproxies", HelpText = "Enable / Disable the usage of proxies (uses config default if not set).")] 55 | public bool? UseProxies { get; set; } 56 | 57 | [Option('p', "proxies", Default = null, HelpText = "Proxy file to be processed.")] 58 | public string ProxyFile { get; set; } 59 | 60 | [Option("ptype", Default = ProxyType.Http, HelpText = "Type of proxies loaded (Http, Socks4, Socks4a, Socks5).")] 61 | public ProxyType ProxyType { get; set; } 62 | 63 | [Option('v', "verbose", Default = false, HelpText = "Prints all bots behaviour.")] 64 | public bool Verbose { get; set; } 65 | 66 | [Option('s', "skip", Default = 1, HelpText = "Number of lines to skip in the Wordlist.")] 67 | public int Skip { get; set; } 68 | 69 | [Option('b', "bots", Default = 0, HelpText = "Number of concurrent bots working. If not specified, the config default will be used.")] 70 | public int BotsNumber { get; set; } 71 | 72 | [Usage(ApplicationAlias = "OpenBulletCLI.exe")] 73 | public static IEnumerable Examples 74 | { 75 | get 76 | { 77 | return new List() { 78 | new Example("Simple POC CLI Implementation of RuriLib that executes a Runner.", 79 | new Options { 80 | ConfigFile = "config.loli", 81 | WordlistFile = "rockyou.txt", 82 | WordlistType = "Default", 83 | ProxyFile = "proxies.txt", 84 | OutputFile = "hits.txt", 85 | ProxyType = ProxyType.Http, 86 | UseProxies = true, 87 | Verbose = false, 88 | Skip = 1, 89 | BotsNumber = 1 90 | } 91 | ) 92 | }; 93 | } 94 | } 95 | } 96 | 97 | static void Main(string[] args) 98 | { 99 | // Read Environment file 100 | Env = IOManager.ParseEnvironmentSettings(envFile); 101 | 102 | // Read Settings file 103 | if (!File.Exists(settFile)) IOManager.SaveSettings(settFile, new RLSettingsViewModel()); 104 | RLSettings = IOManager.LoadSettings(settFile); 105 | 106 | // Initialize the Runner (and hook event handlers) 107 | Runner = new RunnerViewModel(Env, RLSettings, random); 108 | Runner.AskCustomInputs += AskCustomInputs; 109 | Runner.DispatchAction += DispatchAction; 110 | Runner.FoundHit += FoundHit; 111 | Runner.MessageArrived += MessageArrived; 112 | Runner.ReloadProxies += ReloadProxies; 113 | Runner.SaveProgress += SaveProgress; 114 | Runner.WorkerStatusChanged += WorkerStatusChanged; 115 | 116 | // Parse the Options 117 | CommandLine.Parser.Default.ParseArguments(args) 118 | .WithParsed(opts => Run(opts)) 119 | .WithNotParsed((errs) => HandleParseError(errs)); 120 | } 121 | 122 | private static void WorkerStatusChanged(IRunnerMessaging obj) 123 | { 124 | // Nothing to do here since the Title is updated every 100 ms anyways 125 | } 126 | 127 | private static void SaveProgress(IRunnerMessaging obj) 128 | { 129 | // TODO: Implement progress saving (maybe to a file) 130 | } 131 | 132 | private static void ReloadProxies(IRunnerMessaging obj) 133 | { 134 | // Set Proxies 135 | if (ProxyFile == null) return; 136 | var proxies = File.ReadLines(ProxyFile) 137 | .Select(p => new CProxy(p, ProxyType)) 138 | .ToList(); 139 | 140 | List toAdd; 141 | if (Runner.Config.Settings.OnlySocks) toAdd = proxies.Where(x => x.Type != ProxyType.Http).ToList(); 142 | else if (Runner.Config.Settings.OnlySsl) toAdd = proxies.Where(x => x.Type == ProxyType.Http).ToList(); 143 | else toAdd = proxies; 144 | 145 | Runner.ProxyPool = new ProxyPool(toAdd); 146 | 147 | } 148 | 149 | private static void MessageArrived(IRunnerMessaging obj, LogLevel level, string message, bool prompt, int timeout) 150 | { 151 | // Do not print anything if no verbose argument was declared 152 | if (!Verbose) return; 153 | 154 | // Select the line color based on the level 155 | Color color = Color.White; 156 | switch (level) 157 | { 158 | case LogLevel.Warning: 159 | color = Color.Orange; 160 | break; 161 | 162 | case LogLevel.Error: 163 | color = Color.Tomato; 164 | break; 165 | } 166 | 167 | // Print the message to the screen 168 | Console.WriteLine($"[{DateTime.Now}][{level}] {message}", color); 169 | } 170 | 171 | private static void FoundHit(IRunnerMessaging obj, Hit hit) 172 | { 173 | // Print the hit information to the screen 174 | Console.WriteLine($"[{DateTime.Now}][{hit.Type}][{hit.Proxy}] {hit.Data}", Color.GreenYellow); 175 | 176 | // If an output file was specified, print them to the output file as well 177 | if (outFile != string.Empty) 178 | { 179 | lock (FileLocker.GetLock(outFile)) 180 | { 181 | File.AppendAllText(outFile, $"[{ DateTime.Now}][{hit.Type}][{hit.Proxy}] {hit.Data}{Environment.NewLine}"); 182 | } 183 | } 184 | } 185 | 186 | private static void DispatchAction(IRunnerMessaging obj, Action action) 187 | { 188 | // No need to delegate the action to the UI thread in CLI, so just invoke it 189 | action.Invoke(); 190 | } 191 | 192 | private static void AskCustomInputs(IRunnerMessaging obj) 193 | { 194 | // Ask all the custom inputs in the console and set their values in the Runner 195 | foreach (var input in Runner.Config.Settings.CustomInputs) 196 | { 197 | Console.WriteLine($"Set custom input ({input.Description}): ", Color.Aquamarine); 198 | Runner.CustomInputs.Add(new KeyValuePair(input.VariableName, Console.ReadLine())); 199 | } 200 | } 201 | 202 | private static void Run(Options opts) 203 | { 204 | // Set Runner settings from the specified Options 205 | LoadOptions(opts); 206 | 207 | // Create the hits file 208 | if (opts.OutputFile != string.Empty) 209 | { 210 | File.Create(outFile).Close(); 211 | Console.WriteLine($"The hits file is {outFile}", Color.Aquamarine); 212 | } 213 | 214 | // Start the runner 215 | Runner.Start(); 216 | 217 | // Wait until it finished 218 | while (Runner.Busy) 219 | { 220 | Thread.Sleep(100); 221 | UpdateTitle(); 222 | } 223 | 224 | // Print colored finish message 225 | Console.Write($"Finished. Found: "); 226 | Console.Write($"{Runner.HitCount} hits, ", Color.GreenYellow); 227 | Console.Write($"{Runner.CustomCount} custom, ", Color.DarkOrange); 228 | Console.WriteLine($"{Runner.ToCheckCount} to check.", Color.Aquamarine); 229 | 230 | // Prevent console from closing until the user presses return, then close 231 | Console.ReadLine(); 232 | Environment.Exit(0); 233 | } 234 | 235 | private static void HandleParseError(IEnumerable errs) 236 | { 237 | 238 | } 239 | 240 | private static void LoadOptions(Options opts) 241 | { 242 | // Load the user-defined options into local variables or into the local Runner instance 243 | Verbose = opts.Verbose; 244 | outFile = opts.OutputFile; 245 | ProxyFile = opts.ProxyFile; 246 | ProxyType = opts.ProxyType; 247 | Runner.SetConfig(IOManager.LoadConfig(opts.ConfigFile), false); 248 | Runner.SetWordlist(new Wordlist(opts.WordlistFile, opts.WordlistFile, opts.WordlistType, "")); 249 | Runner.StartingPoint = opts.Skip; 250 | if (opts.BotsNumber <= 0) Runner.BotsAmount = Runner.Config.Settings.SuggestedBots; 251 | else Runner.BotsAmount = opts.BotsNumber; 252 | 253 | if (opts.ProxyFile != null && opts.UseProxies != null) 254 | { 255 | Runner.ProxyMode = (bool)opts.UseProxies ? ProxyMode.On : ProxyMode.Off; 256 | } 257 | } 258 | 259 | private static void LogErrorAndExit(string message) 260 | { 261 | Console.WriteLine($"ERROR: {message}", Color.Tomato); 262 | Console.ReadLine(); 263 | Environment.Exit(0); 264 | } 265 | 266 | private static void UpdateTitle() 267 | { 268 | Console.Title = $"OpenBulletCLI - {Runner.Master.Status} | " + 269 | $"Config: {Runner.ConfigName} | " + 270 | $"Wordlist {Runner.WordlistName} | " + 271 | $"Bots {Runner.BotsAmount} | " + 272 | $"CPM: {Runner.CPM} | " + 273 | $"Progress: {Runner.ProgressCount} / {Runner.WordlistSize} ({Runner.Progress}%) | " + 274 | $"Hits: {Runner.HitCount} Custom: {Runner.CustomCount} ToCheck: {Runner.ToCheckCount} Fails: {Runner.FailCount} Retries: {Runner.RetryCount} | " + 275 | $"Proxies: {Runner.AliveProxiesCount} / {Runner.TotalProxiesCount}"; 276 | } 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /OpenBulletCLI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Le informazioni generali relative a un assembly sono controllate dal seguente 6 | // set di attributi. Modificare i valori di questi attributi per modificare le informazioni 7 | // associate a un assembly. 8 | [assembly: AssemblyTitle("OpenBulletCLI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OpenBulletCLI")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili 18 | // ai componenti COM. Se è necessario accedere a un tipo in questo assembly da 19 | // COM, impostare su true l'attributo ComVisible per tale tipo. 20 | [assembly: ComVisible(false)] 21 | 22 | // Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi 23 | [assembly: Guid("0b6d8b01-861e-4caf-b1c9-6670884381db")] 24 | 25 | // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: 26 | // 27 | // Versione principale 28 | // Versione secondaria 29 | // Numero di build 30 | // Revisione 31 | // 32 | // È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build 33 | // usando l'asterisco '*' come illustrato di seguito: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /OpenBulletCLI/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

3 |

4 | 5 | 6 | 7 | 8 | 9 |
10 |

11 | 12 | ### Screenshot 13 | 14 | ![OpenBullet](https://user-images.githubusercontent.com/110566590/182718470-3193a28c-363a-4897-8610-540889854233.png) 15 | 16 | OpenBullet is a webtesting suite that allows to perform requests towards a target webapp and offers a lot of tools to work with the results. 17 | This software can be used for scraping and parsing data, automated pentesting, unit testing through selenium and much more. 18 | 19 | IMPORTANT! Performing (D)DoS attacks or credential stuffing on sites you do not own (or you do not have permission to test) is illegal! 20 | The developer will not be held responsible for improper use of this software. 21 | 22 | ### Required 23 | [C++ 2015+ Redistributable x64 and x86](https://www.microsoft.com/en-us/download/details.aspx?id=52685) 24 | 25 | #### Found a bug? [Create an issue!](https://help.github.com/en/articles/creating-an-issue) 26 | 27 | Download and setup 28 | - [Final Release](https://github.com/OpenBulletAnomaly/OpenBullet-Anomaly/releases) 29 | - [AnomalyUpdater](https://github.com/OpenBulletAnomaly/OpenBullet-Anomaly/releases/download/1.4.5/AnomalyUpdater.exe) 30 | 31 | ### License 32 | This software is licensed under the MIT License 33 | --------------------------------------------------------------------------------