Skip to content

Creating Problems

rugo edited this page Feb 22, 2017 · 11 revisions

Creating problems is easy.

If you don't know what a Berlyne problem is, check out the terminology page.

Problems are installed via packages.

A problem is a service that has a security vulnerability and somehow reads the flag from /opt/flag.txt.

Problems should be written to run on Ubuntu > 14.04.

Package content

A package consists of these three elemetns:

  • config.json - the configuration parameters
  • setup - the provisioning script
  • content directory - the problem's actual content

in a folder. The folder's name is the problem's unique slug.

config.json

The config.json file contains, as the name implies, the meta data that is needed during the installation process of the problem.

These are the supported configuration parameters:

  • points[Integer] - The default points of the task, should be >= 1 and <=500, see points
  • ports[Array] - If this is empty, no VM will be created. Contains port Objects with the keys:
    • host[Integer], the tcp port used on the host system. If 0, a unused port will be used. This should always be 0
    • guest[Integer], the tcp port used in the guest OS
    • desc[String], a short description of the function the port fullfills
  • category[String] - A category name, multiple categories should be separated via slash
  • tags[Array] - Contains Strings that are used as tags (e.g. reversing, web, or SQLi), these are used for finding tasks
  • downloads[Object] - These are key value pairs that represent the name (key) and relative path (value) in the problem's content folder.
  • name[String] - Name of the problem. This is shown in the UI
  • desc[String] - Description of the task. Placeholders and HTML can be used here (see placeholders)
  • flag[String] - The flag that needs to get captured to receive points. This parameter should only be used in case the problem's service can't read the flag from /opt/flag.txt (see example problem). This has to be set in case a problem does not define ports and therefore has no VM.

For a full example, see example problem.

During installation these values are used to initialize database objects and the problem instance, the config.json file itself will never be modified by Berlyne.

Placeholders

The description (see config.json, desc) can and should use placeholders.

Placeholders are variables that are replaced by the system when a task description is viewed in a course. Placeholders are written in braces, an example usage could look like this:

"desc": "Access this cool service <a href='http://{HOST}:{PORT_80}'>here</a>"

which would be delivered as:

Access this cool service <a href='http://mydomain.example.com:1234'>here</a>

Note that the {PORT_80} placeholder got replaced by whatever port on the host machine was automatically assigned to the problems port 80.

The currently available placeholders are:

  • PORT_[GUEST_PORT] - this will be replaced by the host port associated with a port in the guest system.
  • HOST - this will be replaced by the hostname/ip address of the guest system.
  • DL_[NAME] - this will be replaced by the download URL for a file specified in the downloads object of the config.json.

For an example usage, see example problem.

Points

The points assigned to a problem are a suggestion to the teacher, they will be taken as the default value, but can be overwritten in a course.

The points should be chosen following this scheme:

  • 50 - Solvable without prior knowledge
  • 100 - No big knowledge about the field is needed
  • 200 - Solvable without much knowledge in the field but requires a very steep learning curve
  • 300 - Solvable only with solid background knowledge in the field
  • 400 - Solvable only with expert knowledge in the required field
  • 500 - Only solvable with expert knowledge in multiple fields of IT sec

A problems "point" attribute is just a small int, so everything your DBMS supports can be chosen, no checks (<= 500 etc.) are performed.

To make the above list more comprehensible, here are some examples:

  • 50 - A JavaScript password can be viewed in the source code of a website
  • 100 - A PHP script that has a SQL injection vulnerability
  • 200 - A program that encrypts secrets with RSA using a fixed and small exponent
  • 300 - Reversing a stripped, obfuscated binary, to extract a weak algorithm
  • 400 - Get a key using an invalid curve attack on a TLS-ECDH service
  • 500 - Restore a program from a memory dump, exploit it on a server using a ROP chain

setup

This is a bash script that runs as root on the first startup of the guest system and if the system is rebuild, see Vagrant Docs.

This script should set up users, install programs, set permissions and install/start the vulnerable service.

For a setup example, see example problem.

This script should use the $CONTENT_DIR environment variable and not the fixed path /opt/problem!

content directory

This content directory contains all files needed for the guest system and the files that should be served as download.

The values of the downloads parameter in the config.json file are relative paths inside the content folder.

The content folder can contain a folder named dl_only which will not be synced to the guest system. All remaining files will be available in the guest system under the path /opt/problem with permissions 0775 for directories and 0664 for files.

A content directory with the structure:

├── dl_only
│   └── some_wierd_dump.pcap
├── my_vuln_webpage.php
└── template
    └── awes00me_page.html

Would cause the guest system to have the files:

├── flag.txt
├── problem/
    └── my_vuln_webpage.php
    └── template/
        └── awes00me_page.html

synced to the folder /opt.

The synchronization is always one way (to the guest system) and only happens when the instance is created (during first start or rebuild).

The file some_wierd_dump.pcap would not be synced to the guest system, but would still be available as a download (see config.json):

"downloads": {"dump" : "dl_only/some_wierd_dump.pcap"},
"desc": "... download dump here: <a href='{DL_dump}'>Dump</a> ..."
Clone this wiki locally