-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
982 changed files
with
110,028 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 Andrea Biondo, Matteo Chen, Patric Gruber, Daniele Lain, | ||
Maximilian Lehrbaum, Daniel Marth, Georg Merzdovnik, | ||
Leonardo Nodari, Patrick Pirker, Michael Pucher, | ||
Martin Schwarzl, Marco Squarcina, Lorenzo Veronese, | ||
Roland Wallner | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# ctf-services | ||
A/D CTF services developed for ECSC 2022 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
Aquaeductus | ||
=========== | ||
Who'd have known that balcony gardening would become the most valuable skill in the new world? Long gone are the times of supermarkets and industrial food processing. Now small greenhouses ornate every building, pulsating with the lights of the machines that control them - optimizing every precious drop of water, and every ray of the pale sun that filters through the pollution. Skilled gardeners are the new rockstars, touring across the communes to tend on their vegetable patches, communing with the AIs that forecast the ever-worsening weather. Be sure to be the first to book them. | ||
|
||
Description | ||
----------- | ||
This service manages futuristic gardens where AI predict growth based on weather forecasts, and users can insert their own gardens, and apply and accept requests to water them. | ||
|
||
Flags are stored as private information of the admin's garden, and as a comment at the end of the admin's weather report files. | ||
|
||
|
||
Vulnerabilities | ||
--------------- | ||
The service has two flagstores: | ||
- Flagstore 1 - Third line of the admin's weather report files | ||
- Flagstore 2 - Watering instructions of the admin's garden | ||
|
||
### Flagstore 1 - Vuln 1 | ||
`WeatherLayer` does not check that the number of requested nodes is at most the number of floats that make up a weather report. | ||
By asking for a number of nodes greater than the number of floats there are, a user can also read the flag as input to their neural network. | ||
|
||
### Flagstore 1 - Vuln 2 | ||
`WeatherLayer` allows for special types of activation functions that take a parameter, besides the input. | ||
These parameters can be provided in the second line of a weather report (as a list of floats) but are _optional_. | ||
However, there is no check when asking for such activation function that the file contains these parameters as second line. | ||
This means you read characters of the flag as floats, and use them as parameters for the `explu` layer, where they multiply the floats of the first line of the weather report. This might be exploitable. | ||
|
||
### Flagstore 2 - Vuln 1 | ||
`WateringController.Approve` is checking the garden ownership, but it is not fetching the watering request from the garden. | ||
|
||
### Flagstore 2 - Vuln 2 | ||
`WeatherLayer` allows to specify arbitrary golang attributes for navigation, included `Garden.Instructions`. | ||
This might eventually give you access to more application data if abused enough. | ||
|
||
### Flagstore 2 - Vuln 3 | ||
`LocationLayer` allows to retrieve arbitrary properties from the garden model, included `Garden.Instructions`. | ||
Property value is lost during float parsing, but logs output the flag in hex. | ||
|
||
|
||
Patches | ||
------- | ||
|
||
### Flagstore 1 - Patch 1 | ||
Validate the input size in wasm (look for new line) or filter out the extra data in golang. | ||
|
||
### Flagstore 1 - Patch 2 | ||
Check if the second line is empty or not when asked for a layer with parameters. | ||
|
||
### Flagstore 2 - Patch 1 | ||
`WateringController.Approve` must verify request garden matches input garden. | ||
|
||
### Flagstore 2 - Patch 2 | ||
Limit `rpcRetrieve` to `ReportData`. | ||
|
||
### Flagstore 2 - Patch 3 | ||
Remove `console.log` from `ParseFloat`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
share/python-wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.nox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
*.py,cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
cover/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
db.sqlite3-journal | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
.pybuilder/ | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
|
||
# pyenv | ||
# For a library or package, you might want to ignore these files since the code is | ||
# intended to run in multiple environments; otherwise, check them in: | ||
# .python-version | ||
|
||
# pipenv | ||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
# However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
# having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
# install all needed dependencies. | ||
#Pipfile.lock | ||
|
||
# poetry | ||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. | ||
# This is especially recommended for binary packages to ensure reproducibility, and is more | ||
# commonly ignored for libraries. | ||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control | ||
#poetry.lock | ||
|
||
# pdm | ||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. | ||
#pdm.lock | ||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it | ||
# in version control. | ||
# https://pdm.fming.dev/#use-with-ide | ||
.pdm.toml | ||
|
||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm | ||
__pypackages__/ | ||
|
||
# Celery stuff | ||
celerybeat-schedule | ||
celerybeat.pid | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
|
||
# Pyre type checker | ||
.pyre/ | ||
|
||
# pytype static type analyzer | ||
.pytype/ | ||
|
||
# Cython debug symbols | ||
cython_debug/ | ||
|
||
# PyCharm | ||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can | ||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore | ||
# and can be added to the global gitignore or merged into this file. For a more nuclear | ||
# option (not recommended) you can uncomment the following to ignore the entire idea folder. | ||
#.idea/ | ||
|
||
|
||
report*.bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
FROM wert310/gameserver-basechecker:ef3af01 | ||
|
||
RUN mkdir -p /checker | ||
WORKDIR /checker | ||
|
||
COPY requirements.txt /checker/requirements.txt | ||
RUN pip install -r requirements.txt | ||
|
||
COPY checker.py /checker/checker.py | ||
COPY Network.py /checker/Network.py | ||
COPY WeatherReport.py /checker/WeatherReport.py | ||
USER ctf-checkermaster | ||
ENV CTF_CHECKERSCRIPT /checker/checker.py | ||
|
||
# set this to <yourchallengename>_checker<X> | ||
ENV CTF_SERVICE aquaeductus_checker1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
from numpy.random import Generator | ||
|
||
MAX_NODES = 32 | ||
MAX_NODES_BIG = 128 | ||
BIG_LAYER_PROBABILITY = 0.15 | ||
ACTIVATION_FUNCS = ['linear', 'sigmoid', 'relu', 'selu', 'softplus'] | ||
|
||
|
||
def generate_layer(rng: Generator, layer_name, node_count, extra_info=None, extra_weather_info=None): | ||
if layer_name == 'WeatherLayer' and extra_weather_info: | ||
activation = rng.choice(ACTIVATION_FUNCS + ['explu']) | ||
else: | ||
activation = rng.choice(ACTIVATION_FUNCS) | ||
out = [f"{layer_name} {activation}", f"{node_count}"] | ||
if layer_name == "InputLayer": | ||
inputs = rng.choice(rng.random(rng.integers(1, node_count, endpoint=True)), node_count) | ||
out += [f"InputNode {_in}" for _in in inputs] + ['\n'] | ||
elif layer_name == "WeatherLayer": | ||
out += [f"InputNode 1" for _ in range(node_count)] + [extra_info + '\n'] | ||
elif layer_name == "RandomLayer": | ||
out += [f"InputNode 1" for _ in range(node_count)] + ['\n'] | ||
elif layer_name == "PermutationLayer": | ||
out += [f"InputNode 1" for _ in range(node_count)] + ['\n'] | ||
elif layer_name == "DenseLayer": | ||
weights = [rng.random(extra_info) for _ in range(node_count)] | ||
out += [f"DenseNode {','.join([str(x) for x in weight])}" for weight in weights] + ['\n'] | ||
|
||
return '\n'.join(out) | ||
|
||
|
||
def generate_layer_size(rng: Generator): | ||
if rng.random() < BIG_LAYER_PROBABILITY: | ||
return rng.integers(1, MAX_NODES_BIG) | ||
else: | ||
return rng.integers(1, MAX_NODES) | ||
|
||
|
||
def generate_network(rng: Generator, weather_layer_name=None, weather_layer_size=None, weather_layer_extra=None): | ||
prev_layer_size = 0 | ||
net_definition = "" | ||
|
||
# How many layers (1 - 10) | ||
layers_count = rng.integers(1, 10, endpoint=True) | ||
|
||
# First layer in [weather, random, input] | ||
if weather_layer_name: | ||
layer = "WeatherLayer" | ||
layer_size = weather_layer_size | ||
net_definition += generate_layer(rng, layer, layer_size, extra_info=weather_layer_name, | ||
extra_weather_info=weather_layer_extra) | ||
else: | ||
layer = rng.choice(["RandomLayer", "InputLayer"]) | ||
layer_size = generate_layer_size(rng) | ||
net_definition += generate_layer(rng, layer, layer_size) | ||
|
||
prev_layer_size = layer_size | ||
|
||
# Second -- N-1 layer in [dense, permutation] | ||
for _ in range(layers_count - 1): | ||
layer = rng.choice(["DenseLayer", "PermutationLayer"]) | ||
layer_size = generate_layer_size(rng) | ||
if layer == "DenseLayer": | ||
net_definition += generate_layer(rng, layer, layer_size, prev_layer_size) | ||
prev_layer_size = layer_size | ||
else: | ||
net_definition += generate_layer(rng, layer, prev_layer_size) | ||
|
||
return net_definition, prev_layer_size |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
### Building and running the checker | ||
|
||
Run the application (from `/dist`) | ||
``` | ||
docker-compose up | ||
``` | ||
|
||
Run the checker for one tick (from `/checker/checker1`) | ||
``` | ||
TICK=0 docker-compose up | ||
``` | ||
|
||
This will do the following: | ||
|
||
- call place_flag for the current tick | ||
- call check_service | ||
- call check_flag for up to 5 previous ticks (one invocation per tick) | ||
|
||
To test that checking previous ticks works, call the checker with increasing tick numbers: | ||
``` | ||
TICK=1 docker-compose up # checked ticks: 0, 1 | ||
TICK=2 docker-compose up # checked ticks: 0, 1, 2 | ||
TICK=3 docker-compose up # checked ticks: 0, 1, 2, 3 | ||
TICK=4 docker-compose up # checked ticks: 0, 1, 2, 3, 4 | ||
TICK=5 docker-compose up # checked ticks: 0, 1, 2, 3, 4, 5 | ||
TICK=6 docker-compose up # checked ticks: 1, 2, 3, 4, 5, 6 | ||
... | ||
``` |
Oops, something went wrong.