forked from glzjin/CTFd-Whale
-
Notifications
You must be signed in to change notification settings - Fork 29
/
models.py
105 lines (82 loc) · 3.68 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import random
import uuid
from datetime import datetime
from jinja2 import Template
from CTFd.utils import get_config
from CTFd.models import db
from CTFd.plugins.dynamic_challenges import DynamicChallenge
class WhaleConfig(db.Model):
key = db.Column(db.String(length=128), primary_key=True)
value = db.Column(db.Text)
def __init__(self, key, value):
self.key = key
self.value = value
def __repr__(self):
return "<WhaleConfig {0} {1}>".format(self.key, self.value)
class WhaleRedirectTemplate(db.Model):
key = db.Column(db.String(20), primary_key=True)
frp_template = db.Column(db.Text)
access_template = db.Column(db.Text)
def __init__(self, key, access_template, frp_template):
self.key = key
self.access_template = access_template
self.frp_template = frp_template
def __repr__(self):
return "<WhaleRedirectTemplate {0}>".format(self.key)
class DynamicDockerChallenge(DynamicChallenge):
__mapper_args__ = {"polymorphic_identity": "dynamic_docker"}
id = db.Column(
db.Integer, db.ForeignKey("dynamic_challenge.id", ondelete="CASCADE"), primary_key=True
)
memory_limit = db.Column(db.Text, default="128m")
cpu_limit = db.Column(db.Float, default=0.5)
dynamic_score = db.Column(db.Integer, default=0)
docker_image = db.Column(db.Text, default=0)
redirect_type = db.Column(db.Text, default=0)
redirect_port = db.Column(db.Integer, default=0)
def __init__(self, *args, **kwargs):
kwargs["initial"] = kwargs["value"]
super(DynamicDockerChallenge, self).__init__(**kwargs)
class WhaleContainer(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
user_id = db.Column(None, db.ForeignKey("users.id"))
challenge_id = db.Column(None, db.ForeignKey("challenges.id"))
start_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
renew_count = db.Column(db.Integer, nullable=False, default=0)
status = db.Column(db.Integer, default=1)
uuid = db.Column(db.String(256))
port = db.Column(db.Integer, nullable=True, default=0)
flag = db.Column(db.String(128), nullable=False)
# Relationships
user = db.relationship(
"Users", foreign_keys="WhaleContainer.user_id", lazy="select")
challenge = db.relationship(
"DynamicDockerChallenge", foreign_keys="WhaleContainer.challenge_id", lazy="select"
)
@property
def http_subdomain(self):
return Template(get_config(
'whale:template_http_subdomain', '{{ container.uuid }}'
)).render(container=self)
def __init__(self, user_id, challenge_id):
self.user_id = user_id
self.challenge_id = challenge_id
self.start_time = datetime.now()
self.renew_count = 0
self.uuid = str(uuid.uuid4())
self.flag = Template(get_config(
'whale:template_chall_flag', '{{ "flag{"+uuid.uuid4()|string+"}" }}'
)).render(container=self, uuid=uuid, random=random, get_config=get_config)
@property
def user_access(self):
return Template(WhaleRedirectTemplate.query.filter_by(
key=self.challenge.redirect_type
).first().access_template).render(container=self, get_config=get_config)
@property
def frp_config(self):
return Template(WhaleRedirectTemplate.query.filter_by(
key=self.challenge.redirect_type
).first().frp_template).render(container=self, get_config=get_config)
def __repr__(self):
return "<WhaleContainer ID:{0} {1} {2} {3} {4}>".format(self.id, self.user_id, self.challenge_id,
self.start_time, self.renew_count)