Skip to content

Commit 94fe875

Browse files
committed
🎉 Initial commit
1 parent 1b391a9 commit 94fe875

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+6227
-0
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "ansible"]
2+
path = ansible
3+
url = [email protected]:toucan-project/deploy-scripts.git

CA/enrolled-hosts

Whitespace-only changes.
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
take CA
2+
mkdir certs crl newcerts private
3+
cp /dev/null index.txt
4+
openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 1825 -config openssl.cnf
5+
openssl req -nodes -new -x509 -keyout serverkey.pem -out serverreq.pem -days 730 -config openssl.cnf
6+
openssl x509 -x509toreq -in serverreq.pem -signkey serverkey.pem -out tmp.pem
7+
openssl ca -config openssl.cnf -policy policy_anything -out servercert.pem -infiles tmp.pem
8+
cp index.txt index.txt.attr
9+
openssl ca -config openssl.cnf -policy policy_anything -out servercert.pem -infiles tmp.pem
10+
rm tmp.pem
11+
openssl req -nodes -new -x509 -keyout clientkey.pem -out clientreq.pem -days 730 -config openssl.cnf
12+
openssl x509 -x509toreq -in clientreq.pem -signkey clientkey.pem -out tmp.pem
13+
openssl ca -config openssl.cnf -policy policy_anything -out clientcert.pem -infiles tmp.pem
14+

CA/managed_certificates/openssl.cnf

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
HOME = .
2+
3+
oid_section = new_oids
4+
5+
[ new_oids ]
6+
tsa_policy1 = 1.2.3.4.1
7+
tsa_policy2 = 1.2.3.4.5.6
8+
tsa_policy3 = 1.2.3.4.5.7
9+
10+
####################################################################
11+
[ ca ]
12+
default_ca = CA_default # The default ca section
13+
14+
####################################################################
15+
[ CA_default ]
16+
17+
dir = . # Where everything is kept
18+
certs = $dir/certs # Where the issued certs are kept
19+
crl_dir = $dir/crl # Where the issued crl are kept
20+
database = $dir/index.txt # database index file.
21+
#unique_subject = no # Set to 'no' to allow creation of
22+
# several certs with same subject.
23+
new_certs_dir = $dir/newcerts # default place for new certs.
24+
25+
certificate = $dir/cacert.pem # The CA certificate
26+
serial = $dir/serial # The current serial number
27+
crlnumber = $dir/crlnumber # the current crl number
28+
# must be commented out to leave a V1 CRL
29+
crl = $dir/crl.pem # The current CRL
30+
private_key = $dir/private/cakey.pem# The private key
31+
32+
x509_extensions = usr_cert # The extensions to add to the cert
33+
34+
# Comment out the following two lines for the "traditional"
35+
# (and highly broken) format.
36+
name_opt = ca_default # Subject Name options
37+
cert_opt = ca_default # Certificate field options
38+
39+
default_days = 730 # how long to certify for
40+
default_crl_days= 30 # how long before next CRL
41+
default_md = default # use public key default MD
42+
preserve = no # keep passed DN ordering
43+
44+
policy = policy_match
45+
46+
# For the CA policy
47+
[ policy_match ]
48+
countryName = supplied
49+
stateOrProvinceName = supplied
50+
organizationName = supplied
51+
commonName = supplied
52+
53+
# For the 'anything' policy
54+
# At this point in time, you must list all acceptable 'object'
55+
# types.
56+
[ policy_anything ]
57+
countryName = supplied
58+
stateOrProvinceName = supplied
59+
localityName = supplied
60+
organizationName = supplied
61+
commonName = supplied
62+
63+
####################################################################
64+
[ req ]
65+
default_bits = 4096
66+
default_keyfile = privkey.pem
67+
distinguished_name = req_distinguished_name
68+
attributes = req_attributes
69+
x509_extensions = v3_ca # The extensions to add to the self signed cert
70+
71+
# Passwords for private keys if not present they will be prompted for
72+
# input_password = secret
73+
# output_password = secret
74+
75+
# This sets a mask for permitted string types. There are several options.
76+
# default: PrintableString, T61String, BMPString.
77+
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
78+
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
79+
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
80+
# MASK:XXXX a literal mask value.
81+
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
82+
string_mask = utf8only
83+
84+
# req_extensions = v3_req # The extensions to add to a certificate request
85+
86+
[ req_attributes ]
87+
challengePassword = A challenge password
88+
challengePassword_min = 4
89+
challengePassword_max = 20
90+
91+
unstructuredName = An optional company name
92+
93+
[ usr_cert ]
94+
basicConstraints=CA:FALSE
95+
nsComment = "OpenSSL Generated Certificate"
96+
97+
subjectKeyIdentifier=hash
98+
authorityKeyIdentifier=keyid,issuer
99+
100+
[ v3_req ]
101+
basicConstraints = CA:FALSE
102+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
103+
104+
[ v3_ca ]
105+
subjectKeyIdentifier=hash
106+
authorityKeyIdentifier=keyid:always,issuer
107+
basicConstraints = critical,CA:true
108+
109+
[ crl_ext ]
110+
authorityKeyIdentifier=keyid:always
111+
112+
[ proxy_cert_ext ]
113+
basicConstraints=CA:FALSE
114+
nsComment = "OpenSSL Generated Certificate"
115+
subjectKeyIdentifier=hash
116+
authorityKeyIdentifier=keyid,issuer
117+
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
118+
119+
####################################################################
120+
[ tsa ]
121+
122+
default_tsa = tsa_config1 # the default TSA section
123+
124+
[ tsa_config1 ]
125+
dir = /etc/ssl # TSA root directory
126+
serial = $dir/tsaserial # The current serial number (mandatory)
127+
crypto_device = builtin # OpenSSL engine to use for signing
128+
signer_cert = $dir/tsacert.pem # The TSA signing certificate
129+
# (optional)
130+
certs = $dir/cacert.pem # Certificate chain to include in reply
131+
# (optional)
132+
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
133+
signer_digest = sha256 # Signing digest to use. (Optional)
134+
default_policy = tsa_policy1 # Policy if request did not specify it
135+
# (optional)
136+
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
137+
digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory)
138+
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
139+
clock_precision_digits = 0 # number of digits after dot. (optional)
140+
ordering = yes # Is ordering defined for timestamps?
141+
# (optional, default: no)
142+
tsa_name = yes # Must the TSA name be included in the reply?
143+
# (optional, default: no)
144+
ess_cert_id_chain = no # Must the ESS cert id chain be included?
145+
# (optional, default: no)
146+
ess_cert_id_alg = sha1 # algorithm to compute certificate
147+
# identifier (optional, default: sha1)

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# TOUCAN
2+
<!-- vim-markdown-toc GitLab -->
3+
4+
* [Prequisities](#prequisities)
5+
* [Installation](#installation)
6+
7+
<!-- vim-markdown-toc -->
8+
9+
## Prequisities
10+
There are two machines required for this to work.
11+
12+
1. Canary machine, with an HTTP server and SMB.
13+
2. Alert machine, has DNS and `syslog-ng` listeners.
14+
15+
The canary machine pushes logs to the alert machine, and in case of an event coming from a canary document,
16+
sends an alert to a predefined user.
17+
18+
It is recommended to use Ubuntu 19.xx as server OS.
19+
20+
## Installation
21+
[coming soon]

ansible

Submodule ansible added at b04d729

django/__init__.py

Whitespace-only changes.

django/alert_api/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from sys import path
2+
path.insert(0, '../')

django/alert_api/admin.py

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
from django.urls import reverse
2+
from django.http import Http404
3+
from django.conf.urls import url
4+
from django.contrib import admin
5+
from django.utils.html import format_html
6+
from django.shortcuts import render_to_response
7+
8+
from requests import post
9+
10+
from manage_api.admin import admin_site
11+
from manage_api.models import ExternalAPISetting
12+
13+
from alert_api.models import MimiAlertItem, SampleItem, CanaryAlertItem
14+
15+
16+
class MimiAlertItemAdmin(admin.ModelAdmin):
17+
18+
readonly_fields = ["target", "source", "stack", "accessMask",
19+
"sha1", "md5", "date", "pid", "sid", "machinename",
20+
"virustotal_actions"]
21+
list_display = ['date', 'machinename', 'target', 'source']
22+
list_filter = ['machinename', 'source']
23+
24+
def has_add_permission(self, request, obj=None):
25+
return False
26+
27+
def has_delete_permission(self, request, obj=None):
28+
return False
29+
30+
def has_change_permission(self, request, obj=None):
31+
return False
32+
33+
def get_urls(self):
34+
urls = super().get_urls()
35+
custom_urls = [
36+
url(
37+
r'^(?P<md5>.+)/check/$',
38+
self.admin_site.admin_view(self.process_md5),
39+
name='process-md5',
40+
),
41+
url(
42+
r'^(?P<sha1>.+)/check/$',
43+
self.admin_site.admin_view(self.process_sha1),
44+
name='process-sha1',
45+
),
46+
]
47+
return custom_urls + urls
48+
49+
def process_md5(self, request, md5, *args, **kwargs):
50+
return self.process_action(
51+
request=request,
52+
hash=md5,
53+
action_title='MD5',
54+
)
55+
56+
def process_sha1(self, request, sha1, *args, **kwargs):
57+
return self.process_action(
58+
request=request,
59+
hash=sha1,
60+
action_title='SHA1',
61+
)
62+
63+
def virustotal_actions(self, obj):
64+
return format_html(
65+
'<a class="button" href="{}">MD5</a>&nbsp;'
66+
'<a class="button" href="{}">SHA1</a>',
67+
reverse('admin:process-md5', args=[obj.md5]),
68+
reverse('admin:process-sha1', args=[obj.sha1]),
69+
)
70+
71+
def process_action(self, request, hash, action_title):
72+
73+
args = {}
74+
args.update(request)
75+
76+
item = ExternalAPISetting.get_api_item_by_name('virustotal')
77+
vt_key = item.api_key
78+
79+
params = {'apikey': vt_key, 'resource': hash}
80+
response = post('https://www.virustotal.com/vtapi/v2/file/rescan',
81+
params=params)
82+
83+
if response.status_code != 200:
84+
raise Http404('Could not obtain report, invalid response '
85+
'from remote site.')
86+
87+
response = response.json()
88+
report = response.get('permalink', False)
89+
90+
if not report:
91+
raise Http404({'error': f"no report for {hash}"})
92+
93+
response = post('https://www.virustotal.com/vtapi/v2/file/report',
94+
params=params)
95+
96+
# Sort dictionary by value: True
97+
response_dict = sorted(response.json()['scans'].items(),
98+
key=lambda x: x[1]['detected'], reverse=True)
99+
args['contents'] = response_dict
100+
args['hash'] = hash
101+
args['report'] = report
102+
103+
return render_to_response('virustotal_report_template.html', args)
104+
105+
106+
class SampleItemAdmin(admin.ModelAdmin):
107+
108+
list_display = ['md5', 'related_alert_items']
109+
fields = ['md5', 'related_alert_items', 'download_sample']
110+
111+
def has_add_permission(self, request, obj=None):
112+
return False
113+
114+
def has_delete_permission(self, request, obj=None):
115+
return True
116+
117+
def has_change_permission(self, request, obj=None):
118+
return False
119+
120+
def related_alert_items(self, obj):
121+
items = SampleItem.get_related_alert_items_as_url(obj.md5)
122+
return format_html(items)
123+
124+
def download_sample(self, obj):
125+
return format_html(
126+
'<a class="button" href="{}">Sample</a>',
127+
reverse('download-sample', args=[obj.md5]))
128+
129+
130+
class CanaryAlertItemAdmin(admin.ModelAdmin):
131+
132+
list_display = ['date', 'identifier', 'canary_type', 'location']
133+
list_filter = ['identifier']
134+
135+
def has_add_permission(self, request, obj=None):
136+
return False
137+
138+
def has_delete_permission(self, request, obj=None):
139+
return True
140+
141+
def has_change_permission(self, request, obj=None):
142+
return False
143+
144+
145+
admin_site.register(SampleItem, SampleItemAdmin)
146+
admin_site.register(MimiAlertItem, MimiAlertItemAdmin)
147+
admin_site.register(CanaryAlertItem, CanaryAlertItemAdmin)

django/alert_api/apps.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class SysmonapiConfig(AppConfig):
5+
name = 'sysmonAPI'

0 commit comments

Comments
 (0)