Skip to content

Commit

Permalink
A bunch of code
Browse files Browse the repository at this point in the history
  • Loading branch information
U039b committed Mar 20, 2023
1 parent d8d5532 commit 56def32
Show file tree
Hide file tree
Showing 35 changed files with 941 additions and 330 deletions.
17 changes: 17 additions & 0 deletions .envs/.local/.keycloak
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
DB_VENDOR=postgres
KEYCLOAK_DATABASE_HOST=keycloak-db
KEYCLOAK_DATABASE_PORT=5432
# Database name (replace with yours)
KEYCLOAK_DATABASE_NAME=keycloakdb
# Database user (replace with yours)
KEYCLOAK_DATABASE_USER=hhGArHWVrVQjuDcgBUNNlQqZNfqyNPfQ
# Database password (replace with yours)
KEYCLOAK_DATABASE_PASSWORD=vW9WtXmFWpsq5tATgcYNAi62cC1tWar1BsSrksBodMrra2bv4NHVvRyIm9k29Ro9

# Keycloak user (replace with yours)
KEYCLOAK_USER=keycloakadmin
# Keycloak password (replace with yours)
KEYCLOAK_PASSWORD=rwXPqspCABJzqh47i723wf9

PROXY_ADDRESS_FORWARDING='true'
KEYCLOAK_LOGLEVEL=DEBUG
4 changes: 3 additions & 1 deletion .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion colander/core/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib import admin

from colander.core.models import ObservableType, Observable, Case, Threat, ObservableRelation, \
Artifact, ArtifactType, Event, Actor, EventType, Comment, PiRogueExperiment, EntityRelation
Artifact, ArtifactType, Event, Actor, EventType, Comment, PiRogueExperiment, EntityRelation, BackendCredentials


class ArtifactTypeAdmin(admin.ModelAdmin):
Expand Down Expand Up @@ -81,3 +81,9 @@ class EntityRelationAdmin(admin.ModelAdmin):
# list_filter = ('name', 'observable_from', 'observable_to')
admin.site.register(EntityRelation, EntityRelationAdmin)


class BackendCredentialsAdmin(admin.ModelAdmin):
list_display = ('backend',)
# list_filter = ('name', 'observable_from', 'observable_to')
admin.site.register(BackendCredentials, BackendCredentialsAdmin)

1 change: 1 addition & 0 deletions colander/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class InvestigateSearchForm(forms.Form):
types = [(t.short_name, t.name) for t in ObservableType.objects.all()]
type = forms.ChoiceField(choices=types)
value = forms.CharField(max_length=128)
force_update = forms.BooleanField(required=False, label='Update results from vendors.')


class DocumentationForm(forms.Form):
Expand Down
1 change: 1 addition & 0 deletions colander/core/management/commands/data/event_types.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[
{"short_name": "COMMUNICATION", "name": "Communication", "description": "", "svg_icon": "", "nf_icon": "nf-mdi-lan_connect"},
{"short_name": "RESOLVE", "name": "Resolution", "description": "", "svg_icon": "", "nf_icon": "nf-mdi-search_web"},
{"short_name": "PASSIVE_DNS", "name": "Passive DNS", "description": "", "svg_icon": "", "nf_icon": "nf-mdi-search_web"},
{"short_name": "COMPROMISE", "name": "Compromise", "description": "", "svg_icon": "", "nf_icon": "nf-mdi-disk_alert"},
{"short_name": "INFECTION", "name": "Infection", "description": "", "svg_icon": "", "nf_icon": "nf-mdi-disk_alert"},
{"short_name": "ALERT", "name": "Alert", "description": "", "svg_icon": "", "nf_icon": "nf-oct-alert"},
Expand Down
3 changes: 3 additions & 0 deletions colander/core/middlewares.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from django.conf import settings

from colander.core.forms import DocumentationForm
from colander.core.models import Case

Expand Down Expand Up @@ -33,4 +35,5 @@ def active_case(request):
return {
'active_case': active_case,
'user_cases': user_cases,
'cyberchef_base_url': settings.CYBERCHEF_BASE_URL,
}
19 changes: 19 additions & 0 deletions colander/core/migrations/0009_entityrelation_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 3.2.18 on 2023-03-09 18:16

import django.contrib.postgres.fields.hstore
from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0008_pirogueexperiment_aes_trace'),
]

operations = [
migrations.AddField(
model_name='entityrelation',
name='attributes',
field=django.contrib.postgres.fields.hstore.HStoreField(blank=True, null=True),
),
]
29 changes: 29 additions & 0 deletions colander/core/migrations/0010_backendcredentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.18 on 2023-03-18 15:22

import django.contrib.postgres.fields.hstore
from django.db import migrations, models
import django.utils.timezone
import uuid


class Migration(migrations.Migration):

dependencies = [
('core', '0009_entityrelation_attributes'),
]

operations = [
migrations.CreateModel(
name='BackendCredentials',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='Unique identifier.', primary_key=True, serialize=False)),
('backend', models.CharField(default='', max_length=512, verbose_name='backend identifier')),
('last_usage', models.DateTimeField(default=django.utils.timezone.now)),
('credentials', django.contrib.postgres.fields.hstore.HStoreField(default=dict)),
],
options={
'ordering': ['last_usage'],
'unique_together': {('backend', 'credentials')},
},
),
]
48 changes: 48 additions & 0 deletions colander/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,31 @@ def get_mermaid(self):
text = f'flowchart LR\n\t{node_txt}\n\t{click_txt}\n\t{link_txt}\n\t{class_txt}'
return text

def get_mermaid_events(self):
events = Event.objects.filter(case=self).order_by('type__short_name', 'first_seen')
graph = 'gantt\n\tdateFormat YYYY-MM-DD HH:mm'
current_section = ''
for event in events:
first_seen = event.first_seen.strftime('%Y-%m-%d %H:%M')
last_seen = event.last_seen.strftime('%Y-%m-%d %H:%M')
if current_section != event.type.name:
current_section = event.type.name
graph += f'\n\tsection {current_section}'
if event.first_seen == event.last_seen:
graph += f'\n\t{event.name}: milestone, {event.id}, {first_seen}, 2min'
else:
graph += f'\n\t{event.name}: {event.id}, {first_seen}, {last_seen}'
return graph


@property
def to_mermaid(self):
return self.get_mermaid()

@property
def to_mermaid_events(self):
return self.get_mermaid_events()

@staticmethod
def get_user_cases(user):
return Case.objects.filter(owner=user)
Expand Down Expand Up @@ -941,6 +962,10 @@ class Meta:
help_text=_('Latest modification of this object.'),
auto_now=True
)
attributes = HStoreField(
blank=True,
null=True
)
obj_from_id = models.UUIDField()
obj_from_type = models.ForeignKey(ContentType, on_delete=models.PROTECT, related_name='obj_from_types')
obj_from = GenericForeignKey('obj_from_type', 'obj_from_id')
Expand Down Expand Up @@ -1402,6 +1427,29 @@ class ObservableAnalysisEngine(models.Model):
blank=True
)

class BackendCredentials(models.Model):
class Meta:
ordering = ['last_usage']
unique_together = ['backend', 'credentials']

id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
help_text=_('Unique identifier.'),
editable=False
)
backend = models.CharField(
max_length=512,
verbose_name=_('backend identifier'),
default=''
)
last_usage = models.DateTimeField(
default=timezone.now
)
credentials = HStoreField(
default=dict
)


class PiRogueExperimentAnalysis(Document):
owner = Keyword(required=True)
Expand Down
18 changes: 18 additions & 0 deletions colander/core/templatetags/colander_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,21 @@ def to_cyberchef_input(instance):
return instance
encoded = instance.encode('utf-8')
return f'input={urlsafe_b64encode(encoded).decode()}'


@register.filter(name="to_title")
def to_title(instance):
if not instance or type(instance) is not str:
return instance
words = instance.split('_')
words[0] = words[0].title()
title = ' '.join(words)
return title


@register.filter(name="split")
def split(instance, delim):
if not instance or type(instance) is not str:
return instance
words = instance.split(delim)
return words
Loading

0 comments on commit 56def32

Please sign in to comment.