{"id":15040614,"url":"https://github.com/plus-postech/soma","last_synced_at":"2025-04-14T17:30:46.429Z","repository":{"id":57667923,"uuid":"163246590","full_name":"PLUS-POSTECH/soma","owner":"PLUS-POSTECH","description":"Cross-platform CTF problem container manager","archived":false,"fork":false,"pushed_at":"2019-05-20T13:39:01.000Z","size":344,"stargazers_count":24,"open_issues_count":17,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-15T15:24:24.938Z","etag":null,"topics":["ctf","ctf-tools","pwn","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PLUS-POSTECH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-27T04:20:56.000Z","updated_at":"2024-05-09T15:13:55.000Z","dependencies_parsed_at":"2022-09-07T15:41:43.150Z","dependency_job_id":null,"html_url":"https://github.com/PLUS-POSTECH/soma","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLUS-POSTECH%2Fsoma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLUS-POSTECH%2Fsoma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLUS-POSTECH%2Fsoma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLUS-POSTECH%2Fsoma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PLUS-POSTECH","download_url":"https://codeload.github.com/PLUS-POSTECH/soma/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219843493,"owners_count":16556506,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ctf","ctf-tools","pwn","rust"],"created_at":"2024-09-24T20:44:49.488Z","updated_at":"2024-10-15T15:24:57.689Z","avatar_url":"https://github.com/PLUS-POSTECH.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Soma: Your one-stop CTF problem management tool\n\n[![Build Status](https://dev.azure.com/plus-postech/soma/_apis/build/status/PLUS-POSTECH.soma?branchName=master)](https://dev.azure.com/plus-postech/soma/_build/latest?definitionId=1?branchName=master)\n\n- [What is Soma?](#what-is-soma-)\n  * [For problem solvers](#for-problem-solvers)\n  * [For problem setters](#for-problem-setters)\n  * [Dependency](#dependency)\n- [Current Status](#current-status)\n  * [Roadmap](#roadmap)\n- [How to Use](#how-to-use)\n  * [Installation](#installation)\n  * [Command overview](#command-overview)\n  * [Adding repositories](#adding-repositories)\n  * [Building problem images](#building-problem-images)\n  * [Running problems](#running-problems)\n  * [Fetching problem attachments](#fetching-problem-attachments)\n  * [Stopping problems](#stopping-problems)\n  * [Removing problem images](#removing-problem-images)\n  * [Removing repositories](#removing-repositories)\n  * [Updating repositories](#updating-repositories)\n  * [Notes on repository and problem names](#notes-on-repository-and-problem-names)\n    + [Problem query](#problem-query)\n    + [Name rules](#name-rules)\n- [How to Add Soma Support to Your Repository](#how-to-add-soma-support-to-your-repository)\n  * [`soma.toml` syntax](#somatoml-syntax)\n    + [The root section](#the-root-section)\n      - [The `name` field](#the-name-field)\n      - [The `work_dir` field (optional)](#the-work_dir-field-optional)\n    + [The `[binary]` section](#the-binary-section)\n      - [The `os` field](#the-os-field)\n      - [The `cmd` field](#the-cmd-field)\n      - [File entries](#file-entries)\n        * [The `path` field](#the-path-field)\n        * [The `target_path` field (optional)](#the-target_path-field-optional)\n        * [The `public` field (optional)](#the-public-field-optional)\n    + [Other subconfigurations](#other-subconfigurations)\n  * [`soma-list.toml` syntax](#soma-listtoml-syntax)\n    + [The `problems` field](#the-problems-field)\n- [Development](#development)\n  * [Prerequisites](#prerequisites)\n  * [Testing, Building, and Running](#testing-building-and-running)\n- [License](#license)\n  * [Contribution](#contribution)\n\n\n## What is Soma?\n\nSoma is a cross-platform CTF problem container manager.\n\n* Soma helps *problem authors* to easily create and distribute reproducible CTF problem environment.\n* Soma helps *CTF players* to easily download and run CTF problems on their local machine after contests.\n\n### For problem solvers\n\nDownloading and running a problem is as easy as running three commands.\n\n```bash\n$ soma add https://github.com/PLUS-POSTECH/simple-bof.git\n$ soma build simple-bof\n$ soma run simple-bof 31337\n```\n\nCTF problems often contain public files. You can also fetch them easily with soma.\n\n```bash\n# this will copy public files to the current working directory\n$ soma fetch simple-bof\n```\n\n\n### For problem setters\n\nAdd `soma.toml` that describes your problem in your project's root directory. The config file below shows an example of it.\n\n```toml\nname = \"simple-bof\"\n\n[binary]\nos = \"ubuntu:16.04\"\ncmd = \"./simple-bof\"\n\n[[binary.executable]]\npath = \"build/simple-bof\"\npublic = true\n\n[[binary.readonly]]\npath = \"flag\"\n```\n\nThat's all! Soma gets enough information to run your binary from these 12 lines of configuration.\n\nSoma will use reasonable default value for the other things not specified such as\ndefault working directory, file permissions, fork daemon, and standard stream buffering.\nOf course they can be manually configured if needed :)\n\nIf your project contains more than one problems, you can put `soma-list.toml` that lists each problem directory.\n\n```toml\nproblems = [\n    # these subdirectories contain soma.toml files\n    \"problem1\",\n    \"sub-dir/problem2\"\n]\n```\n\n### Dependency\n\nSoma requires [Docker][docker] to be installed on the system.\n\n## Current Status\n\nSoma is in its *alpha* stage. Currently, it supports running a binary file under a `socat` fork server.\n\nWe hope to add more scenarios to it, notably a web problem setup which uses PHP with MySQL and a Python-based setup.\n\nIssues related to 0.1.0 release are marked with [`0.1.0` milestone].\n\n\n### Roadmap\n\n- Better documentation of features. (priority: high)\n- Support multiple containers for a single problem. (priority: low)\n- Support cloud deployment such as AWS, GCP, Azure as well as local deployment. (priority: low)\n\n\n## How to Use\n\n### Installation\n\nUse `cargo install soma-ctf` if you have [Rust][rust-lang] toolchain on your system.\nThis command will download the latest released version from [crates.io][crates.io] and build the executable file.\n\n```bash\n$ cargo install soma-ctf\n```\n\nOr, download the precompiled binary from [the release page][releases].\n\nIf you want to try the cutting-edge master branch, you can also build your own binary from the source. In detail, clone this git repository and run `cargo install`.\n\n```bash\n$ git clone https://github.com/PLUS-POSTECH/soma.git\n$ cd soma\n$ cargo install\n```\n\n### Command overview\n\n|          | Add / Create | Remove |\n| -------- | ------------ | ------ |\n| Repository | [add](#adding-repositories) | [remove](#removing-repositories) |\n| Image | [build](#building-problem-images) | [clean](#removing-problem-images) |\n| Container | [run](#running-problems) | [stop](#stopping-problems) |\n\nAdditionally, [update](#updating-repositories)\n\n\n### Adding repositories\n\nSoma repository has `soma.toml` or `soma-list.toml` in its top level directory and can contain one or more problems. To use Soma, start by adding problem repositories. We will use [`soma-bata-list`][soma-bata-list] as an example throughout this document.\n\nYou can add a repository with `add` subcommand:\n\n```bash\n$ soma add https://github.com/PLUS-POSTECH/soma-bata-list.git\n```\n\n`add` subcommand takes a repository source as an argument, which is `https://github.com/PLUS-POSTECH/soma-bata-list.git` in the command above. Soma supports the following repository sources:\n\n- Git repository (only HTTPS without authentication is supported for now)\n\n  e.g., `https://github.com/PLUS-POSTECH/soma-bata-list.git`\n\n- Local file system directory\n\n  e.g., `/home/linux-user/soma-repo`\n\nBy default, Soma will parse the name of the repository from the repository source string. For example, `https://github.com/PLUS-POSTECH/soma-bata-list.git` will return `soma-bata-list` and `/home/linux-user/soma-repo` will return `soma-repo` as a default repository name. If you want to use another name, you can use `--name [NAME]` flag. This flag will make Soma register the repository under the given name.\n\nAlso, note that there are a few requirements for repository names. See \"[Name rules](#name-rules)\" section for more details.\n\n\n### Building problem images\n\nSoma uses [Docker][docker] to manage problem images and containers. An image is a snapshot of a problem environment, and a container is an instance of an image. In order to run a problem, you should build the problem image first.\n\nSoma will automatically generate Dockerfile from the problem manifest when you execute the build command. You can build a problem image by executing the following command:\n\n```bash\n$ soma build r0pbaby\n# or\n$ soma build soma-bata-list.r0pbaby\n```\n\nAs you can see, there are two different ways to select a problem. See \"[Problem query](#problem-query)\" section for more details.\n\n\n### Running problems\n\nWhen the problem image is ready, you can run the problem container! The problem container can be started with the following command:\n\n```bash\n$ soma run r0pbaby 13337\n# or\n$ soma run soma-bata-list.r0pbaby 13337\n```\n\nHere, `13337` indicates the port number which binds to the problem container. This port number will expose the problem to the host network. In this example, `r0pbaby` is accessible through `your.host.address:13337`. Try `nc localhost 13337` on your machine to start solving the problem.\n\n`run` command requires a port number for now, but we are planning to support automatic port binding in the future (see [#64][issue #64]).\n\n\n### Fetching problem attachments\n\nCTF problems often provide a few attachments (usually problem binaries). There is a dedicated subcommand to fetch these files to your current working directory:\n\n```bash\n$ soma fetch r0pbaby\n# or\n$ soma fetch soma-bata-list.r0pbaby\n```\n\n\n### Stopping problems\n\nAfter finish solving a problem, stop and remove the problem container by invoking:\n\n```bash\n$ soma stop r0pbaby\n# or\n$ soma stop soma-bata-list.r0pbaby\n```\n\n\n### Removing problem images\n\nYou may want to remove existing problem images for several reasons (e.g., free disk space, remove repository). You can clean up existing images by:\n\n```bash\n$ soma clean r0pbaby\n# or\n$ soma clean soma-bata-list.r0pbaby\n```\n\nBefore trying to remove the image, check if any associated container exists. Soma will reject the command if there is a running container from the image.\n\n\n### Removing repositories\n\nIf you want to remove a registered repository, use the following command:\n\n```bash\n$ soma remove soma-bata-list\n```\n\nThere should be no problem image or container associated to the repository when you use this command. Use `clean` and `stop` command to remove them if necessary. Auto pruning for your convenience will be implemented in the future (see [#115][issue #115]).\n\n\n### Updating repositories\n\nYou can update and sync repositories with `update` command:\n\n```bash\n$ soma update soma-bata-list\n```\n\nNote that problem containers that are already running are untouched by this command. You might want to stop, build, and run the problem again after updating a repository.\n\n\n### Notes on repository and problem names\n\n#### Problem query\n\nThere are two ways to identify a problem. You can specify only the name of a problem (e.g., `r0pbaby`) or the full name of a problem containing what repository it is in (e.g., `soma-bata-list.r0pbaby`).\n\nIf the problem name is unique (i.e., the problem name is used only in a single repository), you can use the former method. Otherwise, you must use the latter or Soma will give you an error message that the problem name is found among multiple repositories.\n\n\n#### Name rules\n\nAll repository and problem names should follow the docker name component rules with no `.` (i.e., `^[a-z0-9]+((?:_|__|[-]*)[a-z0-9]+)*$`, see [Docker regexp definitions][docker-regexp] for more details). This measure is to prevent Soma from behaving bad when malicious input is provided. We chose docker name component rules as repository and problem names are substrings of Docker image name. And 'no `.`' rule is added because Soma utilizes `.` as a name separator.\n\n\n## How to Add Soma Support to Your Repository\n\nIn order to support Soma, a repository should have `soma.toml` or `soma-list.toml` in its top level directory. `soma-list.toml` lists each subdirectory that contains a `soma.toml` file, and `soma.toml` is the name of Soma problem manifest file.\n\nIf your repository contains only one problem in its top level directory, `soma.toml` can be used directly without `soma-list.toml`.\n\n\n### `soma.toml` syntax\n\nEach problem in a repository needs a manifest file, `soma.toml`, in its directory. The problem manifest file contains necessary information for Soma to manage problems. We will discuss the syntax of `soma.toml` section by section with this example.\n\n```toml\nname = \"simple-bof\"\nwork_dir = \"/home/simple-bof\"\n\n[binary]\nos = \"ubuntu:16.04\"\ncmd = \"./simple-bof\"\n\n[[binary.executable]]\npath = \"build/simple-bof\"\npublic = true\n\n[[binary.readonly]]\npath = \"flag\"\ntarget_path = \"/you_cannot_guess_this_very_secret_flag_name\"\n```\n\n#### The root section\n\nManifest root contains two metadata for the problem.\n\n```toml\nname = \"simple-bof\"\nwork_dir = \"/home/simple-bof\"\n```\n\n##### The `name` field\n\nThe `name` field of the root section defines the name of the problem. Soma will recognize this field (not the directory name) as the problem name.\n\n##### The `work_dir` field (optional)\n\nThe `work_dir` field of the root section contains the path of the working directory inside the problem image. Default value for this field is the home directory of the user whose name is same with the name of the problem (for the example above, `\"/home/simple-bof\"`).\n\n#### The `[binary]` section\n\nThe `[binary]` section contains information required to use binary subconfiguration. Binary subconfiguration supports a scenario which runs an executable and pipes standard input and output through a TCP connection with a fork daemon; this is one of the most common setups in CTF competitions.\n\n```toml\n[binary]\nos = \"ubuntu:16.04\"\ncmd = \"./simple-bof\"\n\n[[binary.executable]]\npath = \"build/simple-bof\"\npublic = true\n\n[[binary.readonly]]\npath = \"flag\"\ntarget_path = \"/you_cannot_guess_this_very_secret_flag_name\"\n```\n\n##### The `os` field\n\nThe `os` field indicates what OS flavor is used by the problem. This field is currently redirected into the parent image name of `Dockerfile`. However, it will only allow pre-selected choices in the future.\n\n##### The `cmd` field\n\nThe `cmd` field defines how to run the problem binary. The specified binary will be executed through [socat](https://linux.die.net/man/1/socat) daemon.\n\n##### File entries\n\n`[[binary.executable]]`, `[[binary.readonly]]` sections contain file entries of the subconfiguration.\n\n`[[binary.readwrite]]`, `[[binary.with-permissions]]`, and `[[binary.fetchonly]]` are reserved for a future implementation (see [#50][issue #50] and [#84][issue #84]).\n\n###### The `path` field\n\nThe `path` field contains a relative path to the file from the problem directory. Supporting external sources such as URL is planned in the future (see [#114][issue #114]).\n\n###### The `target_path` field (optional)\n\nThe `target_path` field specifies where the file should be copied inside the problem image. This field defaults to `work_dir` in the root section.\n\n###### The `public` field (optional)\n\nFile entries with `public` field set to `true` will be copied to the current working directory when users invoke `fetch` subcommand. This field has a default value of `false`.\n\n#### Other subconfigurations\n\nOther subconfigurations for common CTF setups such as `apache-php7`, `python-uwsgi`, or `mysql` are planned to be supported in a future release (see [#50][issue #50]). Subconfiguration syntax is designed to support multi-configuration problem in the future, which will be handled similarly to [Docker compose][docker-compose].\n\n\n### `soma-list.toml` syntax\n\n#### The `problems` field\n\n`soma-list.toml` contains a single field `problems` which is an array of relative paths to each problem directory.\n\n```toml\nproblems = [\n    # these subdirectories contain soma.toml files\n    \"simple-bof\",\n    \"hard/complicated-bof\"\n]\n```\n\n\n## Development\n\n### Prerequisites\n\n* Install [Rust][rust-lang] stable toolchain.\n* Install `openssl` (Required by `openssl-sys` crate).\n* Install `clippy` and `rustfmt`.\n    * `rustup component add clippy rustfmt`\n* Copy files in `hooks` directory to `.git/hooks`.\n\n\n### Testing, Building, and Running\n\nSoma is written with Rust and utilizes Cargo as a building and testing system.\n\nYou can test, build, and run with the following command.\n\n```bash\n$ cargo test\n$ cargo build\n$ cargo run\n```\n\n\n## License\n\nLicensed under either of\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\nat your option.\n\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.\n\n\n[issue #50]: https://github.com/PLUS-POSTECH/soma/issues/50\n[issue #64]: https://github.com/PLUS-POSTECH/soma/issues/64\n[issue #84]: https://github.com/PLUS-POSTECH/soma/issues/84\n[issue #114]: https://github.com/PLUS-POSTECH/soma/issues/114\n[issue #115]: https://github.com/PLUS-POSTECH/soma/issues/115\n[`0.1.0` milestone]: https://github.com/PLUS-POSTECH/soma/milestone/1\n\n[crates.io]: https://crates.io/\n[docker]: https://www.docker.com/\n[docker-compose]: https://docs.docker.com/compose/\n[docker-regexp]: https://github.com/docker/distribution/blob/master/reference/regexp.go\n[releases]: https://github.com/PLUS-POSTECH/soma/releases\n[rust-lang]: https://www.rust-lang.org/\n[soma-bata-list]: https://github.com/PLUS-POSTECH/soma-bata-list\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplus-postech%2Fsoma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplus-postech%2Fsoma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplus-postech%2Fsoma/lists"}