Project configuration

Projects (aka builders) are folders containing source code and other information needed to compile agents. Agents can be written in whatever language you prefer, but each project MUST follow a certain schema.

├── docker
│   └── builder
│       └── Dockerfile
├── royal.yaml
├── service.py

Only the required files / folders are shown in the project root tree above.

All included items are name and case sensitive, except service.py, which needs to be implemented in some python file regardless.

Royal.yaml

The royal.yaml configuration file is arguably the most important file in your project. It contains all extra build options for your agent, as well as commands and their details, such as the number of parameters required.

Here is an example royal.yaml.

name: Empress
version: 0.0.1
author: pygrum
url: https://github.com/pygrum/Empress
supported_os: [ windows, linux, darwin ]

cmd_schema:
  - name: cd
    usage: cd [path]
    max_args: 1
    opcode: 0
    description_short: change current working directory
  - name: ls
    usage: ls [path]
    max_args: 1
    # When opcode is specified, the provided integer opcode is used in place of the command name, promoting better OpSec
    opcode: 1
    description_short: list files in a directory

builder:
  build_args:
    - name: mode
      type: string
      description: the mode of the compiled agent - session / beacon
      default: session
      required: true
      choices:
        - session
        - beacon

Most of the content of Royal is entirely up to you. It's important that the provided configurations are valid. To check its validity, you can use the Royal Linter.

Command schema

Each item in the command schema section of your configuration has the following structure.

	name    string
	usage   string
	// Specifies the range of arguments this command accepts, with a negative
	// upper bound meaning infinite
	min_args int32
	max_args int32
	// Specifies whether this command requires admin privileges or not
	admin bool
	// the provided integer opcode is used in place of the command name,
	// promoting better OpSec
	opcode           int32
	description_short string
	description_long  string 

Build arguments

Each item in the build arguments section of your configuration has the following structure.

	name        string
	description string
	default     string
	required    bool
	// the variable type - is it a boolean, string, integer?
	type        string
	// The range of choices that this build argument could be set to
	choices     []string

Possible variable types are as follows:

  • bool

  • int

  • string

  • float

It is strongly recommended to use the linter to validate your royal.yaml.

Dockerfile

docker/builder/Dockerfile is a Dockerfile used to create the image for the implant builder, which is tagged and started as a container by Monarch.

Here is a valid example of a builder Dockerfile.

FROM pygrum/monarch:latest

WORKDIR /app

COPY . .

CMD [ "/app/royal.yaml", "/app/service.py" ]

CMD requires 2 arguments.

  1. The path to your royal.yaml

  2. The path to your Python builder service

  3. (optional) The path to your requirements.txt for your builder service

If provided, Monarch's builder application will install your requirements.txt. Then, it will start your builder service in the background and load your Royal to provide the C2 with build options and agent commands on request.

Last updated