From 99e36eb37a2de6a2c579368e5ed9851a72573f13 Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Fri, 22 Sep 2023 14:37:50 -0400 Subject: [PATCH] Add Discord Bot Example --- README.md | 2 + docs/dev/helpers/index.md | 29 ++++++++++++ docs/dev/index.md | 92 +++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 3 +- 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 docs/dev/helpers/index.md create mode 100644 docs/dev/index.md diff --git a/README.md b/README.md index 02f6f27cd..d447be51a 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,8 @@ For details, see [Configuration](https://www.blacklanternsecurity.com/bbot/scann ## BBOT as a Python library +BBOT exposes a Python API that allows it to be used for all kinds of fun and nefarious purposes, like a [Discord Bot that responds to `/scan evilcorp.com`](https://www.blacklanternsecurity.com/bbot/dev/#bbot-python-library-advanced-usage#discord-bot-example). + **Synchronous** ```python diff --git a/docs/dev/helpers/index.md b/docs/dev/helpers/index.md new file mode 100644 index 000000000..be7365fe1 --- /dev/null +++ b/docs/dev/helpers/index.md @@ -0,0 +1,29 @@ +# BBOT Helpers + +In this section are various helper functions that are designed to make your life easier when devving on BBOT. Whether you're extending BBOT by writing a module or working on its core engine, these functions are designed to act as useful machine parts to perform essential tasks, such as making a web request or executing a DNS query. + +The vast majority of these helpers can be accessed directly from the `.helpers` attribute of a scan or module, like so: + +```python +class MyModule(BaseModule): + + ... + + async def handle_event(self, event): + # Web Request + response = await self.helpers.request("https://www.evilcorp.com") + + # DNS query + for ip in await self.helpers.resolve("www.evilcorp.com"): + self.hugesuccess(str(ip)) + + # Execute shell command + completed_process = self.helpers.run("ls", "-l") + self.hugesuccess(completed_process.stdout) + + # Split a DNS name into subdomain / domain + self.helpers.split_domain("www.internal.evilcorp.co.uk") + # ("www.internal", "evilcorp.co.uk") +``` + +[Next Up: Command Helpers -->](command.md){ .md-button .md-button--primary } diff --git a/docs/dev/index.md b/docs/dev/index.md new file mode 100644 index 000000000..982b04e05 --- /dev/null +++ b/docs/dev/index.md @@ -0,0 +1,92 @@ +# BBOT Developer Reference + +BBOT exposes a convenient API that allows you to create, start, and stop scans using Python code. + +Documented in this section are commonly-used classes and functions within BBOT, along with usage examples. + +## Discord Bot Example + +Below is a simple Discord bot designed to run BBOT scans. + +```python +import asyncio +import discord +from discord.ext import commands + +from bbot.scanner import Scanner +from bbot.modules import module_loader +from bbot.modules.output.discord import Discord + + +# make list of BBOT modules +bbot_modules = ["excavate", "speculate", "aggregate"] +for module_name, preloaded in module_loader.preloaded().items(): + flags = preloaded["flags"] + if "subdomain-enum" in flags and "passive" in flags and "slow" not in flags: + bbot_modules.append(module_name) + + +class BBOTDiscordBot(commands.Cog): + """ + A simple Discord bot capable of running a BBOT scan. + + To set up: + 1. Go to Discord Developer Portal (https://discord.com/developers) + 2. Create a new application + 3. Create an invite link for the bot, visit the link to invite it to your server + - Your Application --> OAuth2 --> URL Generator + - For Scopes, select "bot"" + - For Bot Permissions, select: + - Read Messages/View Channels + - Send Messages + 4. Turn on "Message Content Intent" + - Your Application --> Bot --> Privileged Gateway Intents --> Message Content Intent + 5. Copy your Discord Bot Token and put it at the top this file + - Your Application --> Bot --> Reset Token + 6. Run this script + + To scan evilcorp.com, you would type: + + /scan evilcorp.com + + Results will be output to the same channel. + """ + def __init__(self): + self.current_scan = None + + @commands.command(name="scan", description="Scan a target with BBOT.") + async def scan(self, ctx, target: str): + if self.current_scan is not None: + self.current_scan.stop() + await ctx.send(f"Starting scan against {target}.") + + self.current_scan = Scanner(target, modules=bbot_modules) + discord_module = Discord(self.current_scan) + + seen = set() + num_events = 0 + async for event in self.current_scan.async_start(): + if hash(event) in seen: + continue + seen.add(hash(event)) + await ctx.send(discord_module.format_message(event)) + num_events += 1 + + await ctx.send(f"Finished scan against {target}. {num_events:,} results.") + self.current_scan = None + + +if __name__ == "__main__": + intents = discord.Intents.default() + intents.message_content = True + bot = commands.Bot(command_prefix="/", intents=intents) + + @bot.event + async def on_ready(): + print(f"We have logged in as {bot.user}") + await bot.add_cog(BBOTDiscordBot()) + + bot.run("DISCORD_BOT_TOKEN_HERE") +``` + +[Next Up: Scanner -->](scanner.md){ .md-button .md-button--primary } diff --git a/mkdocs.yml b/mkdocs.yml index 4bec84f24..75fabc6e7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -31,12 +31,13 @@ nav: - Contribution: - How to Write a Module: contribution.md - Developer Reference: + - Overview: dev/index.md - Scanner: dev/scanner.md - Event: dev/event.md - Target: dev/target.md - BaseModule: dev/basemodule.md - Helpers: - # dev/helpers/index.md + - Overview: dev/helpers/index.md - Command: dev/helpers/command.md - DNS: dev/helpers/dns.md - Interactsh: dev/helpers/interactsh.md