Setup of forcAD done, now services
parent
f8a9e46491
commit
3ced1d8807
|
@ -27,3 +27,9 @@ Ansible:
|
|||
## Start
|
||||
You shuold firstly specify server in the `invenvtory` file. Then start the root of repo and execute ` ansible-playbook -i inventory deploy_forcad.yml` command.
|
||||
|
||||
|
||||
## Todo:
|
||||
- create N teams
|
||||
- fix docker installation
|
||||
- VPN
|
||||
- test
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
- name: Setup ForcAD infra
|
||||
hosts: faust_ad
|
||||
hosts: forc_ad
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
|
@ -8,3 +8,8 @@
|
|||
include_role:
|
||||
name: docker
|
||||
tasks_from: main
|
||||
|
||||
- name: Install and setup forcAD
|
||||
include_role:
|
||||
name: forcad
|
||||
tasks_from: main
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[faust_ad]
|
||||
ubuntu.vic ansible_connection=ssh
|
||||
[forc_ad]
|
||||
192.168.88.130 ansible_connection=ssh ansible_user=root ansible_ssh_pass=root
|
||||
|
|
|
@ -10,15 +10,16 @@
|
|||
- python3-setuptools
|
||||
update_cache: true
|
||||
|
||||
- name: Add Docker GPG apt Key
|
||||
apt_key:
|
||||
url: 'https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg'
|
||||
state: present
|
||||
|
||||
- name: Add Docker Repository
|
||||
apt_repository:
|
||||
repo: 'deb https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable'
|
||||
state: present
|
||||
##### WARNING OUTDATED!!! NEED FIX ASAP
|
||||
#- name: Add Docker GPG apt Key
|
||||
# apt_key:
|
||||
# url: 'https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg'
|
||||
# state: present
|
||||
#
|
||||
#- name: Add Docker Repository
|
||||
# apt_repository:
|
||||
# repo: 'deb https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable'
|
||||
# state: present
|
||||
|
||||
- name: Install Docker
|
||||
apt:
|
||||
|
@ -29,7 +30,7 @@
|
|||
- docker-compose-plugin
|
||||
update_cache: true
|
||||
|
||||
- name: Install Docker Module for Python
|
||||
- name: Install docker-compose
|
||||
pip:
|
||||
name:
|
||||
- docker
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
admin:
|
||||
password: 4206942069
|
||||
username: forcad
|
||||
game:
|
||||
mode: classic
|
||||
round_time: 20
|
||||
start_time: 2019-11-30 15:30:00
|
||||
timezone: Europe/Ljubljana
|
||||
|
||||
default_score: 2500
|
||||
flag_lifetime: 5
|
||||
game_hardness: 10.0
|
||||
inflation: true
|
||||
|
||||
tasks:
|
||||
- checker: test_service/checker.py
|
||||
checker_timeout: 10
|
||||
checker_type: hackerdom
|
||||
gets: 2
|
||||
name: test_basic_service
|
||||
places: 5
|
||||
puts: 2
|
||||
|
||||
- checker: test_service/gevent_checker.py
|
||||
checker_timeout: 10
|
||||
checker_type: gevent
|
||||
gets: 2
|
||||
name: test_gevent_service_1
|
||||
places: 5
|
||||
puts: 2
|
||||
|
||||
teams:
|
||||
- ip: 192.168.1.2
|
||||
name: "Team 1"
|
||||
|
||||
- ip: 192.168.1.3
|
||||
name: "Team 2 (highlighted)"
|
||||
highlighted: true
|
|
@ -0,0 +1,44 @@
|
|||
- name: Create forcAD directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ forc_ad_directory }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Download forcAD files
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ forc_ad_link }}"
|
||||
dest: "{{ forc_ad_directory }}"
|
||||
|
||||
- name: Unzip forcAD files
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ forc_ad_directory}}/{{ forc_ad_zipfile }}"
|
||||
dest: "{{ forc_ad_directory }}"
|
||||
remote_src: true
|
||||
|
||||
- name: Set unzipped directory
|
||||
ansible.builtin.set_fact:
|
||||
forc_ad_directory: "{{ forc_ad_directory }}/{{ forc_ad_zipfile.split('.z')[0] }}"
|
||||
|
||||
- name: Make sure python and python-venv are installed
|
||||
ansible.builtin.apt:
|
||||
pkg:
|
||||
- python3
|
||||
- python3-venv
|
||||
|
||||
- name: Create venv
|
||||
ansible.builtin.pip:
|
||||
requirements: "{{ item }}"
|
||||
virtualenv: "{{ forc_ad_directory }}//.venv"
|
||||
virtualenv_python: python3
|
||||
with_items:
|
||||
- "{{ forc_ad_directory }}/cli/requirements.txt"
|
||||
- "{{ forc_ad_directory }}/checkers/requirements.txt"
|
||||
|
||||
- name: Copy forcAD config
|
||||
ansible.builtin.copy:
|
||||
src: "config.yml"
|
||||
dest: "{{ forc_ad_directory }}"
|
||||
|
||||
- name: Setup forcAD
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ forc_ad_directory }}/.venv/bin/python3 {{ forc_ad_directory }}/control.py setup"
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
# Default directory for forcAD files
|
||||
forc_ad_directory: '/forc_ad'
|
||||
|
||||
# forcAD download link
|
||||
forc_ad_link: 'https://github.com/pomo-mondreganto/ForcAD/releases/download/v1.4.0/ForcAD_v1.4.0.zip'
|
||||
|
||||
# forcAd zipfile
|
||||
forc_ad_zipfile: 'ForcAD_v1.4.0.zip'
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Author: Angelo Delicato
|
||||
# Description: Just a checker for the BabySql ForcAD Vulnbox
|
||||
# Note: Use this file inside the checker folder in ForcAD
|
||||
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
BASE_DIR = Path(__file__).absolute().resolve().parent
|
||||
sys.path.insert(0, str(BASE_DIR))
|
||||
|
||||
from service_lib import *
|
||||
|
||||
class Checker(BaseChecker):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Checker, self).__init__(*args, **kwargs)
|
||||
self.mch = CheckMachine(self)
|
||||
|
||||
def action(self, action, *args, **kwargs):
|
||||
try:
|
||||
super(Checker, self).action(action, *args, **kwargs)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.cquit(
|
||||
Status.DOWN,
|
||||
'Connection error',
|
||||
'Got requests connection error',
|
||||
)
|
||||
|
||||
def check(self):
|
||||
self.mch.ping()
|
||||
self.cquit(Status.OK)
|
||||
|
||||
def put(self, flag_id, flag, vuln):
|
||||
new_id = self.mch.put_flag(flag, vuln)
|
||||
self.cquit(Status.OK, new_id)
|
||||
|
||||
def get(self, flag_id, flag, vuln):
|
||||
got_flag = self.mch.get_flag(flag_id, vuln)
|
||||
self.assert_eq(got_flag, flag, 'Could not get flag', status=Status.CORRUPT)
|
||||
self.cquit(Status.OK)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
c = Checker(sys.argv[2])
|
||||
try:
|
||||
c.action(sys.argv[1], *sys.argv[3:])
|
||||
except c.get_check_finished_exception():
|
||||
cquit(Status(c.status), c.public, c.private)
|
|
@ -0,0 +1,46 @@
|
|||
import requests
|
||||
from checklib import *
|
||||
|
||||
PORT = 5005
|
||||
|
||||
class CheckMachine:
|
||||
|
||||
def __init__(self, checker):
|
||||
self.checker = checker
|
||||
|
||||
def ping(self):
|
||||
r = requests.get(f'http://{self.checker.host}:{PORT}/ping/', timeout=2)
|
||||
self.checker.check_response(r, 'Check failed')
|
||||
|
||||
def put_flag(self, flag, vuln):
|
||||
new_id = rnd_string(10)
|
||||
r = requests.post(
|
||||
f'http://{self.checker.host}:{PORT}/put/',
|
||||
json={
|
||||
'id': new_id,
|
||||
'vuln': vuln,
|
||||
'flag': flag,
|
||||
},
|
||||
timeout=2,
|
||||
)
|
||||
self.checker.check_response(r, 'Could not put flag')
|
||||
|
||||
return new_id
|
||||
|
||||
def get_flag(self, flag_id, vuln):
|
||||
r = requests.get(
|
||||
f'http://{self.checker.host}:{PORT}/get/',
|
||||
params={
|
||||
'id': flag_id,
|
||||
'vuln': vuln,
|
||||
},
|
||||
timeout=2,
|
||||
)
|
||||
self.checker.check_response(r, 'Could not get flag')
|
||||
data = self.checker.get_json(r, 'Invalid response from /get/')
|
||||
self.checker.assert_in(
|
||||
'flag', data,
|
||||
'Could not get flag',
|
||||
status=Status.CORRUPT,
|
||||
)
|
||||
return data['flag']
|
|
@ -0,0 +1,9 @@
|
|||
FROM mysql:5.7
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV MYSQL_ROOT_PASSWORD=root
|
||||
ENV MYSQL_USER=baby
|
||||
ENV MYSQL_PASSWORD=sql
|
||||
ENV MYSQL_DATABASE=babysql
|
||||
|
||||
COPY default-users.sql /docker-entrypoint-initdb.d
|
|
@ -0,0 +1,2 @@
|
|||
CREATE TABLE `babysql`.`users` (`id` INT NOT NULL , `username` VARCHAR(255) NOT NULL , `pwd` VARCHAR(255) NOT NULL ) ENGINE = InnoDB;
|
||||
INSERT INTO `users` (`id`, `username`, `pwd`) VALUES ('1', 'admin', 'CCIT{D3f4ult}');
|
|
@ -0,0 +1,56 @@
|
|||
version: '3.9'
|
||||
|
||||
services:
|
||||
db:
|
||||
build:
|
||||
context: ./db
|
||||
ports:
|
||||
- 3306:3306
|
||||
restart: always
|
||||
|
||||
phpmyadmin:
|
||||
image: phpmyadmin/phpmyadmin:5.2.0
|
||||
restart: always
|
||||
ports:
|
||||
- 5004:80
|
||||
links:
|
||||
- db
|
||||
environment:
|
||||
- PMA_HOST=db
|
||||
- PMA_PORT=3306
|
||||
- PMA_ARBITRARY=1
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
web:
|
||||
build:
|
||||
context: ./web
|
||||
restart: always
|
||||
environment:
|
||||
- DBHOST=db
|
||||
- DBUSER=baby
|
||||
- DBPASS=sql
|
||||
- DBSCHEMA=babysql
|
||||
links:
|
||||
- db
|
||||
ports:
|
||||
- 5003:80
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
# Do not tamper this!
|
||||
flag_manager:
|
||||
build:
|
||||
context: ./flag_manager
|
||||
restart: always
|
||||
links:
|
||||
- db
|
||||
environment:
|
||||
- DBHOST=db
|
||||
- DBUSER=baby
|
||||
- DBPASS=sql
|
||||
- DBSCHEMA=babysql
|
||||
ports:
|
||||
- 5005:5005
|
||||
depends_on:
|
||||
- db
|
|
@ -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/
|
||||
|
||||
# Flags file
|
||||
flags.json
|
|
@ -0,0 +1,9 @@
|
|||
FROM python:3.9.13-slim
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY api.py flags.py main.py requirements.txt ./
|
||||
RUN pip install -r requirements.txt
|
||||
EXPOSE 5005
|
||||
|
||||
CMD ["python", "main.py"]
|
|
@ -0,0 +1,31 @@
|
|||
import flags
|
||||
from flask import Blueprint, jsonify, make_response, request
|
||||
|
||||
rest_api = Blueprint('api', __name__)
|
||||
|
||||
@rest_api.route('/ping/', methods = ['GET'])
|
||||
def ping():
|
||||
return make_response("I am alive!")
|
||||
|
||||
@rest_api.route('/get/', methods = ['GET'])
|
||||
def get_flag():
|
||||
try:
|
||||
args = request.args
|
||||
id = args['id']
|
||||
vuln = args['vuln']
|
||||
flag = flags.Singleton().get_flag(id, vuln)
|
||||
return make_response(jsonify({'flag': flag}))
|
||||
except Exception as e:
|
||||
return make_response(str(e))
|
||||
|
||||
@rest_api.route('/put/', methods = ['POST'])
|
||||
def set_flag():
|
||||
try:
|
||||
body = request.get_json()
|
||||
id = body['id']
|
||||
vuln = body['vuln']
|
||||
flag = body['flag']
|
||||
flags.Singleton().set_flag(id, vuln, flag)
|
||||
return make_response('Flag correctly set')
|
||||
except Exception as e:
|
||||
return make_response(str(e))
|
|
@ -0,0 +1,44 @@
|
|||
import os
|
||||
import peewee
|
||||
import json
|
||||
|
||||
dbschema = os.getenv('DBSCHEMA', default=None)
|
||||
dbuser = os.getenv('DBUSER', default=None)
|
||||
dbpwd = os.getenv('DBPASS', default=None)
|
||||
dbhost = os.getenv('DBHOST', default=None)
|
||||
|
||||
database = peewee.MySQLDatabase(dbschema, user=dbuser, password=dbpwd, host=dbhost, port=3306)
|
||||
|
||||
class Singleton():
|
||||
flags = []
|
||||
|
||||
"""Implement it as a Singleton"""
|
||||
def __new__(cls):
|
||||
if not hasattr(cls, 'instance'):
|
||||
cls.instance = super(Singleton, cls).__new__(cls)
|
||||
return cls.instance
|
||||
|
||||
def get_flag(self, id, vuln):
|
||||
is_correct_flag = lambda f: f['id'] == id and f['vuln'] == vuln
|
||||
flag = next(filter(is_correct_flag, self.flags), None)['flag']
|
||||
return flag
|
||||
|
||||
def set_flag(self, id, vuln, flag):
|
||||
new_flag = {'id': id, 'vuln': vuln, 'flag': flag}
|
||||
self.flags.append(new_flag)
|
||||
with open('flags.json', 'w') as outfile:
|
||||
json.dump(self.flags, outfile, sort_keys=True, indent=4, separators=(',', ': '))
|
||||
database.connect()
|
||||
query = Users.update({Users.pwd:flag}).where(Users.username == "admin")
|
||||
query.execute()
|
||||
database.close()
|
||||
|
||||
class BaseModel(peewee.Model):
|
||||
class Meta:
|
||||
database = database
|
||||
|
||||
class Users(BaseModel):
|
||||
id = peewee.IntegerField(unique=True)
|
||||
username = peewee.CharField()
|
||||
pwd = peewee.CharField()
|
||||
base = BaseModel()
|
|
@ -0,0 +1,20 @@
|
|||
import flask
|
||||
import flags
|
||||
from api import rest_api
|
||||
|
||||
PORT = 5005
|
||||
|
||||
def main():
|
||||
app = flask.Flask(__name__)
|
||||
app.register_blueprint(rest_api)
|
||||
|
||||
# Instantiate Flags Singleton
|
||||
flags.Singleton()
|
||||
|
||||
# Load server
|
||||
print(f"BabySql Flag Manager running on port {PORT}")
|
||||
app.run(host='0.0.0.0', port=PORT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,9 @@
|
|||
click==8.1.3
|
||||
Flask==2.1.2
|
||||
inputimeout==1.0.4
|
||||
itsdangerous==2.1.2
|
||||
Jinja2==3.1.2
|
||||
MarkupSafe==2.1.1
|
||||
peewee==3.15.0
|
||||
PyMySQL==1.0.2
|
||||
Werkzeug==2.1.2
|
|
@ -0,0 +1,7 @@
|
|||
FROM php:7.2-apache
|
||||
|
||||
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
|
||||
COPY index.php /var/www/html/index.php
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
error_reporting(0);
|
||||
if(isset($_GET['source'])){
|
||||
highlight_file(__FILE__);
|
||||
die();
|
||||
}
|
||||
function do_query($query){
|
||||
|
||||
$servername = getenv('DBHOST');
|
||||
$username = getenv('DBUSER');
|
||||
$password = getenv('DBPASS');
|
||||
$dbschema = getenv('DBSCHEMA');
|
||||
|
||||
$conn = new mysqli($servername, $username, $password, $dbschema, 3306);
|
||||
|
||||
if ($conn->connect_error) {
|
||||
die("Connection failed: " . $conn->connect_error);
|
||||
}
|
||||
|
||||
$result = $conn->query($query);
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
return $result->fetch_assoc();
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['password'])){
|
||||
#$password = addslashes($_POST['password']);
|
||||
$password = $_POST['password'];
|
||||
|
||||
$query = "SELECT * FROM users WHERE pwd=('$password') AND username=('admin')";
|
||||
|
||||
if (preg_match('/INSERT|UPDATE|DELETE|CREATE|ALTER|DROP/i', $query)) {
|
||||
die("Sorry! You cannot do that.");
|
||||
}
|
||||
|
||||
$res = do_query($query);
|
||||
|
||||
if(isset($res['username'])){
|
||||
$name = $res['username'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<title></title>
|
||||
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<!-- Optional theme -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h1>BabySql</h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p class="lead">
|
||||
Welcome to BabySql! If you want you can view the source code <a href="?source">here</a>. Happy Injection:)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<form class="form form-inline" method='POST'>
|
||||
<input class="form-control" name='password' class='form-control' type='password' value='' placeholder='Password'>
|
||||
<input class="form-control btn btn-default" name="submit" value='Go' type='submit'>
|
||||
</form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p class="lead">
|
||||
<?php
|
||||
if($name){?>
|
||||
Logged as <?= htmlspecialchars($name) ?>
|
||||
<?php }; ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Author: Angelo Delicato
|
||||
# Description: Just a dummy checker for the Dummy ForcAD Vulnbox
|
||||
# Note: Use this file inside the checker folder in ForcAD
|
||||
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
BASE_DIR = Path(__file__).absolute().resolve().parent
|
||||
sys.path.insert(0, str(BASE_DIR))
|
||||
|
||||
from service_lib import *
|
||||
|
||||
class Checker(BaseChecker):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Checker, self).__init__(*args, **kwargs)
|
||||
self.mch = CheckMachine(self)
|
||||
|
||||
def action(self, action, *args, **kwargs):
|
||||
try:
|
||||
super(Checker, self).action(action, *args, **kwargs)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.cquit(
|
||||
Status.DOWN,
|
||||
'Connection error',
|
||||
'Got requests connection error',
|
||||
)
|
||||
|
||||
def check(self):
|
||||
self.mch.ping()
|
||||
self.cquit(Status.OK)
|
||||
|
||||
def put(self, flag_id, flag, vuln):
|
||||
new_id = self.mch.put_flag(flag, vuln)
|
||||
self.cquit(Status.OK, new_id)
|
||||
|
||||
def get(self, flag_id, flag, vuln):
|
||||
got_flag = self.mch.get_flag(flag_id, vuln)
|
||||
self.assert_eq(got_flag, flag, 'Could not get flag', status=Status.CORRUPT)
|
||||
self.cquit(Status.OK)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
c = Checker(sys.argv[2])
|
||||
try:
|
||||
c.action(sys.argv[1], *sys.argv[3:])
|
||||
except c.get_check_finished_exception():
|
||||
cquit(Status(c.status), c.public, c.private)
|
|
@ -0,0 +1,46 @@
|
|||
import requests
|
||||
from checklib import *
|
||||
|
||||
PORT = 5001
|
||||
|
||||
class CheckMachine:
|
||||
|
||||
def __init__(self, checker):
|
||||
self.checker = checker
|
||||
|
||||
def ping(self):
|
||||
r = requests.get(f'http://{self.checker.host}:{PORT}/ping', timeout=2)
|
||||
self.checker.check_response(r, 'Check failed')
|
||||
|
||||
def put_flag(self, flag, vuln):
|
||||
new_id = rnd_string(10)
|
||||
r = requests.post(
|
||||
f'http://{self.checker.host}:{PORT}/put',
|
||||
json={
|
||||
'id': new_id,
|
||||
'vuln': vuln,
|
||||
'flag': flag,
|
||||
},
|
||||
timeout=2,
|
||||
)
|
||||
self.checker.check_response(r, 'Could not put flag')
|
||||
|
||||
return new_id
|
||||
|
||||
def get_flag(self, flag_id, vuln):
|
||||
r = requests.get(
|
||||
f'http://{self.checker.host}:{PORT}/get',
|
||||
params={
|
||||
'id': flag_id,
|
||||
'vuln': vuln,
|
||||
},
|
||||
timeout=2,
|
||||
)
|
||||
self.checker.check_response(r, 'Could not get flag')
|
||||
data = self.checker.get_json(r, 'Invalid response from /get')
|
||||
self.checker.assert_in(
|
||||
'flag', data,
|
||||
'Could not get flag',
|
||||
status=Status.CORRUPT,
|
||||
)
|
||||
return data['flag']
|
|
@ -0,0 +1,130 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
|
@ -0,0 +1,10 @@
|
|||
FROM node:alpine3.16
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY src ./src
|
||||
RUN yarn install
|
||||
EXPOSE 5001
|
||||
|
||||
CMD ["node", "src/server.js"]
|
|
@ -0,0 +1,6 @@
|
|||
version: "3.9"
|
||||
services:
|
||||
dummy:
|
||||
build: .
|
||||
ports:
|
||||
- "5001:5001"
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "Dummy-ForcAD-Vulnbox",
|
||||
"version": "1.0.0",
|
||||
"main": "src/server.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.20.0",
|
||||
"express": "^4.18.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
class FlagService {
|
||||
constructor() {
|
||||
this.flags = []
|
||||
}
|
||||
|
||||
getFlag(id, vuln) {
|
||||
return this.flags.find((f) => f.id === id && f.vuln === vuln).flag
|
||||
}
|
||||
|
||||
setFlag(id, vuln, flag) {
|
||||
const newFlag = {id, vuln, flag}
|
||||
this.flags.push(newFlag);
|
||||
}
|
||||
|
||||
getLastFlag() {
|
||||
const index = this.flags.length-1
|
||||
return this.flags[index].flag
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new FlagService();
|
|
@ -0,0 +1,65 @@
|
|||
const express = require('express')
|
||||
const bodyParser = require('body-parser')
|
||||
const flagService = require('./flag')
|
||||
const app = express()
|
||||
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
app.use(express.json());
|
||||
|
||||
PORT = 5001;
|
||||
|
||||
const log = (msg) => {
|
||||
const currentDate = new Date().toUTCString();
|
||||
console.log(`[${currentDate}] ${msg}`)
|
||||
}
|
||||
|
||||
app.get('/', (_req, res) => {
|
||||
log("GET on /")
|
||||
res.send('I am just a dummy Vulnbox')
|
||||
})
|
||||
|
||||
app.get('/ping', (_req, res) => {
|
||||
log("GET on /ping")
|
||||
res.send('I am just a dummy Vulnbox')
|
||||
})
|
||||
|
||||
app.get('/get', (req, res) => {
|
||||
log("GET on /get")
|
||||
|
||||
if (req.query && req.query.id && req.query.vuln) {
|
||||
log(`Received id: ${req.query.id} - vuln: ${req.query.vuln}`)
|
||||
const id = req.query.id
|
||||
const vuln = req.query.vuln
|
||||
res.json({flag:flagService.getFlag(id, vuln)})
|
||||
}
|
||||
else {
|
||||
res.send("ERROR: flag not set")
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/put', (req, res) => {
|
||||
log("POST on /put")
|
||||
|
||||
if (req.body && req.body.id && req.body.vuln && req.body.flag) {
|
||||
log(`Received body with id: ${req.body.id} - vuln: ${req.body.vuln} - flag: ${req.body.flag}`)
|
||||
const id = req.body.id
|
||||
const vuln = req.body.vuln
|
||||
const flag = req.body.flag
|
||||
|
||||
flagService.setFlag(id, vuln, flag)
|
||||
res.send("Flag correctly set")
|
||||
}
|
||||
else {
|
||||
res.send("ERROR: flag not set")
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/hackme', (_req, res) => {
|
||||
log("GET on /hackme")
|
||||
res.json({flag: flagService.getLastFlag()})
|
||||
})
|
||||
|
||||
log(`Starting Dummy ForcAD Vulnbox on port ${PORT}`)
|
||||
app.listen(PORT)
|
|
@ -0,0 +1,405 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
accepts@~1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
|
||||
dependencies:
|
||||
mime-types "~2.1.34"
|
||||
negotiator "0.6.3"
|
||||
|
||||
array-flatten@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
|
||||
|
||||
body-parser@1.20.0, body-parser@^1.20.0:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5"
|
||||
integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==
|
||||
dependencies:
|
||||
bytes "3.1.2"
|
||||
content-type "~1.0.4"
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
destroy "1.2.0"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
on-finished "2.4.1"
|
||||
qs "6.10.3"
|
||||
raw-body "2.5.1"
|
||||
type-is "~1.6.18"
|
||||
unpipe "1.0.0"
|
||||
|
||||
bytes@3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
|
||||
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
|
||||
|
||||
call-bind@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||
integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.2"
|
||||
|
||||
content-disposition@0.5.4:
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
||||
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
|
||||
dependencies:
|
||||
safe-buffer "5.2.1"
|
||||
|
||||
content-type@~1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
cookie-signature@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
|
||||
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
|
||||
|
||||
cookie@0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
|
||||
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
|
||||
|
||||
debug@2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
depd@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
|
||||
destroy@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
|
||||
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
|
||||
|
||||
escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
|
||||
|
||||
etag@~1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
||||
|
||||
express@^4.18.1:
|
||||
version "4.18.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf"
|
||||
integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==
|
||||
dependencies:
|
||||
accepts "~1.3.8"
|
||||
array-flatten "1.1.1"
|
||||
body-parser "1.20.0"
|
||||
content-disposition "0.5.4"
|
||||
content-type "~1.0.4"
|
||||
cookie "0.5.0"
|
||||
cookie-signature "1.0.6"
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
finalhandler "1.2.0"
|
||||
fresh "0.5.2"
|
||||
http-errors "2.0.0"
|
||||
merge-descriptors "1.0.1"
|
||||
methods "~1.1.2"
|
||||
on-finished "2.4.1"
|
||||
parseurl "~1.3.3"
|
||||
path-to-regexp "0.1.7"
|
||||
proxy-addr "~2.0.7"
|
||||
qs "6.10.3"
|
||||
range-parser "~1.2.1"
|
||||
safe-buffer "5.2.1"
|
||||
send "0.18.0"
|
||||
serve-static "1.15.0"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "2.0.1"
|
||||
type-is "~1.6.18"
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
finalhandler@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
|
||||
integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
on-finished "2.4.1"
|
||||
parseurl "~1.3.3"
|
||||
statuses "2.0.1"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
forwarded@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
||||
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||
|
||||
fresh@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
get-intrinsic@^1.0.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
|
||||
integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.3"
|
||||
|
||||
has-symbols@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
http-errors@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
|
||||
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
|
||||
dependencies:
|
||||
depd "2.0.0"
|
||||
inherits "2.0.4"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "2.0.1"
|
||||
toidentifier "1.0.1"
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
inherits@2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
ipaddr.js@1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
||||
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
|
||||
|
||||
merge-descriptors@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@~2.1.24, mime-types@~2.1.34:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
mime@1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
|
||||
|
||||
ms@2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
negotiator@0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
||||
|
||||
object-inspect@^1.9.0:
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
|
||||
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
|
||||
|
||||
on-finished@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
||||
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
|
||||
dependencies:
|
||||
ee-first "1.1.1"
|
||||
|
||||
parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
|
||||
|
||||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
|
||||
|
||||
proxy-addr@~2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
|
||||
integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
|
||||
dependencies:
|
||||
forwarded "0.2.0"
|
||||
ipaddr.js "1.9.1"
|
||||
|
||||
qs@6.10.3:
|
||||
version "6.10.3"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e"
|
||||
integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
|
||||
dependencies:
|
||||
side-channel "^1.0.4"
|
||||
|
||||
range-parser@~1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||
|
||||
raw-body@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
|
||||
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
|
||||
dependencies:
|
||||
bytes "3.1.2"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
send@0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
|
||||
integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
destroy "1.2.0"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
fresh "0.5.2"
|
||||
http-errors "2.0.0"
|
||||
mime "1.6.0"
|
||||
ms "2.1.3"
|
||||
on-finished "2.4.1"
|
||||
range-parser "~1.2.1"
|
||||
statuses "2.0.1"
|
||||
|
||||
serve-static@1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
|
||||
integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
|
||||
dependencies:
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
parseurl "~1.3.3"
|
||||
send "0.18.0"
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
|
||||
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
|
||||
|
||||
side-channel@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
|
||||
dependencies:
|
||||
call-bind "^1.0.0"
|
||||
get-intrinsic "^1.0.2"
|
||||
object-inspect "^1.9.0"
|
||||
|
||||
statuses@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
toidentifier@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||
|
||||
type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
|
||||
dependencies:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
|
||||
|
||||
utils-merge@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
||||
|
||||
vary@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Author: Angelo Delicato
|
||||
# Description: Just a checker for the HashMePlease ForcAD Vulnbox
|
||||
# Note: Use this file inside the checker folder in ForcAD
|
||||
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
BASE_DIR = Path(__file__).absolute().resolve().parent
|
||||
sys.path.insert(0, str(BASE_DIR))
|
||||
|
||||
from service_lib import *
|
||||
|
||||
class Checker(BaseChecker):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Checker, self).__init__(*args, **kwargs)
|
||||
self.mch = CheckMachine(self)
|
||||
|
||||
def action(self, action, *args, **kwargs):
|
||||
try:
|
||||
super(Checker, self).action(action, *args, **kwargs)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.cquit(
|
||||
Status.DOWN,
|
||||
'Connection error',
|
||||
'Got requests connection error',
|
||||
)
|
||||
|
||||
def check(self):
|
||||
self.mch.ping()
|
||||
self.cquit(Status.OK)
|
||||
|
||||
def put(self, flag_id, flag, vuln):
|
||||
new_id = self.mch.put_flag(flag, vuln)
|
||||
self.cquit(Status.OK, new_id)
|
||||
|
||||
def get(self, flag_id, flag, vuln):
|
||||
got_flag = self.mch.get_flag(flag_id, vuln)
|
||||
self.assert_eq(got_flag, flag, 'Could not get flag', status=Status.CORRUPT)
|
||||
self.cquit(Status.OK)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
c = Checker(sys.argv[2])
|
||||
try:
|
||||
c.action(sys.argv[1], *sys.argv[3:])
|
||||
except c.get_check_finished_exception():
|
||||
cquit(Status(c.status), c.public, c.private)
|
|
@ -0,0 +1,46 @@
|
|||
import requests
|
||||
from checklib import *
|
||||
|
||||
PORT = 5002
|
||||
|
||||
class CheckMachine:
|
||||
|
||||
def __init__(self, checker):
|
||||
self.checker = checker
|
||||
|
||||
def ping(self):
|
||||
r = requests.get(f'http://{self.checker.host}:{PORT}/ping/', timeout=2)
|
||||
self.checker.check_response(r, 'Check failed')
|
||||
|
||||
def put_flag(self, flag, vuln):
|
||||
new_id = rnd_string(10)
|
||||
r = requests.post(
|
||||
f'http://{self.checker.host}:{PORT}/put/',
|
||||
json={
|
||||
'id': new_id,
|
||||
'vuln': vuln,
|
||||
'flag': flag,
|
||||
},
|
||||
timeout=2,
|
||||
)
|
||||
self.checker.check_response(r, 'Could not put flag')
|
||||
|
||||
return new_id
|
||||
|
||||
def get_flag(self, flag_id, vuln):
|
||||
r = requests.get(
|
||||
f'http://{self.checker.host}:{PORT}/get/',
|
||||
params={
|
||||
'id': flag_id,
|
||||
'vuln': vuln,
|
||||
},
|
||||
timeout=2,
|
||||
)
|
||||
self.checker.check_response(r, 'Could not get flag')
|
||||
data = self.checker.get_json(r, 'Invalid response from /get/')
|
||||
self.checker.assert_in(
|
||||
'flag', data,
|
||||
'Could not get flag',
|
||||
status=Status.CORRUPT,
|
||||
)
|
||||
return data['flag']
|
|
@ -0,0 +1 @@
|
|||
This folder will contain the flags.json file
|
|
@ -0,0 +1,19 @@
|
|||
version: "3.9"
|
||||
services:
|
||||
netcat:
|
||||
build:
|
||||
context: ./netcat
|
||||
ports:
|
||||
- "9600:9600"
|
||||
volumes:
|
||||
- ./:/data
|
||||
|
||||
# Do not tamper with this!
|
||||
flag_manager:
|
||||
build:
|
||||
context: ./flag_manager
|
||||
restart: always
|
||||
ports:
|
||||
- "5002:5002"
|
||||
volumes:
|
||||
- ./:/data
|
|
@ -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/
|
||||
|
||||
# Flags file
|
||||
flags.json
|
|
@ -0,0 +1,9 @@
|
|||
FROM python:3.9.13-slim
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY api.py flags.py main.py requirements.txt ./
|
||||
RUN pip install -r requirements.txt
|
||||
EXPOSE 5002
|
||||
|
||||
CMD ["python", "main.py"]
|
|
@ -0,0 +1,31 @@
|
|||
import flags
|
||||
from flask import Blueprint, jsonify, make_response, request
|
||||
|
||||
rest_api = Blueprint('api', __name__)
|
||||
|
||||
@rest_api.route('/ping/', methods = ['GET'])
|
||||
def ping():
|
||||
return make_response("I am alive!")
|
||||
|
||||
@rest_api.route('/get/', methods = ['GET'])
|
||||
def get_flag():
|
||||
try:
|
||||
args = request.args
|
||||
id = args['id']
|
||||
vuln = args['vuln']
|
||||
flag = flags.Singleton().get_flag(id, vuln)
|
||||
return make_response(jsonify({'flag': flag}))
|
||||
except Exception as e:
|
||||
return make_response(str(e))
|
||||
|
||||
@rest_api.route('/put/', methods = ['POST'])
|
||||
def set_flag():
|
||||
try:
|
||||
body = request.get_json()
|
||||
id = body['id']
|
||||
vuln = body['vuln']
|
||||
flag = body['flag']
|
||||
flags.Singleton().set_flag(id, vuln, flag)
|
||||
return make_response('Flag correctly set')
|
||||
except Exception as e:
|
||||
return make_response(str(e))
|
|
@ -0,0 +1,23 @@
|
|||
import json
|
||||
|
||||
DATA_FOLDER = "/data"
|
||||
|
||||
class Singleton():
|
||||
flags = []
|
||||
|
||||
"""Implement it as a Singleton"""
|
||||
def __new__(cls):
|
||||
if not hasattr(cls, 'instance'):
|
||||
cls.instance = super(Singleton, cls).__new__(cls)
|
||||
return cls.instance
|
||||
|
||||
def get_flag(self, id, vuln):
|
||||
is_correct_flag = lambda f: f['id'] == id and f['vuln'] == vuln
|
||||
flag = next(filter(is_correct_flag, self.flags), None)['flag']
|
||||
return flag
|
||||
|
||||
def set_flag(self, id, vuln, flag):
|
||||
new_flag = {'id': id, 'vuln': vuln, 'flag': flag}
|
||||
self.flags.append(new_flag)
|
||||
with open(f"{DATA_FOLDER}/flags.json", 'w') as outfile:
|
||||
json.dump(self.flags, outfile, sort_keys=True, indent=4, separators=(',', ': '))
|
|
@ -0,0 +1,20 @@
|
|||
import flask
|
||||
import flags
|
||||
from api import rest_api
|
||||
|
||||
PORT = 5002
|
||||
|
||||
def main():
|
||||
app = flask.Flask(__name__)
|
||||
app.register_blueprint(rest_api)
|
||||
|
||||
# Instantiate Flags Singleton
|
||||
flags.Singleton()
|
||||
|
||||
# Load server
|
||||
print(f"HashMePlease Flag Manager running on port {PORT}")
|
||||
app.run(host='0.0.0.0', port=PORT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,6 @@
|
|||
click==8.1.3
|
||||
Flask==2.1.2
|
||||
itsdangerous==2.1.2
|
||||
Jinja2==3.1.2
|
||||
MarkupSafe==2.1.1
|
||||
Werkzeug==2.1.2
|
|
@ -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/
|
||||
|
||||
# Flags file
|
||||
flags.json
|
|
@ -0,0 +1,9 @@
|
|||
FROM alpine/socat:1.7.4.3-r0
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY hashme.py requirements.txt ./
|
||||
RUN apk update && apk add python3 py3-pip && pip install -r requirements.txt
|
||||
EXPOSE 9600
|
||||
|
||||
ENTRYPOINT ["socat", "TCP-LISTEN:9600,fork", "EXEC:'python3 hashme.py'"]
|
|
@ -0,0 +1,49 @@
|
|||
import signal
|
||||
import sys
|
||||
import string
|
||||
import random
|
||||
import json
|
||||
import hashlib
|
||||
from inputimeout import inputimeout, TimeoutOccurred
|
||||
|
||||
DATA_FOLDER = "/data"
|
||||
TIMEOUT = 300
|
||||
BANNER = "Welcome to Hash Me Please!"
|
||||
BYEBYE_MSG = "Unfortunately the hash is not correct. Byeeee!"
|
||||
|
||||
def get_last_flag():
|
||||
try:
|
||||
with open(f"{DATA_FOLDER}/flags.json") as json_file:
|
||||
data = json.load(json_file)
|
||||
return data[-1]['flag']
|
||||
except:
|
||||
print("An error occured, it's not your fault!")
|
||||
|
||||
def hash_me():
|
||||
random_value = ''.join(random.sample(string.ascii_lowercase,15))
|
||||
correct_hash = hashlib.sha512(random_value.encode()).hexdigest()
|
||||
print(f"If you hash me I'll give you a gift: {random_value}")
|
||||
try:
|
||||
user_hash = inputimeout(prompt='>>', timeout=5)
|
||||
if user_hash == correct_hash:
|
||||
print(f"Here is your flag: {get_last_flag()}")
|
||||
else:
|
||||
print(BYEBYE_MSG)
|
||||
except TimeoutOccurred:
|
||||
print(BYEBYE_MSG)
|
||||
|
||||
def handle():
|
||||
print(BANNER)
|
||||
|
||||
print("What do you want to do?")
|
||||
print("1. Hash me")
|
||||
print("0. Exit")
|
||||
ch = int(input("> "))
|
||||
if ch == 1:
|
||||
hash_me()
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
signal.alarm(TIMEOUT)
|
||||
handle()
|
|
@ -0,0 +1 @@
|
|||
inputimeout==1.0.4
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
- name: Todo
|
Loading…
Reference in New Issue