master
nihonium 2 years ago
parent 3b3c9a9417
commit 8e1b388a9e
No known key found for this signature in database
GPG Key ID: 0251623741027CFC

@ -0,0 +1,13 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
[VERSION]
insert_final_newline = false
[*.py]
charset = utf-8
indent_style = space
indent_size = 4

@ -0,0 +1,12 @@
FROM python:3.7.14-slim
ADD src VERSION /dist/
WORKDIR /dist
# setup the services
RUN pip install --requirement aesthetic/requirements.txt
RUN pip install --requirement editor/requirements.txt
RUN pip install --requirement jinnice/requirements.txt
RUN pip install --requirement myblog/requirements.txt
# start game simulation
CMD ["python", "-u", "main.py"]

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2022 VolgaCTF
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.

@ -0,0 +1,67 @@
# VolgaCTF 2022 Final Homework
This repo contains all the checkers from `VolgaCTF 2022 Final` along with a game-simulating script.
Could be useful to do your _homework_.
## Build
```bash
$ docker build -t volgactf2022/homework-image .
```
## Run
```bash
$ docker run \
-e TEAM_IP=<host-ip> \
-e ROUND_DURATION=10 \
--rm \
volgactf2022/homework-image
```
## Optional environment variables
### Simulation-related variables
| Var name | Description | Default value |
|-----------------------------|------------------------------------------------------|:-------------------:|
| `ROUND_DURATION` | Round duration (time between two consecutive PUSHes) | 30 sec |
| `SKIP_EDITOR` | Skip `Editor` service | False |
| `SKIP_AESTHETIC` | Skip `Aesthetic` service | False |
| `SKIP_MYBLOG` | Skip `MyBlog` service | False |
| `SKIP_JINNICE` | Skip `Jinnice` service | False |
| `PULL_COUNT` | Number of PULLs for each round | 5 |
| `PRINT_STATS_EVERY_N_ROUND` | Output stats frequency | 1 |
| `PRINT_STATS_SINGLE_COLUMN` | Output stats in a single column | False (two columns) |
### Checkers' variables
| Var name | Description | Default value |
|--------------------------------|------------------------------------------|:-------------:|
| `EDITOR_PORT` | `Editor` service port | 8080 |
| `EDITOR_TIMEOUT` | `Editor` service connection timeout | 30 |
| `EDITOR_N_MAX_IMAGES_PER_PUSH` | Max number of images to PUSH to `Editor` | 3 |
| `AESTHETIC_PORT` | `Aesthetic` service port | 8777 |
| `AESTHETIC_TIMEOUT` | `Aesthetic` service connection timeout | 15 |
| `MYBLOG_PORT` | `MyBlog` service port | 13377 |
| `MYBLOG_TIMEOUT` | `MyBlog` service connection timeout | 20 |
| `JINNICE_PORT` | `Jinnice` service port | 8888 |
| `JINNICE_TIMEOUT` | `Jinnice` service connection timeout | 30 |
### Example with more options
Below is an example usage which assumes that only `Editor` and `MyBlog` services are spawned,
`Editor`'s port is `18080`, and `MyBlog` checker's connection timeout is increased (e.g. for debugging purposes):
```bash
$ docker run \
-e TEAM_IP=<host-ip> \
-e ROUND_DURATION=10 \
-e SKIP_AESTHETIC= \
-e SKIP_JINNICE= \
-e EDITOR_PORT=18080 \
-e MYBLOG_TIMEOUT=1800 \
--rm \
volgactf2022/homework-image
```
## License
MIT @ [VolgaCTF](https://github.com/VolgaCTF)

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from .main import push, pull

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIF/LZh6xyFkuNfwP349RlC4PBv4DyGPt6BzBiublvj1yoAoGCCqGSM49
AwEHoUQDQgAEGySmc8D9mKY0VGif5el/bnbIlQeRhLEWYtvvINH/IM5W2BfgtrrZ
Vl5dyGy7tAWqpcqluIipcmcYcHqJndIneg==
-----END EC PRIVATE KEY-----

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from random import choice
from string import ascii_letters, digits
def get_random_message(size=16):
return ''.join(choice(ascii_letters + digits) for _ in range(size))

@ -0,0 +1,117 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import base64
import hashlib
import logging
import os
import socket
import jwt
from volgactf.final.checker.result import Result
from .utils import read_message, send_message
logger = logging.getLogger(__name__)
SERVICE_PORT = int(os.getenv('AESTHETIC_PORT', 8777))
SESSION_TOTAL_TIMEOUT = int(os.getenv('AESTHETIC_TIMEOUT', 15))
async def push(endpoint, capsule: str, label, metadata):
try:
logger.debug('[%s on PUSH]: connecting', endpoint)
fd = socket.create_connection((endpoint, SERVICE_PORT), timeout=SESSION_TOTAL_TIMEOUT)
logger.debug('[%s on PUSH]: connected to service', endpoint)
except Exception as ex:
logger.error('[%s on PUSH]: failed to connect, reason: %s', endpoint, str(ex))
return Result.DOWN, '', 'Failed to connect'
try:
send_message(fd, b'PUSH')
iv = b'\x70\x67\x4a\xd5\xaf\x53\x92\xf9\xb2\x94\xde\x78' + os.urandom(4)
send_message(fd, capsule.encode('utf-8'))
send_message(fd, metadata.round.to_bytes(4, 'big'))
send_message(fd, iv)
encrypted_capsule = read_message(fd)
ec_hash = hashlib.sha256(encrypted_capsule).digest()
auth_tag = read_message(fd)
with open('ec_private.pem', 'rb') as jwtkey:
key = jwtkey.read()
signature = jwt.encode(
{'message': 'It\'s me, Mario!'},
key=key,
algorithm='ES256'
)
send_message(fd, signature.encode('utf-8'))
if read_message(fd) != b"+":
send_message(fd, b'EXIT')
read_message(fd)
return Result.MUMBLE, '', ''
send_message(fd, b'EXIT')
read_message(fd)
return Result.UP, \
(base64.b64encode(iv) + b'::' +
base64.b64encode(auth_tag) + b'::' +
base64.b64encode(ec_hash)).decode(), \
'UP'
except Exception as ex:
logger.error('[%s on PUSH]: failed on PUSH, reason: %s', endpoint, str(ex))
return Result.MUMBLE, '', ''
async def pull(endpoint, capsule: bytes, label: str, metadata):
try:
logger.debug('[%s on PULL]: connecting', endpoint)
fd = socket.create_connection((endpoint, SERVICE_PORT), timeout=SESSION_TOTAL_TIMEOUT)
logger.debug('[%s on PULL]: connected to service', endpoint)
except Exception as ex:
logger.error('[%s on PULL]: failed to connect, reason: %s', endpoint, str(ex))
return Result.DOWN, ''
try:
b64_iv, b64_auth_tag, b64_ec_hash = label.encode().split(b'::')
iv = base64.b64decode(b64_iv)
auth_tag = base64.b64decode(b64_auth_tag)
ec_hash = base64.b64decode(b64_ec_hash)
send_message(fd, b'PULL')
send_message(fd, metadata.round.to_bytes(4, 'big'))
received_enc_capsule = read_message(fd)
rec_hash = hashlib.sha256(received_enc_capsule).digest()
if rec_hash != ec_hash:
print(rec_hash, ec_hash)
send_message(fd, b'-')
send_message(fd, b'EXIT')
read_message(fd)
return Result.DOWN, 'Wrong hash'
else:
send_message(fd, b'+')
send_message(fd, iv)
send_message(fd, auth_tag)
recv_capsule = read_message(fd)
if recv_capsule.decode('utf-8') != capsule:
send_message(fd, b'EXIT')
read_message(fd)
return Result.DOWN, 'Corrupted flag'
send_message(fd, b'EXIT')
read_message(fd)
return Result.UP, 'UP'
except Exception as ex:
logger.error('[%s on PULL]: failed on PULL, reason: %s', endpoint, str(ex))
return Result.MUMBLE, ''

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
import logging
import struct
logger = logging.getLogger('service')
"""
Communication
"""
class InputOverflowException(Exception):
pass
class InputUnderflowException(Exception):
pass
def read_message(s, max_input_length=1024*16) -> bytes:
received_buffer = s.recv(8)
if len(received_buffer) < 8:
raise InputUnderflowException('Failed to receive data: the received length is less than 8 bytes long')
to_receive = struct.unpack('<Q', received_buffer[0:8])[0]
if to_receive > max_input_length:
raise InputOverflowException('Failed to receive data: requested to accept too much data')
received_buffer = b''
while len(received_buffer) < to_receive:
data = s.recv(to_receive - len(received_buffer))
if len(data) == 0:
raise InputUnderflowException('Failed to receive data: the pipe must have been broken')
received_buffer += data
if len(received_buffer) > max_input_length:
raise InputOverflowException('Failed to receive data: accepted too much data')
return received_buffer
def send_message(s, message: bytes):
send_buffer = struct.pack('<Q', len(message)) + message
s.sendall(send_buffer)

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from .main import push, pull

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save