class Cheaters(db.Model): __tablename__ = "cheaters" id = db.Column(db.Integer, primary_key=True) cheater_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE")) cheatee_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE")) cheater_challenge_id = db.Column( db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE")) cheatee_challenge_id = db.Column( db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE")) challenge_data = db.Column(db.Text) date = db.Column(db.DateTime, default=datetime.datetime.utcnow) cheater = db.relationship("Users", foreign_keys="Cheaters.cheater_id", lazy="select") cheatee = db.relationship("Users", foreign_keys="Cheaters.cheatee_id", lazy="select") cheater_challenge = db.relationship( "Challenges", foreign_keys="Cheaters.cheater_challenge_id", lazy="select") cheatee_challenge = db.relationship( "Challenges", foreign_keys="Cheaters.cheatee_challenge_id", lazy="select")
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("Challenges", foreign_keys="WhaleContainer.challenge_id", lazy="select") def __init__(self, user_id, challenge_id, flag, uuid, port): self.user_id = user_id self.challenge_id = challenge_id self.start_time = datetime.now() self.renew_count = 0 self.flag = flag self.uuid = str(uuid) self.port = port 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)
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, port): 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.port = port 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)
class GlowwormInitLog(Submissions): __tablename__ = "glowworm_init_log" id = db.Column( None, db.ForeignKey("submissions.id", ondelete="CASCADE"), primary_key=True ) challenge_id = column_property( db.Column(db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE")), Submissions.challenge_id, ) user_id = column_property( db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE")), Submissions.user_id, ) team_id = column_property( db.Column(db.Integer, db.ForeignKey("teams.id", ondelete="CASCADE")), Submissions.team_id, ) victim_user_id = column_property( db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE")) ) victim_team_id = column_property( db.Column(db.Integer, db.ForeignKey("teams.id", ondelete="CASCADE")) ) user = db.relationship("Users", foreign_keys="GlowwormInitLog.user_id", lazy="select") team = db.relationship("Teams", foreign_keys="GlowwormInitLog.team_id", lazy="select") challenge = db.relationship( "Challenges", foreign_keys="GlowwormInitLog.challenge_id", lazy="select" ) __mapper_args__ = {"polymorphic_identity": "init"}
class Attributes(db.Model): __tablename__ = "attributes" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text) type = db.Column(db.Text, default="checkbox") default = db.Column(db.Text, default="") hidden = db.Column(db.Boolean, default=False) private = db.Column(db.Boolean, default=True) frozen = db.Column(db.Boolean, default=False) teams = db.relationship("IntersectionTeamAttr", backref="attribute", foreign_keys="IntersectionTeamAttr.attr_id") def get_team_value(self, team_id): intersec = IntersectionTeamAttr.query.filter_by( attr_id=self.id).filter_by(team_id=team_id) if intersec.count() > 0: return intersec.one() return None def get_options(self): intersec = AttributesSelectOptions.query.filter_by(attr_id=self.id) return intersec.all() def __init__(self, **kwargs): super(Attributes, self).__init__(**kwargs) def __repr__(self): return "<Attribute %r>" % self.name
class Brackets(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, index=True, unique=True) hidden = db.Column(db.Boolean) # super hacked up way to get the chal_bracket attribute on the parent # model class (Teams) without actually modifying it teams = db.relationship("Teams", backref=db.backref("chal_bracket", uselist=False), secondary=tb, primaryjoin=id == tb.c.bracket_id, secondaryjoin=Teams.id == tb.c.team_id) users = db.relationship("Users", backref=db.backref("chal_bracket", uselist=False), secondary=ub, primaryjoin=id == ub.c.bracket_id, secondaryjoin=Users.id == ub.c.user_id)
class UserSalt(db.Model): __tablename__ = 'usersalt' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE')) challenge_id = db.Column( db.Integer, db.ForeignKey('challenges.id', ondelete='CASCADE')) salt = db.Column(db.Text, unique=True) user = db.relationship("Users", foreign_keys='UserSalt.user_id', lazy='select') #, back_populates="salt") challenge = db.relationship("Challenges", foreign_keys='UserSalt.challenge_id', lazy='select') #, back_populates="user_salts") def __init__(self, *args, **kwargs): super(UserSalt, self).__init__(**kwargs)
class Competitions(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(46)) description = db.Column(db.Text) startTime = db.Column(db.DateTime, default=datetime.datetime.utcnow) endTime = db.Column(db.DateTime, default=datetime.datetime.utcnow) profile = db.Column(db.String(50), default='default.jpg') chals = db.relationship('Chalcomp', backref='competition') def __init__(self, title, description): self.title = title self.description = description
class WebChallenge(Challenges): __mapper_args__ = {'polymorphic_identity': 'web'} id = db.Column(None, db.ForeignKey('challenges.id'), primary_key=True) initial = db.Column(db.Integer, default=0) minimum = db.Column(db.Integer, default=0) decay = db.Column(db.Integer, default=0) docker_name = db.Column(db.String(32), default="") ports = db.relationship("Ports", backref="challenge") def __init__(self, *args, **kwargs): super(WebChallenge, self).__init__(**kwargs) self.initial = kwargs['value']
class AliyunECS(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("users.id")) challenge_id = db.Column(db.Integer, db.ForeignKey("challenges.id")) instance_id = db.Column(db.String(32)) ip = db.Column(db.String(32)) start_time = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) renew_count = db.Column(db.Integer, nullable=False, default=0) flag = db.Column(db.String(128), nullable=False) # Relationships user = db.relationship("Users", foreign_keys="AliyunECS.user_id", lazy="select") challenge = db.relationship( "Challenges", foreign_keys="AliyunECS.challenge_id", lazy="select" ) def __init__(self, *args, **kwargs): super(AliyunECS, self).__init__(**kwargs)
class FirstBloodAward(Awards): __mapper_args__ = {"polymorphic_identity": "firstblood"} id = db.Column(db.Integer, db.ForeignKey("awards.id", ondelete="CASCADE"), primary_key=True) solve_id = db.Column( db.Integer, db.ForeignKey("solves.id", ondelete="RESTRICT") ) # It doesn't seem possible to do this well on the database level (FirstBloodAward always gets removed without the base Awards entry), so we do it on the application level solve_num = db.Column(db.Integer, nullable=False) solve = db.relationship("Solves", foreign_keys="FirstBloodAward.solve_id", lazy="select")
class PSubmission(db.Model): id = db.Column(db.Integer, primary_key=True) uuid = db.Column(db.Text, default=str(uuid.uuid4())) code = db.Column(db.Text, default='') lang = db.Column(db.Text, default='') status = db.Column(db.Text, default='added to queue') result = db.Column(db.Text, default='unknown') time = db.Column(db.Integer, default=0) memory = db.Column(db.Integer, default=0) challenge_id = db.Column(db.Integer, db.ForeignKey('challenges.id')) author = db.Column(db.Integer, db.ForeignKey('users.id')) author_team = db.Column(db.Integer, db.ForeignKey("teams.id")) date = db.Column(db.DateTime, default=datetime.datetime.utcnow) ip = db.Column(db.String(46)) challenge = db.relationship(DynICPCModel, foreign_keys="PSubmission.challenge_id", lazy="select") user = db.relationship(Users, foreign_keys="PSubmission.author", lazy="select") team = db.relationship(Teams, foreign_keys="PSubmission.author_team", lazy="select") def __init__(self, code, lang, chall_id, user_id, team_id, ip, *args, **kwargs): super(PSubmission, self).__init__(**kwargs) self.code = code self.lang = lang self.challenge_id = chall_id self.author = user_id self.author_team = team_id self.ip = ip
class WriteUpChallenges(Challenges): id = db.Column(None, db.ForeignKey('challenges.id'), primary_key=True) solve_req = db.Column(db.Boolean, default=True, nullable=False) for_id = db.Column(db.Integer, db.ForeignKey("challenges.id")) wu_for = db.relationship("Challenges", foreign_keys=[for_id], backref=db.backref('writeup_challenge', uselist=False)) __mapper_args__ = { 'polymorphic_identity': 'writeup', 'inherit_condition': (id == Challenges.id) } def __init__(self, *args, **kwargs): super(WriteUpChallenges, self).__init__(state='hidden', *args, **kwargs)
class IntersectionTeamAttr(db.Model): __tablename__ = "intersecTeamAttr" id = db.Column(db.Integer, primary_key=True) team_id = db.Column(db.Integer, db.ForeignKey("teams.id", ondelete="CASCADE")) attr_id = db.Column(db.Integer, db.ForeignKey("attributes.id", ondelete="CASCADE")) value = db.Column(db.Text) team = db.relationship("Teams", foreign_keys="IntersectionTeamAttr.team_id", lazy="select") def __init__(self, **kwargs): super(IntersectionTeamAttr, self).__init__(**kwargs) def __repr__(self): return "<IntTeamAttr team{0} attr{1}>".format(self.team_id, self.attr_id)
class GlowwormContainers(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer) challenge_id = db.Column(db.Integer, db.ForeignKey("challenges.id")) docker_id = db.Column(db.String(32), unique=True) ip = db.Column(db.String(32)) service_port = db.Column(db.Integer) ssh_port = db.Column(db.Integer) ssh_key = db.Column(db.String(36)) create_time = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) flag = db.Column(db.String(128), nullable=True) key = db.Column(db.String(36)) # Todo 数据库预留可视化信息 # Relationships challenge = db.relationship( "Challenges", foreign_keys="GlowwormContainers.challenge_id", lazy="select" ) def __init__(self, *args, **kwargs): super(GlowwormContainers, self).__init__(**kwargs)
class Chalcomp(db.Model): id = db.Column(db.Integer, primary_key=True) chalid = db.Column(db.Integer, db.ForeignKey('challenges.id')) compid = db.Column(db.Integer, db.ForeignKey('competitions.id')) chal = db.relationship('Challenges', backref=db.backref('chalcomp'))
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): from .utils.db import DBConfig return Template(DBConfig.get_config( 'template_http_subdomain', '{{ container.uuid }}' )).render(container=self) def __init__(self, user_id, challenge_id, port): from .utils.db import DBConfig 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.port = port self.flag = Template(DBConfig.get_config( 'template_chall_flag', '{{ "flag{"+uuid.uuid4()|string+"}" }}' )).render(container=self, uuid=uuid, random=random) @property def user_access(self): configs = {} for c in WhaleConfig.query.all(): configs[str(c.key)] = str(c.value) access = '' if self.challenge.redirect_type == 'http': subdomain_host = configs.get("frp_http_domain_suffix", "").lstrip(".") access = f'http://{self.http_subdomain}.{subdomain_host}' if configs.get('frp_http_port', '80') != '80': access += ':' + configs.get('frp_http_port') elif self.challenge.redirect_type == 'direct': access = f'nc {configs.get("frp_direct_ip_address", "")} {self.port}' return access @property def frp_config(self): configs = {} for c in WhaleConfig.query.all(): configs[str(c.key)] = str(c.value) if self.challenge.redirect_type == 'http': return f""" [http_{str(self.user_id)}-{self.uuid}] type = http local_ip = {str(self.user_id)}-{self.uuid} local_port = {self.challenge.redirect_port} subdomain = {self.http_subdomain} use_compression = true """ elif self.challenge.redirect_type == 'direct': return f""" [direct_{str(self.user_id)}-{self.uuid}] type = tcp local_ip = {str(self.user_id)}-{self.uuid} local_port = {self.challenge.redirect_port} remote_port = {self.port} use_compression = true [direct_{str(self.user_id)}-{self.uuid}_udp] type = udp local_ip = {str(self.user_id)}-{self.uuid} local_port = {self.challenge.redirect_port} remote_port = {self.port} use_compression = true """ 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)