class SampleMatch(db.Model): """ Match between samples. Used to spot samples similarities on analysis. Displayed to user. """ __tablename__ = 'samplematch' id = db.Column(db.Integer, primary_key=True) sid_1 = db.Column(db.Integer, db.ForeignKey('sample.id'), index=True) sid_2 = db.Column(db.Integer, db.ForeignKey('sample.id'), index=True) match_type = db.Column(db.String(), index=True)
def create_link_tables(table1, table2): """ Create a joint table for n-n relationships """ table = db.Table( table1 + table2, db.Column(table1 + '_id', db.Integer, db.ForeignKey(table1 + '.id'), index=True), db.Column(table2 + '_id', db.Integer, db.ForeignKey(table2 + '.id'), index=True)) return table
class IDAAction(db.Model): """ Abstract class for implementing IDA actions. This mirrors actions done by the analyst on his database """ __tablename__ = "idaactions" id = db.Column(db.Integer(), primary_key=True) # The action data data = db.Column(db.String()) # The address where the action occured address = db.Column(db.Integer(), index=True) # We must keep timestamp to reorder actions timestamp = db.Column(db.DateTime()) # We also keep the last user user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # The action type type = db.Column(db.String()) __mapper_args__ = { 'polymorphic_identity': 'analysisresult', 'polymorphic_on': type }
class IDAApplyStructs(IDAAction): # This is the action of applying a structure to an address __tablename__ = 'idaapplystructs' id = db.Column(db.Integer(), db.ForeignKey('idaactions.id'), primary_key=True) __mapper_args__ = {'polymorphic_identity': 'idaapplystructs'}
class IDAStructMember(db.Model): __tablename__ = "idastructmember" id = db.Column(db.Integer(), primary_key=True) struct_id = db.Column(db.Integer(), db.ForeignKey("idastructs.id")) name = db.Column(db.String(), index=True) size = db.Column(db.Integer()) mtype = db.Column(db.String()) offset = db.Column(db.Integer())
class FileName(db.Model): """ Sample's files names. """ __tablename__ = 'filename' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String()) sample_id = db.Column(db.Integer(), db.ForeignKey("sample.id"))
class IDANameAction(IDAAction): """ This represents global names in IDA. """ __tablename__ = 'idanames' id = db.Column(db.Integer(), db.ForeignKey('idaactions.id'), primary_key=True) __mapper_args__ = {'polymorphic_identity': 'idanames'}
class StringsItem(db.Model): """ Strings contained in a binary file. Strings types are defined by the StringsType enum class. """ __tablename__ = 'stringsitem' id = db.Column(db.Integer, primary_key=True) string_type = db.Column(db.Integer(), index=True) string_value = db.Column(db.String()) sample_id = db.Column(db.Integer(), db.ForeignKey("sample.id"), index=True)
class IDACommentAction(IDAAction): """ Implement comments """ __tablename__ = 'idacomments' id = db.Column(db.Integer(), db.ForeignKey('idaactions.id'), primary_key=True) comment = db.Column(db.String()) __mapper_args__ = {'polymorphic_identity': 'idacomment'}
class IDATypeAction(IDAAction): """ This represents the types as applied by the shortcut 'Y' in IDA Pro """ __tablename__ = 'idatypes' id = db.Column(db.Integer(), db.ForeignKey('idaactions.id'), primary_key=True) __mapper_args__ = {'polymorphic_identity': 'idatypes'}
class SampleMetadata(db.Model): """ Generic table used to store generic file metadata. Type must be defined in the SampleMetadataType enum class below. Value contains the metadata itself. """ __tablename__ = 'samplemetadata' id = db.Column(db.Integer, primary_key=True) type_id = db.Column(db.Integer(), index=True) value = db.Column(db.String()) sample_id = db.Column(db.Integer(), db.ForeignKey("sample.id"), index=True)
class FamilyDataFile(db.Model): """ Family data file. Whatever you want, script, report, etc. """ __tablename__ = "family_file" id = db.Column(db.Integer, primary_key=True) filepath = db.Column(db.String()) filename = db.Column(db.String()) description = db.Column(db.String()) TLP_sensibility = db.Column(db.Integer(), default=TLPLevel.TLPAMBER) family_id = db.Column(db.Integer(), db.ForeignKey("family.id"))
class FunctionInfo(db.Model): """ Function information. Contains function's name, machoc hash and address. Used for quick function access. Machoc hash can be updated by tasks or by skelenox itself. """ __tablename__ = 'functioninfo' id = db.Column(db.Integer, primary_key=True) address = db.Column(db.BigInteger(), index=True) name = db.Column(db.String(), index=True) machoc_hash = db.Column(db.BigInteger(), index=True) sample_id = db.Column(db.Integer(), db.ForeignKey("sample.id"), index=True)
class DetectionElement(db.Model): """ Detection element: provided by users, can be any of the DetectionType values. """ __tablename__ = "detection_element" id = db.Column(db.Integer, primary_key=True) abstract = db.Column(db.String()) name = db.Column(db.String()) TLP_sensibility = db.Column(db.Integer(), default=TLPLevel.TLPAMBER) item_type = db.Column(db.Integer()) family_id = db.Column(db.Integer(), db.ForeignKey("family.id"))
class AnalysisResult(db.Model): """ Containing all PE analysis data. """ __tablename__ = "analysisresult" id = db.Column(db.Integer(), primary_key=True) sample_id = db.Column(db.Integer(), db.ForeignKey('sample.id')) analysis_status = db.Column(db.Boolean()) analysis_date = db.Column(db.DateTime()) title = db.Column(db.String()) data = db.Column(db.String()) type = db.Column(db.String())
class IDAStruct(IDAAction): """ Structures are a particular type of actions, as the address and will always be null, and they store a relationship with their members The management of the members is done by the controller, and at each update the structure's timestamp is updated """ __tablename__ = "idastructs" id = db.Column(db.Integer(), db.ForeignKey('idaactions.id'), primary_key=True) name = db.Column(db.String()) size = db.Column(db.Integer()) members = db.relationship("IDAStructMember", backref=db.backref("struct"), remote_side=[id]) __mapper_args__ = {"polymorphic_identity": "idastructs"}
class Family(db.Model): """ Family model. """ __tablename__ = 'family' id = db.Column(db.Integer, primary_key=True) # N-N relationships samples = db.relationship('Sample', secondary=familytosample, backref=db.backref('families', lazy='dynamic')) yaras = db.relationship('YaraRule', secondary=familytoyara, backref=db.backref('families', lazy='dynamic')) # 1-N relationships parent_id = db.Column(db.Integer, db.ForeignKey('family.id')) subfamilies = db.relationship('Family', backref=db.backref('parents', remote_side=[id])) # 1-N relationships, without any backrefs for now associated_files = db.relationship('FamilyDataFile') detection_items = db.relationship('DetectionElement') # Family name's name = db.Column(db.String(), index=True, unique=True) # User-supplied abstract abstract = db.Column(db.String()) # Analysis status status = db.Column(db.Integer(), default=FamilyStatus.NOT_STARTED) # Tlp level TLP_sensibility = db.Column(db.Integer(), default=TLPLevel.TLPAMBER) def __repr__(self): return 'Family %d %s' % (self.id, self.name) def __init__(self, name=None): if name is None: raise IOError self.name = name
class CheckList(db.Model): """ Checklist fields and description. This is a global information, set in the admin panel, links will just determine if checked or not. """ __tablename__ = 'checklist' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String()) description = db.Column(db.String()) sampletochecklist = db.Table( 'sampletochecklist', db.Column('checklist_id', db.Integer, db.ForeignKey('checklist.id')), db.Column('sample_id', db.Integer, db.ForeignKey('sample.id'))) """ Matched Yara rules relationship. """ sampletoyara = db.Table( 'sampletoyara', db.Column('yara_id', db.Integer, db.ForeignKey('yararule.id')), db.Column('sample_id', db.Integer, db.ForeignKey('sample.id'))) """ IDA actions relationship. """ sampletoactions = db.Table( 'sampletoactions', db.Column('sample_id', db.Integer, db.ForeignKey('sample.id'), index=True), db.Column('action_id',
""" This file is part of Polichombr. (c) 2016 ANSSI-FR Description: User data model. Dependant on Flask-Login for authentication """ from poli import db, ma from flask_security import UserMixin, RoleMixin usersample = db.Table( 'usersample', db.Column('user_id', db.Integer, db.ForeignKey('user.id')), db.Column('sample_id', db.Integer, db.ForeignKey('sample.id'))) userfamily = db.Table( 'userfamily', db.Column('user_id', db.Integer, db.ForeignKey('user.id')), db.Column('family_id', db.Integer, db.ForeignKey('family.id'))) roles_users = db.Table( 'roles_users', db.Column('user_id', db.Integer(), db.ForeignKey('user.id')), db.Column('role_id', db.Integer(), db.ForeignKey('auth_role.id'))) class Role(db.Model, RoleMixin): __tablename__ = 'auth_role' id = db.Column(db.Integer, primary_key=True)
(c) 2016 ANSSI-FR Description: User data model. Dependant on Flask-Login for authentication """ from poli import db, ma from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash usersample = db.Table('usersample', db.Column('user_id', db.Integer, db.ForeignKey('user.id')), db.Column('sample_id', db.Integer, db.ForeignKey('sample.id')) ) userfamily = db.Table('userfamily', db.Column('user_id', db.Integer, db.ForeignKey('user.id')), db.Column('family_id', db.Integer, db.ForeignKey('family.id')) ) class UserPrivilege: """ User privileges. Not used for now.
@classmethod def tostring(cls, val): for k, v in vars(cls).iteritems(): if v == val: return k return "" @classmethod def fromstring(cls, val): return getattr(cls, val, None) # Yara signatures relationship (auto-classification). familytoyara = db.Table( 'familytoyara', db.Column('yara_id', db.Integer, db.ForeignKey('yararule.id')), db.Column('family_id', db.Integer, db.ForeignKey('family.id'))) # Samples relationship. familytosample = db.Table( 'familytosample', db.Column('sample_id', db.Integer, db.ForeignKey('sample.id')), db.Column('family_id', db.Integer, db.ForeignKey('family.id'))) class Family(db.Model): """ Family model. """ __tablename__ = 'family' id = db.Column(db.Integer, primary_key=True)
class Sample(db.Model): """ Samples model. """ __tablename__ = 'sample' id = db.Column(db.Integer, primary_key=True) # N-N relationships family_id = db.Column(db.Integer, db.ForeignKey('family.id')) check_list = db.relationship('CheckList', secondary=sampletochecklist, backref=db.backref('samples', lazy='dynamic')) actions = db.relationship('IDAAction', secondary=sampletoactions, backref=db.backref('samples', lazy='dynamic')) yaras = db.relationship('YaraRule', secondary=sampletoyara, backref=db.backref('samples', lazy='dynamic')) # Enriched N-N relationships (double link) linked_samples = db.relationship('SampleMatch', backref=db.backref('sample1', remote_side=[id]), foreign_keys=[SampleMatch.sid_1]) linked_samples_2 = db.relationship('SampleMatch', backref=db.backref('sample2', remote_side=[id]), foreign_keys=[SampleMatch.sid_2]) # 1-N relationships strings = db.relationship( "StringsItem", backref=db.backref( 'sample', remote_side=[id])) s_metadata = db.relationship( "SampleMetadata", backref=db.backref( 'sample', remote_side=[id])) functions = db.relationship( "FunctionInfo", backref=db.backref( 'sample', remote_side=[id]), lazy="dynamic") filenames = db.relationship( "FileName", backref=db.backref( 'sample', remote_side=[id])) analysis_data = db.relationship( 'AnalysisResult', backref=db.backref( "sample", remote_side=[id])) # Sample's binary path storage_file = db.Column(db.String()) # File size size = db.Column(db.Integer()) # File's internal date (compilation timestamp, etc.) file_date = db.Column(db.DateTime(), index=True) # Hashes md5 = db.Column(db.String(32), index=True, nullable=False) sha1 = db.Column(db.String(40), index=True, nullable=False) sha256 = db.Column(db.String(64), index=True, nullable=False) # Mime type mime_type = db.Column(db.String()) full_mime_type = db.Column(db.String()) # Abstract, set by user abstract = db.Column(db.String()) # Import hash, set by tasks import_hash = db.Column(db.String(), index=True) # TLP level, mandatory TLP_sensibility = db.Column( db.Integer(), nullable=False, default=TLPLevel.TLPAMBER) # Analysis status analysis_status = db.Column( db.Integer(), nullable=False, default=AnalysisStatus.TOSTART) # Sample's analysis date analysis_date = db.Column(db.DateTime()) # "status" is not used, for now # status = db.Column(db.Integer()) def __repr__(self): return 'Sample %d' % self.id
class CheckList(db.Model): """ Checklist fields and description. This is a global information, set in the admin panel, links will just determine if checked or not. """ __tablename__ = 'checklist' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String()) description = db.Column(db.String()) sampletochecklist = db.Table('sampletochecklist', db.Column('checklist_id', db.Integer, db.ForeignKey('checklist.id')), db.Column('sample_id', db.Integer, db.ForeignKey('sample.id'))) """ Matched Yara rules relationship. """ sampletoyara = db.Table('sampletoyara', db.Column('yara_id', db.Integer, db.ForeignKey('yararule.id')), db.Column('sample_id', db.Integer, db.ForeignKey('sample.id')))