Skip to content

Commit 0767d2d

Browse files
Merge branch 'dev' into mcp_additions
2 parents 60b1502 + 21e4552 commit 0767d2d

File tree

88 files changed

+4868
-2863
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+4868
-2863
lines changed

.github/workflows/docker-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrency:
1212

1313
jobs:
1414
docker-test:
15-
runs-on: self-hosted
15+
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v4
1818
- name: Set up Python

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrency:
1212

1313
jobs:
1414
test:
15-
runs-on: self-hosted
15+
runs-on: ubuntu-latest
1616
strategy:
1717
fail-fast: false
1818
matrix:
@@ -42,7 +42,7 @@ jobs:
4242
poetry run ruff format --check
4343
- name: Run tests
4444
run: |
45-
NO_COLOR=true poetry run pytest --disable-warnings --log-cli-level=INFO --cov-report xml:cov.xml --cov=bbot_server .
45+
NO_COLOR=true poetry run pytest --reruns 2 --disable-warnings --log-cli-level=INFO --cov-report xml:cov.xml --cov=bbot_server .
4646
- name: Upload Code Coverage
4747
uses: codecov/codecov-action@v3
4848
with:

README.md

Lines changed: 95 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,45 +136,48 @@ To start a scan in BBOT server, you need to first create a **Preset** and **Targ
136136

137137
1. Create Preset
138138

139-
The preset defines which flags, modules, API keys, etc. will be used for the scan. It typically looks something like this:
139+
The preset defines which flags, modules, API keys, etc. will be used for the scan. It typically looks something like this:
140140

141-
**`my_preset.yml`**:
142-
```yaml
143-
include:
144-
- subdomain-enum
145-
- cloud-enum
146-
- code-enum
141+
**`my_preset.yml`**:
142+
```yaml
143+
include:
144+
- subdomain-enum
145+
- cloud-enum
146+
- code-enum
147147
148-
modules:
149-
- nuclei
148+
modules:
149+
- nuclei
150150
151-
config:
152-
- virustotal:
153-
api_key: deadbeef
154-
```
151+
config:
152+
modules:
153+
virustotal:
154+
api_key: deadbeef
155+
```
155156

156-
```bash
157-
# create a new scan preset
158-
bbctl scan preset create my_preset.yml
159-
```
157+
```bash
158+
# create a new scan preset
159+
bbctl scan preset create my_preset.yml
160+
```
161+
162+
For more guidance and examples on presets, check out the [bbot docs](https://www.blacklanternsecurity.com/bbot/Stable/scanning/presets/).
160163

161164
2. Create Target
162165

163-
A target defines what's in-scope for the scan. They can also be used when filtering assets.
166+
A target defines what's in-scope for the scan. They can also be used when filtering assets.
164167

165-
```bash
166-
# create a new scan target
167-
bbctl scan target create --seeds evilcorp.txt --name "my_target"
168-
```
168+
```bash
169+
# create a new scan target
170+
bbctl scan target create --seeds evilcorp.txt --name "my_target"
171+
```
169172

170173
3. Start Scan
171174

172-
Now that we've created a preset and target, we can start the scan:
175+
Now that we've created a preset and target, we can start the scan:
173176

174-
```bash
175-
# start the scan
176-
bbctl scan start --preset my_preset --target my_target --name "demonic_jimmy"
177-
```
177+
```bash
178+
# start the scan
179+
bbctl scan start --preset my_preset --target my_target --name "demonic_jimmy"
180+
```
178181

179182
## Monitor scan progress
180183

@@ -325,6 +328,71 @@ The SSE server listens at `http://localhost:8807/v1/mcp/`
325328

326329
After connecting your AI client to BBOT Server, you can ask it sensible questions like, "Use MCP to get all the bbot findings", "what are the top open ports?", "what else can you do with BBOT MCP?", etc.
327330

331+
## As a Python Library
332+
333+
You can interact fully with BBOT Server as a Python library. It supports either local or remote connections, and the interface to both is identical:
334+
335+
### Asynchronous
336+
337+
```python
338+
import asyncio
339+
from bbot_server import BBOTServer
340+
341+
async def main():
342+
# talk directly to local MongoDB + Redis
343+
bbot_server = BBOTServer(interface="python")
344+
345+
# or to a remote BBOT Server instance (config must contain a valid API key)
346+
bbot_server = BBOTServer(interface="http", url="http://bbot:8807/v1/")
347+
348+
# one-time setup
349+
await bbot_server.setup()
350+
351+
hosts = await bbot_server.get_hosts()
352+
print(f"hosts: {hosts}")
353+
354+
if __name__ == "__main__":
355+
asyncio.run(main())
356+
```
357+
358+
### Synchronous
359+
360+
```python
361+
from bbot_server import BBOTServer
362+
363+
if __name__ == "__main__":
364+
# talk directly to local MongoDB + Redis
365+
bbot_server = BBOTServer(interface="python", synchronous=True)
366+
367+
# or to a remote BBOT Server instance (config must contain a valid API key)
368+
bbot_server = BBOTServer(interface="http", url="http://bbot:8807/v1/", synchronous=True)
369+
370+
# one-time setup
371+
bbot_server.setup()
372+
373+
hosts = bbot_server.get_hosts()
374+
print(f"hosts: {hosts}")
375+
```
376+
377+
## Running Tests
378+
379+
When running tests, first start MongoDB and Redis via Docker:
380+
381+
```bash
382+
docker run --rm -p 27017:27017 mongo
383+
docker run --rm -p 6379:6379 redis
384+
```
385+
386+
Then execute `pytest`:
387+
388+
```bash
389+
# run all tests
390+
poetry run pytest -v
391+
392+
# run specific tests
393+
poetry run pytest -v -k test_applet_scans
394+
```
395+
328396
## Screenshots
329397

330398
*Tailing activities in real time*

bbot_server/api/mcp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import logging
2-
from fastapi_mcp import FastApiMCP
32

43
MCP_ENDPOINTS = {}
54

65
log = logging.getLogger("bbot_server.api.mcp")
76

87

98
def make_mcp_server(fastapi_app, config, mcp_endpoints=None):
9+
from fastapi_mcp import FastApiMCP
10+
1011
if mcp_endpoints is None:
1112
mcp_endpoints = MCP_ENDPOINTS
1213
log.debug(f"Creating MCP server with endpoints: {','.join(mcp_endpoints)}")

bbot_server/applets/_root.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
class RootApplet(BaseApplet):
77
name = "Root Applet"
88

9-
attach_to = ""
10-
119
_nested = False
1210

1311
_route_prefix = ""
@@ -28,26 +26,18 @@ async def setup(self):
2826
if self.is_native:
2927
# set up asset store, user store, and gridfs buckets
3028
if self.asset_store is None:
31-
from bbot_server.store.user_store import UserStore
32-
from bbot_server.store.asset_store import AssetStore
29+
from bbot_server.store import UserStore, AssetStore, EventStore
3330

3431
self.asset_store = AssetStore()
3532
await self.asset_store.setup()
36-
self.asset_db = self.asset_store.db
37-
self.asset_fs = self.asset_store.fs
3833

3934
self.user_store = UserStore()
4035
await self.user_store.setup()
41-
self.user_db = self.user_store.db
42-
self.user_fs = self.user_store.fs
43-
44-
# set up event store
45-
from bbot_server.event_store import EventStore
4636

47-
self.event_store = EventStore()
48-
await self.event_store.setup()
37+
self.event_store = EventStore()
38+
await self.event_store.setup()
4939

50-
# set up NATS client
40+
# set up message queue
5141
from bbot_server.message_queue import MessageQueue
5242

5343
self.message_queue = MessageQueue()

0 commit comments

Comments
 (0)