mirror of
https://github.com/avatao-content/test-tutorial-framework
synced 2024-11-12 19:47:18 +00:00
Initial commit, first version of test TFW project
This commit is contained in:
commit
6d6262b220
11
config.yml
Normal file
11
config.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
version: 'v2.0.0'
|
||||||
|
difficulty: 10
|
||||||
|
enable_flag_input: false
|
||||||
|
name: 'test-tutorial-framework'
|
||||||
|
skills: []
|
||||||
|
owners: ['kristof.toth@avatao.com']
|
||||||
|
crp_config:
|
||||||
|
controller:
|
||||||
|
ports: ["4444/controller"]
|
||||||
|
solvable:
|
||||||
|
ports: ["8888/http"]
|
1
controller/Dockerfile
Normal file
1
controller/Dockerfile
Normal file
@ -0,0 +1 @@
|
|||||||
|
FROM avatao/controller:ubuntu-16.04
|
19
solvable/Dockerfile
Normal file
19
solvable/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM baseimage-tutorial-framework
|
||||||
|
|
||||||
|
ENV TFW_APP_DIR="/srv/app" \
|
||||||
|
TFW_LOGIN_APP_DIR="/tmp/source_code_server" \
|
||||||
|
TFW_WEBIDE_WD="/home/${AVATAO_USER}/workdir" \
|
||||||
|
TFW_TERMINADO_WD="/home/${AVATAO_USER}/workdir"
|
||||||
|
|
||||||
|
COPY solvable/src/demo ${TFW_APP_DIR}/
|
||||||
|
COPY solvable/src/demo/source_code_server/server.py ${TFW_LOGIN_APP_DIR}/
|
||||||
|
COPY solvable/src/demo/source_code_server/users.db ${TFW_LOGIN_APP_DIR}/
|
||||||
|
COPY solvable/src/demo/source_code_server/login_component.py ${TFW_WEBIDE_WD}/
|
||||||
|
|
||||||
|
RUN chown -R ${AVATAO_USER} ${TFW_WEBIDE_WD} &&\
|
||||||
|
chmod -R 755 ${TFW_WEBIDE_WD}
|
||||||
|
|
||||||
|
VOLUME ["/home/${AVATAO_USER}"]
|
||||||
|
USER ${AVATAO_USER}
|
||||||
|
WORKDIR /home/${AVATAO_USER}
|
||||||
|
|
3
solvable/nginx/components/login.conf
Normal file
3
solvable/nginx/components/login.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
location = /login {
|
||||||
|
proxy_pass http://127.0.0.1:${TFW_LOGIN_APP_PORT};
|
||||||
|
}
|
6
solvable/nginx/components/terminal.conf
Normal file
6
solvable/nginx/components/terminal.conf
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
location = /terminal {
|
||||||
|
proxy_pass http://127.0.0.1:${TFW_TERMINADO_PORT};
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
21
solvable/src/demo/app.py
Normal file
21
solvable/src/demo/app.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import sys
|
||||||
|
import tornado
|
||||||
|
import zmq
|
||||||
|
from tornado.ioloop import IOLoop
|
||||||
|
|
||||||
|
from sql_injection_fsm import SQLInjectionFSM
|
||||||
|
from tfw.networking.server.tfw_server import TFWServer
|
||||||
|
from tfw.config import tfwenv
|
||||||
|
from tfw.config.logs import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
server = TFWServer(SQLInjectionFSM)
|
||||||
|
server.listen(tfwenv.WEB_PORT)
|
||||||
|
log.debug('Python version: {}'.format(sys.version[:5]))
|
||||||
|
log.debug('Tornado version: {}'.format(tornado.version))
|
||||||
|
log.debug('ZeroMQ version: {}'.format(zmq.zmq_version()))
|
||||||
|
log.debug('PyZMQ version: {}'.format(zmq.pyzmq_version()))
|
||||||
|
log.info('Tornado application listening on port {}'.format(tfwenv.WEB_PORT))
|
||||||
|
IOLoop.instance().start()
|
21
solvable/src/demo/event_handler_main.py
Normal file
21
solvable/src/demo/event_handler_main.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from tornado.ioloop import IOLoop
|
||||||
|
|
||||||
|
from tfw.components.source_code_event_handler import SourceCodeEventHandler
|
||||||
|
from tfw.components.terminado_event_handler import TerminadoEventHandler
|
||||||
|
from tfw.components.process_managing_event_handler import ProcessManagingEventHandler
|
||||||
|
from tfw.config import tfwenv
|
||||||
|
from tfw.config.logs import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
ide = SourceCodeEventHandler(key='webide', directory=tfwenv.WEBIDE_WD, exclude=['__pycache__'])
|
||||||
|
terminado = TerminadoEventHandler(key='shell')
|
||||||
|
terminado.historymonitor.subscribe_callback(callback=lambda hist: log.debug('User executed command: "{}"'.format(hist[-1])))
|
||||||
|
processmanager = ProcessManagingEventHandler(key='processmanager', dirmonitor=ide.monitor)
|
||||||
|
|
||||||
|
eventhandlers = {ide, terminado, processmanager}
|
||||||
|
try:
|
||||||
|
IOLoop.instance().start()
|
||||||
|
finally:
|
||||||
|
for eh in eventhandlers: eh.cleanup()
|
27
solvable/src/demo/source_code_server/login_component.py
Normal file
27
solvable/src/demo/source_code_server/login_component.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
|
def get_db():
|
||||||
|
return sqlite3.connect('users.db')
|
||||||
|
|
||||||
|
|
||||||
|
def authorize_login(email, password):
|
||||||
|
"""
|
||||||
|
This method checks if a user is authorized and has admin privileges.
|
||||||
|
:param email: The email address of the user.
|
||||||
|
:param password: The password of the user.
|
||||||
|
:return: A tuple, the first element is the email address if the user exists,
|
||||||
|
and None if they don't; the second element is a boolean, which is True if
|
||||||
|
the user has admin privileges.
|
||||||
|
"""
|
||||||
|
conn = get_db()
|
||||||
|
sql_statement = '''SELECT email, is_admin FROM users
|
||||||
|
WHERE email="{}" AND password="{}"'''
|
||||||
|
# The problem with this approach is that it substitutes any value received
|
||||||
|
# from the user, even if it is a valid SQL statement!
|
||||||
|
result = conn.execute(sql_statement.format(email, password)).fetchone()
|
||||||
|
if result is None:
|
||||||
|
return None, False
|
||||||
|
else:
|
||||||
|
email, is_admin = result
|
||||||
|
return email, is_admin == 1
|
27
solvable/src/demo/source_code_server/server.py
Normal file
27
solvable/src/demo/source_code_server/server.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import json, sys
|
||||||
|
from tornado.ioloop import IOLoop
|
||||||
|
from tornado.web import RequestHandler, Application
|
||||||
|
|
||||||
|
from tfw.config import tfwenv
|
||||||
|
|
||||||
|
sys.path.append(tfwenv.WEBIDE_WD)
|
||||||
|
from login_component import authorize_login
|
||||||
|
|
||||||
|
|
||||||
|
class LoginHandler(RequestHandler):
|
||||||
|
def post(self, *args, **kwargs):
|
||||||
|
request = json.loads(self.request.body)
|
||||||
|
email, is_admin = authorize_login(
|
||||||
|
request['email'],
|
||||||
|
request['password']
|
||||||
|
)
|
||||||
|
self.write({
|
||||||
|
'email': email,
|
||||||
|
'is_admin': is_admin
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
application = Application([(r'/login', LoginHandler)])
|
||||||
|
application.listen(tfwenv.LOGIN_APP_PORT)
|
||||||
|
IOLoop.instance().start()
|
BIN
solvable/src/demo/source_code_server/users.db
Normal file
BIN
solvable/src/demo/source_code_server/users.db
Normal file
Binary file not shown.
26
solvable/src/demo/sql_injection_fsm.py
Normal file
26
solvable/src/demo/sql_injection_fsm.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from tfw.fsm_base import FSMBase
|
||||||
|
|
||||||
|
|
||||||
|
class SQLInjectionFSM(FSMBase):
|
||||||
|
states = [
|
||||||
|
'start',
|
||||||
|
'stripped_code',
|
||||||
|
'sql',
|
||||||
|
'commented_code',
|
||||||
|
'sql_with_substitutions',
|
||||||
|
'sql_output',
|
||||||
|
'end',
|
||||||
|
]
|
||||||
|
transitions = [
|
||||||
|
{'trigger': 'webide', 'source': '*', 'dest': 'stripped_code'}, # TODO: delet this
|
||||||
|
{'trigger': 'webide', 'source': 'start', 'dest': 'stripped_code'},
|
||||||
|
{'trigger': 'login', 'source': 'stripped_code', 'dest': 'sql'},
|
||||||
|
{'trigger': 'logger', 'source': 'sql', 'dest': 'commented_code'},
|
||||||
|
{'trigger': 'webide', 'source': 'commented_code', 'dest': 'sql_with_substitutions'},
|
||||||
|
{'trigger': 'logger', 'source': 'sql_with_substitutions', 'dest': 'sql_output'},
|
||||||
|
{'trigger': 'logger', 'source': 'sql_output', 'dest': 'end'},
|
||||||
|
{'trigger': 'reset', 'source': 'end', 'dest': 'start'},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__('start')
|
3
solvable/supervisor/components/event_handlers.conf
Normal file
3
solvable/supervisor/components/event_handlers.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[program:event_handler_main]
|
||||||
|
directory=%(ENV_TFW_APP_DIR)s
|
||||||
|
command=env python event_handler_main.py
|
4
solvable/supervisor/components/login.conf
Normal file
4
solvable/supervisor/components/login.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[program:login]
|
||||||
|
directory=%(ENV_TFW_LOGIN_APP_DIR)s
|
||||||
|
command=env python server.py
|
||||||
|
autostart=false
|
Loading…
Reference in New Issue
Block a user