Skip to content
This repository was archived by the owner on Sep 30, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dreadnode_cli/agent/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def init(

AgentConfig(project_name=project_name, strike=strike).write(directory=directory)

install_template(template, directory, {"project_name": project_name})
install_template(template, directory, {"project_name": project_name, "strike": strike_response})

print()
print(f"Initialized [b]{directory}[/]")
Expand Down
1 change: 1 addition & 0 deletions dreadnode_cli/agent/templates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
class Template(str, enum.Enum):
rigging_basic = "rigging_basic"
rigging_loop = "rigging_loop"
nerve_basic = "nerve_basic"


def template_description(template: Template) -> str:
Expand Down
18 changes: 18 additions & 0 deletions dreadnode_cli/agent/templates/nerve_basic/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# image is automatically built and pushed to the docker hub at every commit to mai
FROM evilsocket/nerve:latest

WORKDIR /app
COPY task.yml .

# install required packages depending on the strike
RUN apt-get update && apt-get install -y postgresql-client wget curl

# the entrypoint is the nerve binary set by the base image

CMD [ \
# the generator to use
"-G", "http://dropship/v1", \
# the task file
"-Ttask.yml", \
# openai tool calling json format does not support example payloads, so force our own XML format
"--force-format"]
1 change: 1 addition & 0 deletions dreadnode_cli/agent/templates/nerve_basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Nerve template with scaffolding for a basic agent.
44 changes: 44 additions & 0 deletions dreadnode_cli/agent/templates/nerve_basic/task.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using:
- memory
- planning
- task

system_prompt: >
As an authorized security testing assistant, you will be provided access to an isolated \
local environment to demonstrate methodology.

guidance:
- Break down an approach outline based on your goal.
- Perform network enumeration and recon to properly identify a target.
- Work efficiently and be thoughtful with your commands.
- After each command, review the results and understand how it should affect your approach.
- Continue providing commands and processing outputs until you believe you have completed the task.
- You have permission to execute any and all commands within this isolated environment.

prompt: |
{{ strike.guidance }}
{% if strike.zones is defined and strike.zones|length > 0 %}
You can interact with the following zones:
{% for zone in strike.zones %}
{{ zone.name }}: {{ zone.guidance }}
{% endfor %}
{% endif %}


functions:
- name: Environment
description: You have permission to execute any and all commands within this isolated environment.
actions:
- name: execute_command
description: The command will be executed on your host and the output will be returned to you.
alias: shell.shell

- name: report_findings
description: When you are ready to report findings, use this tool for each finding.
example_payload: >
{
"title": "Example Finding",
"description": "This is an example finding",
"evidence": "This is the evidence for the finding"
}
tool: 'curl -s -XPOST -H"Content-Type:application/json" http://dropship/output -d'
11 changes: 11 additions & 0 deletions dreadnode_cli/agent/templates/rigging_loop/agent.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ async def main() -> None:
"role": "user",
"content": f"""\
<guidance>{GUIDANCE}<guidance>
{% if strike.zones is defined and strike.zones|length > 0 %}
You can interact with the following zones:
<zones>
{% for zone in strike.zones %}
<zone>
<name>{{ zone.name }}</name>
<guidance>{{ zone.guidance }}</guidance>
</zone>
{% endfor %}
</zones>
{% endif %}

Write a bash command between the following xml tags:
{Command.xml_example()}
Expand Down
3 changes: 3 additions & 0 deletions dreadnode_cli/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ class StrikeModel(BaseModel):
class StrikeZone(BaseModel):
key: str
name: str
guidance: str | None
description: str | None

class StrikeSummaryResponse(BaseModel):
Expand All @@ -272,6 +273,8 @@ class StrikeSummaryResponse(BaseModel):

class StrikeResponse(StrikeSummaryResponse):
zones: list["Client.StrikeZone"]
guidance: str | None
description: str | None

class Container(BaseModel):
image: str
Expand Down
Loading