Skip to content

Commit ce1c140

Browse files
ReaperBot integration (#169)
* ReaperBot integration * build ui * add key back for built-in agent config --------- Co-authored-by: Josh Larsen <2565382+joshlarsen@users.noreply.github.com>
1 parent 122b7ab commit ce1c140

32 files changed

+2420
-22
lines changed

.air.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tmp_dir = "tmp"
77
bin = "./tmp/reaper-server"
88
cmd = "go build -o ./tmp/reaper-server ./cmd/reaper"
99
delay = 1000
10-
exclude_dir = ["assets", "files", "tmp", "vendor", "docs", "ui"]
10+
exclude_dir = ["assets", "files", "tmp", "vendor", "docs", "ui", "reaperbot"]
1111
exclude_file = []
1212
exclude_regex = ["_test.go"]
1313
exclude_unchanged = false

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ ui/dist/**
4242

4343
# ...even if they are in subdirectories
4444
!*/
45+
46+
!/reaperbot/
47+
!/reaperbot/**

cmd/reaper/dist/assets/index-BPSUUKh2.js renamed to cmd/reaper/dist/assets/index-YOw9QSzM.js

Lines changed: 19 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/reaper/dist/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<link rel="icon" type="image/svg+xml" href="https://d1548abrjij03p.cloudfront.net/icon.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Reaper - A Ghost Labs Project</title>
8-
<script type="module" crossorigin src="/assets/index-BPSUUKh2.js"></script>
8+
<script type="module" crossorigin src="/assets/index-YOw9QSzM.js"></script>
99
<link rel="stylesheet" crossorigin href="/assets/index-BAugfWnD.css">
1010
</head>
1111
<body class="h-screen">

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ services:
33
build:
44
context: .
55
dockerfile: Dockerfile
6+
env_file: .env
67
environment:
78
- ENV=docker
89
- HOST=0.0.0.0
910
- PORT=8000
1011
- PROXY_PORT=8080
11-
- NGROK_AUTHTOKEN=your_nrok_token
1212
- OPENAI_API_KEY=your_openai_key
1313
volumes:
1414
- ./files:/app/files

reaperbot/.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Python-generated files
2+
__pycache__/
3+
*.py[oc]
4+
build/
5+
dist/
6+
wheels/
7+
*.egg-info
8+
9+
# Virtual environments
10+
.venv
11+
12+
# Config files
13+
.env
14+
utils/*.sqlite

reaperbot/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

reaperbot/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.PHONY: run ui
2+
3+
run:
4+
# Start the FastAPI app using uvicorn
5+
uv run python3 main.py
6+
ui:
7+
# Open Chrome at the specified URL
8+
open http://localhost:11000

reaperbot/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# ReaperBot
2+
3+
ReaperBot is an experimental Agentic AI system designed specifically to orchestrate the Reaper project via its APIs to solve the Ghostbank challenge and showcase the emergent behavior of this type of system applied to the AppSec testing space. It uses multiple specialized agents using the [Pydantic-AI](https://ai.pydantic.dev/) framework powered by [OpenAI](https://openai.com/api/) models for tasks like discovering live hosts, scanning domains, identifying potential security vulnerabilities (e.g., BOLA/IDOR), and reporting on the findings.
4+
5+
## Setup Instructions
6+
7+
1. **Clone the repository**:
8+
```bash
9+
git clone https://github.com/yourusername/reaperbot.git
10+
cd reaperbot
11+
```
12+
13+
2. **Ensure you have Python 3.13+ and uv installed**.
14+
```bash
15+
python3 --version
16+
uv -V
17+
```
18+
19+
3. **Install the dependencies**:
20+
```bash
21+
uv sync
22+
```
23+
24+
4. **Obtain API keys**:
25+
- [OpenAI API Key](https://platform.openai.com/account/api-keys)
26+
- Reaper Token - Navigate to the Reaper UI and fetch the token by clicking the key icon in the lower left of the navbar.
27+
28+
5. **Set up environment variables**:
29+
Create a `.env` file based on the `sample.env` and fill in the required keys:
30+
```ini
31+
OPENAI_API_KEY="sk_your_openai_api_key"
32+
X_REAPER_TOKEN="your_reaper_api_key"
33+
REAPER_BASE_URL="http://localhost:8000"
34+
```
35+
36+
6. **Run the application**:
37+
Start the FastAPI app with Uvicorn:
38+
```bash
39+
make run
40+
```
41+
42+
7. **Access the chat interface**:
43+
```
44+
make ui
45+
```
46+
or browse to `http://localhost:11000`
47+
48+
![ReaperBot Chat UI](static/chat-ui.png)
49+
50+
## Usage
51+
52+
Once the application is running, you can interact with ReaperBot through the WebSocket interface. Type in a command or request related to web application security, and ReaperBot will guide you through the steps to scan domains, find live hosts and endpoints, and test for vulnerabilities.
53+
54+
### Example Commands:
55+
- "Scan the (domain_name) domain"
56+
- "What are the live hosts for (domain_name)?"
57+
- "What endpoints in (domain_name) are vulnerable to BOLA?"
58+
- "Which endpoints in the (domain_name) application are vulnerable to BOLA? Write a technical report on the findings."
59+
60+
61+
## License
62+
63+
This project is licensed under the Apache 2.0 License - see the [LICENSE](../LICENSE) file for details.

reaperbot/__init__.py

Whitespace-only changes.

reaperbot/agents/__init__.py

Whitespace-only changes.

reaperbot/agents/discoverer.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import asyncio
2+
3+
from pydantic_ai import Agent
4+
from dotenv import load_dotenv
5+
from devtools import debug
6+
from pydantic_ai.settings import ModelSettings
7+
from agents.tools.reaper_tools import (
8+
reaper_get_scanned_domain_by_id,
9+
reaper_get_scanned_domains,
10+
reaper_scan_domain,
11+
reaper_get_live_hosts_for_domains,
12+
reaper_get_live_endpoints_for_domains,
13+
reaper_get_requests_for_endpoint_id,
14+
)
15+
16+
load_dotenv()
17+
18+
model_settings = ModelSettings(temperature=0.01, max_tokens=16384)
19+
discoverer_agent = Agent(
20+
'openai:gpt-4o-mini',
21+
result_type=str,
22+
tools=[
23+
reaper_get_scanned_domain_by_id,
24+
reaper_get_scanned_domains,
25+
reaper_scan_domain,
26+
reaper_get_live_hosts_for_domains,
27+
reaper_get_live_endpoints_for_domains,
28+
reaper_get_requests_for_endpoint_id,
29+
],
30+
model_settings=model_settings,
31+
system_prompt="""
32+
You are an advanced tool calling assistant interacting on behalf of
33+
an expert application security engineer with a system called
34+
Reaper to perform web application enumeration and testing actions to
35+
gather data about target domains, hosts, and endpoints.
36+
37+
The goal is to help the engineer perform some or all of the following
38+
tasks for a given domain:
39+
1. Use a tool (reaper) to scan a domain to discover live hosts if not already
40+
scanned by reaper.
41+
2. Use a tool (reaper) to retrieve live hosts in that domain
42+
3. Use a tool (reaper) to retrive live endpoints on those hosts with certain
43+
characteristics useful for planning a test attack.
44+
45+
The primary starting point for a workflow is a domain name, and most
46+
workflows will be focused on that domain until the user changes to another
47+
domain to focus on. Break down complex questions into simple steps that
48+
can be answered with tool calls and execute them in logical order.
49+
50+
Important: If you haven't been given a domain to focus on by
51+
the user, prompt the user to choose one. Do not make up a domain to scan.
52+
Do not use example.com, for example. If a tool is not available, do not
53+
make up responses.
54+
55+
You are encouraged to run these tools and use their response details to decide
56+
which step to take next and run more tools to get the information you
57+
need to answer the request.
58+
""",
59+
retries=2,
60+
)

reaperbot/agents/reaperbot.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from pydantic_ai import Agent, RunContext
2+
from pydantic_ai.settings import ModelSettings
3+
from dataclasses import dataclass
4+
5+
from agents.discoverer import discoverer_agent
6+
from agents.tester import tester_agent
7+
from utils.logging import send_log_message
8+
9+
@dataclass
10+
class ReaperBotDeps: # (1)!
11+
discoverer_agent: Agent
12+
tester_agent: Agent
13+
14+
reaperbot_deps = ReaperBotDeps(
15+
discoverer_agent=discoverer_agent,
16+
tester_agent=tester_agent,
17+
)
18+
19+
model_settings = ModelSettings(temperature=0.1, max_tokens=16384)
20+
reaperbot_agent = Agent(
21+
'openai:gpt-4o-mini',
22+
deps_type=ReaperBotDeps,
23+
result_type=str,
24+
model_settings=model_settings,
25+
system_prompt=(
26+
"You are an assistant helping an expert application security engineer interact with several specialized agents via tools that can complete tasks and fetch data with tools of their own.",
27+
"Your job is to take the input from the user, synthesize a step by step plan that aligns to the agents capabilities and tools, prompt the user with an outline of that plan, and execute that plan if the user confirms.",
28+
"If the user does not confirm, you should prompt the user with a message asking for adjustments to the plan.",
29+
"If the user does not confirm after a few retries, you should prompt the user with a message that you cannot help with that and provide some example questions you can ask.",
30+
"Only prompt for confirmation if the user's question requires a plan of multiple steps, is actionable, and can be executed by the agents/tools available to you.",
31+
"To provide the best answers about recommendations or fixes, be sure to have the relevant context about the application, fetch example request/responses to the application, and analyze its source code and related security findings.",
32+
"Use the available agents for the actionable portions of the execution. If the user's question is not related to the capabilities of your tools/agents, say you cannot help with that and prompt the user with some example questions you can ask.",
33+
"However, you are not a generalized security advice assistant, so only provide recommendations of steps to take that align with the agents/tools available to you.",
34+
"Use the discoverer agent to perform live domain scans and host discovery.",
35+
"Use the tester agent to perform live security testing of target applications, APIs, and endpoints.",
36+
"When invoking an agent, provide it with sufficient context to perform the task and what it's expected to provide back.",
37+
"If one agent responds with an inability to perform a task, see if another agent can perform the task.",
38+
"If the tester tool responds with a test result, provide that to the user directly and do not overly summarize.",
39+
"Summarize the actions taken, but provide the user with the full details and code snippets from the responses from the agents.",
40+
"Domains have hosts and endpoints.",
41+
"Apps/Applications are synonymous in this context.",
42+
"Endpoints are synonymous with APIs in this context.",
43+
"Apps have hosts, apis, and endpoints.",
44+
"Apps have metadata, openapi specs, source code, security findings.",
45+
"Source code has code, languages, and repo information.",
46+
"Endpoints have requests/responses.",
47+
),
48+
retries=1,
49+
)
50+
@reaperbot_agent.system_prompt
51+
async def reaperbot_agent_system_prompt_example_questions(ctx: RunContext[str]) -> str:
52+
examples = [
53+
"Scan the (domain_name) domain",
54+
"Which applications are written in go?",
55+
"Which hosts in the (domain_name) are live?",
56+
"What is the status of the (domain_name) domain scan?",
57+
"Which endpoints in the (domain_name) domain are susceptible to BOLA?",
58+
"Write a technical security report of the endpoints vulnerable to BOLA in the (domain_name) domain.",
59+
]
60+
title = 'The following are example questions you can ask me:\n'
61+
return title + '\n- '.join(examples)
62+
63+
64+
@reaperbot_agent.tool
65+
async def invoke_discoverer_agent(ctx: RunContext[ReaperBotDeps], input_text: str) -> str:
66+
"""
67+
Discoverer Tool that interfaces/hands-off with the DiscovererAgent.
68+
Performs live domain scans, host discovery, retrieves full request/responses hitting applications,
69+
and other discovery tasks.
70+
"""
71+
deps: ReaperBotDeps = ctx.deps
72+
await send_log_message(f"ReaperBot: Invoking Discoverer Agent with input: {input_text}")
73+
res = await deps.discoverer_agent.run(input_text, deps=deps)
74+
await send_log_message(f"ReaperBot: Discoverer Agent responded with: {res.data}")
75+
return res.data
76+
77+
@reaperbot_agent.tool
78+
async def invoke_tester_agent(ctx: RunContext[ReaperBotDeps], input_text: str) -> str:
79+
"""
80+
Tester Tool that interfaces/hands-off with the TesterAgent.
81+
Performs security testing of applications/apps, APIs, and endpoints for the following
82+
vulnerabilities:
83+
- BOLA/IDOR
84+
85+
This agent can provide example code/scripts that would demonstrate how a security
86+
vulnerability could be exploited in the application if present.
87+
"""
88+
deps: ReaperBotDeps = ctx.deps
89+
await send_log_message(f"ReaperBot: Invoking Tester Agent with input: {input_text}")
90+
res = await deps.tester_agent.run(input_text, deps=deps)
91+
await send_log_message(f"ReaperBot: Tester Agent responded with: {res.data}")
92+
return res.data

reaperbot/agents/tester.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import asyncio
2+
3+
from pydantic_ai import Agent
4+
from pydantic_ai.settings import ModelSettings
5+
from dotenv import load_dotenv
6+
7+
from agents.tester_bola import tester_bola_agent
8+
from utils.logging import send_log_message
9+
10+
load_dotenv()
11+
12+
model_settings = ModelSettings(temperature=0.01, max_tokens=16384)
13+
tester_agent = Agent(
14+
'openai:gpt-4o-mini',
15+
result_type=str,
16+
model_settings=model_settings,
17+
system_prompt="""
18+
You are an application security tester agent that is focused on finding and
19+
probing for validation of specific application security flaws.
20+
21+
You have access to your own specialized agents via tools that you are
22+
to delegate the actual testing actions to. Do not perform tests on your own. The
23+
agent tools you have access to are your only testing abilities. If you are
24+
asked to perform a test that you do not have a tool for, state that you
25+
cannot perform that test and offer the types of tests that you can perform.
26+
27+
Your job is to use only these tools to satisfy the high level request
28+
from the orchestrator agent and produce a response derived solely from that data.
29+
""",
30+
retries=2,
31+
)
32+
33+
@tester_agent.tool_plain
34+
async def invoke_tester_bola_agent(input_text: str) -> str:
35+
"""Tester Tool that interfaces/hands-off with the BOLA specific TesterAgent."""
36+
await send_log_message(f"Tester BOLA Agent: invoke_tester_bola_agent input: {input_text}")
37+
res = await tester_bola_agent.run(input_text)
38+
return res.data

reaperbot/agents/tester_bola.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import asyncio
2+
3+
from pydantic_ai import Agent
4+
from pydantic_ai.settings import ModelSettings
5+
from dotenv import load_dotenv
6+
from devtools import debug
7+
8+
from agents.tools.reaper_tools import (
9+
reaper_get_live_endpoints_for_domains,
10+
reaper_get_requests_for_endpoint_id,
11+
reaper_test_attack_endpoint_id,
12+
reaper_get_attack_results,
13+
)
14+
15+
load_dotenv()
16+
17+
model_settings = ModelSettings(temperature=0.01, max_tokens=16384)
18+
tester_bola_agent = Agent(
19+
'openai:gpt-4o-mini',
20+
result_type=str,
21+
tools=[
22+
reaper_get_live_endpoints_for_domains,
23+
reaper_get_requests_for_endpoint_id,
24+
reaper_test_attack_endpoint_id,
25+
reaper_get_attack_results,
26+
],
27+
model_settings=model_settings,
28+
system_prompt="""
29+
You are an application security tester agent that is focused on finding and
30+
probing for validation of "Broken Object Level Accesss" (BOLA) / "Insecure
31+
Direct Object Reference" (IDOR) flaws.
32+
33+
You have access to tools that you are able to use to safely
34+
perform probes against specific endpoints for bola/idor
35+
susceptibility/vulnerability. These endpoints are typically GET requests
36+
with url parameters and POST requests with body parameters.
37+
38+
Break down complex questions into simple steps that can be answered with tool
39+
calls and execute them in logical order. Actively attack/test only the
40+
endpoints that are most likely to be susceptible unless otherwise
41+
instructed.
42+
43+
The agent tools you have access to are your only testing abilities. If you
44+
are asked to perform a test that is not bola/idor related, state that you
45+
cannot perform that test and offer the types of tests that you can perform.
46+
47+
Your job is to use only these tools to satisfy the high level request
48+
from the orchestrator agent and produce a response derived solely from that data.
49+
50+
If no endpoints were found or found to be vulnerable, respond with "No BOLA/IDOR
51+
vulnerabilities found."
52+
""",
53+
retries=2,
54+
)

reaperbot/agents/tools/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)